From 2a69ecd89fa336e6bf1408f1214a820d5090ce65 Mon Sep 17 00:00:00 2001 From: Yongjin Choi Date: Mon, 20 Apr 2015 09:06:44 +0900 Subject: [PATCH] TAJO-1556: fix a bug in buildProjectedInsert --- .../java/org/apache/tajo/catalog/Schema.java | 12 +++++++--- .../engine/planner/TestLogicalPlanner.java | 23 +++++++++++++++++-- .../org/apache/tajo/plan/LogicalPlanner.java | 9 ++++---- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Schema.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Schema.java index ed2cd2c651..baa7a7d598 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Schema.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/Schema.java @@ -157,13 +157,19 @@ public Column getColumn(int id) { } public Column getColumn(Column column) { + int idx = getIndex(column); + return idx >= 0 ? fields.get(idx) : null; + } + + public int getIndex(Column column) { if (!contains(column)) { - return null; + return -1; } + if (column.hasQualifier()) { - return fields.get(fieldsByQualifiedName.get(column.getQualifiedName())); + return fieldsByQualifiedName.get(column.getQualifiedName()); } else { - return fields.get(fieldsByName.get(column.getSimpleName()).get(0)); + return fieldsByName.get(column.getSimpleName()).get(0); } } diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java b/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java index 0b59bc7a35..af0aa6aebc 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/planner/TestLogicalPlanner.java @@ -1106,7 +1106,7 @@ public void testJsonSerDerObject(LogicalNode rootNode) { // Table descriptions // // employee (name text, empid int4, deptname text) - // dept (deptname text, nameger text) + // dept (deptname text, manager text) // score (deptname text, score inet4) static final String [] insertStatements = { @@ -1115,7 +1115,8 @@ public void testJsonSerDerObject(LogicalNode rootNode) { "insert into employee (name, deptname) select * from dept", // 2 "insert into location '/tmp/data' select name, empid from employee", // 3 "insert overwrite into employee (name, deptname) select * from dept", // 4 - "insert overwrite into LOCATION '/tmp/data' select * from dept" // 5 + "insert overwrite into LOCATION '/tmp/data' select * from dept", // 5 + "insert into employee (deptname, name) select deptname, manager from dept" // 6 }; @Test @@ -1198,6 +1199,24 @@ public final void testInsertInto5() throws PlanningException { assertTrue(insertNode.hasPath()); } + @Test + public final void testInsertInto6() throws PlanningException { + QueryContext qc = new QueryContext(util.getConfiguration(), session); + + Expr expr = sqlAnalyzer.parse(insertStatements[6]); + LogicalPlan plan = planner.createPlan(qc, expr); + assertEquals(1, plan.getQueryBlocks().size()); + InsertNode insertNode = getInsertNode(plan); + + ProjectionNode subquery = insertNode.getChild(); + Target[] targets = subquery.getTargets(); + // targets MUST be manager, NULL as empid, deptname + assertEquals(targets[0].getNamedColumn().getQualifiedName(), "default.dept.manager"); + assertEquals(targets[1].getAlias(), "empid"); + assertEquals(targets[1].getEvalTree().getType(), EvalType.CONST); + assertEquals(targets[2].getNamedColumn().getQualifiedName(), "default.dept.deptname"); + } + private static InsertNode getInsertNode(LogicalPlan plan) { LogicalRootNode root = plan.getRootBlock().getRoot(); assertEquals(NodeType.INSERT, root.getChild().getType()); diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java index d1c1a150e5..e0b4f7e86f 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java @@ -1524,7 +1524,7 @@ private InsertNode buildInsertIntoTablePlan(PlanContext context, InsertNode inse // we use only a sequence of preceding columns of target table's schema // as target columns. // - // For example, consider a target table and an 'insert into' query are give as follows: + // For example, consider a target table and an 'insert into' query are given as follows: // // CREATE TABLE TB1 (col1 int, col2 int, col3 long); // || || @@ -1586,11 +1586,12 @@ private void buildProjectedInsert(PlanContext context, InsertNode insertNode) { // Modifying projected columns by adding NULL constants // It is because that table appender does not support target columns to be written. List targets = TUtil.newList(); - for (int i = 0, j = 0; i < tableSchema.size(); i++) { + for (int i = 0; i < tableSchema.size(); i++) { Column column = tableSchema.getColumn(i); - if(targetColumns.contains(column) && j < projectionNode.getTargets().length) { - targets.add(projectionNode.getTargets()[j++]); + int idxInProjectionNode = targetColumns.getIndex(column); + if (idxInProjectionNode >= 0 && idxInProjectionNode < projectionNode.getTargets().length) { + targets.add(projectionNode.getTargets()[idxInProjectionNode]); } else { targets.add(new Target(new ConstEval(NullDatum.get()), column.getSimpleName())); }