RexNode rexAgg = exprConverter.convertCall(bb, aggCall); rexAgg = rexBuilder.ensureType( validator.getValidatedNodeType(call), rexAgg, false);
/** * Ensures expression is interpreted as a specified type. The returned * expression may be wrapped with a cast. * * @param type desired type * @param node expression * @param matchNullability whether to correct nullability of specified * type to match the expression; this usually should * be true, except for explicit casts which can * override default nullability * @return a casted expression or the original expression */ protected RexNode ensureType( RelDataType type, RexNode node, boolean matchNullability) { return builder.ensureType(type, node, matchNullability); }
/** * Ensures expression is interpreted as a specified type. The returned * expression may be wrapped with a cast. * * @param type desired type * @param node expression * @param matchNullability whether to correct nullability of specified * type to match the expression; this usually should be true, except for * explicit casts which can override default nullability * * @return a casted expression or the original expression */ protected RexNode ensureType( RelDataType type, RexNode node, boolean matchNullability) { return builder.ensureType(type, node, matchNullability); }
private void ensureSameType(SqlRexContext cx, final List<RexNode> exprs) { RelDataType type = cx.getTypeFactory().leastRestrictive( new AbstractList<RelDataType>() { public RelDataType get(int index) { return exprs.get(index).getType(); } public int size() { return exprs.size(); } }); for (int i = 0; i < exprs.size(); i++) { // REVIEW: assigning to a list that may be immutable? exprs.set( i, cx.getRexBuilder().ensureType(type, exprs.get(i), true)); } }
private void ensureSameType(SqlRexContext cx, final List<RexNode> exprs) { RelDataType type = cx.getTypeFactory().leastRestrictive( new AbstractList<RelDataType>() { public RelDataType get(int index) { return exprs.get(index).getType(); } public int size() { return exprs.size(); } }); for (int i = 0; i < exprs.size(); i++) { // REVIEW: assigning to a list that may be immutable? exprs.set( i, cx.getRexBuilder().ensureType(type, exprs.get(i), true)); } }
private Expression implementRecurse( RexToLixTranslator translator, RexCall call, int i) { List<RexNode> operands = call.getOperands(); if (i == operands.size() - 1) { // the "else" clause return translator.translate( translator.builder.ensureType( call.getType(), operands.get(i), false)); } else { return Expressions.condition( translator.translate(operands.get(i), NullAs.FALSE), translator.translate( translator.builder.ensureType(call.getType(), operands.get(i + 1), false)), implementRecurse(translator, call, i + 2)); } } }
/** * Casts a decimal's integer representation to a decimal node. If the * expression is not the expected integer type, then it is casted first. * * <p>An overflow check may be requested to ensure the internal value * does not exceed the maximum value of the decimal type. * * @param value integer representation of decimal * @param type type integer will be reinterpreted as * @param checkOverflow indicates whether an overflow check is required * when reinterpreting this particular value as the * decimal type. A check usually not required for * arithmetic, but is often required for rounding and * explicit casts. * @return the integer reinterpreted as an opaque decimal type */ public RexNode encodeIntervalOrDecimal( RexNode value, RelDataType type, boolean checkOverflow) { RelDataType bigintType = typeFactory.createSqlType( SqlTypeName.BIGINT); RexNode cast = ensureType(bigintType, value, true); return makeReinterpretCast(type, cast, makeLiteral(checkOverflow)); }
translator.builder.ensureType( call.getType(), operands.get(i), false), nullAs); } else { try { ifTrue = translator.translate( translator.builder.ensureType(call.getType(), operands.get(i + 1), false), nullAs);
/** * Casts a decimal's integer representation to a decimal node. If the * expression is not the expected integer type, then it is casted first. * * <p>An overflow check may be requested to ensure the internal value * does not exceed the maximum value of the decimal type. * * @param value integer representation of decimal * @param type type integer will be reinterpreted as * @param checkOverflow indicates whether an overflow check is required * when reinterpreting this particular value as the decimal type. A * check usually not required for arithmetic, but is often required for * rounding and explicit casts. * * @return the integer reinterpreted as an opaque decimal type */ public RexNode encodeIntervalOrDecimal( RexNode value, RelDataType type, boolean checkOverflow) { RelDataType bigintType = typeFactory.createSqlType( SqlTypeName.BIGINT); RexNode cast = ensureType(bigintType, value, true); return makeReinterpretCast( type, cast, makeLiteral(checkOverflow)); }
/** Ensures that operands have identical type. */ private static List<RexNode> harmonize( final RexToLixTranslator translator, final List<RexNode> operands) { int nullCount = 0; final List<RelDataType> types = new ArrayList<RelDataType>(); final RelDataTypeFactory typeFactory = translator.builder.getTypeFactory(); for (RexNode operand : operands) { RelDataType type = operand.getType(); if (translator.isNullable(operand)) { ++nullCount; } else { type = typeFactory.createTypeWithNullability(type, false); } types.add(type); } if (allSame(types)) { // Operands have the same nullability and type. Return them // unchanged. return operands; } final RelDataType type = typeFactory.leastRestrictive(types); assert (nullCount > 0) == type.isNullable(); final List<RexNode> list = new ArrayList<RexNode>(); for (RexNode operand : operands) { list.add( translator.builder.ensureType(type, operand, false)); } return list; }
for (RexNode operand : operands) { list.add( translator.builder.ensureType(type, operand, false));
private MutableRel invert(MutableRel model, MutableRel input, MutableProject project) { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer("SubstitutionVisitor: invert:\n" + "model: " + model + "\n" + "input: " + input + "\n" + "project: " + project + "\n"); } final List<RexNode> exprList = new ArrayList<RexNode>(); final RexBuilder rexBuilder = model.cluster.getRexBuilder(); for (RelDataTypeField field : model.getRowType().getFieldList()) { exprList.add(rexBuilder.makeZeroLiteral(field.getType())); } for (Ord<RexNode> expr : Ord.zip(project.getProjects())) { if (expr.e instanceof RexInputRef) { final int target = ((RexInputRef) expr.e).getIndex(); exprList.set(expr.i, rexBuilder.ensureType(expr.e.getType(), RexInputRef.of(target, input.rowType), false)); } else { throw MatchFailed.INSTANCE; } } return MutableProject.of(model.rowType, input, exprList); } }
/** * Converts a CASE expression. */ public RexNode convertCase( SqlRexContext cx, SqlCase call) { SqlNodeList whenList = call.getWhenOperands(); SqlNodeList thenList = call.getThenOperands(); assert whenList.size() == thenList.size(); final List<RexNode> exprList = new ArrayList<RexNode>(); for (int i = 0; i < whenList.size(); i++) { exprList.add(cx.convertExpression(whenList.get(i))); exprList.add(cx.convertExpression(thenList.get(i))); } exprList.add(cx.convertExpression(call.getElseOperand())); RexBuilder rexBuilder = cx.getRexBuilder(); RelDataType type = rexBuilder.deriveReturnType(call.getOperator(), exprList); for (int i : elseArgs(exprList.size())) { exprList.set(i, rexBuilder.ensureType(type, exprList.get(i), false)); } return rexBuilder.makeCall(type, SqlStdOperatorTable.CASE, exprList); }
/** * Converts a CASE expression. */ public RexNode convertCase( SqlRexContext cx, SqlCase call) { SqlNodeList whenList = call.getWhenOperands(); SqlNodeList thenList = call.getThenOperands(); assert (whenList.size() == thenList.size()); final List<RexNode> exprList = new ArrayList<RexNode>(); for (int i = 0; i < whenList.size(); i++) { exprList.add(cx.convertExpression(whenList.get(i))); exprList.add(cx.convertExpression(thenList.get(i))); } exprList.add(cx.convertExpression(call.getElseOperand())); RexBuilder rexBuilder = cx.getRexBuilder(); RelDataType type = rexBuilder.deriveReturnType( call.getOperator(), cx.getTypeFactory(), exprList); for (int i : elseArgs(exprList.size())) { exprList.set( i, rexBuilder.ensureType(type, exprList.get(i), false)); } return rexBuilder.makeCall( SqlStdOperatorTable.caseOperator, exprList); }
private RexNode makeCastExactToInterval(RelDataType toType, RexNode exp) { IntervalSqlType intervalType = (IntervalSqlType) toType; TimeUnit endUnit = intervalType.getIntervalQualifier().getEndUnit(); if (endUnit == null) { endUnit = intervalType.getIntervalQualifier().getStartUnit(); } int scale = 0; if (endUnit == TimeUnit.SECOND) { scale = Math.min( intervalType.getIntervalQualifier() .getFractionalSecondPrecision(), 3); } BigDecimal multiplier = BigDecimal.valueOf(endUnit.multiplier) .divide(BigDecimal.TEN.pow(scale)); RelDataType decimalType = getTypeFactory().createSqlType( SqlTypeName.DECIMAL, scale + intervalType.getPrecision(), scale); RexNode value = decodeIntervalOrDecimal(ensureType(decimalType, exp, true)); if (multiplier.longValue() != 1) { value = makeCall( SqlStdOperatorTable.MULTIPLY, value, makeExactLiteral(multiplier)); } return encodeIntervalOrDecimal(value, toType, false); }
private RexNode makeCastExactToInterval(RelDataType toType, RexNode exp) { IntervalSqlType intervalType = (IntervalSqlType) toType; TimeUnit endUnit = intervalType.getIntervalQualifier().getEndUnit(); if (endUnit == null) { endUnit = intervalType.getIntervalQualifier().getStartUnit(); } int scale = 0; if (endUnit == TimeUnit.SECOND) { scale = Math.min( intervalType.getIntervalQualifier() .getFractionalSecondPrecision(), 3); } BigDecimal multiplier = BigDecimal.valueOf(endUnit.multiplier) .divide(BigDecimal.TEN.pow(scale)); RelDataType decimalType = getTypeFactory().createSqlType( SqlTypeName.DECIMAL, scale + intervalType.getPrecision(), scale); RexNode value = decodeIntervalOrDecimal( ensureType(decimalType, exp, true)); if (multiplier.longValue() != 1) { value = makeCall( SqlStdOperatorTable.multiplyOperator, value, makeExactLiteral(multiplier)); } return encodeIntervalOrDecimal(value, toType, false); }
value = encodeIntervalOrDecimal(value, decimalType, false); return ensureType(toType, value, false);
private RexNode makeCastIntervalToExact(RelDataType toType, RexNode exp) { IntervalSqlType intervalType = (IntervalSqlType) exp.getType(); TimeUnit endUnit = intervalType.getIntervalQualifier().getEndUnit(); if (endUnit == null) { endUnit = intervalType.getIntervalQualifier().getStartUnit(); } int scale = 0; if (endUnit == TimeUnit.SECOND) { scale = Math.min( intervalType.getIntervalQualifier() .getFractionalSecondPrecision(), 3); } BigDecimal multiplier = BigDecimal.valueOf(endUnit.multiplier) .divide(BigDecimal.TEN.pow(scale)); RexNode value = decodeIntervalOrDecimal(exp); if (multiplier.longValue() != 1) { value = makeCall( SqlStdOperatorTable.DIVIDE_INTEGER, value, makeBigintLiteral(multiplier)); } if (scale > 0) { RelDataType decimalType = getTypeFactory().createSqlType( SqlTypeName.DECIMAL, scale + intervalType.getPrecision(), scale); value = encodeIntervalOrDecimal(value, decimalType, false); } return ensureType(toType, value, false); }
public RexNode convertCall(SqlRexContext cx, SqlCall call) { assert call.operandCount() == 1; final SqlNode arg = call.operand(0); final SqlNode expr; switch (subtype) { case AVG: expr = expandAvg(arg); break; case STDDEV_POP: expr = expandVariance(arg, true, true); break; case STDDEV_SAMP: expr = expandVariance(arg, false, true); break; case VAR_POP: expr = expandVariance(arg, true, false); break; case VAR_SAMP: expr = expandVariance(arg, false, false); break; default: throw Util.unexpected(subtype); } RelDataType type = cx.getValidator().getValidatedNodeType(call); RexNode rex = cx.convertExpression(expr); return cx.getRexBuilder().ensureType(type, rex, true); }
cx.getValidator().getValidatedNodeType(call); RexNode rex = cx.convertExpression(expr); return cx.getRexBuilder().ensureType(type, rex, true);