You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tajo.apache.org by hy...@apache.org on 2013/07/29 06:03:31 UTC
[02/13] TAJO-87: Integration of tajo algebra module and SQL parser
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/00c3ee2b/tajo-frontend/tajo-frontend-sql/src/main/java/org/apache/tajo/frontend/sql/SQLAnalyzer.java
----------------------------------------------------------------------
diff --git a/tajo-frontend/tajo-frontend-sql/src/main/java/org/apache/tajo/frontend/sql/SQLAnalyzer.java b/tajo-frontend/tajo-frontend-sql/src/main/java/org/apache/tajo/frontend/sql/SQLAnalyzer.java
deleted file mode 100644
index 9157d44..0000000
--- a/tajo-frontend/tajo-frontend-sql/src/main/java/org/apache/tajo/frontend/sql/SQLAnalyzer.java
+++ /dev/null
@@ -1,932 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.frontend.sql;
-
-import com.google.common.base.Preconditions;
-import org.antlr.runtime.ANTLRStringStream;
-import org.antlr.runtime.CommonTokenStream;
-import org.antlr.runtime.RecognitionException;
-import org.antlr.runtime.tree.CommonTree;
-import org.antlr.runtime.tree.Tree;
-import org.apache.tajo.algebra.*;
-import org.apache.tajo.algebra.Aggregation.GroupElement;
-import org.apache.tajo.algebra.Aggregation.GroupType;
-import org.apache.tajo.algebra.LiteralExpr.LiteralType;
-import org.apache.tajo.algebra.Sort.SortSpec;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.apache.tajo.algebra.CreateTable.ColumnDefinition;
-
-public class SQLAnalyzer {
-
- public Expr parse(String sql) throws SQLSyntaxError {
- ParsingContext context = new ParsingContext(sql);
- CommonTree tree = parseSQL(sql);
- return transform(context, tree);
- }
-
- private static class ParsingContext {
- private String rawQuery;
- public ParsingContext(String sql) {
- this.rawQuery = sql;
- }
- }
-
- public static CommonTree parseSQL(String sql) {
- ANTLRStringStream input = new ANTLRStringStream(sql);
- SQLLexer lexer = new SQLLexer(input);
- CommonTokenStream tokens = new CommonTokenStream(lexer);
- SQLParser parser = new SQLParser(tokens);
-
- CommonTree ast;
- try {
- ast = ((CommonTree) parser.statement().getTree());
- } catch (RecognitionException e) {
- throw new SQLParseError(e.getMessage());
- }
-
- return ast;
- }
-
- Expr transform(ParsingContext context, CommonTree ast) throws SQLSyntaxError {
- switch (ast.getType()) {
- case SQLParser.SELECT:
- return parseSelectStatement(context, ast);
-
- case SQLParser.UNION:
- case SQLParser.EXCEPT:
- case SQLParser.INTERSECT:
- return parseSetStatement(context, ast);
-
- case SQLParser.INSERT:
-
- case SQLParser.CREATE_INDEX:
-
- case SQLParser.CREATE_TABLE:
- return parseCreateStatement(context, ast);
-
- case SQLParser.DROP_TABLE:
-
- default:
- return null;
- }
- }
-
- /**
- * t=table ASSIGN select_stmt -> ^(CREATE_TABLE $t select_stmt)
- * | CREATE TABLE t=table AS select_stmt -> ^(CREATE_TABLE $t select_stmt)
- *
- * @param ast
- * @return
- */
- private CreateTable parseCreateStatement(final ParsingContext context,
- final CommonTree ast) throws SQLSyntaxError {
- CreateTable createTable;
-
- int idx = 0;
- CommonTree node;
- String tableName = ast.getChild(idx).getText();
- idx++;
-
- boolean external = false;
- ColumnDefinition [] tableElements = null;
- String storeType = null;
- Map<String, String> params = null;
- Expr nestedAlgebra = null;
- String location = null;
- while(idx < ast.getChildCount()) {
- node = (CommonTree) ast.getChild(idx);
- switch (node.getType()) {
- case SQLParser.EXTERNAL:
- external = true;
- break;
-
- case SQLParser.TABLE_DEF:
- tableElements = parseTableElementList(node);
- break;
-
- case SQLParser.USING:
- storeType = node.getChild(0).getText();
- break;
-
- case SQLParser.PARAMS:
- params = parseParams(node);
- break;
-
- case SQLParser.AS:
- nestedAlgebra = parseSelectStatement(context, node.getChild(0));
- break;
-
- case SQLParser.LOCATION:
- location = node.getChild(0).getText();
- break;
-
- default:
- throw new SQLSyntaxError(context.rawQuery, "ERROR: not yet supported query");
- }
- idx++;
- }
-
- if (nestedAlgebra != null) {
- createTable = new CreateTable(tableName, nestedAlgebra);
- } else {
- createTable = new CreateTable(tableName);
- if (external) {
- if (location != null) {
- createTable.setLocation(location);
- }
- }
- }
-
- if (tableElements != null) {
- createTable.setTableElements(tableElements);
- }
-
- if (storeType != null) {
- createTable.setStorageType(storeType);
- if (params != null) {
- createTable.setParams(params);
- }
- }
-
- // constraints
- if (external && location == null) {
- throw new SQLSyntaxError(context.rawQuery,
- "CREATE EXTERNAL TABLE statement requires LOCATION clause.");
- }
- if (!external && location != null) {
- throw new SQLSyntaxError(context.rawQuery,
- "LOCATION clause can be only used in CREATE EXTERNAL TABLE statement.");
- }
- if (tableElements == null && location != null) {
- throw new SQLSyntaxError(context.rawQuery,
- "LOCATION clause requires a schema definition.");
- }
-
- return createTable;
- }
-
- private ColumnDefinition [] parseTableElementList(final CommonTree ast) {
- ColumnDefinition [] tableDef = new ColumnDefinition[ast.getChildCount()];
- for (int i = 0; i < ast.getChildCount(); i++) {
- tableDef[i] = new ColumnDefinition(ast.getChild(i).getChild(0).getText(),
- ast.getChild(i).getChild(1).getText());;
- }
-
- return tableDef;
- }
-
- /**
- * Should be given Params Node
- *
- * EBNF: WITH LEFT_PAREN param (COMMA param)* RIGHT_PAREN
- * AST: ^(PARAMS param+)
- *
- * @param ast
- * @return
- */
- private static Map<String,String> parseParams(final CommonTree ast) {
- Map<String, String> params = new HashMap<String, String>();
-
- Tree child;
- for (int i = 0; i < ast.getChildCount(); i++) {
- child = ast.getChild(i);
- params.put(child.getChild(0).getText(), child.getChild(1).getText());
- }
- return params;
- }
-
- private Expr parseSelectStatement(final ParsingContext context, final Tree ast) throws SQLSyntaxError {
- CommonTree node;
- QueryBlock block = new QueryBlock();
- for (int cur = 0; cur < ast.getChildCount(); cur++) {
- node = (CommonTree) ast.getChild(cur);
-
- switch (node.getType()) {
- case SQLParser.FROM:
- Expr fromClause = parseFromClause(context, node);
- block.setTableExpression(fromClause);
- break;
-
- case SQLParser.SET_QUALIFIER:
- if (parseSetQualifier(node)) {
- block.setDistinct();
- }
- break;
-
- case SQLParser.SEL_LIST:
- Projection projection = parseSelectList(context, node);
- block.setProjection(projection);
- break;
-
- case SQLParser.WHERE:
- block.setSearchCondition(parseWhereClause(context, node));
- break;
-
- case SQLParser.GROUP_BY:
- Aggregation aggregation = parseGroupByClause(node);
- block.setAggregation(aggregation);
- break;
-
- case SQLParser.HAVING:
- Expr expr = parseHavingClause(context, node);
- block.setHavingCondition(expr);
- break;
-
- case SQLParser.ORDER_BY:
- SortSpec [] sortSpecs = parseSortSpecifiers(node.getChild(0));
- block.setSort(new Sort(sortSpecs));
- break;
-
- case SQLParser.LIMIT:
- block.setLimit(parseLimitClause(context, node));
- break;
-
- default:
- }
- }
-
- return transformQueryBlock(context, block);
- }
-
- /**
- * There is an algebraic order of a QueryBlock.
- * Relation (or Join) -> Selection -> Aggregation -> Sort -> Limit
- *
- * @param context
- * @param block
- * @return
- */
- private Expr transformQueryBlock(ParsingContext context, QueryBlock block) throws SQLSyntaxError {
- Expr current = null;
-
- // Selection
- if (block.hasTableExpression()) {
- current = block.getTableExpression();
- }
-
- if (block.hasSearchCondition()) {
- if (current == null) {
- throw new SQLSyntaxError(context.rawQuery,
- "No TableExpression, but there exists search condition");
- }
- Selection selection = new Selection(current, block.getSearchCondition());
- current = selection;
- }
-
- // Aggregation
- Aggregation aggregation = null;
- if (block.hasAggregation()) {
- if (current == null) {
- throw new SQLSyntaxError(context.rawQuery,
- "No TableExpression, but there exists a group-by clause");
- }
- aggregation = block.getAggregation();
-
- if (block.hasAggregation()) {
- aggregation.setHavingCondition(block.getHavingCondition());
- }
-
- aggregation.setChild(current);
- current = aggregation;
- }
-
- if (block.hasSort()) {
- if (current == null) {
- throw new SQLSyntaxError(context.rawQuery,
- "No TableExpression, but there exists a sort clause");
- }
- Sort sort = block.getSort();
- sort.setChild(current);
- current = sort;
- }
-
- if (block.hasLimit()) {
- if (current == null) {
- throw new SQLSyntaxError(context.rawQuery,
- "No TableExpression, but there exists a limit clause");
- }
- Limit limit = block.getLimit();
- limit.setChild(current);
- current = limit;
- }
-
- Projection projection = block.getProjection();
- if (block.hasAggregation()) {
- aggregation.setTargets(projection.getTargets());
- } else {
- if (block.isDistinct()) {
- projection.setDistinct();
- }
- if (current != null) {
- projection.setChild(current);
- }
- current = projection;
- }
-
- return current;
- }
-
- private Expr parseSetStatement(final ParsingContext context,
- final CommonTree ast) throws SQLSyntaxError {
- Expr left;
- Expr right;
-
- ExprType type = tokenToExprType(ast.getType());
-
- int idx = 0;
- left = transform(context, (CommonTree) ast.getChild(idx));
- idx++;
- int nodeType = ast.getChild(idx).getType();
- boolean distinct = true; // distinct is default in ANSI SQL standards
- if (nodeType == SQLParser.ALL) {
- distinct = true;
- idx++;
- } else if (nodeType == SQLParser.DISTINCT) {
- distinct = false;
- idx++;
- }
- right = transform(context, (CommonTree) ast.getChild(idx));
- return new SetOperation(type, left, right, distinct);
- }
-
- /**
- * @return true if SELECT DISTINCT. Otherwise, it will be false.
- */
- private boolean parseSetQualifier(final CommonTree ast) {
- int idx = 0;
-
- if (ast.getChild(idx).getType() == SQLParser.DISTINCT) {
- return true;
- } else {
- return false;
- }
- }
-
- private Expr parseHavingClause(final ParsingContext context, final CommonTree ast)
- throws SQLSyntaxError {
- return createExpression(context, ast.getChild(0));
- }
-
- private Limit parseLimitClause(final ParsingContext context, final CommonTree ast)
- throws SQLSyntaxError {
- Expr expr = createExpression(context, ast.getChild(0));
-
- if (expr instanceof LiteralExpr) {
- Limit limitClause = new Limit(expr);
- return limitClause;
- }
-
- throw new SQLSyntaxError(context.rawQuery, "LIMIT clause cannot have the parameter "
- + expr);
- }
-
- /**
- * Should be given SortSpecifiers Node
- *
- * EBNF: sort_specifier (COMMA sort_specifier)* -> sort_specifier+
- *
- * @param ast
- */
- private SortSpec[] parseSortSpecifiers(final Tree ast) {
- int numSortKeys = ast.getChildCount();
- SortSpec[] sortSpecs = new SortSpec[numSortKeys];
- CommonTree node;
- ColumnReferenceExpr column;
-
- // Each child has the following EBNF and AST:
- // EBNF: fn=fieldName a=order_specification? o=null_ordering?
- // AST: ^(SORT_KEY $fn $a? $o?)
- for (int i = 0; i < numSortKeys; i++) {
- node = (CommonTree) ast.getChild(i);
- column = checkAndGetColumnByAST(node.getChild(0));
- sortSpecs[i] = new SortSpec(column);
-
- if (node.getChildCount() > 1) {
- Tree child;
- for (int j = 1; j < node.getChildCount(); j++) {
- child = node.getChild(j);
-
- // AST: ^(ORDER ASC) | ^(ORDER DESC)
- if (child.getType() == SQLParser.ORDER) {
- if (child.getChild(0).getType() == SQLParser.DESC) {
- sortSpecs[i].setDescending();
- }
- } else if (child.getType() == SQLParser.NULL_ORDER) {
- // AST: ^(NULL_ORDER FIRST) | ^(NULL_ORDER LAST)
- if (child.getChild(0).getType() == SQLParser.FIRST) {
- sortSpecs[i].setNullFirst();
- }
- }
- }
- }
- }
-
- return sortSpecs;
- }
-
- /**
- * See 'groupby_clause' rule in SQL.g
- *
- * @param ast
- */
- private Aggregation parseGroupByClause(final CommonTree ast) {
- int idx = 0;
- Aggregation clause = new Aggregation();
- if (ast.getChild(idx).getType() == SQLParser.EMPTY_GROUPING_SET) {
-
- } else {
- // the remain ones are grouping fields.
- Tree group;
- List<ColumnReferenceExpr> columnRefs = new ArrayList<ColumnReferenceExpr>();
- ColumnReferenceExpr[] columns;
- ColumnReferenceExpr column;
- List<GroupElement> groups = new ArrayList<GroupElement>();
- for (; idx < ast.getChildCount(); idx++) {
- group = ast.getChild(idx);
- switch (group.getType()) {
- case SQLParser.CUBE:
- columns = parseColumnReferences((CommonTree) group);
- GroupElement cube = new GroupElement(GroupType.CUBE, columns);
- groups.add(cube);
- break;
-
- case SQLParser.ROLLUP:
- columns = parseColumnReferences((CommonTree) group);
- GroupElement rollup = new GroupElement(GroupType.ROLLUP, columns);
- groups.add(rollup);
- break;
-
- case SQLParser.FIELD_NAME:
- column = checkAndGetColumnByAST(group);
- columnRefs.add(column);
- break;
- }
- }
-
- if (columnRefs.size() > 0) {
- ColumnReferenceExpr[] groupingFields = columnRefs.toArray(new ColumnReferenceExpr[columnRefs.size()]);
- GroupElement g = new GroupElement(GroupType.GROUPBY, groupingFields);
- groups.add(g);
- }
-
- clause.setGroups(groups.toArray(new GroupElement[groups.size()]));
- }
- return clause;
- }
-
-
-
- /**
- * It parses the below EBNF.
- * <pre>
- * column_reference
- * : fieldName (COMMA fieldName)* -> fieldName+
- * ;
- * </pre>
- * @param parent
- * @return
- */
- private ColumnReferenceExpr[] parseColumnReferences(final CommonTree parent) {
- ColumnReferenceExpr[] columns = new ColumnReferenceExpr[parent.getChildCount()];
-
- for (int i = 0; i < columns.length; i++) {
- columns[i] = checkAndGetColumnByAST(parent.getChild(i));
- }
-
- return columns;
- }
-
- private Expr parseWhereClause(final ParsingContext context, final CommonTree ast)
- throws SQLSyntaxError {
- return createExpression(context, ast.getChild(0));
- }
-
- /**
- * This method parses the select list of a query statement.
- * <pre>
- * EBNF:
- *
- * selectList
- * : MULTIPLY -> ^(SEL_LIST ALL)
- * | derivedColumn (COMMA derivedColumn)* -> ^(SEL_LIST derivedColumn+)
- * ;
- *
- * derivedColumn
- * : bool_expr asClause? -> ^(COLUMN bool_expr asClause?)
- * ;
- *
- * @param ast
- */
- private Projection parseSelectList(ParsingContext context, final CommonTree ast)
- throws SQLSyntaxError {
- Projection projection = new Projection();
- if (ast.getChild(0).getType() == SQLParser.ALL) {
- projection.setAll();
- } else {
- CommonTree node;
- int numTargets = ast.getChildCount();
- Target [] targets = new Target[numTargets];
- Expr evalTree;
- String alias;
-
- // the final one for each target is the alias
- // EBNF: bool_expr AS? fieldName
- for (int i = 0; i < ast.getChildCount(); i++) {
- node = (CommonTree) ast.getChild(i);
- evalTree = createExpression(context, node);
- targets[i] = new Target(evalTree);
- if (node.getChildCount() > 1) {
- alias = node.getChild(node.getChildCount() - 1).getChild(0).getText();
- targets[i].setAlias(alias);
- }
- }
- projection.setTargets(targets);
- }
-
- return projection;
- }
-
- /**
- * EBNF: table_list -> tableRef (COMMA tableRef)
- * @param ast
- */
- private Expr parseFromClause(ParsingContext context, final CommonTree ast) throws SQLSyntaxError {
- Expr previous = null;
- CommonTree node;
- for (int i = 0; i < ast.getChildCount(); i++) {
- node = (CommonTree) ast.getChild(i);
-
- switch (node.getType()) {
-
- case SQLParser.TABLE:
- // table (AS ID)?
- // 0 - a table name, 1 - table alias
- if (previous != null) {
- Expr inner = parseTable(node);
- Join newJoin = new Join(JoinType.INNER);
- newJoin.setLeft(previous);
- newJoin.setRight(inner);
- previous = newJoin;
- } else {
- previous = parseTable(node);
- }
- break;
- case SQLParser.JOIN:
- Join newJoin = parseExplicitJoinClause(context, node);
- newJoin.setLeft(previous);
- previous = newJoin;
- break;
-
- case SQLParser.SUBQUERY:
- Expr nestedAlgebra = parseSelectStatement(context, node.getChild(0));
- String alias = node.getChild(1).getText();
- previous = new TableSubQuery(alias, nestedAlgebra);
- break;
-
- default:
- throw new SQLSyntaxError(context.rawQuery, "Wrong From Clause");
- } // switch
- } // for each derievedTable
-
- return previous;
- }
-
- private Relation parseTable(final CommonTree tableAST) {
- String tableName = tableAST.getChild(0).getText();
- Relation table = new Relation(tableName);
-
- if (tableAST.getChildCount() > 1) {
- table.setAlias(tableAST.getChild(1).getText());
- }
-
- return table;
- }
-
- private Join parseExplicitJoinClause(ParsingContext ctx, final CommonTree ast)
- throws SQLSyntaxError {
-
- int idx = 0;
- int parsedJoinType = ast.getChild(idx).getType();
-
- Join joinClause;
-
- switch (parsedJoinType) {
- case SQLParser.CROSS:
- case SQLParser.UNION:
- joinClause = parseCrossAndUnionJoin(ast);
- break;
-
- case SQLParser.NATURAL:
- joinClause = parseNaturalJoinClause(ctx, ast);
- break;
-
- case SQLParser.INNER:
- case SQLParser.OUTER:
- joinClause = parseQualifiedJoinClause(ctx, ast, 0);
- break;
-
- default: // default join (without join type) is inner join
- joinClause = parseQualifiedJoinClause(ctx, ast, 0);
- }
-
- return joinClause;
- }
-
- private Join parseNaturalJoinClause(ParsingContext ctx, Tree ast) throws SQLSyntaxError {
- Join join = parseQualifiedJoinClause(ctx, ast, 1);
- join.setNatural();
- return join;
- }
-
- private Join parseQualifiedJoinClause(ParsingContext context, final Tree ast, final int idx)
- throws SQLSyntaxError {
- int childIdx = idx;
- Join join = null;
-
- if (ast.getChild(childIdx).getType() == SQLParser.TABLE) { // default join
- join = new Join(JoinType.INNER);
- join.setRight(parseTable((CommonTree) ast.getChild(childIdx)));
-
- } else {
-
- if (ast.getChild(childIdx).getType() == SQLParser.INNER) {
- join = new Join(JoinType.INNER);
-
- } else if (ast.getChild(childIdx).getType() == SQLParser.OUTER) {
-
- switch (ast.getChild(childIdx).getChild(0).getType()) {
- case SQLParser.LEFT:
- join = new Join(JoinType.LEFT_OUTER);
- break;
- case SQLParser.RIGHT:
- join = new Join(JoinType.RIGHT_OUTER);
- break;
- case SQLParser.FULL:
- join = new Join(JoinType.FULL_OUTER);
- break;
- default:
- throw new SQLSyntaxError(context.rawQuery, "Unknown Join Type");
- }
- }
-
- childIdx++;
- join.setRight(parseTable((CommonTree) ast.getChild(childIdx)));
- }
-
- childIdx++;
-
- if (ast.getChildCount() > childIdx) {
- CommonTree joinQual = (CommonTree) ast.getChild(childIdx);
-
- if (joinQual.getType() == SQLParser.ON) {
- Expr joinCond = parseJoinCondition(context, joinQual);
- join.setQual(joinCond);
-
- } else if (joinQual.getType() == SQLParser.USING) {
- ColumnReferenceExpr[] joinColumns = parseJoinColumns(joinQual);
- join.setJoinColumns(joinColumns);
- }
- }
-
- return join;
- }
-
- private Join parseCrossAndUnionJoin(Tree ast) {
- JoinType joinType;
-
- if (ast.getChild(0).getType() == SQLParser.CROSS) {
- joinType = JoinType.CROSS_JOIN;
- } else if (ast.getChild(0).getType() == SQLParser.UNION) {
- joinType = JoinType.UNION;
- } else {
- throw new IllegalStateException("Neither the AST has cross join or union join:\n"
- + ast.toStringTree());
- }
-
- Join join = new Join(joinType);
- Preconditions.checkState(ast.getChild(1).getType() == SQLParser.TABLE);
- join.setRight(parseTable((CommonTree) ast.getChild(1)));
-
- return join;
- }
-
- private ColumnReferenceExpr[] parseJoinColumns(final CommonTree ast) {
- ColumnReferenceExpr[] joinColumns = new ColumnReferenceExpr[ast.getChildCount()];
-
- for (int i = 0; i < ast.getChildCount(); i++) {
- joinColumns[i] = checkAndGetColumnByAST(ast.getChild(i));
- }
- return joinColumns;
- }
-
- private Expr parseJoinCondition(ParsingContext context, CommonTree ast) throws SQLSyntaxError {
- return createExpression(context, ast.getChild(0));
- }
-
- private ColumnReferenceExpr checkAndGetColumnByAST(final Tree fieldNode) {
- Preconditions.checkArgument(SQLParser.FIELD_NAME == fieldNode.getType());
-
- String columnName = fieldNode.getChild(0).getText();
- ColumnReferenceExpr column = new ColumnReferenceExpr(columnName);
-
- String tableName = null;
- if (fieldNode.getChildCount() > 1) {
- tableName = fieldNode.getChild(1).getText();
- column.setRelationName(tableName);
- }
-
- return column;
- }
-
- /**
- * The EBNF of case statement
- * <pre>
- * searched_case
- * : CASE s=searched_when_clauses e=else_clause END -> ^(CASE $s $e)
- * ;
- *
- * searched_when_clauses
- * : searched_when_clause searched_when_clause* -> searched_when_clause+
- * ;
- *
- * searched_when_clause
- * : WHEN c=search_condition THEN r=result -> ^(WHEN $c $r)
- * ;
- *
- * else_clause
- * : ELSE r=result -> ^(ELSE $r)
- * ;
- * </pre>
- * @param tree
- * @return
- */
- public CaseWhenExpr parseCaseWhen(ParsingContext context, final Tree tree) throws SQLSyntaxError {
- int idx = 0;
-
- CaseWhenExpr caseEval = new CaseWhenExpr();
- Expr cond;
- Expr thenResult;
- Tree when;
-
- for (; idx < tree.getChildCount() &&
- tree.getChild(idx).getType() == SQLParser.WHEN; idx++) {
-
- when = tree.getChild(idx);
- cond = createExpression(context, when.getChild(0));
- thenResult = createExpression(context, when.getChild(1));
- caseEval.addWhen(cond, thenResult);
- }
-
- if (tree.getChild(idx) != null &&
- tree.getChild(idx).getType() == SQLParser.ELSE) {
- Expr elseResult = createExpression(context, tree.getChild(idx).getChild(0));
- caseEval.setElseResult(elseResult);
- }
-
- return caseEval;
- }
-
- /**
- * <pre>
- * like_predicate : fieldName NOT? LIKE string_value_expr
- * -> ^(LIKE NOT? fieldName string_value_expr)
- * </pre>
- * @param tree
- * @return
- */
- private LikeExpr parseLike(ParsingContext context, final Tree tree) throws SQLSyntaxError {
- int idx = 0;
-
- boolean not = false;
- if (tree.getChild(idx).getType() == SQLParser.NOT) {
- not = true;
- idx++;
- }
-
- ColumnReferenceExpr field = (ColumnReferenceExpr) createExpression(context, tree.getChild(idx));
- idx++;
- Expr pattern = createExpression(context, tree.getChild(idx));
-
- return new LikeExpr(not, field, pattern);
- }
-
- public Expr createExpression(final ParsingContext context, final Tree ast) throws SQLSyntaxError {
- switch(ast.getType()) {
-
- // constants
- case SQLParser.Unsigned_Integer:
- return new LiteralExpr(ast.getText(), LiteralType.Unsigned_Integer);
- case SQLParser.Unsigned_Float:
- return new LiteralExpr(ast.getText(), LiteralType.Unsigned_Float);
- case SQLParser.Unsigned_Large_Integer:
- return new LiteralExpr(ast.getText(), LiteralType.Unsigned_Large_Integer);
-
- case SQLParser.Character_String_Literal:
- return new LiteralExpr(ast.getText(), LiteralType.String);
-
- // unary expression
- case SQLParser.NOT:
- ;
-
- // binary expressions
- case SQLParser.LIKE:
- return parseLike(context, ast);
-
- case SQLParser.IS:
- break;
-
- case SQLParser.AND:
- case SQLParser.OR:
- case SQLParser.Equals_Operator:
- case SQLParser.Not_Equals_Operator:
- case SQLParser.Less_Than_Operator:
- case SQLParser.Less_Or_Equals_Operator:
- case SQLParser.Greater_Than_Operator:
- case SQLParser.Greater_Or_Equals_Operator:
- case SQLParser.Plus_Sign:
- case SQLParser.Minus_Sign:
- case SQLParser.Asterisk:
- case SQLParser.Slash:
- case SQLParser.Percent:
- return new BinaryOperator(tokenToExprType(ast.getType()),
- createExpression(context, ast.getChild(0)),
- createExpression(context, ast.getChild(1)));
-
- // others
- case SQLParser.COLUMN:
- return createExpression(context, ast.getChild(0));
-
- case SQLParser.FIELD_NAME:
- return checkAndGetColumnByAST(ast);
-
- case SQLParser.FUNCTION:
- String signature = ast.getText();
- FunctionExpr func = new FunctionExpr(signature);
- Expr[] givenArgs = new Expr[ast.getChildCount()];
-
- for (int i = 0; i < ast.getChildCount(); i++) {
- givenArgs[i] = createExpression(context, ast.getChild(i));
- }
- func.setParams(givenArgs);
-
- break;
- case SQLParser.COUNT_VAL:
-
- case SQLParser.COUNT_ROWS:
-
-
- case SQLParser.CASE:
- return parseCaseWhen(context, ast);
-
- case SQLParser.SUBQUERY: // ^(SUBQUERY subquery)
- return new ScalarSubQuery(parseSelectStatement(context, ast.getChild(0)));
-
- default:
- }
- return null;
- }
-
- public static ExprType tokenToExprType(int tokenId) {
- switch (tokenId) {
- case SQLParser.UNION: return ExprType.Union;
- case SQLParser.EXCEPT: return ExprType.Except;
- case SQLParser.INTERSECT: return ExprType.Intersect;
-
- case SQLParser.AND: return ExprType.And;
- case SQLParser.OR: return ExprType.Or;
- case SQLParser.Equals_Operator: return ExprType.Equals;
- case SQLParser.Less_Than_Operator: return ExprType.LessThan;
- case SQLParser.Less_Or_Equals_Operator: return ExprType.LessThan;
- case SQLParser.Greater_Than_Operator: return ExprType.GreaterThan;
- case SQLParser.Greater_Or_Equals_Operator: return ExprType.GreaterThanOrEquals;
- case SQLParser.Plus_Sign: return ExprType.Plus;
- case SQLParser.Minus_Sign: return ExprType.Minus;
- case SQLParser.Asterisk: return ExprType.Multiply;
- case SQLParser.Slash: return ExprType.Divide;
- case SQLParser.Percent: return ExprType.Mod;
-
- default: throw new RuntimeException("Unknown Token Id: " + tokenId);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/00c3ee2b/tajo-frontend/tajo-frontend-sql/src/main/java/org/apache/tajo/frontend/sql/SQLParseError.java
----------------------------------------------------------------------
diff --git a/tajo-frontend/tajo-frontend-sql/src/main/java/org/apache/tajo/frontend/sql/SQLParseError.java b/tajo-frontend/tajo-frontend-sql/src/main/java/org/apache/tajo/frontend/sql/SQLParseError.java
deleted file mode 100644
index d3d6d91..0000000
--- a/tajo-frontend/tajo-frontend-sql/src/main/java/org/apache/tajo/frontend/sql/SQLParseError.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.frontend.sql;
-
-
-@SuppressWarnings("UnusedDeclaration")
-public class SQLParseError extends RuntimeException {
- public SQLParseError(String parseErrorMessage) {
- super(parseErrorMessage);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/00c3ee2b/tajo-frontend/tajo-frontend-sql/src/main/java/org/apache/tajo/frontend/sql/SQLSyntaxError.java
----------------------------------------------------------------------
diff --git a/tajo-frontend/tajo-frontend-sql/src/main/java/org/apache/tajo/frontend/sql/SQLSyntaxError.java b/tajo-frontend/tajo-frontend-sql/src/main/java/org/apache/tajo/frontend/sql/SQLSyntaxError.java
deleted file mode 100644
index 0aa1276..0000000
--- a/tajo-frontend/tajo-frontend-sql/src/main/java/org/apache/tajo/frontend/sql/SQLSyntaxError.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.frontend.sql;
-
-
-public class SQLSyntaxError extends Exception {
- private static final long serialVersionUID = 5388279335175632066L;
-
- private String query;
- private String errorMessage;
- private String detailedMessage;
-
- public SQLSyntaxError(String query, String errorMessage) {
- this.query = query;
- this.errorMessage = errorMessage;
- }
-
- @Override
- public String getMessage() {
- if (detailedMessage == null) {
- StringBuilder sb = new StringBuilder();
- sb.append("ERROR: " + errorMessage).append("\n");
- sb.append("LINE: " + query);
- detailedMessage = sb.toString();
- }
-
- return detailedMessage;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tajo/blob/00c3ee2b/tajo-frontend/tajo-frontend-sql/src/test/java/org/apache/tajo/frontend/sql/TestSQLAnalyzer.java
----------------------------------------------------------------------
diff --git a/tajo-frontend/tajo-frontend-sql/src/test/java/org/apache/tajo/frontend/sql/TestSQLAnalyzer.java b/tajo-frontend/tajo-frontend-sql/src/test/java/org/apache/tajo/frontend/sql/TestSQLAnalyzer.java
deleted file mode 100644
index 7f3755c..0000000
--- a/tajo-frontend/tajo-frontend-sql/src/test/java/org/apache/tajo/frontend/sql/TestSQLAnalyzer.java
+++ /dev/null
@@ -1,572 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tajo.frontend.sql;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.apache.tajo.algebra.*;
-import org.apache.tajo.algebra.Aggregation.GroupElement;
-
-import static junit.framework.Assert.*;
-import static org.apache.tajo.algebra.Aggregation.GroupType;
-
-public class TestSQLAnalyzer {
- private static SQLAnalyzer analyzer = null;
-
- @BeforeClass
- public static void setup() {
- analyzer = new SQLAnalyzer();
- }
-
- private String[] QUERIES = {
- "select id, name, score, age from people", // 0
- "select name, score, age from people where score > 30", // 1
- "select name, score, age from people where 3 + 5 * 3", // 2
- "select age, sumtest(score) as total from people group by age having sumtest(score) > 30", // 3
- "select p.id, s.id, score, dept from people as p, student as s where p.id = s.id", // 4
- "select name, score from people order by score asc, age desc null first", // 5
- // only expr
- "select 7 + 8 as total", // 6
- // limit test
- "select id, name, score, age from people limit 3" // 7
- };
-
- @Test
- public final void testSelectStatement() throws SQLSyntaxError {
- Expr expr = analyzer.parse(QUERIES[0]);
- assertEquals(ExprType.Projection, expr.getType());
- Projection projection = (Projection) expr;
- assertEquals(ExprType.Relation, projection.getChild().getType());
- Relation relation = (Relation) projection.getChild();
- assertEquals("people", relation.getName());
- }
-
- @Test
- public final void testSelectStatementWithAlias() throws SQLSyntaxError {
- Expr expr = analyzer.parse(QUERIES[4]);
- assertEquals(ExprType.Projection, expr.getType());
- Projection projection = (Projection) expr;
- assertEquals(ExprType.Selection, projection.getChild().getType());
- Selection selection = (Selection) projection.getChild();
- assertEquals(ExprType.Join, selection.getChild().getType());
- Join join = (Join) selection.getChild();
- assertEquals(ExprType.Relation, join.getLeft().getType());
- Relation outer = (Relation) join.getLeft();
- assertEquals("p", outer.getAlias());
- assertEquals(ExprType.Relation, join.getRight().getType());
- Relation inner = (Relation) join.getRight();
- assertEquals("s", inner.getAlias());
- }
-
- @Test
- public final void testOrderByClause() throws SQLSyntaxError {
- Expr block = analyzer.parse(QUERIES[5]);
- testOrderByCluse(block);
- }
-
- @Test
- public final void testOnlyExpr() throws SQLSyntaxError {
- Expr expr = analyzer.parse(QUERIES[6]);
- assertEquals(ExprType.Projection, expr.getType());
- Projection projection = (Projection) expr;
- assertEquals(1, projection.getTargets().length);
- Target target = projection.getTargets()[0];
- assertEquals("total", target.getAlias());
- assertEquals(ExprType.Plus, target.getExpr().getType());
- }
-
- @Test
- public void testLimit() throws SQLSyntaxError {
- Expr expr = analyzer.parse(QUERIES[7]);
- assertEquals(ExprType.Projection, expr.getType());
- Projection projection = (Projection) expr;
- assertEquals(ExprType.Limit, projection.getChild().getType());
- }
-
- private String[] GROUP_BY = {
- "select age, sumtest(score) as total from people group by age having sumtest(score) > 30", // 0
- "select name, age, sumtest(score) total from people group by cube (name,age)", // 1
- "select name, age, sumtest(score) total from people group by rollup (name,age)", // 2
- "select id, name, age, sumtest(score) total from people group by id, cube (name), rollup (age)", // 3
- "select id, name, age, sumtest(score) total from people group by ()", // 4
- };
-
- @Test
- public final void testGroupByStatement() throws SQLSyntaxError {
- Expr expr = analyzer.parse(GROUP_BY[0]);
- assertEquals(ExprType.Aggregation, expr.getType());
- Aggregation aggregation = (Aggregation) expr;
-
- assertEquals(1, aggregation.getGroupSet().length);
- assertEquals("age", aggregation.getGroupSet()[0].getColumns()[0].getName());
- assertTrue(aggregation.hasHavingCondition());
- assertEquals(ExprType.GreaterThan, aggregation.getHavingCondition().getType());
- }
-
- @Test
- public final void testCubeByStatement() throws SQLSyntaxError {
- Expr expr = analyzer.parse(GROUP_BY[1]);
- assertEquals(ExprType.Aggregation, expr.getType());
- Aggregation aggregation = (Aggregation) expr;
- assertEquals(1, aggregation.getGroupSet().length);
- assertEquals(GroupType.CUBE, aggregation.getGroupSet()[0].getType());
- GroupElement[] groups = aggregation.getGroupSet();
- assertEquals("name", groups[0].getColumns()[0].getName());
- assertEquals("age", groups[0].getColumns()[1].getName());
- }
-
- @Test
- public final void testRollUpStatement() throws SQLSyntaxError {
- Expr expr = analyzer.parse(GROUP_BY[2]);
- assertEquals(ExprType.Aggregation, expr.getType());
- Aggregation aggregation = (Aggregation) expr;
-
- assertEquals(1, aggregation.getGroupSet().length);
- assertEquals(GroupType.ROLLUP, aggregation.getGroupSet()[0].getType());
- GroupElement [] groups = aggregation.getGroupSet();
- assertEquals("name", groups[0].getColumns()[0].getName());
- assertEquals("age", groups[0].getColumns()[1].getName());
- }
-
- @Test
- public final void testMixedGroupByStatement() throws SQLSyntaxError {
- Expr expr = analyzer.parse(GROUP_BY[3]);
- assertEquals(ExprType.Aggregation, expr.getType());
- Aggregation aggregation = (Aggregation) expr;
- assertEquals(3, aggregation.getGroupSet().length);
- int gid = 0;
- GroupElement group = aggregation.getGroupSet()[gid++];
- assertEquals(GroupType.CUBE, group.getType());
- assertEquals("name", group.getColumns()[0].getName());
- group = aggregation.getGroupSet()[gid++];
- assertEquals(GroupType.ROLLUP, group.getType());
- assertEquals("age", group.getColumns()[0].getName());
- group = aggregation.getGroupSet()[gid++];
- assertEquals(GroupType.GROUPBY, group.getType());
- assertEquals("id", group.getColumns()[0].getName());
- }
-
- @Test
- public final void testEmptyGroupSetStatement() throws SQLSyntaxError {
- Expr expr = analyzer.parse(GROUP_BY[4]);
- assertEquals(ExprType.Aggregation, expr.getType());
- Aggregation block = (Aggregation) expr;
- assertTrue(block.isEmptyGrouping());
- }
-
-
- static String [] JOINS = {
- "select p.id, name, branch_name from people as p natural join student natural join branch", // 0
- "select name, dept from people as p inner join student as s on p.id = s.people_id", // 1
- "select name, dept from people as p inner join student as s using (p.id)", // 2
- "select p.id, name, branch_name from people as p cross join student cross join branch", // 3
- "select p.id, dept from people as p left outer join student as s on p.id = s.people_id", // 4
- "select p.id, dept from people as p right outer join student as s on p.id = s.people_id", // 5
- "select p.id, dept from people as p join student as s on p.id = s.people_id", // 6
- "select p.id, dept from people as p left join student as s on p.id = s.people_id", // 7
- "select p.id, dept from people as p right join student as s on p.id= s.people_id", // 8
- "select * from table1 " +
- "cross join table2 " +
- "join table3 on table1.id = table3.id " +
- "inner join table4 on table1.id = table4.id " +
- "left outer join table5 on table1.id = table5.id " +
- "right outer join table6 on table1.id = table6.id " +
- "full outer join table7 on table1.id = table7.id " +
- "natural join table8 " +
- "natural inner join table9 " +
- "natural left outer join table10 " +
- "natural right outer join table11 " +
- "natural full outer join table12 ", // 9 - all possible join clauses*/
- "select s_acctbal, s_name, n_name, p_partkey, p_mfgr, s_address, s_phone, s_comment, ps_supplycost " + // 10
- "from region join nation on n_regionkey = r_regionkey and r_name = 'EUROPE' " +
- "join supplier on s_nationekey = n_nationkey " +
- "join partsupp on s_suppkey = ps_ps_suppkey " +
- "join part on p_partkey = ps_partkey and p_type like '%BRASS' and p_size = 15"
-
- };
-
- @Test
- /**
- * join
- * / \
- * join branch
- * / \
- * people student
- *
- */
- public final void testNaturalJoinClause() throws SQLSyntaxError {
- Expr expr = analyzer.parse(JOINS[0]);
-
-
- Join join = commonJoinTest(expr);
- assertEquals(JoinType.INNER, join.getJoinType());
- assertTrue(join.isNatural());
- Relation branch = (Relation) join.getRight();
- assertEquals("branch", branch.getName());
- assertEquals(ExprType.Join, join.getLeft().getType());
- Join leftJoin = (Join) join.getLeft();
- Relation people = (Relation) leftJoin.getLeft();
- Relation student = (Relation) leftJoin.getRight();
- assertEquals("people", people.getName());
- assertEquals("student", student.getName());
- }
-
- private Join commonJoinTest(Expr expr) {
- assertEquals(ExprType.Projection, expr.getType());
- Projection projection = (Projection) expr;
-
- return (Join) projection.getChild();
- }
-
- @Test
- /**
- * join
- * / \
- * people student
- *
- */
- public final void testInnerJoinClause() throws SQLSyntaxError {
- Expr expr = analyzer.parse(JOINS[1]);
-
- Join join = commonJoinTest(expr);
- assertEquals(JoinType.INNER, join.getJoinType());
- Relation people = (Relation) join.getLeft();
- assertEquals("people", people.getName());
- assertEquals("p", people.getAlias());
-
- Relation student = (Relation) join.getRight();
- assertEquals("student", student.getName());
- assertEquals("s", student.getAlias());
- assertTrue(join.hasQual());
- assertEquals(ExprType.Equals, join.getQual().getType());
-
- Expr expr2 = analyzer.parse(JOINS[2]);
- join = commonJoinTest(expr2);
- assertEquals(JoinType.INNER, join.getJoinType());
- Relation people2 = (Relation) join.getLeft();
- assertEquals("people", people2.getName());
- assertEquals("p", people2.getAlias());
- Relation student2 = (Relation) join.getRight();
- assertEquals("student", student2.getName());
- assertEquals("s", student2.getAlias());
- assertTrue(join.hasJoinColumns());
- assertEquals("id", join.getJoinColumns()[0].getName());
- }
-
- @Test
- public final void testCrossJoinClause() throws SQLSyntaxError {
- Expr expr = analyzer.parse(JOINS[3]);
-
- Join join = commonJoinTest(expr);
- assertEquals(JoinType.CROSS_JOIN, join.getJoinType());
- Relation branch = (Relation) join.getRight();
- assertEquals("branch", branch.getName());
- assertEquals(ExprType.Join, join.getLeft().getType());
- Join leftJoin = (Join) join.getLeft();
- Relation people = (Relation) leftJoin.getLeft();
- Relation student = (Relation) leftJoin.getRight();
- assertEquals("people", people.getName());
- assertEquals("student", student.getName());
- }
-
- @Test
- public final void testLeftOuterJoinClause() throws SQLSyntaxError {
- Expr expr = analyzer.parse(JOINS[4]);
-
- Join join = commonJoinTest(expr);
- assertEquals(JoinType.LEFT_OUTER, join.getJoinType());
- Relation people = (Relation) join.getLeft();
- assertEquals("people", people.getName());
- assertEquals("p", people.getAlias());
- Relation student = (Relation) join.getRight();
- assertEquals("student", student.getName());
- assertEquals("s", student.getAlias());
- assertTrue(join.hasQual());
- assertEquals(ExprType.Equals, join.getQual().getType());
- }
-
- @Test
- public final void testRightOuterJoinClause() throws SQLSyntaxError {
- Expr expr = analyzer.parse(JOINS[5]);
-
- Join join = commonJoinTest(expr);
- assertEquals(JoinType.RIGHT_OUTER, join.getJoinType());
- Relation people = (Relation) join.getLeft();
- assertEquals("people", people.getName());
- assertEquals("p", people.getAlias());
- Relation student = (Relation) join.getRight();
- assertEquals("student", student.getName());
- assertEquals("s", student.getAlias());
- assertTrue(join.hasQual());
- assertEquals(ExprType.Equals, join.getQual().getType());
- }
-
- @Test
- public final void testLeftJoinClause() throws SQLSyntaxError {
- Expr expr = analyzer.parse(JOINS[7]);
-
- Join join = commonJoinTest(expr);
- assertEquals(JoinType.LEFT_OUTER, join.getJoinType());
- Relation people = (Relation) join.getLeft();
- assertEquals("people", people.getName());
- assertEquals("p", people.getAlias());
- Relation student = (Relation) join.getRight();
- assertEquals("student", student.getName());
- assertEquals("s", student.getAlias());
- assertTrue(join.hasQual());
- assertEquals(ExprType.Equals, join.getQual().getType());
- }
-
- @Test
- public final void testRightJoinClause() throws SQLSyntaxError {
- Expr expr = analyzer.parse(JOINS[8]);
-
- Join join = commonJoinTest(expr);
- assertEquals(JoinType.RIGHT_OUTER, join.getJoinType());
- Relation people = (Relation) join.getLeft();
- assertEquals("people", people.getName());
- assertEquals("p", people.getAlias());
- Relation student = (Relation) join.getRight();
- assertEquals("student", student.getName());
- assertEquals("s", student.getAlias());
- assertTrue(join.hasQual());
- assertEquals(ExprType.Equals, join.getQual().getType());
- }
-
- private final String [] setClauses = {
- "select id, people_id from student union select id, people_id from branch",
- "select id, people_id from student union select id, people_id from branch " +
- "intersect select id, people_id from branch as b"
- };
-
- @Test
- public final void testUnionClause() throws SQLSyntaxError {
- Expr expr = analyzer.parse(setClauses[0]);
- assertEquals(ExprType.Union, expr.getType());
- SetOperation union = (SetOperation) expr;
- Expr left = union.getLeft();
- Expr right = union.getRight();
-
- assertEquals(ExprType.Projection, left.getType());
- Projection leftProj = (Projection) left;
- Relation student = (Relation) leftProj.getChild();
-
- assertEquals(ExprType.Projection, right.getType());
- Projection rightProj = (Projection) right;
- Relation branch = (Relation) rightProj.getChild();
-
- assertEquals("student", student.getName());
- assertEquals("branch", branch.getName());
-
- // multiple set statements
- expr = analyzer.parse(setClauses[1]);
- assertEquals(ExprType.Union, expr.getType());
- union = (SetOperation) expr;
-
- assertEquals(ExprType.Projection, union.getLeft().getType());
- assertEquals(ExprType.Intersect, union.getRight().getType());
- leftProj = (Projection) union.getLeft();
- student = (Relation) leftProj.getChild();
- assertEquals("student", student.getName());
-
- SetOperation intersect = (SetOperation) union.getRight();
- Relation branch2 = (Relation) ((Projection)intersect.getLeft()).getChild();
- Relation branch3 = (Relation) ((Projection)intersect.getRight()).getChild();
- assertEquals("branch", branch2.getName());
- assertFalse(branch2.hasAlias());
- assertEquals("branch", branch3.getName());
- assertEquals("b", branch3.getAlias());
- }
-
- @Test
- public void testCaseWhen() throws SQLSyntaxError {
- Expr tree = analyzer.parse(
- "select case when p_type like 'PROMO%' then l_extendedprice * (1 - l_discount) " +
- "when p_type = 'MOCC' then l_extendedprice - 100 else 0 end as cond from lineitem, part");
-
- assertEquals(ExprType.Projection, tree.getType());
- Projection projection = (Projection) tree;
- assertTrue(projection.getTargets()[0].hasAlias());
- assertEquals(ExprType.CaseWhen, projection.getTargets()[0].getExpr().getType());
- assertEquals("cond", projection.getTargets()[0].getAlias());
- CaseWhenExpr caseWhen = (CaseWhenExpr) projection.getTargets()[0].getExpr();
- assertEquals(2, caseWhen.getWhens().size());
- }
-
- public static String [] subQueries = {
- "select c1, c2, c3 from (select c1, c2, c3 from employee) as test",
- "select c1, c2, c3 from table1 where c3 < (select c4 from table2)"
- };
-
- @Test
- public void testTableSubQuery() throws SQLSyntaxError {
- Expr expr = analyzer.parse(subQueries[0]);
- assertEquals(ExprType.Projection, expr.getType());
- Projection projection = (Projection) expr;
- assertEquals(ExprType.TableSubQuery, projection.getChild().getType());
- }
-
- @Test
- public void testScalarSubQuery() throws SQLSyntaxError {
- Expr expr = analyzer.parse(subQueries[1]);
- assertEquals(ExprType.Projection, expr.getType());
- Projection projection = (Projection) expr;
- assertEquals(ExprType.Selection, projection.getChild().getType());
- }
-
- static final String [] setQualifier = {
- "select id, people_id from student",
- "select distinct id, people_id from student",
- "select all id, people_id from student",
- };
-
- @Test
- public final void testSetQulaifier() throws SQLSyntaxError {
- Expr expr = analyzer.parse(setQualifier[0]);
- assertEquals(ExprType.Projection, expr.getType());
- Projection projection = (Projection) expr;
- assertFalse(projection.isDistinct());
-
- expr = analyzer.parse(setQualifier[1]);
- assertEquals(ExprType.Projection, expr.getType());
- projection = (Projection) expr;
- assertTrue(projection.isDistinct());
-
- expr = analyzer.parse(setQualifier[2]);
- assertEquals(ExprType.Projection, expr.getType());
- projection = (Projection) expr;
- assertFalse(projection.isDistinct());
- }
-
- static final String [] createTableStmts = {
- "create table table1 (name varchar, age int)",
- "create table table1 (name string, age int) using rcfile",
- "create table table1 (name string, age int) using rcfile with ('rcfile.buffer' = 4096)",
- // create table test
- "create table store1 as select name, score from people order by score asc, age desc null first",// 0
- // create table test
- "create table store1 (c1 string, c2 long) as select name, score from people order by score asc, age desc null first",// 1
- // create table test
- "create table store2 using rcfile with ('rcfile.buffer' = 4096) as select name, score from people order by score asc, age desc null first", // 2
- // create table def
- "create table table1 (name string, age int, earn long, score float) using rcfile with ('rcfile.buffer' = 4096)", // 4
- // create table def with location
- "create external table table1 (name string, age int, earn long, score float) using csv with ('csv.delimiter'='|') location '/tmp/data'" // 5
- };
-
- @Test
- public final void testCreateTable1() throws SQLSyntaxError {
- CreateTable stmt = (CreateTable) analyzer.parse(createTableStmts[0]);
- assertEquals("table1", stmt.getRelationName());
- assertTrue(stmt.hasTableElements());
-
- stmt = (CreateTable) analyzer.parse(createTableStmts[1]);
- assertEquals("table1", stmt.getRelationName());
- assertTrue(stmt.hasTableElements());
- assertTrue(stmt.hasStorageType());
- assertEquals("rcfile", stmt.getStorageType());
-
- stmt = (CreateTable) analyzer.parse(createTableStmts[2]);
- assertEquals("table1", stmt.getRelationName());
- assertTrue(stmt.hasTableElements());
- assertTrue(stmt.hasStorageType());
- assertEquals("rcfile", stmt.getStorageType());
- assertTrue(stmt.hasParams());
- assertEquals("4096", stmt.getParams().get("rcfile.buffer"));
- }
-
- @Test
- public final void testCreateTableAsSelect() throws SQLSyntaxError {
- CreateTable stmt = (CreateTable) analyzer.parse(createTableStmts[3]);
- assertEquals("store1", stmt.getRelationName());
- assertTrue(stmt.hasSubQuery());
- testOrderByCluse(stmt.getSubQuery());
-
- stmt = (CreateTable) analyzer.parse(createTableStmts[4]);
- assertEquals("store1", stmt.getRelationName());
- assertTrue(stmt.hasSubQuery());
- testOrderByCluse(stmt.getSubQuery());
- assertTrue(stmt.hasTableElements());
-
- stmt = (CreateTable) analyzer.parse(createTableStmts[5]);
- assertEquals("store2", stmt.getRelationName());
- assertEquals("rcfile", stmt.getStorageType());
- assertEquals("4096", stmt.getParams().get("rcfile.buffer"));
- testOrderByCluse(stmt.getSubQuery());
- }
-
- private static void testOrderByCluse(Expr block) {
- Projection projection = (Projection) block;
- Sort sort = (Sort) projection.getChild();
-
- assertEquals(2, sort.getSortSpecs().length);
- Sort.SortSpec spec1 = sort.getSortSpecs()[0];
- assertEquals("score", spec1.getKey().getName());
- assertEquals(true, spec1.isAscending());
- assertEquals(false, spec1.isNullFirst());
- Sort.SortSpec spec2 = sort.getSortSpecs()[1];
- assertEquals("age", spec2.getKey().getName());
- assertEquals(false, spec2.isAscending());
- assertEquals(true, spec2.isNullFirst());
- }
-
- @Test
- public final void testCreateTableDef1() throws SQLSyntaxError {
- CreateTable stmt = (CreateTable) analyzer.parse(createTableStmts[6]);
- assertEquals("table1", stmt.getRelationName());
- CreateTable.ColumnDefinition[] elements = stmt.getTableElements();
- assertEquals("name", elements[0].getColumnName());
- assertEquals("string", elements[0].getDataType());
- assertEquals("age", elements[1].getColumnName());
- assertEquals("int", elements[1].getDataType());
- assertEquals("earn", elements[2].getColumnName());
- assertEquals("long", elements[2].getDataType());
- assertEquals("score", elements[3].getColumnName());
- assertEquals("float", elements[3].getDataType());
- assertEquals("rcfile", stmt.getStorageType());
- assertFalse(stmt.hasLocation());
- assertTrue(stmt.hasParams());
- assertEquals("4096", stmt.getParams().get("rcfile.buffer"));
- }
-
- @Test
- public final void testCreateTableDef2() throws SQLSyntaxError {
- CreateTable expr = (CreateTable) analyzer.parse(createTableStmts[7]);
- _testCreateTableDef2(expr);
- CreateTable restored = (CreateTable) AlgebraTestingUtil.testJsonSerializer(expr);
- _testCreateTableDef2(restored);
- }
-
- private void _testCreateTableDef2(CreateTable expr) {
- assertEquals("table1", expr.getRelationName());
- CreateTable.ColumnDefinition[] elements = expr.getTableElements();
- assertEquals("name", elements[0].getColumnName());
- assertEquals("string", elements[0].getDataType());
- assertEquals("age", elements[1].getColumnName());
- assertEquals("int", elements[1].getDataType());
- assertEquals("earn", elements[2].getColumnName());
- assertEquals("long", elements[2].getDataType());
- assertEquals("score", elements[3].getColumnName());
- assertEquals("float", elements[3].getDataType());
- assertEquals("csv", expr.getStorageType());
- assertEquals("/tmp/data", expr.getLocation());
- assertTrue(expr.hasParams());
- assertEquals("|", expr.getParams().get("csv.delimiter"));
- }
-}