@Override public ColumnReferenceExpr visitColumn_reference(Column_referenceContext ctx) { String columnReferenceName = buildIdentifierChain(ctx.identifier()); // find the last dot (.) position to separate a name into both a qualifier and name int lastDotIdx = columnReferenceName.lastIndexOf("."); if (lastDotIdx > 0) { // if any qualifier is given String qualifier = columnReferenceName.substring(0, lastDotIdx); String name = columnReferenceName.substring(lastDotIdx + 1, columnReferenceName.length()); return new ColumnReferenceExpr(qualifier, name); } else { return new ColumnReferenceExpr(ctx.getText()); } }
@Override public ColumnReferenceExpr visitColumn_reference(Column_referenceContext ctx) { String columnReferenceName = buildIdentifierChain(ctx.identifier()); // find the last dot (.) position to separate a name into both a qualifier and name int lastDotIdx = columnReferenceName.lastIndexOf("."); if (lastDotIdx > 0) { // if any qualifier is given String qualifier = columnReferenceName.substring(0, lastDotIdx); String name = columnReferenceName.substring(lastDotIdx + 1, columnReferenceName.length()); return new ColumnReferenceExpr(qualifier, name); } else { return new ColumnReferenceExpr(ctx.getText()); } }
@Override protected EvalNode visitField(Object o, FieldEval evalNode, Stack<EvalNode> stack) { ColumnReferenceExpr expr = new ColumnReferenceExpr(tableName, evalNode.getColumnName()); exprs.push(expr); return super.visitField(o, evalNode, stack); }
/** * Resolve an asterisk expression to the real column reference expressions. * @param ctx context * @param asteriskExpr asterisk expression * @return a list of NamedExpr each of which has ColumnReferenceExprs as its child * @throws TajoException */ private static List<NamedExpr> resolveAsterisk(LogicalPlanner.PlanContext ctx, QualifiedAsteriskExpr asteriskExpr) throws TajoException { Column[] columns = getColumns(ctx, asteriskExpr); List<NamedExpr> newTargetExprs = new ArrayList<>(columns.length); int i; for (i = 0; i < columns.length; i++) { newTargetExprs.add(new NamedExpr(new ColumnReferenceExpr(columns[i].getQualifier(), columns[i].getSimpleName()))); } return newTargetExprs; }
/** * Resolve an asterisk expression to the real column reference expressions. * @param ctx context * @param asteriskExpr asterisk expression * @return a list of NamedExpr each of which has ColumnReferenceExprs as its child * @throws TajoException */ private static List<NamedExpr> resolveAsterisk(LogicalPlanner.PlanContext ctx, QualifiedAsteriskExpr asteriskExpr) throws TajoException { Column[] columns = getColumns(ctx, asteriskExpr); List<NamedExpr> newTargetExprs = new ArrayList<NamedExpr>(columns.length); int i; for (i = 0; i < columns.length; i++) { newTargetExprs.add(new NamedExpr(new ColumnReferenceExpr(columns[i].getQualifier(), columns[i].getSimpleName()))); } return newTargetExprs; }
@Override public Expr visitFunction(ExprNormalizedResult ctx, Stack<Expr> stack, FunctionExpr expr) throws TajoException { stack.push(expr); Expr param; Expr[] paramExprs = expr.getParams(); if (paramExprs != null) { for (int i = 0; i < paramExprs.length; i++) { param = paramExprs[i]; visit(ctx, stack, param); if (OpType.isAggregationFunction(param.getType())) { String referenceName = ctx.plan.generateUniqueColumnName(param); ctx.aggExprs.add(new NamedExpr(param, referenceName)); expr.getParams()[i] = new ColumnReferenceExpr(referenceName); } } } stack.pop(); return expr; }
@Override public Expr visitFunction(ExprNormalizedResult ctx, Stack<Expr> stack, FunctionExpr expr) throws TajoException { stack.push(expr); Expr param; Expr[] paramExprs = expr.getParams(); if (paramExprs != null) { for (int i = 0; i < paramExprs.length; i++) { param = paramExprs[i]; visit(ctx, stack, param); if (OpType.isAggregationFunction(param.getType())) { String referenceName = ctx.plan.generateUniqueColumnName(param); ctx.aggExprs.add(new NamedExpr(param, referenceName)); expr.getParams()[i] = new ColumnReferenceExpr(referenceName); } } } stack.pop(); return expr; }
@Override public Expr visitGeneralSetFunction(ExprNormalizedResult ctx, Stack<Expr> stack, GeneralSetFunctionExpr expr) throws TajoException { stack.push(expr); Expr param; for (int i = 0; i < expr.getParams().length; i++) { param = expr.getParams()[i]; visit(ctx, stack, param); // If parameters are all constants, we don't need to dissect an aggregation expression into two parts: // function and parameter parts. if (!OpType.isLiteralType(param.getType()) && param.getType() != OpType.Column) { String referenceName = ctx.block.namedExprsMgr.addExpr(param); ctx.scalarExprs.add(new NamedExpr(param, referenceName)); expr.getParams()[i] = new ColumnReferenceExpr(referenceName); } } stack.pop(); return expr; }
@Override public Expr visitGeneralSetFunction(ExprNormalizedResult ctx, Stack<Expr> stack, GeneralSetFunctionExpr expr) throws TajoException { stack.push(expr); Expr param; for (int i = 0; i < expr.getParams().length; i++) { param = expr.getParams()[i]; visit(ctx, stack, param); // If parameters are all constants, we don't need to dissect an aggregation expression into two parts: // function and parameter parts. if (!OpType.isLiteralType(param.getType()) && param.getType() != OpType.Column) { String referenceName = ctx.block.namedExprsMgr.addExpr(param); ctx.scalarExprs.add(new NamedExpr(param, referenceName)); expr.getParams()[i] = new ColumnReferenceExpr(referenceName); } } stack.pop(); return expr; }
@Override public Expr visitCastExpr(ExprNormalizedResult ctx, Stack<Expr> stack, CastExpr expr) throws TajoException { super.visitCastExpr(ctx, stack, expr); if (OpType.isAggregationFunction(expr.getType())) { String referenceName = ctx.block.namedExprsMgr.addExpr(expr.getChild()); ctx.aggExprs.add(new NamedExpr(expr.getChild(), referenceName)); expr.setChild(new ColumnReferenceExpr(referenceName)); } return expr; }
@Override public Expr visitCastExpr(ExprNormalizedResult ctx, Stack<Expr> stack, CastExpr expr) throws TajoException { super.visitCastExpr(ctx, stack, expr); if (OpType.isAggregationFunction(expr.getType())) { String referenceName = ctx.block.namedExprsMgr.addExpr(expr.getChild()); ctx.aggExprs.add(new NamedExpr(expr.getChild(), referenceName)); expr.setChild(new ColumnReferenceExpr(referenceName)); } return expr; }
@Override public Expr visitUnaryOperator(ExprNormalizedResult ctx, Stack<Expr> stack, UnaryOperator expr) throws TajoException { super.visitUnaryOperator(ctx, stack, expr); if (OpType.isAggregationFunction(expr.getChild().getType())) { // Get an anonymous column name and replace the aggregation function by the column name String refName = ctx.block.namedExprsMgr.addExpr(expr.getChild()); ctx.aggExprs.add(new NamedExpr(expr.getChild(), refName)); expr.setChild(new ColumnReferenceExpr(refName)); } return expr; }
@Override public Expr visitUnaryOperator(ExprNormalizedResult ctx, Stack<Expr> stack, UnaryOperator expr) throws TajoException { super.visitUnaryOperator(ctx, stack, expr); if (OpType.isAggregationFunction(expr.getChild().getType())) { // Get an anonymous column name and replace the aggregation function by the column name String refName = ctx.block.namedExprsMgr.addExpr(expr.getChild()); ctx.aggExprs.add(new NamedExpr(expr.getChild(), refName)); expr.setChild(new ColumnReferenceExpr(refName)); } return expr; }
@Override public Object visitCaseWhen(ExprNormalizedResult ctx, Stack<Expr> stack, CaseWhenPredicate expr) throws TajoException { stack.push(expr); for (CaseWhenPredicate.WhenExpr when : expr.getWhens()) { visit(ctx, stack, when.getCondition()); visit(ctx, stack, when.getResult()); if (OpType.isAggregationFunction(when.getCondition().getType())) { String referenceName = ctx.block.namedExprsMgr.addExpr(when.getCondition()); ctx.aggExprs.add(new NamedExpr(when.getCondition(), referenceName)); when.setCondition(new ColumnReferenceExpr(referenceName)); } if (OpType.isAggregationFunction(when.getResult().getType())) { String referenceName = ctx.block.namedExprsMgr.addExpr(when.getResult()); ctx.aggExprs.add(new NamedExpr(when.getResult(), referenceName)); when.setResult(new ColumnReferenceExpr(referenceName)); } } if (expr.hasElseResult()) { visit(ctx, stack, expr.getElseResult()); if (OpType.isAggregationFunction(expr.getElseResult().getType())) { String referenceName = ctx.block.namedExprsMgr.addExpr(expr.getElseResult()); ctx.aggExprs.add(new NamedExpr(expr.getElseResult(), referenceName)); expr.setElseResult(new ColumnReferenceExpr(referenceName)); } } stack.pop(); return expr; }
@Override public Object visitCaseWhen(ExprNormalizedResult ctx, Stack<Expr> stack, CaseWhenPredicate expr) throws TajoException { stack.push(expr); for (CaseWhenPredicate.WhenExpr when : expr.getWhens()) { visit(ctx, stack, when.getCondition()); visit(ctx, stack, when.getResult()); if (OpType.isAggregationFunction(when.getCondition().getType())) { String referenceName = ctx.block.namedExprsMgr.addExpr(when.getCondition()); ctx.aggExprs.add(new NamedExpr(when.getCondition(), referenceName)); when.setCondition(new ColumnReferenceExpr(referenceName)); } if (OpType.isAggregationFunction(when.getResult().getType())) { String referenceName = ctx.block.namedExprsMgr.addExpr(when.getResult()); ctx.aggExprs.add(new NamedExpr(when.getResult(), referenceName)); when.setResult(new ColumnReferenceExpr(referenceName)); } } if (expr.hasElseResult()) { visit(ctx, stack, expr.getElseResult()); if (OpType.isAggregationFunction(expr.getElseResult().getType())) { String referenceName = ctx.block.namedExprsMgr.addExpr(expr.getElseResult()); ctx.aggExprs.add(new NamedExpr(expr.getElseResult(), referenceName)); expr.setElseResult(new ColumnReferenceExpr(referenceName)); } } stack.pop(); return expr; }
private Expr generateOneExpr() { Expr expr = new BinaryOperator(OpType.LessThan, new LiteralValue("1", LiteralType.Unsigned_Integer), new LiteralValue("2", LiteralType.Unsigned_Integer)); Relation relation = new Relation("employee"); Selection selection = new Selection(expr); selection.setChild(relation); Aggregation aggregation = new Aggregation(); aggregation.setTargets(new NamedExpr[]{ new NamedExpr(new ColumnReferenceExpr("col1")) }); aggregation.setChild(selection); Sort.SortSpec spec = new Sort.SortSpec(new ColumnReferenceExpr("col2"), false, false); Sort sort = new Sort(new Sort.SortSpec[]{spec}); sort.setChild(aggregation); return sort; }
@Test public void testEquals() throws Exception { Expr expr = new BinaryOperator(OpType.LessThan, new LiteralValue("1", LiteralType.Unsigned_Integer), new LiteralValue("2", LiteralType.Unsigned_Integer)); Relation relation = new Relation("employee"); Selection selection = new Selection(expr); selection.setChild(relation); Aggregation aggregation = new Aggregation(); aggregation.setTargets(new NamedExpr[]{ new NamedExpr(new ColumnReferenceExpr("col1")) } ); aggregation.setChild(selection); Sort.SortSpec spec = new Sort.SortSpec(new ColumnReferenceExpr("col2")); Sort sort = new Sort(new Sort.SortSpec[]{spec}); sort.setChild(aggregation); assertEquals(sort, sort); Expr different = generateOneExpr(); assertFalse(sort.equals(different)); }
public List<Integer> normalize(PlanContext context, Projection projection, ExprNormalizedResult [] normalizedExprList, Matcher matcher) throws TajoException { List<Integer> targetIds = new ArrayList<>(); for (int i = 0; i < projection.size(); i++) { NamedExpr namedExpr = projection.getNamedExprs().get(i); if (PlannerUtil.existsAggregationFunction(namedExpr)) { context.queryBlock.setAggregationRequire(); } if (matcher.isMatch(namedExpr.getExpr())) { // If a value is constant value, it adds the constant value with a proper name to the constant map // of the current block if (!namedExpr.hasAlias() && OpType.isLiteralType(namedExpr.getExpr().getType())) { String generatedName = context.plan.generateUniqueColumnName(namedExpr.getExpr()); ConstEval constEval = (ConstEval) exprAnnotator.createEvalNode(context, namedExpr.getExpr(), NameResolvingMode.RELS_ONLY); context.getQueryBlock().addConstReference(generatedName, namedExpr.getExpr(), constEval); normalizedExprList[i] = new ExprNormalizedResult(context, false); normalizedExprList[i].baseExpr = new ColumnReferenceExpr(generatedName); } else { // dissect an expression into multiple parts (at most dissected into three parts) normalizedExprList[i] = normalizer.normalize(context, namedExpr.getExpr()); } targetIds.add(i); } } return targetIds; }
@Test public void testJson2() { Expr expr = new BinaryOperator(OpType.LessThan, new LiteralValue("1", LiteralType.Unsigned_Integer), new LiteralValue("2", LiteralType.Unsigned_Integer)); Relation relation = new Relation("employee"); Selection selection = new Selection(expr); selection.setChild(relation); Aggregation aggregation = new Aggregation(); aggregation.setTargets(new NamedExpr[]{ new NamedExpr(new ColumnReferenceExpr("col1")) } ); aggregation.setChild(selection); Sort.SortSpec spec = new Sort.SortSpec(new ColumnReferenceExpr("col2")); Sort sort = new Sort(new Sort.SortSpec[]{spec}); sort.setChild(aggregation); String json = sort.toJson(); Expr fromJson = JsonHelper.fromJson(json, Expr.class); assertEquals(sort, fromJson); } }
public List<Integer> normalize(PlanContext context, Projection projection, ExprNormalizedResult [] normalizedExprList, Matcher matcher) throws TajoException { List<Integer> targetIds = new ArrayList<Integer>(); for (int i = 0; i < projection.size(); i++) { NamedExpr namedExpr = projection.getNamedExprs()[i]; if (PlannerUtil.existsAggregationFunction(namedExpr)) { context.queryBlock.setAggregationRequire(); } if (matcher.isMatch(namedExpr.getExpr())) { // If a value is constant value, it adds the constant value with a proper name to the constant map // of the current block if (!namedExpr.hasAlias() && OpType.isLiteralType(namedExpr.getExpr().getType())) { String generatedName = context.plan.generateUniqueColumnName(namedExpr.getExpr()); ConstEval constEval = (ConstEval) exprAnnotator.createEvalNode(context, namedExpr.getExpr(), NameResolvingMode.RELS_ONLY); context.getQueryBlock().addConstReference(generatedName, namedExpr.getExpr(), constEval); normalizedExprList[i] = new ExprNormalizedResult(context, false); normalizedExprList[i].baseExpr = new ColumnReferenceExpr(generatedName); } else { // dissect an expression into multiple parts (at most dissected into three parts) normalizedExprList[i] = normalizer.normalize(context, namedExpr.getExpr()); } targetIds.add(i); } } return targetIds; }