Repository: tajo Updated Branches: refs/heads/master 8824ba559 -> 8b5361a06
TAJO-728: Supports expression IN statement. (hyunsik) Project: http://git-wip-us.apache.org/repos/asf/tajo/repo Commit: http://git-wip-us.apache.org/repos/asf/tajo/commit/8b5361a0 Tree: http://git-wip-us.apache.org/repos/asf/tajo/tree/8b5361a0 Diff: http://git-wip-us.apache.org/repos/asf/tajo/diff/8b5361a0 Branch: refs/heads/master Commit: 8b5361a0699406b684bc755bc86957d92a08d6c0 Parents: 8824ba5 Author: Hyunsik Choi <[email protected]> Authored: Tue Apr 8 17:13:36 2014 +0900 Committer: Hyunsik Choi <[email protected]> Committed: Tue Apr 8 17:13:36 2014 +0900 ---------------------------------------------------------------------- CHANGES.txt | 2 ++ .../org/apache/tajo/engine/parser/SQLParser.g4 | 2 +- .../apache/tajo/engine/eval/EvalTreeUtil.java | 9 ++++++++ .../apache/tajo/engine/parser/SQLAnalyzer.java | 12 +++++------ .../tajo/engine/planner/ExprAnnotator.java | 9 +++++--- .../apache/tajo/engine/eval/TestPredicates.java | 22 +++++++++++++++++++- 6 files changed, 45 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tajo/blob/8b5361a0/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index cd3a189..9412ae4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -143,6 +143,8 @@ Release 0.8.0 - unreleased IMPROVEMENTS + TAJO-728: Supports expression IN statement. (hyunsik) + TAJO-725: Broadcast JOIN should supports multiple tables. (hyoungjunkim via jaehwa) TAJO-735: Remove multiple SLF4J bindings message. (hyoungjunkim via hyunsik) http://git-wip-us.apache.org/repos/asf/tajo/blob/8b5361a0/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 ---------------------------------------------------------------------- diff --git a/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 b/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 index 825969a..f25b41f 100644 --- a/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 +++ b/tajo-core/tajo-core-backend/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 @@ -1192,7 +1192,7 @@ in_predicate_value ; in_value_list - : row_value_expression ( COMMA row_value_expression )* + : row_value_predicand ( COMMA row_value_predicand )* ; /* http://git-wip-us.apache.org/repos/asf/tajo/blob/8b5361a0/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/eval/EvalTreeUtil.java ---------------------------------------------------------------------- diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/eval/EvalTreeUtil.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/eval/EvalTreeUtil.java index 1e2298c..0966ee0 100644 --- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/eval/EvalTreeUtil.java +++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/eval/EvalTreeUtil.java @@ -23,6 +23,7 @@ import com.google.common.collect.Sets; import org.apache.tajo.catalog.Column; import org.apache.tajo.catalog.Schema; import org.apache.tajo.common.TajoDataTypes.DataType; +import org.apache.tajo.datum.Datum; import org.apache.tajo.engine.planner.Target; import org.apache.tajo.exception.InternalException; import org.apache.tajo.util.TUtil; @@ -324,4 +325,12 @@ public class EvalTreeUtil { return evalNode; } } + + public static boolean checkIfCanBeConstant(EvalNode evalNode) { + return findUniqueColumns(evalNode).size() == 0 && findDistinctAggFunction(evalNode).size() == 0; + } + + public static Datum evaluateImmediately(EvalNode evalNode) { + return evalNode.eval(null, null); + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/8b5361a0/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java ---------------------------------------------------------------------- diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java index 35ad4c2..3edf768 100644 --- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java +++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java @@ -751,10 +751,10 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> { @Override public Expr visitIn_predicate_value(SQLParser.In_predicate_valueContext ctx) { if (checkIfExist(ctx.in_value_list())) { - int size = ctx.in_value_list().row_value_expression().size(); - Expr[] exprs = new Expr[size]; + int size = ctx.in_value_list().row_value_predicand().size(); + Expr [] exprs = new Expr[size]; for (int i = 0; i < size; i++) { - exprs[i] = visitRow_value_expression(ctx.in_value_list().row_value_expression(i)); + exprs[i] = visitRow_value_predicand(ctx.in_value_list().row_value_predicand(i)); } return new ValueListExpr(exprs); } else { @@ -1097,10 +1097,10 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> { List<ListPartitionSpecifier> specifiers = Lists.newArrayList(); for (List_value_partitionContext listValuePartition : partitions) { - int size = listValuePartition.in_value_list().row_value_expression().size(); - Expr[] exprs = new Expr[size]; + int size = listValuePartition.in_value_list().row_value_predicand().size(); + Expr [] exprs = new Expr[size]; for (int i = 0; i < size; i++) { - exprs[i] = visitRow_value_expression(listValuePartition.in_value_list().row_value_expression(i)); + exprs[i] = visitRow_value_predicand(listValuePartition.in_value_list().row_value_predicand(i)); } specifiers.add(new ListPartitionSpecifier(listValuePartition.partition_name().getText(), new ValueListExpr(exprs))); http://git-wip-us.apache.org/repos/asf/tajo/blob/8b5361a0/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExprAnnotator.java ---------------------------------------------------------------------- diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExprAnnotator.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExprAnnotator.java index 3d09597..1b57b98 100644 --- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExprAnnotator.java +++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/ExprAnnotator.java @@ -221,10 +221,13 @@ public class ExprAnnotator extends BaseAlgebraVisitor<ExprAnnotator.Context, Eva @Override public EvalNode visitValueListExpr(Context ctx, Stack<Expr> stack, ValueListExpr expr) throws PlanningException { Datum[] values = new Datum[expr.getValues().length]; - ConstEval [] constEvals = new ConstEval[expr.getValues().length]; + EvalNode [] evalNodes = new EvalNode[expr.getValues().length]; for (int i = 0; i < expr.getValues().length; i++) { - constEvals[i] = (ConstEval) visit(ctx, stack, expr.getValues()[i]); - values[i] = constEvals[i].getValue(); + evalNodes[i] = visit(ctx, stack, expr.getValues()[i]); + if (!EvalTreeUtil.checkIfCanBeConstant(evalNodes[i])) { + throw new PlanningException("Non constant values cannot be included in IN PREDICATE."); + } + values[i] = EvalTreeUtil.evaluateImmediately(evalNodes[i]); } return new RowConstantEval(values); } http://git-wip-us.apache.org/repos/asf/tajo/blob/8b5361a0/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/eval/TestPredicates.java ---------------------------------------------------------------------- diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/eval/TestPredicates.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/eval/TestPredicates.java index db5cfc7..7811e69 100644 --- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/eval/TestPredicates.java +++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/eval/TestPredicates.java @@ -277,7 +277,7 @@ public class TestPredicates extends ExprTestBase { ////////////////////////////////////////////////////////////////// @Test - public void testInPredicate() throws IOException { + public void testInPredicateWithConstant() throws IOException { Schema schema2 = new Schema(); schema2.addColumn("col1", TEXT); schema2.addColumn("col2", TEXT); @@ -301,6 +301,26 @@ public class TestPredicates extends ExprTestBase { new String[]{"t"}); } + @Test + public void testInPredicateWithSimpleExprs() throws IOException { + Schema schema2 = new Schema(); + schema2.addColumn("col1", TEXT); + schema2.addColumn("col2", INT4); + schema2.addColumn("col3", TEXT); + + testEval(schema2, "table1", "abc,2,3", "select col1 in ('a'||'b'||'c'), col2 in (1 + 1, 2 * 10, 2003) from table1", + new String[]{"t","t"}); + + testEval(schema2, "table1", "abc,2,3", "select col1 in ('a'||'b'), col2 in ('1'::int, '2'::int, 3) from table1", + new String[]{"f","t"}); + + testEval(schema2, + "table1", + "abc,,3", + "select col1 in (reverse('cba')), (col2 in ('1'::int, '2'::int, 3)) is null from table1", + new String[]{"t","t"}); + } + ////////////////////////////////////////////////////////////////// // Null Predicate //////////////////////////////////////////////////////////////////
