private GenSubqueryParamValuesRewriter(StatementContext context) { this.expressionCompiler = new ExpressionCompiler(context); }
int i = 0; for (; i < Math.min(lhsExpr.getChildren().size(),rhsExpr.getChildren().size()); i++) { addBindParamMetaData(lhsNode.getChildren().get(i), rhsNode.getChildren().get(i), lhsExpr.getChildren().get(i), rhsExpr.getChildren().get(i)); addBindParamMetaData(lhsNode.getChildren().get(i), null, lhsExpr.getChildren().get(i), null); addBindParamMetaData(null, rhsNode.getChildren().get(i), null, rhsExpr.getChildren().get(i)); addBindParamMetaData(lhsNode.getChildren().get(0), rhsNode, lhsExpr.getChildren().get(0), rhsExpr); for (int i = 1; i < lhsExpr.getChildren().size(); i++) { addBindParamMetaData(lhsNode.getChildren().get(i), null, lhsExpr.getChildren().get(i), null); addBindParamMetaData(lhsNode, rhsNode.getChildren().get(0), lhsExpr, rhsExpr.getChildren().get(0)); for (int i = 1; i < rhsExpr.getChildren().size(); i++) { addBindParamMetaData(null, rhsNode.getChildren().get(i), null, rhsExpr.getChildren().get(i)); addBindParamMetaData(lhsNode, rhsNode, lhsExpr, rhsExpr); return wrapGroupByExpression(ComparisonExpression.create(op, children, context.getTempPtr(), context.getCurrentTable().getTable().rowKeyOrderOptimizable()));
@Override public Expression visit(ColumnParseNode node) throws SQLException { ColumnRef ref = resolveColumn(node); TableRef tableRef = ref.getTableRef(); ImmutableBytesWritable ptr = context.getTempPtr(); PColumn column = ref.getColumn(); // If we have an UPDATABLE view, then we compile those view constants (i.e. columns in equality constraints // in the view) to constants. This allows the optimize to optimize out reference to them in various scenarios. // If the column is matched in a WHERE clause against a constant not equal to it's constant, then the entire // query would become degenerate. if (!resolveViewConstants && IndexUtil.getViewConstantValue(column, ptr)) { return LiteralExpression.newConstant(column.getDataType().toObject(ptr), column.getDataType()); } if (tableRef.equals(context.getCurrentTable()) && !SchemaUtil.isPKColumn(column)) { // project only kv columns addColumn(column); } Expression expression = ref.newColumnExpression(node.isTableNameCaseSensitive(), node.isCaseSensitive()); Expression wrappedExpression = wrapGroupByExpression(expression); // If we're in an aggregate expression // and we're not in the context of an aggregate function // and we didn't just wrap our column reference // then we're mixing aggregate and non aggregate expressions in the same expression. // This catches cases like this: SELECT sum(a_integer) + a_integer FROM atable GROUP BY a_string if (isAggregate && aggregateFunction == null && wrappedExpression == expression) { throwNonAggExpressionInAggException(expression.toString()); } return wrappedExpression; }
@Override public Expression visitLeave(OrParseNode node, List<Expression> children) throws SQLException { return wrapGroupByExpression(orExpression(children)); }
private static Expression compilePostFilterExpression(StatementContext context, List<ParseNode> postFilters) throws SQLException { if (postFilters.isEmpty()) return null; ExpressionCompiler expressionCompiler = new ExpressionCompiler(context); List<Expression> expressions = new ArrayList<Expression>(postFilters.size()); for (ParseNode postFilter : postFilters) { expressionCompiler.reset(); Expression expression = postFilter.accept(expressionCompiler); expressions.add(expression); } if (expressions.size() == 1) return expressions.get(0); return AndExpression.create(expressions); }
compiler = new ExpressionCompiler(context, GroupBy.EMPTY_GROUP_BY) { @Override protected Expression addExpression(Expression expression) {return expression;} }; } else { compiler = new ExpressionCompiler(context, groupBy); expression = node.getNode().accept(compiler); if (!expression.isStateless() && !compiler.isAggregate()) { if (statement.isAggregate() || statement.isDistinct()) { .setMessage(expression.toString()).build().buildException(); ExpressionCompiler.throwNonAggExpressionInAggException(expression.toString()); orderByExpressions.add(orderByExpression); compiler.reset();
new ExpressionCompiler(context, GroupBy.EMPTY_GROUP_BY); List<Expression> expressions = Lists.newArrayListWithExpectedSize(groupByNodes.size()); for (int i = 0; i < groupByNodes.size(); i++) { Expression expression = node.accept(compiler); if (!expression.isStateless()) { if (compiler.isAggregate()) { throw new SQLExceptionInfo.Builder(SQLExceptionCode.AGGREGATE_IN_GROUP_BY) .setMessage(expression.toString()).build().buildException(); compiler.reset();
public static Expression compile(StatementContext context, SelectStatement statement, GroupBy groupBy) throws SQLException { ParseNode having = statement.getHaving(); if (having == null) { return null; } ExpressionCompiler expressionBuilder = new ExpressionCompiler(context, groupBy); Expression expression = having.accept(expressionBuilder); if (expression.getDataType() != PBoolean.INSTANCE) { throw TypeMismatchException.newException(PBoolean.INSTANCE, expression.getDataType(), expression.toString()); } if (LiteralExpression.isBooleanFalseOrNull(expression)) { context.setScanRanges(ScanRanges.NOTHING); return null; } else if (LiteralExpression.isTrue(expression)) { return null; } if (!expressionBuilder.isAggregate()) { throw new SQLExceptionInfo.Builder(SQLExceptionCode.ONLY_AGGREGATE_IN_HAVING_CLAUSE).build().buildException(); } return expression; }
@Override public Expression visitLeave(CastParseNode node, List<Expression> children) throws SQLException { ParseNode childNode = node.getChildren().get(0); PDataType targetDataType = node.getDataType(); Expression childExpr = children.get(0); PDataType fromDataType = childExpr.getDataType(); if (childNode instanceof BindParseNode) { context.getBindManager().addParamMetaData((BindParseNode)childNode, childExpr); } Expression expr = childExpr; if(fromDataType != null) { /* * IndexStatementRewriter creates a CAST parse node when rewriting the query to use * indexed columns. Without this check present we wrongly and unnecessarily * end up creating a RoundExpression. */ if (context.getCurrentTable().getTable().getType() != PTableType.INDEX) { expr = convertToRoundExpressionIfNeeded(fromDataType, targetDataType, children); } } boolean rowKeyOrderOptimizable = context.getCurrentTable().getTable().rowKeyOrderOptimizable(); return wrapGroupByExpression(CoerceExpression.create(expr, targetDataType, SortOrder.getDefault(), expr.getMaxLength(), rowKeyOrderOptimizable)); }
@Override public Expression visitLeave(InListParseNode node, List<Expression> l) throws SQLException { List<Expression> inChildren = l; Expression firstChild = inChildren.get(0); ImmutableBytesWritable ptr = context.getTempPtr(); PDataType firstChildType = firstChild.getDataType(); ParseNode firstChildNode = node.getChildren().get(0); if (firstChildNode instanceof BindParseNode) { PDatum datum = firstChild; if (firstChildType == null) { datum = inferBindDatum(inChildren); } context.getBindManager().addParamMetaData((BindParseNode)firstChildNode, datum); } for (int i = 1; i < l.size(); i++) { ParseNode childNode = node.getChildren().get(i); if (childNode instanceof BindParseNode) { context.getBindManager().addParamMetaData((BindParseNode)childNode, firstChild); } } return wrapGroupByExpression(InListExpression.create(inChildren, node.isNegate(), ptr, context.getCurrentTable().getTable().rowKeyOrderOptimizable())); }
return ExpressionUtil.getConstantExpression(expression, ptr); expression = addExpression(expression); expression = wrapGroupByExpression(expression); if (aggregateFunction == node) {
@Override public void reset() { super.reset(); elementCount = 0; isCaseSensitive = true; }
@Override public void addElement(List<Expression> l, Expression element) { elementCount++; isCaseSensitive &= elementCount == 1; super.addElement(l, element); }
compiler = new ExpressionCompiler(context, GroupBy.EMPTY_GROUP_BY) { @Override protected Expression addExpression(Expression expression) {return expression;} }; } else { compiler = new ExpressionCompiler(context, groupBy); expression = node.getNode().accept(compiler); if (!expression.isStateless() && !compiler.isAggregate()) { if (statement.isAggregate() || statement.isDistinct()) { .setMessage(expression.toString()).build().buildException(); ExpressionCompiler.throwNonAggExpressionInAggException(expression.toString()); orderByExpressions.add(orderByExpression); compiler.reset();
new ExpressionCompiler(context, GroupBy.EMPTY_GROUP_BY); List<Expression> expressions = Lists.newArrayListWithExpectedSize(groupByNodes.size()); for (int i = 0; i < groupByNodes.size(); i++) { Expression expression = node.accept(compiler); if (!expression.isStateless()) { if (compiler.isAggregate()) { throw new SQLExceptionInfo.Builder(SQLExceptionCode.AGGREGATE_IN_GROUP_BY) .setMessage(expression.toString()).build().buildException(); compiler.reset();
ExpressionCompiler lhsCompiler = new ExpressionCompiler(lhsCtx); ExpressionCompiler rhsCompiler = new ExpressionCompiler(rhsCtx); for (EqualParseNode condition : onConditions) { lhsCompiler.reset(); Expression left = condition.getLHS().accept(lhsCompiler); rhsCompiler.reset(); Expression right = condition.getRHS().accept(rhsCompiler); PDataType toType = getCommonType(left.getDataType(), right.getDataType());
@Override public Expression visitLeave(OrParseNode node, List<Expression> children) throws SQLException { return wrapGroupByExpression(orExpression(children)); }
public static Expression compile(StatementContext context, SelectStatement statement, GroupBy groupBy) throws SQLException { ParseNode having = statement.getHaving(); if (having == null) { return null; } ExpressionCompiler expressionBuilder = new ExpressionCompiler(context, groupBy); Expression expression = having.accept(expressionBuilder); if (expression.getDataType() != PBoolean.INSTANCE) { throw TypeMismatchException.newException(PBoolean.INSTANCE, expression.getDataType(), expression.toString()); } if (LiteralExpression.isBooleanFalseOrNull(expression)) { context.setScanRanges(ScanRanges.NOTHING); return null; } else if (LiteralExpression.isTrue(expression)) { return null; } if (!expressionBuilder.isAggregate()) { throw new SQLExceptionInfo.Builder(SQLExceptionCode.ONLY_AGGREGATE_IN_HAVING_CLAUSE).build().buildException(); } return expression; }
@Override public Expression visitLeave(CastParseNode node, List<Expression> children) throws SQLException { ParseNode childNode = node.getChildren().get(0); PDataType targetDataType = node.getDataType(); Expression childExpr = children.get(0); PDataType fromDataType = childExpr.getDataType(); if (childNode instanceof BindParseNode) { context.getBindManager().addParamMetaData((BindParseNode)childNode, childExpr); } Expression expr = childExpr; if(fromDataType != null) { /* * IndexStatementRewriter creates a CAST parse node when rewriting the query to use * indexed columns. Without this check present we wrongly and unnecessarily * end up creating a RoundExpression. */ if (context.getCurrentTable().getTable().getType() != PTableType.INDEX) { expr = convertToRoundExpressionIfNeeded(fromDataType, targetDataType, children); } } boolean rowKeyOrderOptimizable = context.getCurrentTable().getTable().rowKeyOrderOptimizable(); return wrapGroupByExpression(CoerceExpression.create(expr, targetDataType, SortOrder.getDefault(), expr.getMaxLength(), rowKeyOrderOptimizable)); }
@Override public Expression visitLeave(InListParseNode node, List<Expression> l) throws SQLException { List<Expression> inChildren = l; Expression firstChild = inChildren.get(0); ImmutableBytesWritable ptr = context.getTempPtr(); PDataType firstChildType = firstChild.getDataType(); ParseNode firstChildNode = node.getChildren().get(0); if (firstChildNode instanceof BindParseNode) { PDatum datum = firstChild; if (firstChildType == null) { datum = inferBindDatum(inChildren); } context.getBindManager().addParamMetaData((BindParseNode)firstChildNode, datum); } for (int i = 1; i < l.size(); i++) { ParseNode childNode = node.getChildren().get(i); if (childNode instanceof BindParseNode) { context.getBindManager().addParamMetaData((BindParseNode)childNode, firstChild); } } return wrapGroupByExpression(InListExpression.create(inChildren, node.isNegate(), ptr, context.getCurrentTable().getTable().rowKeyOrderOptimizable())); }