private RexNode convertIsDistinctFrom( SqlRexContext cx, SqlCall call, boolean neg) { RexNode op0 = cx.convertExpression(call.operand(0)); RexNode op1 = cx.convertExpression(call.operand(1)); return RelOptUtil.isDistinctFrom( cx.getRexBuilder(), op0, op1, neg); }
/** * Casts a RexNode value to the validated type of a SqlCall. If the value * was already of the validated type, then the value is returned without an * additional cast. */ public RexNode castToValidatedType( SqlRexContext cx, SqlCall call, RexNode value) { return castToValidatedType(call, value, cx.getValidator(), cx.getRexBuilder()); }
@Override public RexNode convertCall(SqlRexContext cx, SqlCall call) { SqlFlattenOperator operator = (SqlFlattenOperator) call.getOperator(); final List<RexNode> exprs = new LinkedList<>(); for (SqlNode node : call.getOperandList()) { exprs.add(cx.convertExpression(node)); } SqlFlattenOperator indexedOperator = operator.withIndex(((SqlValidatorImpl)cx.getValidator()).nextFlattenIndex()); final RexBuilder rexBuilder = cx.getRexBuilder(); // Since we don't have any way of knowing if the output of the flatten is nullable, we should always assume it is. // This is especially important when accelerating a count(column) query, because the normalizer will convert it to // a count(1) if it thinks this column is non-nullable, and then remove the flatten altogether. This is actually a // problem with the fact that flatten is not really a project operator (because it can output more than one row per input). RelDataType type = rexBuilder .getTypeFactory() .createTypeWithNullability( rexBuilder .getTypeFactory() .createSqlType(SqlTypeName.ANY), true ); return rexBuilder.makeCall(type, indexedOperator, exprs); }
@Override public RexNode convertCall(SqlRexContext cx, SqlCall call) { final RexBuilder rexBuilder = cx.getRexBuilder(); final SqlLiteral literal = (SqlLiteral) call.getOperandList().get(0); final String value = ((NlsString)literal.getValue()).getValue(); TimeUnitRange range = VALID_PERIODS.get(value.toLowerCase()); Preconditions.checkNotNull(range, "Unhandle range type: %s.", value); List<RexNode> exprs = new ArrayList<>(); exprs.add(rexBuilder.makeFlag(range)); exprs.add(cx.convertExpression(call.getOperandList().get(1))); RelDataTypeFactory typeFactory = cx.getTypeFactory(); final RelDataType returnType = typeFactory.createTypeWithNullability(typeFactory.createSqlType(SqlTypeName.BIGINT), exprs.get(1).getType().isNullable()); return rexBuilder.makeCall(returnType, SqlStdOperatorTable.EXTRACT, exprs); }
protected RexNode convertCast( SqlRexContext cx, final SqlCall call) { RelDataTypeFactory typeFactory = cx.getTypeFactory(); assert call.getKind() == SqlKind.CAST; final SqlNode left = call.operand(0); if (left instanceof SqlIntervalLiteral) { RexLiteral sourceInterval = (RexLiteral) cx.convertExpression(left); BigDecimal sourceValue = (BigDecimal) sourceInterval.getValue(); RexLiteral castedInterval = cx.getRexBuilder().makeIntervalLiteral(sourceValue, intervalQualifier); return castToValidatedType(cx, call, castedInterval); } else if (left instanceof SqlNumericLiteral) { RexLiteral sourceInterval = (RexLiteral) cx.convertExpression(left); BigDecimal sourceValue = (BigDecimal) sourceInterval.getValue(); sourceValue = sourceValue.multiply(multiplier); RexLiteral castedInterval = cx.getRexBuilder().makeIntervalLiteral( sourceValue, intervalQualifier); return castToValidatedType(cx, call, castedInterval); return castToValidatedType(cx, call, cx.convertExpression(left));
@Override public RexNode convertCall(final SqlRexContext cx, final SqlCall call) { final SqlOperator operator = call.getOperator(); if (operator.equals(SqlStdOperatorTable.CURRENT_TIMESTAMP) || operator.equals(SqlStdOperatorTable.LOCALTIMESTAMP)) { return cx.getRexBuilder().makeTimestampLiteral( Calcites.jodaToCalciteTimestampString(plannerContext.getLocalNow(), plannerContext.getTimeZone()), RelDataType.PRECISION_NOT_SPECIFIED ); } else if (operator.equals(SqlStdOperatorTable.CURRENT_TIME) || operator.equals(SqlStdOperatorTable.LOCALTIME)) { return cx.getRexBuilder().makeTimeLiteral( Calcites.jodaToCalciteTimeString(plannerContext.getLocalNow(), plannerContext.getTimeZone()), RelDataType.PRECISION_NOT_SPECIFIED ); } else if (operator.equals(SqlStdOperatorTable.CURRENT_DATE)) { return cx.getRexBuilder().makeDateLiteral( Calcites.jodaToCalciteDateString( plannerContext.getLocalNow().hourOfDay().roundFloorCopy(), plannerContext.getTimeZone() ) ); } else { throw new ISE("WTF?! Should not have got here, operator was: %s", operator); } } }
public RexNode convertMultiset( SqlRexContext cx, SqlMultisetValueConstructor op, SqlCall call) { final RelDataType originalType = cx.getValidator().getValidatedNodeType(call); RexRangeRef rr = cx.getSubQueryExpr(call); assert rr != null; RelDataType msType = rr.getType().getFieldList().get(0).getType(); RexNode expr = cx.getRexBuilder().makeInputRef( msType, rr.getOffset()); assert msType.getComponentType().isStruct(); if (!originalType.getComponentType().isStruct()) { // If the type is not a struct, the multiset operator will have // wrapped the type as a record. Add a call to the $SLICE operator // to compensate. For example, // if '<ms>' has type 'RECORD (INTEGER x) MULTISET', // then '$SLICE(<ms>) has type 'INTEGER MULTISET'. // This will be removed as the expression is translated. expr = cx.getRexBuilder().makeCall(originalType, SqlStdOperatorTable.SLICE, ImmutableList.of(expr)); } return expr; }
public RexNode convertAggregateFunction( SqlRexContext cx, SqlAggFunction fun, SqlCall call) { final List<SqlNode> operands = call.getOperandList(); final List<RexNode> exprs; if (call.isCountStar()) { exprs = ImmutableList.of(); } else { exprs = convertExpressionList(cx, operands, SqlOperandTypeChecker.Consistency.NONE); } RelDataType returnType = cx.getValidator().getValidatedNodeTypeIfKnown(call); final int groupCount = cx.getGroupCount(); if (returnType == null) { RexCallBinding binding = new RexCallBinding(cx.getTypeFactory(), fun, exprs, ImmutableList.of()) { @Override public int getGroupCount() { return groupCount; } }; returnType = fun.inferReturnType(binding); } return cx.getRexBuilder().makeCall(returnType, fun, exprs); }
public RexNode convertLiteral( SqlRexContext cx, SqlLiteral literal) { RexBuilder rexBuilder = cx.getRexBuilder(); RelDataTypeFactory typeFactory = cx.getTypeFactory(); SqlValidator validator = cx.getValidator(); if (literal.getValue() == null) {
public RexNode convertJdbc( SqlRexContext cx, SqlJdbcFunctionCall op, SqlCall call) { // Yuck!! The function definition contains arguments! // TODO: adopt a more conventional definition/instance structure final SqlCall convertedCall = op.getLookupCall(); return cx.convertExpression(convertedCall); }
private Pair<RexNode, RexNode> convertOverlapsOperand(SqlRexContext cx, SqlParserPos pos, SqlNode operand) { final SqlNode a0; final SqlNode a1; switch (operand.getKind()) { case ROW: a0 = ((SqlCall) operand).operand(0); final SqlNode a10 = ((SqlCall) operand).operand(1); final RelDataType t1 = cx.getValidator().getValidatedNodeType(a10); if (SqlTypeUtil.isInterval(t1)) { // make t1 = t0 + t1 when t1 is an interval. a1 = plus(pos, a0, a10); } else { a1 = a10; } break; default: a0 = operand; a1 = operand; } final RexNode r0 = cx.convertExpression(a0); final RexNode r1 = cx.convertExpression(a1); return Pair.of(r0, r1); }
private static RexNode makeConstructorCall( SqlRexContext cx, SqlFunction constructor, List<RexNode> exprs) { final RexBuilder rexBuilder = cx.getRexBuilder(); RelDataType type = rexBuilder.deriveReturnType(constructor, exprs); int n = type.getFieldCount(); ImmutableList.Builder<RexNode> initializationExprs = ImmutableList.builder(); final InitializerContext initializerContext = new InitializerContext() { public RexBuilder getRexBuilder() { return rexBuilder; } public RexNode convertExpression(SqlNode e) { throw new UnsupportedOperationException(); } }; for (int i = 0; i < n; ++i) { initializationExprs.add( cx.getInitializerExpressionFactory().newAttributeInitializer( type, constructor, i, exprs, initializerContext)); } List<RexNode> defaultCasts = RexUtil.generateCastExpressions( rexBuilder, type, initializationExprs.build()); return rexBuilder.makeNewInvocation(type, defaultCasts); }
case NUMERIC: nonCharacterTypes.add( cx.getTypeFactory().createSqlType(SqlTypeName.BIGINT)); return cx.getTypeFactory().leastRestrictive(types); default: return null;
/** * Converts a LiteralChain expression: that is, concatenates the operands * immediately, to produce a single literal string. * * <p>Called automatically via reflection. */ public RexNode convertLiteralChain( SqlRexContext cx, SqlLiteralChainOperator op, SqlCall call) { Util.discard(cx); SqlLiteral sum = SqlLiteralChainOperator.concatenateOperands(call); return cx.convertLiteral(sum); }
public RexNode convertCall(SqlRexContext cx, SqlCall call) { assert call.operandCount() == 2; final SqlNode arg1 = call.operand(0); final SqlNode arg2 = call.operand(1); final SqlNode expr; final RelDataType type = cx.getValidator().getValidatedNodeType(call); switch (kind) { case COVAR_POP: expr = expandCovariance(arg1, arg2, null, type, cx, true); break; case COVAR_SAMP: expr = expandCovariance(arg1, arg2, null, type, cx, false); break; case REGR_SXX: expr = expandRegrSzz(arg2, arg1, type, cx, true); break; case REGR_SYY: expr = expandRegrSzz(arg1, arg2, type, cx, true); break; default: throw Util.unexpected(kind); } RexNode rex = cx.convertExpression(expr); return cx.getRexBuilder().ensureType(type, rex, true); }
public RexNode convertCall(SqlRexContext cx, SqlCall call) { final RexBuilder rexBuilder = cx.getRexBuilder(); final SqlLiteral unitLiteral = call.operand(0); TimeUnit unit = unitLiteral.symbolValue(TimeUnit.class); final RexNode op2 = cx.convertExpression(call.operand(2)); final RexNode op1 = cx.convertExpression(call.operand(1)); final RelDataType intervalType = cx.getTypeFactory().createTypeWithNullability( cx.getTypeFactory().createSqlIntervalType(qualifier), op1.getType().isNullable() || op2.getType().isNullable()); final RexCall rexCall = (RexCall) rexBuilder.makeCall( ImmutableList.of(op2, op1)); final RelDataType intType = cx.getTypeFactory().createTypeWithNullability( cx.getTypeFactory().createSqlType(sqlTypeName), SqlTypeUtil.containsNullable(rexCall.getType())); RexNode e = rexBuilder.makeCast(intType, rexCall);
protected RexNode convertCast( SqlRexContext cx, final SqlCall call) { RelDataTypeFactory typeFactory = cx.getTypeFactory(); assert call.getKind() == SqlKind.CAST; final SqlNode left = call.operand(0); if (left instanceof SqlIntervalLiteral) { RexLiteral sourceInterval = (RexLiteral) cx.convertExpression(left); BigDecimal sourceValue = (BigDecimal) sourceInterval.getValue(); RexLiteral castedInterval = cx.getRexBuilder().makeIntervalLiteral(sourceValue, intervalQualifier); return castToValidatedType(cx, call, castedInterval); } else if (left instanceof SqlNumericLiteral) { RexLiteral sourceInterval = (RexLiteral) cx.convertExpression(left); BigDecimal sourceValue = (BigDecimal) sourceInterval.getValue(); sourceValue = sourceValue.multiply(multiplier); RexLiteral castedInterval = cx.getRexBuilder().makeIntervalLiteral( sourceValue, intervalQualifier); return castToValidatedType(cx, call, castedInterval); return castToValidatedType(cx, call, cx.convertExpression(left));
public RexLiteral convertInterval( SqlRexContext cx, SqlIntervalQualifier intervalQualifier) { RexBuilder rexBuilder = cx.getRexBuilder(); return rexBuilder.makeIntervalLiteral(intervalQualifier); }
public RexNode convertMultiset( SqlRexContext cx, SqlMultisetValueConstructor op, SqlCall call) { final RelDataType originalType = cx.getValidator().getValidatedNodeType(call); RexRangeRef rr = cx.getSubQueryExpr(call); assert rr != null; RelDataType msType = rr.getType().getFieldList().get(0).getType(); RexNode expr = cx.getRexBuilder().makeInputRef( msType, rr.getOffset()); assert msType.getComponentType().isStruct(); if (!originalType.getComponentType().isStruct()) { // If the type is not a struct, the multiset operator will have // wrapped the type as a record. Add a call to the $SLICE operator // to compensate. For example, // if '<ms>' has type 'RECORD (INTEGER x) MULTISET', // then '$SLICE(<ms>) has type 'INTEGER MULTISET'. // This will be removed as the expression is translated. expr = cx.getRexBuilder().makeCall(originalType, SqlStdOperatorTable.SLICE, ImmutableList.of(expr)); } return expr; }
public RexNode convertAggregateFunction( SqlRexContext cx, SqlAggFunction fun, SqlCall call) { final List<SqlNode> operands = call.getOperandList(); final List<RexNode> exprs; if (call.isCountStar()) { exprs = ImmutableList.of(); } else { exprs = convertExpressionList(cx, operands, SqlOperandTypeChecker.Consistency.NONE); } RelDataType returnType = cx.getValidator().getValidatedNodeTypeIfKnown(call); final int groupCount = cx.getGroupCount(); if (returnType == null) { RexCallBinding binding = new RexCallBinding(cx.getTypeFactory(), fun, exprs, ImmutableList.of()) { @Override public int getGroupCount() { return groupCount; } }; returnType = fun.inferReturnType(binding); } return cx.getRexBuilder().makeCall(returnType, fun, exprs); }