Search in sources :

Example 11 with RexDynamicParam

use of org.apache.calcite.rex.RexDynamicParam in project beam by apache.

the class BeamSqlUnparseContext method toSql.

@Override
public SqlNode toSql(RexProgram program, RexNode rex) {
    if (rex.getKind().equals(SqlKind.LITERAL)) {
        final RexLiteral literal = (RexLiteral) rex;
        SqlTypeName name = literal.getTypeName();
        SqlTypeFamily family = name.getFamily();
        if (SqlTypeName.TIMESTAMP_WITH_LOCAL_TIME_ZONE.equals(name)) {
            TimestampString timestampString = literal.getValueAs(TimestampString.class);
            return new SqlDateTimeLiteral(timestampString, POS);
        } else if (SqlTypeFamily.BINARY.equals(family)) {
            ByteString byteString = literal.getValueAs(ByteString.class);
            BitString bitString = BitString.createFromHexString(byteString.toString(16));
            return new SqlByteStringLiteral(bitString, POS);
        } else if (SqlTypeFamily.CHARACTER.equals(family)) {
            String escaped = ESCAPE_FOR_ZETA_SQL.translate(literal.getValueAs(String.class));
            return SqlLiteral.createCharString(escaped, POS);
        } else if (SqlTypeName.SYMBOL.equals(literal.getTypeName())) {
            Enum symbol = literal.getValueAs(Enum.class);
            if (TimeUnitRange.DOW.equals(symbol)) {
                return new ReplaceLiteral(literal, POS, "DAYOFWEEK");
            } else if (TimeUnitRange.DOY.equals(symbol)) {
                return new ReplaceLiteral(literal, POS, "DAYOFYEAR");
            } else if (TimeUnitRange.WEEK.equals(symbol)) {
                return new ReplaceLiteral(literal, POS, "ISOWEEK");
            }
        }
    } else if (rex.getKind().equals(SqlKind.DYNAMIC_PARAM)) {
        final RexDynamicParam param = (RexDynamicParam) rex;
        final int index = param.getIndex();
        final String name = "null_param_" + index;
        nullParams.put(name, param.getType());
        return new NamedDynamicParam(index, POS, name);
    } else if (SqlKind.SEARCH.equals(rex.getKind())) {
        // Workaround CALCITE-4716
        RexCall search = (RexCall) rex;
        RexLocalRef ref = (RexLocalRef) search.operands.get(1);
        RexLiteral literal = (RexLiteral) program.getExprList().get(ref.getIndex());
        rex = search.clone(search.getType(), ImmutableList.of(search.operands.get(0), literal));
    }
    return super.toSql(program, rex);
}
Also used : RexLiteral(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexLiteral) SqlTypeName(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.type.SqlTypeName) SqlTypeFamily(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.type.SqlTypeFamily) ByteString(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.avatica.util.ByteString) ByteString(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.avatica.util.ByteString) BitString(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.util.BitString) TimestampString(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.util.TimestampString) RexCall(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexCall) BitString(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.util.BitString) RexLocalRef(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexLocalRef) TimestampString(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.util.TimestampString) RexDynamicParam(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexDynamicParam)

Example 12 with RexDynamicParam

use of org.apache.calcite.rex.RexDynamicParam in project calcite by apache.

the class RexProgramTest method checkExponentialCnf.

private void checkExponentialCnf(int n) {
    final RelDataType booleanType = typeFactory.createSqlType(SqlTypeName.BOOLEAN);
    final RelDataTypeFactory.Builder builder = typeFactory.builder();
    for (int i = 0; i < n; i++) {
        builder.add("x" + i, booleanType).add("y" + i, booleanType);
    }
    final RelDataType rowType3 = builder.build();
    final RexDynamicParam range3 = rexBuilder.makeDynamicParam(rowType3, 0);
    final List<RexNode> list = Lists.newArrayList();
    for (int i = 0; i < n; i++) {
        list.add(and(rexBuilder.makeFieldAccess(range3, i * 2), rexBuilder.makeFieldAccess(range3, i * 2 + 1)));
    }
    final RexNode cnf = RexUtil.toCnf(rexBuilder, or(list));
    final int nodeCount = nodeCount(cnf);
    assertThat((n + 1) * (int) Math.pow(2, n) + 1, equalTo(nodeCount));
    if (n == 3) {
        assertThat(cnf.toString(), equalTo("AND(OR(?0.x0, ?0.x1, ?0.x2), OR(?0.x0, ?0.x1, ?0.y2)," + " OR(?0.x0, ?0.y1, ?0.x2), OR(?0.x0, ?0.y1, ?0.y2)," + " OR(?0.y0, ?0.x1, ?0.x2), OR(?0.y0, ?0.x1, ?0.y2)," + " OR(?0.y0, ?0.y1, ?0.x2), OR(?0.y0, ?0.y1, ?0.y2))"));
    }
}
Also used : RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) RelDataType(org.apache.calcite.rel.type.RelDataType) RexDynamicParam(org.apache.calcite.rex.RexDynamicParam) RexNode(org.apache.calcite.rex.RexNode)

Example 13 with RexDynamicParam

use of org.apache.calcite.rex.RexDynamicParam in project calcite by apache.

the class RexProgramTest method testSimplifyFilter.

@Test
public void testSimplifyFilter() {
    final RelDataType booleanType = typeFactory.createSqlType(SqlTypeName.BOOLEAN);
    final RelDataType intType = typeFactory.createSqlType(SqlTypeName.INTEGER);
    final RelDataType rowType = typeFactory.builder().add("a", booleanType).add("b", booleanType).add("c", booleanType).add("d", booleanType).add("e", booleanType).add("f", booleanType).add("g", booleanType).add("h", intType).build();
    final RexDynamicParam range = rexBuilder.makeDynamicParam(rowType, 0);
    final RexNode aRef = rexBuilder.makeFieldAccess(range, 0);
    final RexNode bRef = rexBuilder.makeFieldAccess(range, 1);
    final RexNode cRef = rexBuilder.makeFieldAccess(range, 2);
    final RexNode dRef = rexBuilder.makeFieldAccess(range, 3);
    final RexLiteral literal1 = rexBuilder.makeExactLiteral(BigDecimal.ONE);
    final RexLiteral literal5 = rexBuilder.makeExactLiteral(new BigDecimal(5));
    final RexLiteral literal10 = rexBuilder.makeExactLiteral(BigDecimal.TEN);
    // condition, and the inverse
    checkSimplifyFilter(and(le(aRef, literal1), gt(aRef, literal1)), "false");
    checkSimplifyFilter(and(le(aRef, literal1), ge(aRef, literal1)), "AND(<=(?0.a, 1), >=(?0.a, 1))");
    checkSimplifyFilter(and(lt(aRef, literal1), eq(aRef, literal1), ge(aRef, literal1)), "false");
    // simplify equals boolean
    final ImmutableList<RexNode> args = ImmutableList.of(eq(eq(aRef, literal1), trueLiteral), eq(bRef, literal1));
    checkSimplifyFilter(and(args), "AND(=(?0.a, 1), =(?0.b, 1))");
    // as previous, using simplifyFilterPredicates
    assertThat(simplify.withUnknownAsFalse(true).simplifyFilterPredicates(args).toString(), equalTo("AND(=(?0.a, 1), =(?0.b, 1))"));
    // "a = 1 and a = 10" is always false
    final ImmutableList<RexNode> args2 = ImmutableList.of(eq(aRef, literal1), eq(aRef, literal10));
    checkSimplifyFilter(and(args2), "false");
    assertThat(simplify.withUnknownAsFalse(true).simplifyFilterPredicates(args2), nullValue());
    // equality on constants, can remove the equality on the variables
    checkSimplifyFilter(and(eq(aRef, literal1), eq(bRef, literal1), eq(aRef, bRef)), "AND(=(?0.a, 1), =(?0.b, 1))");
    // condition not satisfiable
    checkSimplifyFilter(and(eq(aRef, literal1), eq(bRef, literal10), eq(aRef, bRef)), "false");
    // condition not satisfiable
    checkSimplifyFilter(and(gt(aRef, literal10), ge(bRef, literal1), lt(aRef, literal10)), "false");
    // one "and" containing three "or"s
    checkSimplifyFilter(or(gt(aRef, literal10), gt(bRef, literal1), gt(aRef, literal10)), "OR(>(?0.a, 10), >(?0.b, 1))");
    // case: trailing false and null, remove
    checkSimplifyFilter(case_(aRef, trueLiteral, bRef, trueLiteral, cRef, falseLiteral, dRef, falseLiteral, unknownLiteral), "CAST(OR(?0.a, ?0.b)):BOOLEAN");
    // condition with null value for range
    checkSimplifyFilter(and(gt(aRef, unknownLiteral), ge(bRef, literal1)), "false");
    // condition "1 < a && 5 < x" yields "5 < x"
    checkSimplifyFilter(and(lt(literal1, aRef), lt(literal5, aRef)), RelOptPredicateList.EMPTY, "<(5, ?0.a)");
    // condition "1 < a && a < 5" is unchanged
    checkSimplifyFilter(and(lt(literal1, aRef), lt(aRef, literal5)), RelOptPredicateList.EMPTY, "AND(<(1, ?0.a), <(?0.a, 5))");
    // condition "1 > a && 5 > x" yields "1 > a"
    checkSimplifyFilter(and(gt(literal1, aRef), gt(literal5, aRef)), RelOptPredicateList.EMPTY, ">(1, ?0.a)");
    // condition "1 > a && a > 5" yields false
    checkSimplifyFilter(and(gt(literal1, aRef), gt(aRef, literal5)), RelOptPredicateList.EMPTY, "false");
    // range with no predicates;
    // condition "a > 1 && a < 10 && a < 5" yields "a < 1 && a < 5"
    checkSimplifyFilter(and(gt(aRef, literal1), lt(aRef, literal10), lt(aRef, literal5)), RelOptPredicateList.EMPTY, "AND(>(?0.a, 1), <(?0.a, 5))");
    // condition "a > 1 && a < 10 && a < 5"
    // with pre-condition "a > 5"
    // yields "false"
    checkSimplifyFilter(and(gt(aRef, literal1), lt(aRef, literal10), lt(aRef, literal5)), RelOptPredicateList.of(rexBuilder, ImmutableList.of(gt(aRef, literal5))), "false");
    // condition "a > 1 && a < 10 && a <= 5"
    // with pre-condition "a >= 5"
    // yields "a = 5"
    // "a <= 5" would also be correct, just a little less concise.
    checkSimplifyFilter(and(gt(aRef, literal1), lt(aRef, literal10), le(aRef, literal5)), RelOptPredicateList.of(rexBuilder, ImmutableList.of(ge(aRef, literal5))), "=(?0.a, 5)");
    // condition "a > 1 && a < 10 && a < 5"
    // with pre-condition "b < 10 && a > 5"
    // yields "a > 1 and a < 5"
    checkSimplifyFilter(and(gt(aRef, literal1), lt(aRef, literal10), lt(aRef, literal5)), RelOptPredicateList.of(rexBuilder, ImmutableList.of(lt(bRef, literal10), ge(aRef, literal1))), "AND(>(?0.a, 1), <(?0.a, 5))");
    // condition "a > 1"
    // with pre-condition "b < 10 && a > 5"
    // yields "true"
    checkSimplifyFilter(gt(aRef, literal1), RelOptPredicateList.of(rexBuilder, ImmutableList.of(lt(bRef, literal10), gt(aRef, literal5))), "true");
    // condition "a < 1"
    // with pre-condition "b < 10 && a > 5"
    // yields "false"
    checkSimplifyFilter(lt(aRef, literal1), RelOptPredicateList.of(rexBuilder, ImmutableList.of(lt(bRef, literal10), gt(aRef, literal5))), "false");
    // condition "a > 5"
    // with pre-condition "b < 10 && a >= 5"
    // yields "a > 5"
    checkSimplifyFilter(gt(aRef, literal5), RelOptPredicateList.of(rexBuilder, ImmutableList.of(lt(bRef, literal10), ge(aRef, literal5))), ">(?0.a, 5)");
    // condition "a > 5"
    // with pre-condition "a <= 5"
    // yields "false"
    checkSimplifyFilter(gt(aRef, literal5), RelOptPredicateList.of(rexBuilder, ImmutableList.of(le(aRef, literal5))), "false");
    // condition "a > 5"
    // with pre-condition "a <= 5 and b <= 5"
    // yields "false"
    checkSimplifyFilter(gt(aRef, literal5), RelOptPredicateList.of(rexBuilder, ImmutableList.of(le(aRef, literal5), le(bRef, literal5))), "false");
    // condition "a > 5 or b > 5"
    // with pre-condition "a <= 5 and b <= 5"
    // should yield "false" but yields "a = 5 or b = 5"
    checkSimplifyFilter(or(gt(aRef, literal5), gt(bRef, literal5)), RelOptPredicateList.of(rexBuilder, ImmutableList.of(le(aRef, literal5), le(bRef, literal5))), "false");
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) RelDataType(org.apache.calcite.rel.type.RelDataType) BigDecimal(java.math.BigDecimal) RexDynamicParam(org.apache.calcite.rex.RexDynamicParam) RexNode(org.apache.calcite.rex.RexNode) Test(org.junit.Test)

Example 14 with RexDynamicParam

use of org.apache.calcite.rex.RexDynamicParam in project druid by druid-io.

the class RelParameterizerShuttle method bind.

private RexNode bind(RexNode node, RexBuilder builder, RelDataTypeFactory typeFactory) {
    if (node instanceof RexDynamicParam) {
        RexDynamicParam dynamicParam = (RexDynamicParam) node;
        // if we have a value for dynamic parameter, replace with a literal, else add to list of unbound parameters
        if (plannerContext.getParameters().size() > dynamicParam.getIndex()) {
            TypedValue param = plannerContext.getParameters().get(dynamicParam.getIndex());
            if (param == null) {
                throw new SqlPlanningException(PlanningError.VALIDATION_ERROR, StringUtils.format("Parameter at position[%s] is not bound", dynamicParam.getIndex()));
            }
            if (param.value == null) {
                return builder.makeNullLiteral(typeFactory.createSqlType(SqlTypeName.NULL));
            }
            SqlTypeName typeName = SqlTypeName.getNameForJdbcType(param.type.typeId);
            return builder.makeLiteral(param.value, typeFactory.createSqlType(typeName), true);
        } else {
            throw new SqlPlanningException(PlanningError.VALIDATION_ERROR, StringUtils.format("Parameter at position[%s] is not bound", dynamicParam.getIndex()));
        }
    }
    return node;
}
Also used : SqlPlanningException(org.apache.druid.sql.SqlPlanningException) SqlTypeName(org.apache.calcite.sql.type.SqlTypeName) RexDynamicParam(org.apache.calcite.rex.RexDynamicParam) TypedValue(org.apache.calcite.avatica.remote.TypedValue)

Example 15 with RexDynamicParam

use of org.apache.calcite.rex.RexDynamicParam in project herddb by diennea.

the class SQLExpressionCompiler method compileExpression.

public static CompiledSQLExpression compileExpression(RexNode expression) {
    if (expression == null) {
        return null;
    }
    if (expression instanceof RexDynamicParam) {
        RexDynamicParam p = (RexDynamicParam) expression;
        return new TypedJdbcParameterExpression(p.getIndex(), CalcitePlanner.convertToHerdType(p.getType()));
    } else if (expression instanceof RexLiteral) {
        RexLiteral p = (RexLiteral) expression;
        if (p.isNull()) {
            return new ConstantExpression(null, ColumnTypes.NULL);
        } else {
            return new ConstantExpression(safeValue(p.getValue3(), p.getType(), p.getTypeName()), CalcitePlanner.convertToHerdType(p.getType()));
        }
    } else if (expression instanceof RexInputRef) {
        RexInputRef p = (RexInputRef) expression;
        return new AccessCurrentRowExpression(p.getIndex(), CalcitePlanner.convertToHerdType(p.getType()));
    } else if (expression instanceof RexCall) {
        RexCall p = (RexCall) expression;
        SqlOperator op = p.op;
        String name = op.getName();
        CompiledSQLExpression[] operands = new CompiledSQLExpression[p.operands.size()];
        int i = 0;
        for (RexNode operand : p.operands) {
            operands[i++] = compileExpression(operand);
        }
        switch(name) {
            case "=":
                return new CompiledEqualsExpression(operands[0], operands[1]);
            case "<>":
                return new CompiledNotEqualsExpression(operands[0], operands[1]);
            case ">":
                return new CompiledGreaterThanExpression(operands[0], operands[1]);
            case ">=":
                return new CompiledGreaterThanEqualsExpression(operands[0], operands[1]);
            case "<":
                return new CompiledMinorThanExpression(operands[0], operands[1]);
            case "<=":
                return new CompiledMinorThanEqualsExpression(operands[0], operands[1]);
            case "+":
                return new CompiledAddExpression(operands[0], operands[1]);
            case "MOD":
                return new CompiledModuloExpression(operands[0], operands[1]);
            case "-":
                if (operands.length == 1) {
                    return new CompiledSignedExpression('-', operands[0]);
                } else if (operands.length == 2) {
                    return new CompiledSubtractExpression(operands[0], operands[1]);
                }
                break;
            case "*":
                return new CompiledMultiplyExpression(operands[0], operands[1]);
            case "/":
                return new CompiledDivideExpression(operands[0], operands[1]);
            case "/INT":
                return new CompiledDivideIntExpression(operands[0], operands[1]);
            case "LIKE":
                if (operands.length == 2) {
                    return new CompiledLikeExpression(operands[0], operands[1]);
                } else {
                    // ESCAPE
                    return new CompiledLikeExpression(operands[0], operands[1], operands[2]);
                }
            case "AND":
                return new CompiledMultiAndExpression(operands);
            case "OR":
                return new CompiledMultiOrExpression(operands);
            case "NOT":
                return new CompiledParenthesisExpression(true, operands[0]);
            case "IS NOT NULL":
                return new CompiledIsNullExpression(true, operands[0]);
            case "IS NOT TRUE":
                return new CompiledIsNotTrueExpression(false, operands[0]);
            case "IS NULL":
                return new CompiledIsNullExpression(false, operands[0]);
            case "SEARCH":
                return convertSearchOperator(p);
            case "CAST":
                return operands[0].cast(CalcitePlanner.convertToHerdType(p.type));
            case "CASE":
                List<Map.Entry<CompiledSQLExpression, CompiledSQLExpression>> cases = new ArrayList<>(operands.length / 2);
                boolean hasElse = operands.length % 2 == 1;
                int numcases = hasElse ? ((operands.length - 1) / 2) : (operands.length / 2);
                for (int j = 0; j < numcases; j++) {
                    cases.add(new AbstractMap.SimpleImmutableEntry<>(operands[j * 2], operands[j * 2 + 1]));
                }
                CompiledSQLExpression elseExp = hasElse ? operands[operands.length - 1] : null;
                return new CompiledCaseExpression(cases, elseExp);
            case BuiltinFunctions.NAME_CURRENT_TIMESTAMP:
                return new CompiledFunction(BuiltinFunctions.CURRENT_TIMESTAMP, Collections.emptyList());
            case BuiltinFunctions.NAME_CURRENT_DATE:
                return new CompiledFunction(BuiltinFunctions.NAME_CURRENT_DATE, Collections.emptyList());
            case BuiltinFunctions.NAME_LOWERCASE:
                return new CompiledFunction(BuiltinFunctions.LOWER, Arrays.asList(operands));
            case BuiltinFunctions.NAME_UPPER:
                return new CompiledFunction(BuiltinFunctions.UPPER, Arrays.asList(operands));
            case BuiltinFunctions.NAME_ABS:
                return new CompiledFunction(BuiltinFunctions.ABS, Arrays.asList(operands));
            case BuiltinFunctions.NAME_ROUND:
                return new CompiledFunction(BuiltinFunctions.ROUND, Arrays.asList(operands));
            case BuiltinFunctions.NAME_EXTRACT:
                return new CompiledFunction(BuiltinFunctions.EXTRACT, Arrays.asList(operands));
            case BuiltinFunctions.NAME_FLOOR:
                return new CompiledFunction(BuiltinFunctions.FLOOR, Arrays.asList(operands));
            case BuiltinFunctions.NAME_RAND:
                return new CompiledFunction(BuiltinFunctions.RAND, Arrays.asList(operands));
            case BuiltinFunctions.NAME_REINTERPRET:
                if (operands.length != 1) {
                    throw new StatementExecutionException("unsupported use of Reinterpret with " + Arrays.toString(operands));
                }
                return (CompiledSQLExpression) operands[0];
            default:
                throw new StatementExecutionException("unsupported operator '" + name + "'");
        }
    } else if (expression instanceof RexFieldAccess) {
        RexFieldAccess p = (RexFieldAccess) expression;
        CompiledSQLExpression object = compileExpression(p.getReferenceExpr());
        return new AccessFieldExpression(object, p.getField().getName());
    } else if (expression instanceof RexCorrelVariable) {
        RexCorrelVariable p = (RexCorrelVariable) expression;
        return new AccessCorrelVariableExpression(p.id.getId(), p.id.getName());
    }
    throw new StatementExecutionException("not implemented expression type " + expression.getClass() + ": " + expression);
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) RexCorrelVariable(org.apache.calcite.rex.RexCorrelVariable) SqlOperator(org.apache.calcite.sql.SqlOperator) NlsString(org.apache.calcite.util.NlsString) StatementExecutionException(herddb.model.StatementExecutionException) RexCall(org.apache.calcite.rex.RexCall) ArrayList(java.util.ArrayList) List(java.util.List) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexInputRef(org.apache.calcite.rex.RexInputRef) Map(java.util.Map) AbstractMap(java.util.AbstractMap) RexDynamicParam(org.apache.calcite.rex.RexDynamicParam) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RexDynamicParam (org.apache.calcite.rex.RexDynamicParam)13 RexNode (org.apache.calcite.rex.RexNode)11 RelDataType (org.apache.calcite.rel.type.RelDataType)10 RexLiteral (org.apache.calcite.rex.RexLiteral)8 Test (org.junit.Test)7 RelNode (org.apache.calcite.rel.RelNode)3 RexDynamicParam (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexDynamicParam)2 RelCollation (org.apache.calcite.rel.RelCollation)2 RelFieldCollation (org.apache.calcite.rel.RelFieldCollation)2 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)2 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)2 Mapping (org.apache.calcite.util.mapping.Mapping)2 StatementExecutionException (herddb.model.StatementExecutionException)1 BigDecimal (java.math.BigDecimal)1 AbstractMap (java.util.AbstractMap)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Map (java.util.Map)1 ByteString (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.avatica.util.ByteString)1 RelCollation (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelCollation)1