Search in sources :

Example 51 with RexBuilder

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

the class RelBuilder method call.

/**
 * Creates a call to a scalar operator.
 */
private RexNode call(SqlOperator operator, List<RexNode> operandList) {
    final RexBuilder builder = cluster.getRexBuilder();
    final RelDataType type = builder.deriveReturnType(operator, operandList);
    if (type == null) {
        throw new IllegalArgumentException("cannot derive type: " + operator + "; operands: " + Lists.transform(operandList, FN_TYPE));
    }
    return builder.makeCall(type, operator, operandList);
}
Also used : RexBuilder(org.apache.calcite.rex.RexBuilder) RelDataType(org.apache.calcite.rel.type.RelDataType)

Example 52 with RexBuilder

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

the class RelOptUtil method createRenameRel.

// to be removed before 2.0
@Deprecated
public static RelNode createRenameRel(RelDataType outputType, RelNode rel) {
    RelDataType inputType = rel.getRowType();
    List<RelDataTypeField> inputFields = inputType.getFieldList();
    int n = inputFields.size();
    List<RelDataTypeField> outputFields = outputType.getFieldList();
    assert outputFields.size() == n : "rename: field count mismatch: in=" + inputType + ", out" + outputType;
    final List<Pair<RexNode, String>> renames = new ArrayList<>();
    for (Pair<RelDataTypeField, RelDataTypeField> pair : Pair.zip(inputFields, outputFields)) {
        final RelDataTypeField inputField = pair.left;
        final RelDataTypeField outputField = pair.right;
        assert inputField.getType().equals(outputField.getType());
        final RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
        renames.add(Pair.<RexNode, String>of(rexBuilder.makeInputRef(inputField.getType(), inputField.getIndex()), outputField.getName()));
    }
    final RelBuilder relBuilder = RelFactories.LOGICAL_BUILDER.create(rel.getCluster(), null);
    return relBuilder.push(rel).project(Pair.left(renames), Pair.right(renames), true).build();
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelBuilder(org.apache.calcite.tools.RelBuilder) ArrayList(java.util.ArrayList) RexBuilder(org.apache.calcite.rex.RexBuilder) RelDataType(org.apache.calcite.rel.type.RelDataType) Pair(org.apache.calcite.util.Pair)

Example 53 with RexBuilder

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

the class RelOptUtil method createExistsPlan.

/**
 * Creates a plan suitable for use in <code>EXISTS</code> or <code>IN</code>
 * statements.
 *
 * @see org.apache.calcite.sql2rel.SqlToRelConverter#convertExists
 *
 * @param seekRel    A query rel, for example the resulting rel from 'select *
 *                   from emp' or 'values (1,2,3)' or '('Foo', 34)'.
 * @param subQueryType Sub-query type
 * @param logic  Whether to use 2- or 3-valued boolean logic
 * @param notIn Whether the operator is NOT IN
 * @param relBuilder Builder for relational expressions
 *
 * @return A pair of a relational expression which outer joins a boolean
 * condition column, and a numeric offset. The offset is 2 if column 0 is
 * the number of rows and column 1 is the number of rows with not-null keys;
 * 0 otherwise.
 */
public static Exists createExistsPlan(RelNode seekRel, SubQueryType subQueryType, Logic logic, boolean notIn, RelBuilder relBuilder) {
    switch(subQueryType) {
        case SCALAR:
            return new Exists(seekRel, false, true);
    }
    switch(logic) {
        case TRUE_FALSE_UNKNOWN:
        case UNKNOWN_AS_TRUE:
            if (notIn && !containsNullableFields(seekRel)) {
                logic = Logic.TRUE_FALSE;
            }
    }
    RelNode ret = seekRel;
    final RelOptCluster cluster = seekRel.getCluster();
    final RexBuilder rexBuilder = cluster.getRexBuilder();
    final int keyCount = ret.getRowType().getFieldCount();
    final boolean outerJoin = notIn || logic == RelOptUtil.Logic.TRUE_FALSE_UNKNOWN;
    if (!outerJoin) {
        final LogicalAggregate aggregate = LogicalAggregate.create(ret, ImmutableBitSet.range(keyCount), null, ImmutableList.<AggregateCall>of());
        return new Exists(aggregate, false, false);
    }
    // for IN/NOT IN, it needs to output the fields
    final List<RexNode> exprs = new ArrayList<>();
    if (subQueryType == SubQueryType.IN) {
        for (int i = 0; i < keyCount; i++) {
            exprs.add(rexBuilder.makeInputRef(ret, i));
        }
    }
    final int projectedKeyCount = exprs.size();
    exprs.add(rexBuilder.makeLiteral(true));
    ret = relBuilder.push(ret).project(exprs).build();
    final AggregateCall aggCall = AggregateCall.create(SqlStdOperatorTable.MIN, false, false, ImmutableList.of(projectedKeyCount), -1, projectedKeyCount, ret, null, null);
    ret = LogicalAggregate.create(ret, ImmutableBitSet.range(projectedKeyCount), null, ImmutableList.of(aggCall));
    switch(logic) {
        case TRUE_FALSE_UNKNOWN:
        case UNKNOWN_AS_TRUE:
            return new Exists(ret, true, true);
        default:
            return new Exists(ret, false, true);
    }
}
Also used : AggregateCall(org.apache.calcite.rel.core.AggregateCall) LogicalAggregate(org.apache.calcite.rel.logical.LogicalAggregate) RelNode(org.apache.calcite.rel.RelNode) ArrayList(java.util.ArrayList) RexBuilder(org.apache.calcite.rex.RexBuilder) RexNode(org.apache.calcite.rex.RexNode)

Example 54 with RexBuilder

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

the class RelOptUtil method splitJoinCondition.

private static void splitJoinCondition(List<RelDataTypeField> sysFieldList, List<RelNode> inputs, RexNode condition, List<List<RexNode>> joinKeys, List<Integer> filterNulls, List<SqlOperator> rangeOp, List<RexNode> nonEquiList) {
    final int sysFieldCount = sysFieldList.size();
    final RelOptCluster cluster = inputs.get(0).getCluster();
    final RexBuilder rexBuilder = cluster.getRexBuilder();
    final RelDataTypeFactory typeFactory = cluster.getTypeFactory();
    final ImmutableBitSet[] inputsRange = new ImmutableBitSet[inputs.size()];
    int totalFieldCount = 0;
    for (int i = 0; i < inputs.size(); i++) {
        final int firstField = totalFieldCount + sysFieldCount;
        totalFieldCount = firstField + inputs.get(i).getRowType().getFieldCount();
        inputsRange[i] = ImmutableBitSet.range(firstField, totalFieldCount);
    }
    // adjustment array
    int[] adjustments = new int[totalFieldCount];
    for (int i = 0; i < inputs.size(); i++) {
        final int adjustment = inputsRange[i].nextSetBit(0);
        for (int j = adjustment; j < inputsRange[i].length(); j++) {
            adjustments[j] = -adjustment;
        }
    }
    if (condition instanceof RexCall) {
        RexCall call = (RexCall) condition;
        if (call.getKind() == SqlKind.AND) {
            for (RexNode operand : call.getOperands()) {
                splitJoinCondition(sysFieldList, inputs, operand, joinKeys, filterNulls, rangeOp, nonEquiList);
            }
            return;
        }
        RexNode leftKey = null;
        RexNode rightKey = null;
        int leftInput = 0;
        int rightInput = 0;
        List<RelDataTypeField> leftFields = null;
        List<RelDataTypeField> rightFields = null;
        boolean reverse = false;
        call = collapseExpandedIsNotDistinctFromExpr(call, rexBuilder);
        SqlKind kind = call.getKind();
        // Only consider range operators if we haven't already seen one
        if ((kind == SqlKind.EQUALS) || (filterNulls != null && kind == SqlKind.IS_NOT_DISTINCT_FROM) || (rangeOp != null && rangeOp.isEmpty() && (kind == SqlKind.GREATER_THAN || kind == SqlKind.GREATER_THAN_OR_EQUAL || kind == SqlKind.LESS_THAN || kind == SqlKind.LESS_THAN_OR_EQUAL))) {
            final List<RexNode> operands = call.getOperands();
            RexNode op0 = operands.get(0);
            RexNode op1 = operands.get(1);
            final ImmutableBitSet projRefs0 = InputFinder.bits(op0);
            final ImmutableBitSet projRefs1 = InputFinder.bits(op1);
            boolean foundBothInputs = false;
            for (int i = 0; i < inputs.size() && !foundBothInputs; i++) {
                if (projRefs0.intersects(inputsRange[i]) && projRefs0.union(inputsRange[i]).equals(inputsRange[i])) {
                    if (leftKey == null) {
                        leftKey = op0;
                        leftInput = i;
                        leftFields = inputs.get(leftInput).getRowType().getFieldList();
                    } else {
                        rightKey = op0;
                        rightInput = i;
                        rightFields = inputs.get(rightInput).getRowType().getFieldList();
                        reverse = true;
                        foundBothInputs = true;
                    }
                } else if (projRefs1.intersects(inputsRange[i]) && projRefs1.union(inputsRange[i]).equals(inputsRange[i])) {
                    if (leftKey == null) {
                        leftKey = op1;
                        leftInput = i;
                        leftFields = inputs.get(leftInput).getRowType().getFieldList();
                    } else {
                        rightKey = op1;
                        rightInput = i;
                        rightFields = inputs.get(rightInput).getRowType().getFieldList();
                        foundBothInputs = true;
                    }
                }
            }
            if ((leftKey != null) && (rightKey != null)) {
                // replace right Key input ref
                rightKey = rightKey.accept(new RelOptUtil.RexInputConverter(rexBuilder, rightFields, rightFields, adjustments));
                // left key only needs to be adjusted if there are system
                // fields, but do it for uniformity
                leftKey = leftKey.accept(new RelOptUtil.RexInputConverter(rexBuilder, leftFields, leftFields, adjustments));
                RelDataType leftKeyType = leftKey.getType();
                RelDataType rightKeyType = rightKey.getType();
                if (leftKeyType != rightKeyType) {
                    // perform casting
                    RelDataType targetKeyType = typeFactory.leastRestrictive(ImmutableList.of(leftKeyType, rightKeyType));
                    if (targetKeyType == null) {
                        throw new AssertionError("Cannot find common type for join keys " + leftKey + " (type " + leftKeyType + ") and " + rightKey + " (type " + rightKeyType + ")");
                    }
                    if (leftKeyType != targetKeyType) {
                        leftKey = rexBuilder.makeCast(targetKeyType, leftKey);
                    }
                    if (rightKeyType != targetKeyType) {
                        rightKey = rexBuilder.makeCast(targetKeyType, rightKey);
                    }
                }
            }
        }
        if ((rangeOp == null) && ((leftKey == null) || (rightKey == null))) {
            // no equality join keys found yet:
            // try transforming the condition to
            // equality "join" conditions, e.g.
            // f(LHS) > 0 ===> ( f(LHS) > 0 ) = TRUE,
            // and make the RHS produce TRUE, but only if we're strictly
            // looking for equi-joins
            final ImmutableBitSet projRefs = InputFinder.bits(condition);
            leftKey = null;
            rightKey = null;
            boolean foundInput = false;
            for (int i = 0; i < inputs.size() && !foundInput; i++) {
                if (inputsRange[i].contains(projRefs)) {
                    leftInput = i;
                    leftFields = inputs.get(leftInput).getRowType().getFieldList();
                    leftKey = condition.accept(new RelOptUtil.RexInputConverter(rexBuilder, leftFields, leftFields, adjustments));
                    rightKey = rexBuilder.makeLiteral(true);
                    // effectively performing an equality comparison
                    kind = SqlKind.EQUALS;
                    foundInput = true;
                }
            }
        }
        if ((leftKey != null) && (rightKey != null)) {
            // found suitable join keys
            // add them to key list, ensuring that if there is a
            // non-equi join predicate, it appears at the end of the
            // key list; also mark the null filtering property
            addJoinKey(joinKeys.get(leftInput), leftKey, (rangeOp != null) && !rangeOp.isEmpty());
            addJoinKey(joinKeys.get(rightInput), rightKey, (rangeOp != null) && !rangeOp.isEmpty());
            if (filterNulls != null && kind == SqlKind.EQUALS) {
                // nulls are considered not matching for equality comparison
                // add the position of the most recently inserted key
                filterNulls.add(joinKeys.get(leftInput).size() - 1);
            }
            if (rangeOp != null && kind != SqlKind.EQUALS && kind != SqlKind.IS_DISTINCT_FROM) {
                if (reverse) {
                    kind = kind.reverse();
                }
                rangeOp.add(op(kind, call.getOperator()));
            }
            return;
        }
    // else fall through and add this condition as nonEqui condition
    }
    // 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 : ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlKind(org.apache.calcite.sql.SqlKind) RexCall(org.apache.calcite.rex.RexCall) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) RexBuilder(org.apache.calcite.rex.RexBuilder) RexNode(org.apache.calcite.rex.RexNode)

Example 55 with RexBuilder

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

the class RelOptUtil method projectJoinInputs.

// to be removed before 2.0
@Deprecated
public static void projectJoinInputs(RelNode[] inputRels, List<RexNode> leftJoinKeys, List<RexNode> rightJoinKeys, int systemColCount, List<Integer> leftKeys, List<Integer> rightKeys, List<Integer> outputProj) {
    RelNode leftRel = inputRels[0];
    RelNode rightRel = inputRels[1];
    final RelOptCluster cluster = leftRel.getCluster();
    final RexBuilder rexBuilder = cluster.getRexBuilder();
    final RelDataTypeSystem typeSystem = cluster.getTypeFactory().getTypeSystem();
    int origLeftInputSize = leftRel.getRowType().getFieldCount();
    int origRightInputSize = rightRel.getRowType().getFieldCount();
    final List<RexNode> newLeftFields = new ArrayList<>();
    final List<String> newLeftFieldNames = new ArrayList<>();
    final List<RexNode> newRightFields = new ArrayList<>();
    final List<String> newRightFieldNames = new ArrayList<>();
    int leftKeyCount = leftJoinKeys.size();
    int rightKeyCount = rightJoinKeys.size();
    int i;
    for (i = 0; i < systemColCount; i++) {
        outputProj.add(i);
    }
    for (i = 0; i < origLeftInputSize; i++) {
        final RelDataTypeField field = leftRel.getRowType().getFieldList().get(i);
        newLeftFields.add(rexBuilder.makeInputRef(field.getType(), i));
        newLeftFieldNames.add(field.getName());
        outputProj.add(systemColCount + i);
    }
    int newLeftKeyCount = 0;
    for (i = 0; i < leftKeyCount; i++) {
        RexNode leftKey = leftJoinKeys.get(i);
        if (leftKey instanceof RexInputRef) {
            // already added to the projected left fields
            // only need to remember the index in the join key list
            leftKeys.add(((RexInputRef) leftKey).getIndex());
        } else {
            newLeftFields.add(leftKey);
            newLeftFieldNames.add(null);
            leftKeys.add(origLeftInputSize + newLeftKeyCount);
            newLeftKeyCount++;
        }
    }
    int leftFieldCount = origLeftInputSize + newLeftKeyCount;
    for (i = 0; i < origRightInputSize; i++) {
        final RelDataTypeField field = rightRel.getRowType().getFieldList().get(i);
        newRightFields.add(rexBuilder.makeInputRef(field.getType(), i));
        newRightFieldNames.add(field.getName());
        outputProj.add(systemColCount + leftFieldCount + i);
    }
    int newRightKeyCount = 0;
    for (i = 0; i < rightKeyCount; i++) {
        RexNode rightKey = rightJoinKeys.get(i);
        if (rightKey instanceof RexInputRef) {
            // already added to the projected left fields
            // only need to remember the index in the join key list
            rightKeys.add(((RexInputRef) rightKey).getIndex());
        } else {
            newRightFields.add(rightKey);
            newRightFieldNames.add(null);
            rightKeys.add(origRightInputSize + newRightKeyCount);
            newRightKeyCount++;
        }
    }
    final RelBuilder relBuilder = RelFactories.LOGICAL_BUILDER.create(cluster, null);
    // fields
    if (newLeftKeyCount > 0) {
        leftRel = relBuilder.push(leftRel).project(newLeftFields, newLeftFieldNames, true).build();
    }
    if (newRightKeyCount > 0) {
        rightRel = relBuilder.push(rightRel).project(newRightFields, newRightFieldNames).build();
    }
    inputRels[0] = leftRel;
    inputRels[1] = rightRel;
}
Also used : RelBuilder(org.apache.calcite.tools.RelBuilder) RelDataTypeSystem(org.apache.calcite.rel.type.RelDataTypeSystem) ArrayList(java.util.ArrayList) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RexBuilder(org.apache.calcite.rex.RexBuilder) RexInputRef(org.apache.calcite.rex.RexInputRef) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RexBuilder (org.apache.calcite.rex.RexBuilder)314 RexNode (org.apache.calcite.rex.RexNode)248 ArrayList (java.util.ArrayList)151 RelNode (org.apache.calcite.rel.RelNode)121 RelDataType (org.apache.calcite.rel.type.RelDataType)121 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)77 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)59 RexInputRef (org.apache.calcite.rex.RexInputRef)49 RelBuilder (org.apache.calcite.tools.RelBuilder)49 AggregateCall (org.apache.calcite.rel.core.AggregateCall)48 List (java.util.List)41 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)41 RelOptCluster (org.apache.calcite.plan.RelOptCluster)36 HashMap (java.util.HashMap)33 RelOptPredicateList (org.apache.calcite.plan.RelOptPredicateList)24 Project (org.apache.calcite.rel.core.Project)24 RexCall (org.apache.calcite.rex.RexCall)24 BigDecimal (java.math.BigDecimal)23 Collectors (java.util.stream.Collectors)23 RelMetadataQuery (org.apache.calcite.rel.metadata.RelMetadataQuery)22