case 2: node = rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, merges); node = rexBuilder.makeAbstractCast(aggregateCall.type, node); break; default:
private RexNode handleExplicitCast(ExprNodeGenericFuncDesc func, List<RexNode> childRexNodeLst) throws CalciteSemanticException { RexNode castExpr = null; if (childRexNodeLst != null && childRexNodeLst.size() == 1) { GenericUDF udf = func.getGenericUDF(); if ((udf instanceof GenericUDFToChar) || (udf instanceof GenericUDFToVarchar) || (udf instanceof GenericUDFToString) || (udf instanceof GenericUDFToDecimal) || (udf instanceof GenericUDFToDate) || (udf instanceof GenericUDFTimestamp) || (udf instanceof GenericUDFToTimestampLocalTZ) || (udf instanceof GenericUDFToBinary) || castExprUsingUDFBridge(udf)) { castExpr = cluster.getRexBuilder().makeAbstractCast( TypeConverter.convert(func.getTypeInfo(), cluster.getTypeFactory()), childRexNodeLst.get(0)); } } return castExpr; }
case 2: node = rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, merges); node = rexBuilder.makeAbstractCast(aggregateCall.type, node); break; default:
@Override public ASTNode visitLiteral(RexLiteral literal) { if (RexUtil.isNull(literal) && literal.getType().getSqlTypeName() != SqlTypeName.NULL && rexBuilder != null) { // It is NULL value with different type, we need to introduce a CAST // to keep it if(nullLiteralMap.containsKey(literal)) { return ASTBuilder.literal(literal, useTypeQualInLiteral); } nullLiteralMap.put(literal, true); RexNode r = rexBuilder.makeAbstractCast(literal.getType(), literal); return r.accept(this); } return ASTBuilder.literal(literal, useTypeQualInLiteral); }
private RexNode handleExplicitCast(ExprNodeGenericFuncDesc func, List<RexNode> childRexNodeLst) throws CalciteSemanticException { RexNode castExpr = null; if (childRexNodeLst != null && childRexNodeLst.size() == 1) { GenericUDF udf = func.getGenericUDF(); if ((udf instanceof GenericUDFToChar) || (udf instanceof GenericUDFToVarchar) || (udf instanceof GenericUDFToDecimal) || (udf instanceof GenericUDFToDate) // Calcite can not specify the scale for timestamp. As a result, all // the millisecond part will be lost || (udf instanceof GenericUDFTimestamp) || (udf instanceof GenericUDFToBinary) || castExprUsingUDFBridge(udf)) { castExpr = cluster.getRexBuilder().makeAbstractCast( TypeConverter.convert(func.getTypeInfo(), cluster.getTypeFactory()), childRexNodeLst.get(0)); } } return castExpr; }
@Test public void testCastFromDate() { testExpression( rexBuilder.makeAbstractCast( typeFactory.createSqlType(SqlTypeName.VARCHAR), rexBuilder.makeAbstractCast( typeFactory.createSqlType(SqlTypeName.DATE), inputRef("t") ) ), DruidExpression.fromExpression( "timestamp_format(timestamp_floor(\"t\",'P1D',null,'UTC'),'yyyy-MM-dd','UTC')" ), "2000-02-03" ); testExpression( rexBuilder.makeAbstractCast( typeFactory.createSqlType(SqlTypeName.BIGINT), rexBuilder.makeAbstractCast( typeFactory.createSqlType(SqlTypeName.DATE), inputRef("t") ) ), DruidExpression.fromExpression("timestamp_floor(\"t\",'P1D',null,'UTC')"), DateTimes.of("2000-02-03").getMillis() ); }
rexBuilder.makeAbstractCast( typeFactory.createSqlType(SqlTypeName.VARCHAR), rexBuilder.makeAbstractCast( typeFactory.createSqlType(SqlTypeName.TIMESTAMP), inputRef("t") rexBuilder.makeAbstractCast( typeFactory.createSqlType(SqlTypeName.BIGINT), rexBuilder.makeAbstractCast( typeFactory.createSqlType(SqlTypeName.TIMESTAMP), inputRef("t")
@Test public void testCastAsDate() { testExpression( rexBuilder.makeAbstractCast( typeFactory.createSqlType(SqlTypeName.DATE), inputRef("t") ), DruidExpression.fromExpression("timestamp_floor(\"t\",'P1D',null,'UTC')"), DateTimes.of("2000-02-03").getMillis() ); testExpression( rexBuilder.makeAbstractCast( typeFactory.createSqlType(SqlTypeName.DATE), inputRef("dstr") ), DruidExpression.fromExpression( "timestamp_floor(timestamp_parse(\"dstr\",null,'UTC'),'P1D',null,'UTC')" ), DateTimes.of("2000-02-03").getMillis() ); }
@Test public void testCastAsTimestamp() { testExpression( rexBuilder.makeAbstractCast( typeFactory.createSqlType(SqlTypeName.TIMESTAMP), inputRef("t") ), DruidExpression.of( SimpleExtraction.of("t", null), "\"t\"" ), DateTimes.of("2000-02-03T04:05:06Z").getMillis() ); testExpression( rexBuilder.makeAbstractCast( typeFactory.createSqlType(SqlTypeName.TIMESTAMP), inputRef("tstr") ), DruidExpression.of( null, "timestamp_parse(\"tstr\",null,'UTC')" ), DateTimes.of("2000-02-03T04:05:06Z").getMillis() ); }
r = select.getCluster().getRexBuilder().makeAbstractCast(r.getType(), r); r = select.getCluster().getRexBuilder().makeAbstractCast(r.getType(), r);
/** * Creates a call to the CAST operator. * * <p>This method enables to create {@code CAST(42 nullable int)} expressions.</p> * * @param e input node * @param type type to cast to * @return call to CAST operator */ protected RexNode abstractCast(RexNode e, RelDataType type) { return rexBuilder.makeAbstractCast(type, e); }
@Override public RexNode makeAbstractCast( RelDataType type, RexNode exp) { if (exp.getType().equals(type)) { return exp; } return super.makeAbstractCast(type, exp); }
/** * Creates a call to the CAST operator. * * <p>This method enables to create {@code CAST(42 nullable int)} expressions.</p> * * @param e input node * @param type type to cast to * @return call to CAST operator */ protected RexNode abstractCast(RexNode e, RelDataType type) { return rexBuilder.makeAbstractCast(type, e); }
private RexNode visit(final RexNode call) { int i = reducibleExps.indexOf(call); if (i == -1) { return null; } RexNode replacement = reducedValues.get(i); if (addCasts.get(i) && (replacement.getType() != call.getType())) { // Handle change from nullable to NOT NULL by claiming // that the result is still nullable, even though // we know it isn't. // // Also, we cannot reduce CAST('abc' AS VARCHAR(4)) to 'abc'. // If we make 'abc' of type VARCHAR(4), we may later encounter // the same expression in a Project's digest where it has // type VARCHAR(3), and that's wrong. replacement = simplify.rexBuilder.makeAbstractCast(call.getType(), replacement); } return replacement; } }
private RexNode visit(final RexNode call) { int i = reducibleExps.indexOf(call); if (i == -1) { return null; } RexNode replacement = reducedValues.get(i); if (addCasts.get(i) && (replacement.getType() != call.getType())) { // Handle change from nullable to NOT NULL by claiming // that the result is still nullable, even though // we know it isn't. // // Also, we cannot reduce CAST('abc' AS VARCHAR(4)) to 'abc'. // If we make 'abc' of type VARCHAR(4), we may later encounter // the same expression in a Project's digest where it has // type VARCHAR(3), and that's wrong. replacement = simplify.rexBuilder.makeAbstractCast(call.getType(), replacement); } return replacement; } }
/** * Makes a cast of a value to NOT NULL; * no-op if the type already has NOT NULL. */ public RexNode makeNotNull(RexNode exp) { final RelDataType type = exp.getType(); if (!type.isNullable()) { return exp; } final RelDataType notNullType = typeFactory.createTypeWithNullability(type, false); return makeAbstractCast(notNullType, exp); }
/** * Makes a cast of a value to NOT NULL; * no-op if the type already has NOT NULL. */ public RexNode makeNotNull(RexNode exp) { final RelDataType type = exp.getType(); if (!type.isNullable()) { return exp; } final RelDataType notNullType = typeFactory.createTypeWithNullability(type, false); return makeAbstractCast(notNullType, exp); }
private RexNode handleExplicitCast(ExprNodeGenericFuncDesc func, List<RexNode> childRexNodeLst) throws CalciteSemanticException { RexNode castExpr = null; if (childRexNodeLst != null && childRexNodeLst.size() == 1) { GenericUDF udf = func.getGenericUDF(); if ((udf instanceof GenericUDFToChar) || (udf instanceof GenericUDFToVarchar) || (udf instanceof GenericUDFToDecimal) || (udf instanceof GenericUDFToDate) || (udf instanceof GenericUDFToBinary) || castExprUsingUDFBridge(udf)) { castExpr = cluster.getRexBuilder().makeAbstractCast( TypeConverter.convert(func.getTypeInfo(), cluster.getTypeFactory()), childRexNodeLst.get(0)); } } return castExpr; }
public AggregateCall topSplit(RexBuilder rexBuilder, Registry<RexNode> extra, int offset, RelDataType inputRowType, AggregateCall aggregateCall, int leftSubTotal, int rightSubTotal) { final List<RexNode> merges = new ArrayList<>(); final List<RelDataTypeField> fieldList = inputRowType.getFieldList(); if (leftSubTotal >= 0) { final RelDataType type = fieldList.get(leftSubTotal).getType(); merges.add(rexBuilder.makeInputRef(type, leftSubTotal)); } if (rightSubTotal >= 0) { final RelDataType type = fieldList.get(rightSubTotal).getType(); merges.add(rexBuilder.makeInputRef(type, rightSubTotal)); } RexNode node; switch (merges.size()) { case 1: node = merges.get(0); break; case 2: node = rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, merges); node = rexBuilder.makeAbstractCast(aggregateCall.type, node); break; default: throw new AssertionError("unexpected count " + merges); } int ordinal = extra.register(node); return AggregateCall.create(getMergeAggFunctionOfTopSplit(), false, false, ImmutableList.of(ordinal), -1, aggregateCall.type, aggregateCall.name); }
private static RexNode simplifyBooleanCase(RexBuilder rexBuilder, List<CaseBranch> inputBranches, RexUnknownAs unknownAs, RelDataType branchType) { RexNode result; // prepare all condition/branches for boolean interpretation // It's done here make these interpretation changes available to case2or simplifications // but not interfere with the normal simplifcation recursion List<CaseBranch> branches = new ArrayList<>(); for (CaseBranch branch : inputBranches) { if (!isSafeExpression(branch.cond) || !isSafeExpression(branch.value)) { return null; } RexNode cond; RexNode value; if (branch.cond.getType().isNullable()) { cond = rexBuilder.makeCall(SqlStdOperatorTable.IS_TRUE, branch.cond); } else { cond = branch.cond; } if (!branchType.equals(branch.value.getType())) { value = rexBuilder.makeAbstractCast(branchType, branch.value); } else { value = branch.value; } branches.add(new CaseBranch(cond, value)); } result = simplifyBooleanCaseGeneric(rexBuilder, branches, branchType); return result; }