Search in sources :

Example 16 with RexLocalRef

use of org.apache.calcite.rex.RexLocalRef 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 17 with RexLocalRef

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

the class CalcRelSplitter method execute.

// ~ Methods ----------------------------------------------------------------
RelNode execute() {
    // expressions to the left.
    assert program.isValid(Litmus.THROW, null);
    final List<RexNode> exprList = program.getExprList();
    final RexNode[] exprs = exprList.toArray(new RexNode[exprList.size()]);
    assert !RexUtil.containComplexExprs(exprList);
    // Figure out what level each expression belongs to.
    int[] exprLevels = new int[exprs.length];
    // The type of a level is given by
    // relTypes[levelTypeOrdinals[level]].
    int[] levelTypeOrdinals = new int[exprs.length];
    int levelCount = chooseLevels(exprs, -1, exprLevels, levelTypeOrdinals);
    // For each expression, figure out which is the highest level where it
    // is used.
    int[] exprMaxUsingLevelOrdinals = new HighestUsageFinder(exprs, exprLevels).getMaxUsingLevelOrdinals();
    // If expressions are used as outputs, mark them as higher than that.
    final List<RexLocalRef> projectRefList = program.getProjectList();
    final RexLocalRef conditionRef = program.getCondition();
    for (RexLocalRef projectRef : projectRefList) {
        exprMaxUsingLevelOrdinals[projectRef.getIndex()] = levelCount;
    }
    if (conditionRef != null) {
        exprMaxUsingLevelOrdinals[conditionRef.getIndex()] = levelCount;
    }
    // Print out what we've got.
    if (RULE_LOGGER.isTraceEnabled()) {
        traceLevelExpressions(exprs, exprLevels, levelTypeOrdinals, levelCount);
    }
    // Now build the calcs.
    RelNode rel = child;
    final int inputFieldCount = program.getInputRowType().getFieldCount();
    int[] inputExprOrdinals = identityArray(inputFieldCount);
    boolean doneCondition = false;
    for (int level = 0; level < levelCount; level++) {
        final int[] projectExprOrdinals;
        final RelDataType outputRowType;
        if (level == (levelCount - 1)) {
            outputRowType = program.getOutputRowType();
            projectExprOrdinals = new int[projectRefList.size()];
            for (int i = 0; i < projectExprOrdinals.length; i++) {
                projectExprOrdinals[i] = projectRefList.get(i).getIndex();
            }
        } else {
            outputRowType = null;
            // Project the expressions which are computed at this level or
            // before, and will be used at later levels.
            List<Integer> projectExprOrdinalList = new ArrayList<>();
            for (int i = 0; i < exprs.length; i++) {
                RexNode expr = exprs[i];
                if (expr instanceof RexLiteral) {
                    // Don't project literals. They are always created in
                    // the level where they are used.
                    exprLevels[i] = -1;
                    continue;
                }
                if ((exprLevels[i] <= level) && (exprMaxUsingLevelOrdinals[i] > level)) {
                    projectExprOrdinalList.add(i);
                }
            }
            projectExprOrdinals = Ints.toArray(projectExprOrdinalList);
        }
        final RelType relType = relTypes[levelTypeOrdinals[level]];
        // Can we do the condition this level?
        int conditionExprOrdinal = -1;
        if ((conditionRef != null) && !doneCondition) {
            conditionExprOrdinal = conditionRef.getIndex();
            if ((exprLevels[conditionExprOrdinal] > level) || !relType.supportsCondition()) {
                // stand down -- we're not ready to do the condition yet
                conditionExprOrdinal = -1;
            } else {
                doneCondition = true;
            }
        }
        RexProgram program1 = createProgramForLevel(level, levelCount, rel.getRowType(), exprs, exprLevels, inputExprOrdinals, projectExprOrdinals, conditionExprOrdinal, outputRowType);
        rel = relType.makeRel(cluster, traits, relBuilder, rel, program1);
        // want these. They cause an explosion in the search space.
        if (rel instanceof LogicalCalc && ((LogicalCalc) rel).getProgram().isTrivial()) {
            rel = rel.getInput(0);
        }
        rel = handle(rel);
        // The outputs of this level will be the inputs to the next level.
        inputExprOrdinals = projectExprOrdinals;
    }
    Preconditions.checkArgument(doneCondition || (conditionRef == null), "unhandled condition");
    return rel;
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) RexProgram(org.apache.calcite.rex.RexProgram) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) RelNode(org.apache.calcite.rel.RelNode) RexLocalRef(org.apache.calcite.rex.RexLocalRef) LogicalCalc(org.apache.calcite.rel.logical.LogicalCalc) RexNode(org.apache.calcite.rex.RexNode)

Example 18 with RexLocalRef

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

the class CalcRelSplitter method createProgramForLevel.

/**
 * Creates a program containing the expressions for a given level.
 *
 * <p>The expression list of the program will consist of all entries in the
 * expression list <code>allExprs[i]</code> for which the corresponding
 * level ordinal <code>exprLevels[i]</code> is equal to <code>level</code>.
 * Expressions are mapped according to <code>inputExprOrdinals</code>.
 *
 * @param level                Level ordinal
 * @param levelCount           Number of levels
 * @param inputRowType         Input row type
 * @param allExprs             Array of all expressions
 * @param exprLevels           Array of the level ordinal of each expression
 * @param inputExprOrdinals    Ordinals in the expression list of input
 *                             expressions. Input expression <code>i</code>
 *                             will be found at position
 *                             <code>inputExprOrdinals[i]</code>.
 * @param projectExprOrdinals  Ordinals of the expressions to be output this
 *                             level.
 * @param conditionExprOrdinal Ordinal of the expression to form the
 *                             condition for this level, or -1 if there is no
 *                             condition.
 * @param outputRowType        Output row type
 * @return Relational expression
 */
private RexProgram createProgramForLevel(int level, int levelCount, RelDataType inputRowType, RexNode[] allExprs, int[] exprLevels, int[] inputExprOrdinals, final int[] projectExprOrdinals, int conditionExprOrdinal, RelDataType outputRowType) {
    // Build a list of expressions to form the calc.
    List<RexNode> exprs = new ArrayList<>();
    // exprInverseOrdinals describes where an expression in allExprs comes
    // from -- from an input, from a calculated expression, or -1 if not
    // available at this level.
    int[] exprInverseOrdinals = new int[allExprs.length];
    Arrays.fill(exprInverseOrdinals, -1);
    int j = 0;
    // and are used here.
    for (int i = 0; i < inputExprOrdinals.length; i++) {
        final int inputExprOrdinal = inputExprOrdinals[i];
        exprs.add(new RexInputRef(i, allExprs[inputExprOrdinal].getType()));
        exprInverseOrdinals[inputExprOrdinal] = j;
        ++j;
    }
    // Next populate the computed expressions.
    final RexShuttle shuttle = new InputToCommonExprConverter(exprInverseOrdinals, exprLevels, level, inputExprOrdinals, allExprs);
    for (int i = 0; i < allExprs.length; i++) {
        if (exprLevels[i] == level || exprLevels[i] == -1 && level == (levelCount - 1) && allExprs[i] instanceof RexLiteral) {
            RexNode expr = allExprs[i];
            final RexNode translatedExpr = expr.accept(shuttle);
            exprs.add(translatedExpr);
            assert exprInverseOrdinals[i] == -1;
            exprInverseOrdinals[i] = j;
            ++j;
        }
    }
    // Form the projection and condition list. Project and condition
    // ordinals are offsets into allExprs, so we need to map them into
    // exprs.
    final List<RexLocalRef> projectRefs = new ArrayList<>(projectExprOrdinals.length);
    final List<String> fieldNames = new ArrayList<>(projectExprOrdinals.length);
    for (int i = 0; i < projectExprOrdinals.length; i++) {
        final int projectExprOrdinal = projectExprOrdinals[i];
        final int index = exprInverseOrdinals[projectExprOrdinal];
        assert index >= 0;
        RexNode expr = allExprs[projectExprOrdinal];
        projectRefs.add(new RexLocalRef(index, expr.getType()));
        // Inherit meaningful field name if possible.
        fieldNames.add(deriveFieldName(expr, i));
    }
    RexLocalRef conditionRef;
    if (conditionExprOrdinal >= 0) {
        final int index = exprInverseOrdinals[conditionExprOrdinal];
        conditionRef = new RexLocalRef(index, allExprs[conditionExprOrdinal].getType());
    } else {
        conditionRef = null;
    }
    if (outputRowType == null) {
        outputRowType = RexUtil.createStructType(typeFactory, projectRefs, fieldNames, null);
    }
    final RexProgram program = new RexProgram(inputRowType, exprs, projectRefs, conditionRef, outputRowType);
    // call operands), since literals should be inlined.
    return program;
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) RexShuttle(org.apache.calcite.rex.RexShuttle) RexProgram(org.apache.calcite.rex.RexProgram) ArrayList(java.util.ArrayList) RexInputRef(org.apache.calcite.rex.RexInputRef) RexLocalRef(org.apache.calcite.rex.RexLocalRef) RexNode(org.apache.calcite.rex.RexNode)

Example 19 with RexLocalRef

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

the class RelToSqlConverter method visit.

/**
 * @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();
}
Also used : RexProgram(org.apache.calcite.rex.RexProgram) ArrayList(java.util.ArrayList) RexLocalRef(org.apache.calcite.rex.RexLocalRef) SqlNodeList(org.apache.calcite.sql.SqlNodeList) SqlNode(org.apache.calcite.sql.SqlNode)

Example 20 with RexLocalRef

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

the class RelMdUtil method estimateFilteredRows.

public static double estimateFilteredRows(RelNode child, RexProgram program, RelMetadataQuery mq) {
    // convert the program's RexLocalRef condition to an expanded RexNode
    RexLocalRef programCondition = program.getCondition();
    RexNode condition;
    if (programCondition == null) {
        condition = null;
    } else {
        condition = program.expandLocalRef(programCondition);
    }
    return estimateFilteredRows(child, condition, mq);
}
Also used : RexLocalRef(org.apache.calcite.rex.RexLocalRef) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RexLocalRef (org.apache.calcite.rex.RexLocalRef)19 RexNode (org.apache.calcite.rex.RexNode)17 ArrayList (java.util.ArrayList)12 RexProgram (org.apache.calcite.rex.RexProgram)9 RexLocalRef (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexLocalRef)7 RelDataType (org.apache.calcite.rel.type.RelDataType)7 RexNode (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)5 RelNode (org.apache.calcite.rel.RelNode)5 RexProgramBuilder (org.apache.calcite.rex.RexProgramBuilder)5 RexInputRef (org.apache.calcite.rex.RexInputRef)4 RexLiteral (org.apache.calcite.rex.RexLiteral)4 RexLiteral (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexLiteral)3 LogicalCalc (org.apache.calcite.rel.logical.LogicalCalc)3 HashMap (java.util.HashMap)2 RexProgram (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexProgram)2 LogicalProject (org.apache.calcite.rel.logical.LogicalProject)2 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)2 RexShuttle (org.apache.calcite.rex.RexShuttle)2 RexWindow (org.apache.calcite.rex.RexWindow)2 ExecutableExpression (org.apache.storm.sql.runtime.calcite.ExecutableExpression)2