private List<SqlNode> toSql(RexProgram program, List<RexNode> operandList) { final List<SqlNode> list = new ArrayList<>(); for (RexNode rex : operandList) { list.add(toSql(program, rex)); } return list; }
private SqlNode createLeftCall(SqlOperator op, List<SqlNode> nodeList) { if (nodeList.size() == 2) { return op.createCall(new SqlNodeList(nodeList, POS)); } final List<SqlNode> butLast = Util.skipLast(nodeList); final SqlNode last = nodeList.get(nodeList.size() - 1); final SqlNode call = createLeftCall(op, butLast); return op.createCall(new SqlNodeList(ImmutableList.of(call, last), POS)); }
case LOCAL_REF: final int index = ((RexLocalRef) rex).getIndex(); return toSql(program, program.getExprList().get(index)); return field(((RexInputRef) rex).getIndex()); assert lastAccess != null; sqlIdentifier = (SqlIdentifier) correlAliasContext .field(lastAccess.getField().getIndex()); break; default: sqlIdentifier = (SqlIdentifier) toSql(program, referencedExpr); final RexPatternFieldRef ref = (RexPatternFieldRef) rex; String pv = ref.getAlpha(); SqlNode refNode = field(ref.getIndex()); final SqlIdentifier id = (SqlIdentifier) refNode; if (id.names.size() > 1) { final RexCall caseCall = (RexCall) rex; final List<SqlNode> caseNodeList = toSql(program, caseCall.getOperands()); final SqlNode valueNode; final List<SqlNode> whenList = Expressions.list(); SqlNode op0; if (operands.size() == 1) { op0 = toSql(program, operands.get(0)); } else {
case LOCAL_REF: final int index = ((RexLocalRef) rex).getIndex(); return toSql(program, program.getExprList().get(index)); return field(((RexInputRef) rex).getIndex()); case CORREL_VARIABLE: final RexCorrelVariable variable = (RexCorrelVariable) referencedExpr; final Context correlAliasContext = getAliasContext(variable); final RexFieldAccess lastAccess = accesses.pollLast(); assert lastAccess != null; sqlIdentifier = (SqlIdentifier) correlAliasContext .field(lastAccess.getField().getIndex()); break; default: sqlIdentifier = (SqlIdentifier) toSql(program, referencedExpr); final RexPatternFieldRef ref = (RexPatternFieldRef) rex; String pv = ref.getAlpha(); SqlNode refNode = field(ref.getIndex()); final SqlIdentifier id = (SqlIdentifier) refNode; if (id.names.size() > 1) { final RexCall caseCall = (RexCall) rex; final List<SqlNode> caseNodeList = toSql(program, caseCall.getOperands()); final SqlNode valueNode; final List<SqlNode> whenList = Expressions.list();
if (e.getPartitionKeys() != null) { for (RexNode rex : e.getPartitionKeys()) { SqlNode sqlNode = context.toSql(null, rex); partitionSqlList.add(sqlNode); boolean first = fc.nullDirection == RelFieldCollation.NullDirection.FIRST; SqlNode nullDirectionNode = dialect.emulateNullDirection(context.field(fc.getFieldIndex()), first, fc.direction.isDescending()); if (nullDirectionNode != null) { orderBySqlList.add(context.toSql(fc)); final SqlNode pattern = context.toSql(null, rexPattern); final SqlLiteral strictStart = SqlLiteral.createBoolean(e.isStrictStart(), POS); final SqlLiteral strictEnd = SqlLiteral.createBoolean(e.isStrictEnd(), POS); SqlIntervalLiteral interval = null; if (rexInterval != null) { interval = (SqlIntervalLiteral) context.toSql(null, rexInterval); for (Map.Entry<String, RexNode> entry : e.getMeasures().entrySet()) { final String alias = entry.getKey(); final SqlNode sqlNode = context.toSql(null, entry.getValue()); measureList.add(as(sqlNode, alias)); for (Map.Entry<String, RexNode> entry : e.getPatternDefinitions().entrySet()) { final String alias = entry.getKey(); final SqlNode sqlNode = context.toSql(null, entry.getValue());
Context joinContext = leftContext.implementor().joinContext(leftContext, rightContext); return joinContext.toSql(null, node); leftContext.field(op0.getIndex()), rightContext.field(op1.getIndex() - leftFieldCount)); leftContext.field(op1.getIndex()), rightContext.field(op0.getIndex() - leftFieldCount)); leftContext.implementor().joinContext(leftContext, rightContext); return joinContext.toSql(null, node); case IS_NULL: case IS_NOT_NULL: final RexInputRef op0 = (RexInputRef) operands.get(0); if (op0.getIndex() < leftFieldCount) { return op.createCall(POS, leftContext.field(op0.getIndex())); } else { return op.createCall(POS, rightContext.field(op0.getIndex() - leftFieldCount)); leftContext.implementor().joinContext(leftContext, rightContext); return joinContext.toSql(null, node); default: throw new AssertionError(node);
leftContext.field(op0.getIndex()), rightContext.field(op1.getIndex() - leftFieldCount)); leftContext.field(op1.getIndex()), rightContext.field(op0.getIndex() - leftFieldCount)); leftContext.implementor().joinContext(leftContext, rightContext); return joinContext.toSql(null, node); case IS_NULL: case IS_NOT_NULL: final RexInputRef op0 = (RexInputRef) operands.get(0); if (op0.getIndex() < leftFieldCount) { return op.createCall(POS, leftContext.field(op0.getIndex())); } else { return op.createCall(POS, rightContext.field(op0.getIndex() - leftFieldCount)); leftContext.implementor().joinContext(leftContext, rightContext); return joinContext.toSql(null, node); default: throw new AssertionError(node);
if (e.getPartitionKeys() != null) { for (RexNode rex : e.getPartitionKeys()) { SqlNode sqlNode = context.toSql(null, rex); partitionSqlList.add(sqlNode); boolean first = fc.nullDirection == RelFieldCollation.NullDirection.FIRST; SqlNode nullDirectionNode = dialect.emulateNullDirection(context.field(fc.getFieldIndex()), first, fc.direction.isDescending()); if (nullDirectionNode != null) { orderBySqlList.add(context.toSql(fc)); final SqlNode pattern = context.toSql(null, rexPattern); final SqlLiteral strictStart = SqlLiteral.createBoolean(e.isStrictStart(), POS); final SqlLiteral strictEnd = SqlLiteral.createBoolean(e.isStrictEnd(), POS); SqlIntervalLiteral interval = null; if (rexInterval != null) { interval = (SqlIntervalLiteral) context.toSql(null, rexInterval); for (Map.Entry<String, RexNode> entry : e.getMeasures().entrySet()) { final String alias = entry.getKey(); final SqlNode sqlNode = context.toSql(null, entry.getValue()); measureList.add(as(sqlNode, alias)); for (Map.Entry<String, RexNode> entry : e.getPatternDefinitions().entrySet()) { final String alias = entry.getKey(); final SqlNode sqlNode = context.toSql(null, entry.getValue());
final List<SqlNode> selectList = new ArrayList<>(); for (int group : e.getGroupSet()) { final SqlNode field = builder.context.field(group); addSelect(selectList, field, e.getRowType()); groupByList.add(field); SqlNode aggCallSqlNode = builder.context.toSql(aggCall); if (aggCall.getAggregation() instanceof SqlSingleValueAggFunction) { aggCallSqlNode = dialect.
final List<SqlNode> selectList = new ArrayList<>(); for (int group : e.getGroupSet()) { final SqlNode field = builder.context.field(group); addSelect(selectList, field, e.getRowType()); groupByList.add(field); SqlNode aggCallSqlNode = builder.context.toSql(aggCall); if (aggCall.getAggregation() instanceof SqlSingleValueAggFunction) { aggCallSqlNode = dialect.
private SqlCall toSql(RexProgram program, RexOver rexOver) { final RexWindow rexWindow = rexOver.getWindow(); final SqlNodeList partitionList = new SqlNodeList( toSql(program, rexWindow.partitionKeys), POS); ImmutableList.Builder<SqlNode> orderNodes = ImmutableList.builder(); if (rexWindow.orderKeys != null) { for (RexFieldCollation rfc : rexWindow.orderKeys) { orderNodes.add(toSql(program, rfc)); } } final SqlNodeList orderList = new SqlNodeList(orderNodes.build(), POS); final SqlLiteral isRows = SqlLiteral.createBoolean(rexWindow.isRows(), POS); final SqlNode lowerBound = createSqlWindowBound(rexWindow.getLowerBound()); final SqlNode upperBound = createSqlWindowBound(rexWindow.getUpperBound()); // null defaults to true. // During parsing the allowPartial == false (e.g. disallow partial) // is expand into CASE expression and is handled as a such. // Not sure if we can collapse this CASE expression back into // "disallow partial" and set the allowPartial = false. final SqlLiteral allowPartial = null; final SqlWindow sqlWindow = SqlWindow.create(null, null, partitionList, orderList, isRows, lowerBound, upperBound, allowPartial, POS); final List<SqlNode> nodeList = toSql(program, rexOver.getOperands()); return createOverCall(rexOver.getAggOperator(), nodeList, sqlWindow); }
private SqlCall toSql(RexProgram program, RexOver rexOver) { final RexWindow rexWindow = rexOver.getWindow(); final SqlNodeList partitionList = new SqlNodeList( toSql(program, rexWindow.partitionKeys), POS); orderNodes.add(toSql(program, rfc)); createSqlWindowBound(rexWindow.getLowerBound()); final SqlNode upperBound = createSqlWindowBound(rexWindow.getUpperBound()); orderList, isRows, lowerBound, upperBound, allowPartial, POS); final List<SqlNode> nodeList = toSql(program, rexOver.getOperands()); final SqlCall aggFunctionCall = rexOver.getAggOperator().createCall(POS, nodeList);
/** @see #dispatch */ public Result visit(Calc e) { Result x = visitChild(0, e.getInput()); parseCorrelTable(e, x); final RexProgram program = e.getProgram(); Builder builder = program.getCondition() != null ? x.builder(e, Clause.WHERE) : x.builder(e); if (!isStar(program)) { final List<SqlNode> selectList = new ArrayList<>(); for (RexLocalRef ref : program.getProjectList()) { SqlNode sqlExpr = builder.context.toSql(program, ref); addSelect(selectList, sqlExpr, e.getRowType()); } builder.setSelect(new SqlNodeList(selectList, POS)); } if (program.getCondition() != null) { builder.setWhere( builder.context.toSql(program, program.getCondition())); } return builder.result(); }
/** @see #dispatch */ public Result visit(Calc e) { Result x = visitChild(0, e.getInput()); parseCorrelTable(e, x); final RexProgram program = e.getProgram(); Builder builder = program.getCondition() != null ? x.builder(e, Clause.WHERE) : x.builder(e); if (!isStar(program)) { final List<SqlNode> selectList = new ArrayList<>(); for (RexLocalRef ref : program.getProjectList()) { SqlNode sqlExpr = builder.context.toSql(program, ref); addSelect(selectList, sqlExpr, e.getRowType()); } builder.setSelect(new SqlNodeList(selectList, POS)); } if (program.getCondition() != null) { builder.setWhere( builder.context.toSql(program, program.getCondition())); } return builder.result(); }
/** @see #dispatch */ public Result visit(Filter e) { final RelNode input = e.getInput(); Result x = visitChild(0, input); parseCorrelTable(e, x); if (input instanceof Aggregate) { final Builder builder; if (((Aggregate) input).getInput() instanceof Project) { builder = x.builder(e); builder.clauses.add(Clause.HAVING); } else { builder = x.builder(e, Clause.HAVING); } builder.setHaving(builder.context.toSql(null, e.getCondition())); return builder.result(); } else { final Builder builder = x.builder(e, Clause.WHERE); builder.setWhere(builder.context.toSql(null, e.getCondition())); return builder.result(); } }
/** @see #dispatch */ public Result visit(Sort e) { Result x = visitChild(0, e.getInput()); Builder builder = x.builder(e, Clause.ORDER_BY); List<SqlNode> orderByList = Expressions.list(); for (RelFieldCollation field : e.getCollation().getFieldCollations()) { builder.addOrderItem(orderByList, field); } if (!orderByList.isEmpty()) { builder.setOrderBy(new SqlNodeList(orderByList, POS)); x = builder.result(); } if (e.fetch != null) { builder = x.builder(e, Clause.FETCH); builder.setFetch(builder.context.toSql(null, e.fetch)); x = builder.result(); } if (e.offset != null) { builder = x.builder(e, Clause.OFFSET); builder.setOffset(builder.context.toSql(null, e.offset)); x = builder.result(); } return x; }
/** Converts a call to an aggregate function to an expression. */ public SqlNode toSql(AggregateCall aggCall) { final SqlOperator op = aggCall.getAggregation(); final List<SqlNode> operandList = Expressions.list(); for (int arg : aggCall.getArgList()) { operandList.add(field(arg)); } final SqlLiteral qualifier = aggCall.isDistinct() ? SqlSelectKeyword.DISTINCT.symbol(POS) : null; final SqlNode[] operands = operandList.toArray(new SqlNode[0]); List<SqlNode> orderByList = Expressions.list(); for (RelFieldCollation field : aggCall.collation.getFieldCollations()) { addOrderItem(orderByList, field); } SqlNodeList orderList = new SqlNodeList(orderByList, POS); if (op instanceof SqlSumEmptyIsZeroAggFunction) { final SqlNode node = withOrder( SqlStdOperatorTable.SUM.createCall(qualifier, POS, operands), orderList); return SqlStdOperatorTable.COALESCE.createCall(POS, node, SqlLiteral.createExactNumeric("0", POS)); } else { return withOrder(op.createCall(qualifier, POS, operands), orderList); } }
/** Converts a collation to an ORDER BY item. */ public SqlNode toSql(RelFieldCollation collation) { SqlNode node = field(collation.getFieldIndex()); switch (collation.getDirection()) { case DESCENDING: case STRICTLY_DESCENDING: node = SqlStdOperatorTable.DESC.createCall(POS, node); } if (collation.nullDirection != dialect.defaultNullDirection(collation.direction)) { switch (collation.nullDirection) { case FIRST: node = SqlStdOperatorTable.NULLS_FIRST.createCall(POS, node); break; case LAST: node = SqlStdOperatorTable.NULLS_LAST.createCall(POS, node); break; } } return node; }
/** @see #dispatch */ public Result visit(Sort e) { Result x = visitChild(0, e.getInput()); Builder builder = x.builder(e, Clause.ORDER_BY); List<SqlNode> orderByList = Expressions.list(); for (RelFieldCollation field : e.getCollation().getFieldCollations()) { builder.addOrderItem(orderByList, field); } if (!orderByList.isEmpty()) { builder.setOrderBy(new SqlNodeList(orderByList, POS)); x = builder.result(); } if (e.fetch != null) { builder = x.builder(e, Clause.FETCH); builder.setFetch(builder.context.toSql(null, e.fetch)); x = builder.result(); } if (e.offset != null) { builder = x.builder(e, Clause.OFFSET); builder.setOffset(builder.context.toSql(null, e.offset)); x = builder.result(); } return x; }
private SqlNode createSqlWindowBound(RexWindowBound rexWindowBound) { if (rexWindowBound.isCurrentRow()) { return SqlWindow.createCurrentRow(POS); } if (rexWindowBound.isPreceding()) { if (rexWindowBound.isUnbounded()) { return SqlWindow.createUnboundedPreceding(POS); } else { SqlNode literal = toSql(null, rexWindowBound.getOffset()); return SqlWindow.createPreceding(literal, POS); } } if (rexWindowBound.isFollowing()) { if (rexWindowBound.isUnbounded()) { return SqlWindow.createUnboundedFollowing(POS); } else { SqlNode literal = toSql(null, rexWindowBound.getOffset()); return SqlWindow.createFollowing(literal, POS); } } throw new AssertionError("Unsupported Window bound: " + rexWindowBound); }