Search in sources :

Example 51 with RexInputRef

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexInputRef in project calcite by apache.

the class RelOptUtil method splitCorrelatedFilterCondition.

private static void splitCorrelatedFilterCondition(LogicalFilter filter, RexNode condition, List<RexNode> joinKeys, List<RexNode> correlatedJoinKeys, List<RexNode> nonEquiList, boolean extractCorrelatedFieldAccess) {
    if (condition instanceof RexCall) {
        RexCall call = (RexCall) condition;
        if (call.getOperator().getKind() == SqlKind.AND) {
            for (RexNode operand : call.getOperands()) {
                splitCorrelatedFilterCondition(filter, operand, joinKeys, correlatedJoinKeys, nonEquiList, extractCorrelatedFieldAccess);
            }
            return;
        }
        if (call.getOperator().getKind() == SqlKind.EQUALS) {
            final List<RexNode> operands = call.getOperands();
            RexNode op0 = operands.get(0);
            RexNode op1 = operands.get(1);
            if (extractCorrelatedFieldAccess) {
                if (!RexUtil.containsFieldAccess(op0) && (op1 instanceof RexFieldAccess)) {
                    joinKeys.add(op0);
                    correlatedJoinKeys.add(op1);
                    return;
                } else if ((op0 instanceof RexFieldAccess) && !RexUtil.containsFieldAccess(op1)) {
                    correlatedJoinKeys.add(op0);
                    joinKeys.add(op1);
                    return;
                }
            } else {
                if (!(RexUtil.containsInputRef(op0)) && (op1 instanceof RexInputRef)) {
                    correlatedJoinKeys.add(op0);
                    joinKeys.add(op1);
                    return;
                } else if ((op0 instanceof RexInputRef) && !(RexUtil.containsInputRef(op1))) {
                    joinKeys.add(op0);
                    correlatedJoinKeys.add(op1);
                    return;
                }
            }
        }
    }
    // The operator is not of RexCall type
    // So we fail. Fall through.
    // Add this condition to the list of non-equi-join conditions.
    nonEquiList.add(condition);
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RexInputRef(org.apache.calcite.rex.RexInputRef) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexNode(org.apache.calcite.rex.RexNode)

Example 52 with RexInputRef

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexInputRef in project calcite by apache.

the class RexProgramTest method testSimplifyIsNotNull.

@Test
public void testSimplifyIsNotNull() {
    RelDataType intType = typeFactory.createTypeWithNullability(typeFactory.createSqlType(SqlTypeName.INTEGER), false);
    RelDataType intNullableType = typeFactory.createTypeWithNullability(typeFactory.createSqlType(SqlTypeName.INTEGER), true);
    final RexInputRef i0 = rexBuilder.makeInputRef(intNullableType, 0);
    final RexInputRef i1 = rexBuilder.makeInputRef(intNullableType, 1);
    final RexInputRef i2 = rexBuilder.makeInputRef(intType, 2);
    final RexInputRef i3 = rexBuilder.makeInputRef(intType, 3);
    final RexLiteral one = rexBuilder.makeExactLiteral(BigDecimal.ONE);
    final RexLiteral null_ = rexBuilder.makeNullLiteral(intType);
    checkSimplify(isNotNull(lt(i0, i1)), "AND(IS NOT NULL($0), IS NOT NULL($1))");
    checkSimplify(isNotNull(lt(i0, i2)), "IS NOT NULL($0)");
    checkSimplify(isNotNull(lt(i2, i3)), "true");
    checkSimplify(isNotNull(lt(i0, one)), "IS NOT NULL($0)");
    checkSimplify(isNotNull(lt(i0, null_)), "false");
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) RexInputRef(org.apache.calcite.rex.RexInputRef) RelDataType(org.apache.calcite.rel.type.RelDataType) Test(org.junit.Test)

Example 53 with RexInputRef

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexInputRef in project calcite by apache.

the class DruidExpressions method toDruidExpression.

/**
 * Translates Calcite rexNode to Druid Expression when possible
 * @param rexNode rexNode to convert to a Druid Expression
 * @param inputRowType input row type of the rexNode to translate
 * @param druidRel Druid query
 *
 * @return Druid Expression or null when can not convert the RexNode
 */
@Nullable
public static String toDruidExpression(final RexNode rexNode, final RelDataType inputRowType, final DruidQuery druidRel) {
    SqlKind kind = rexNode.getKind();
    SqlTypeName sqlTypeName = rexNode.getType().getSqlTypeName();
    if (kind == SqlKind.INPUT_REF) {
        final RexInputRef ref = (RexInputRef) rexNode;
        final String columnName = inputRowType.getFieldNames().get(ref.getIndex());
        if (columnName == null) {
            return null;
        }
        if (druidRel.getDruidTable().timestampFieldName.equals(columnName)) {
            return DruidExpressions.fromColumn(DruidTable.DEFAULT_TIMESTAMP_COLUMN);
        }
        return DruidExpressions.fromColumn(columnName);
    }
    if (rexNode instanceof RexCall) {
        final SqlOperator operator = ((RexCall) rexNode).getOperator();
        final DruidSqlOperatorConverter conversion = druidRel.getOperatorConversionMap().get(operator);
        if (conversion == null) {
            // unknown operator can not translate
            return null;
        } else {
            return conversion.toDruidExpression(rexNode, inputRowType, druidRel);
        }
    }
    if (kind == SqlKind.LITERAL) {
        // Translate literal.
        if (RexLiteral.isNullLiteral(rexNode)) {
            // case the filter/project might yield to unknown let Calcite deal with this for now
            return null;
        } else if (SqlTypeName.NUMERIC_TYPES.contains(sqlTypeName)) {
            return DruidExpressions.numberLiteral((Number) RexLiteral.value(rexNode));
        } else if (SqlTypeFamily.INTERVAL_DAY_TIME == sqlTypeName.getFamily()) {
            // Calcite represents DAY-TIME intervals in milliseconds.
            final long milliseconds = ((Number) RexLiteral.value(rexNode)).longValue();
            return DruidExpressions.numberLiteral(milliseconds);
        } else if (SqlTypeFamily.INTERVAL_YEAR_MONTH == sqlTypeName.getFamily()) {
            // Calcite represents YEAR-MONTH intervals in months.
            final long months = ((Number) RexLiteral.value(rexNode)).longValue();
            return DruidExpressions.numberLiteral(months);
        } else if (SqlTypeName.STRING_TYPES.contains(sqlTypeName)) {
            return DruidExpressions.stringLiteral(RexLiteral.stringValue(rexNode));
        } else if (SqlTypeName.TIMESTAMP == sqlTypeName || SqlTypeName.DATE == sqlTypeName || SqlTypeName.TIME_WITH_LOCAL_TIME_ZONE == sqlTypeName) {
            return DruidExpressions.numberLiteral(DruidDateTimeUtils.literalValue(rexNode, TimeZone.getTimeZone(druidRel.getConnectionConfig().timeZone())).getMillisSinceEpoch());
        } else if (SqlTypeName.BOOLEAN == sqlTypeName) {
            return DruidExpressions.numberLiteral(RexLiteral.booleanValue(rexNode) ? 1 : 0);
        }
    }
    // Not Literal/InputRef/RexCall or unknown type?
    return null;
}
Also used : RexCall(org.apache.calcite.rex.RexCall) SqlTypeName(org.apache.calcite.sql.type.SqlTypeName) SqlOperator(org.apache.calcite.sql.SqlOperator) RexInputRef(org.apache.calcite.rex.RexInputRef) SqlKind(org.apache.calcite.sql.SqlKind) Nullable(javax.annotation.Nullable)

Example 54 with RexInputRef

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexInputRef in project calcite by apache.

the class ProjectWindowTransposeRule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    final LogicalProject project = call.rel(0);
    final LogicalWindow window = call.rel(1);
    final RelOptCluster cluster = window.getCluster();
    final List<RelDataTypeField> rowTypeWindowInput = window.getInput().getRowType().getFieldList();
    final int windowInputColumn = rowTypeWindowInput.size();
    // Record the window input columns which are actually referred
    // either in the LogicalProject above LogicalWindow or LogicalWindow itself
    // (Note that the constants used in LogicalWindow are not considered here)
    final ImmutableBitSet beReferred = findReference(project, window);
    // it is impossible to trim anyone of them out
    if (beReferred.cardinality() == windowInputColumn) {
        return;
    }
    // Put a DrillProjectRel below LogicalWindow
    final List<RexNode> exps = new ArrayList<>();
    final RelDataTypeFactory.Builder builder = cluster.getTypeFactory().builder();
    // Keep only the fields which are referred
    for (int index : BitSets.toIter(beReferred)) {
        final RelDataTypeField relDataTypeField = rowTypeWindowInput.get(index);
        exps.add(new RexInputRef(index, relDataTypeField.getType()));
        builder.add(relDataTypeField);
    }
    final LogicalProject projectBelowWindow = new LogicalProject(cluster, window.getTraitSet(), window.getInput(), exps, builder.build());
    // Create a new LogicalWindow with necessary inputs only
    final List<Window.Group> groups = new ArrayList<>();
    // As the un-referred columns are trimmed by the LogicalProject,
    // the indices specified in LogicalWindow would need to be adjusted
    final RexShuttle indexAdjustment = new RexShuttle() {

        @Override
        public RexNode visitInputRef(RexInputRef inputRef) {
            final int newIndex = getAdjustedIndex(inputRef.getIndex(), beReferred, windowInputColumn);
            return new RexInputRef(newIndex, inputRef.getType());
        }

        @Override
        public RexNode visitCall(final RexCall call) {
            if (call instanceof Window.RexWinAggCall) {
                boolean[] update = { false };
                final List<RexNode> clonedOperands = visitList(call.operands, update);
                if (update[0]) {
                    return new Window.RexWinAggCall((SqlAggFunction) call.getOperator(), call.getType(), clonedOperands, ((Window.RexWinAggCall) call).ordinal, ((Window.RexWinAggCall) call).distinct);
                } else {
                    return call;
                }
            } else {
                return super.visitCall(call);
            }
        }
    };
    int aggCallIndex = windowInputColumn;
    final RelDataTypeFactory.Builder outputBuilder = cluster.getTypeFactory().builder();
    outputBuilder.addAll(projectBelowWindow.getRowType().getFieldList());
    for (Window.Group group : window.groups) {
        final ImmutableBitSet.Builder keys = ImmutableBitSet.builder();
        final List<RelFieldCollation> orderKeys = new ArrayList<>();
        final List<Window.RexWinAggCall> aggCalls = new ArrayList<>();
        // Adjust keys
        for (int index : group.keys) {
            keys.set(getAdjustedIndex(index, beReferred, windowInputColumn));
        }
        // Adjust orderKeys
        for (RelFieldCollation relFieldCollation : group.orderKeys.getFieldCollations()) {
            final int index = relFieldCollation.getFieldIndex();
            orderKeys.add(relFieldCollation.copy(getAdjustedIndex(index, beReferred, windowInputColumn)));
        }
        // Adjust Window Functions
        for (Window.RexWinAggCall rexWinAggCall : group.aggCalls) {
            aggCalls.add((Window.RexWinAggCall) rexWinAggCall.accept(indexAdjustment));
            final RelDataTypeField relDataTypeField = window.getRowType().getFieldList().get(aggCallIndex);
            outputBuilder.add(relDataTypeField);
            ++aggCallIndex;
        }
        groups.add(new Window.Group(keys.build(), group.isRows, group.lowerBound, group.upperBound, RelCollations.of(orderKeys), aggCalls));
    }
    final LogicalWindow newLogicalWindow = LogicalWindow.create(window.getTraitSet(), projectBelowWindow, window.constants, outputBuilder.build(), groups);
    // Modify the top LogicalProject
    final List<RexNode> topProjExps = new ArrayList<>();
    for (RexNode rexNode : project.getChildExps()) {
        topProjExps.add(rexNode.accept(indexAdjustment));
    }
    final LogicalProject newTopProj = project.copy(newLogicalWindow.getTraitSet(), newLogicalWindow, topProjExps, project.getRowType());
    if (ProjectRemoveRule.isTrivial(newTopProj)) {
        call.transformTo(newLogicalWindow);
    } else {
        call.transformTo(newTopProj);
    }
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) ArrayList(java.util.ArrayList) RexCall(org.apache.calcite.rex.RexCall) LogicalWindow(org.apache.calcite.rel.logical.LogicalWindow) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) Window(org.apache.calcite.rel.core.Window) LogicalWindow(org.apache.calcite.rel.logical.LogicalWindow) RexShuttle(org.apache.calcite.rex.RexShuttle) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) RexInputRef(org.apache.calcite.rex.RexInputRef) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) RexNode(org.apache.calcite.rex.RexNode)

Example 55 with RexInputRef

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexInputRef in project calcite by apache.

the class SemiJoinProjectTransposeRule method onMatch.

// ~ Methods ----------------------------------------------------------------
public void onMatch(RelOptRuleCall call) {
    SemiJoin semiJoin = call.rel(0);
    LogicalProject project = call.rel(1);
    // Convert the LHS semi-join keys to reference the child projection
    // expression; all projection expressions must be RexInputRefs,
    // otherwise, we wouldn't have created this semi-join.
    final List<Integer> newLeftKeys = new ArrayList<>();
    final List<Integer> leftKeys = semiJoin.getLeftKeys();
    final List<RexNode> projExprs = project.getProjects();
    for (int leftKey : leftKeys) {
        RexInputRef inputRef = (RexInputRef) projExprs.get(leftKey);
        newLeftKeys.add(inputRef.getIndex());
    }
    // convert the semijoin condition to reflect the LHS with the project
    // pulled up
    RexNode newCondition = adjustCondition(project, semiJoin);
    SemiJoin newSemiJoin = SemiJoin.create(project.getInput(), semiJoin.getRight(), newCondition, ImmutableIntList.copyOf(newLeftKeys), semiJoin.getRightKeys());
    // Create the new projection.  Note that the projection expressions
    // are the same as the original because they only reference the LHS
    // of the semijoin and the semijoin only projects out the LHS
    final RelBuilder relBuilder = call.builder();
    relBuilder.push(newSemiJoin);
    relBuilder.project(projExprs, project.getRowType().getFieldNames());
    call.transformTo(relBuilder.build());
}
Also used : RelBuilder(org.apache.calcite.tools.RelBuilder) ArrayList(java.util.ArrayList) RexInputRef(org.apache.calcite.rex.RexInputRef) SemiJoin(org.apache.calcite.rel.core.SemiJoin) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RexInputRef (org.apache.calcite.rex.RexInputRef)241 RexNode (org.apache.calcite.rex.RexNode)200 ArrayList (java.util.ArrayList)105 RelNode (org.apache.calcite.rel.RelNode)85 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)80 RexCall (org.apache.calcite.rex.RexCall)67 RelDataType (org.apache.calcite.rel.type.RelDataType)63 RexBuilder (org.apache.calcite.rex.RexBuilder)54 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)52 HashMap (java.util.HashMap)47 AggregateCall (org.apache.calcite.rel.core.AggregateCall)36 List (java.util.List)35 HashSet (java.util.HashSet)32 Pair (org.apache.calcite.util.Pair)32 RexLiteral (org.apache.calcite.rex.RexLiteral)29 Map (java.util.Map)24 RelOptUtil (org.apache.calcite.plan.RelOptUtil)24 Set (java.util.Set)20 ImmutableList (com.google.common.collect.ImmutableList)19 LinkedHashMap (java.util.LinkedHashMap)19