Search in sources :

Example 21 with CorrelationId

use of org.apache.calcite.rel.core.CorrelationId in project calcite by apache.

the class SubQueryRemoveRule method matchFilter.

private static void matchFilter(SubQueryRemoveRule rule, RelOptRuleCall call) {
    final Filter filter = call.rel(0);
    final RelBuilder builder = call.builder();
    builder.push(filter.getInput());
    int count = 0;
    RexNode c = filter.getCondition();
    while (true) {
        final RexSubQuery e = RexUtil.SubQueryFinder.find(c);
        if (e == null) {
            assert count > 0;
            break;
        }
        ++count;
        final RelOptUtil.Logic logic = LogicVisitor.find(RelOptUtil.Logic.TRUE, ImmutableList.of(c), e);
        final Set<CorrelationId> variablesSet = RelOptUtil.getVariablesUsed(e.rel);
        final RexNode target = rule.apply(e, variablesSet, logic, builder, 1, builder.peek().getRowType().getFieldCount());
        final RexShuttle shuttle = new ReplaceSubQueryShuttle(e, target);
        c = c.accept(shuttle);
    }
    builder.filter(c);
    builder.project(fields(builder, filter.getRowType().getFieldCount()));
    call.transformTo(builder.build());
}
Also used : RelBuilder(org.apache.calcite.tools.RelBuilder) RexShuttle(org.apache.calcite.rex.RexShuttle) Filter(org.apache.calcite.rel.core.Filter) RelOptUtil(org.apache.calcite.plan.RelOptUtil) CorrelationId(org.apache.calcite.rel.core.CorrelationId) RexSubQuery(org.apache.calcite.rex.RexSubQuery) RexNode(org.apache.calcite.rex.RexNode)

Example 22 with CorrelationId

use of org.apache.calcite.rel.core.CorrelationId in project calcite by apache.

the class RelFieldTrimmer method trimChild.

/**
 * Trims the fields of an input relational expression.
 *
 * @param rel        Relational expression
 * @param input      Input relational expression, whose fields to trim
 * @param fieldsUsed Bitmap of fields needed by the consumer
 * @return New relational expression and its field mapping
 */
protected TrimResult trimChild(RelNode rel, RelNode input, final ImmutableBitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
    final ImmutableBitSet.Builder fieldsUsedBuilder = fieldsUsed.rebuild();
    // Fields that define the collation cannot be discarded.
    final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
    final ImmutableList<RelCollation> collations = mq.collations(input);
    if (collations != null) {
        for (RelCollation collation : collations) {
            for (RelFieldCollation fieldCollation : collation.getFieldCollations()) {
                fieldsUsedBuilder.set(fieldCollation.getFieldIndex());
            }
        }
    }
    // fields.
    for (final CorrelationId correlation : rel.getVariablesSet()) {
        rel.accept(new CorrelationReferenceFinder() {

            @Override
            protected RexNode handle(RexFieldAccess fieldAccess) {
                final RexCorrelVariable v = (RexCorrelVariable) fieldAccess.getReferenceExpr();
                if (v.id.equals(correlation)) {
                    fieldsUsedBuilder.set(fieldAccess.getField().getIndex());
                }
                return fieldAccess;
            }
        });
    }
    return dispatchTrimFields(input, fieldsUsedBuilder.build(), extraFields);
}
Also used : RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) RexCorrelVariable(org.apache.calcite.rex.RexCorrelVariable) RelCollation(org.apache.calcite.rel.RelCollation) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) CorrelationId(org.apache.calcite.rel.core.CorrelationId) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexNode(org.apache.calcite.rex.RexNode)

Example 23 with CorrelationId

use of org.apache.calcite.rel.core.CorrelationId in project calcite by apache.

the class RelBuilder method join.

/**
 * Creates a {@link Join} with correlating variables.
 */
public RelBuilder join(JoinRelType joinType, RexNode condition, Set<CorrelationId> variablesSet) {
    Frame right = stack.pop();
    final Frame left = stack.pop();
    final RelNode join;
    final boolean correlate = checkIfCorrelated(variablesSet, joinType, left.rel, right.rel);
    RexNode postCondition = literal(true);
    if (config.simplify()) {
        // transform the expression to something unrecognizable
        if (condition instanceof RexCall) {
            condition = RelOptUtil.collapseExpandedIsNotDistinctFromExpr((RexCall) condition, getRexBuilder());
        }
        condition = simplifier.simplifyUnknownAsFalse(condition);
    }
    if (correlate) {
        final CorrelationId id = Iterables.getOnlyElement(variablesSet);
        // Correlate does not have an ON clause.
        switch(joinType) {
            case LEFT:
            case SEMI:
            case ANTI:
                // For a LEFT/SEMI/ANTI, predicate must be evaluated first.
                stack.push(right);
                filter(condition.accept(new Shifter(left.rel, id, right.rel)));
                right = stack.pop();
                break;
            case INNER:
                // For INNER, we can defer.
                postCondition = condition;
                break;
            default:
                throw new IllegalArgumentException("Correlated " + joinType + " join is not supported");
        }
        final ImmutableBitSet requiredColumns = RelOptUtil.correlationColumns(id, right.rel);
        join = struct.correlateFactory.createCorrelate(left.rel, right.rel, ImmutableList.of(), id, requiredColumns, joinType);
    } else {
        RelNode join0 = struct.joinFactory.createJoin(left.rel, right.rel, ImmutableList.of(), condition, variablesSet, joinType, false);
        if (join0 instanceof Join && config.pushJoinCondition()) {
            join = RelOptUtil.pushDownJoinConditions((Join) join0, this);
        } else {
            join = join0;
        }
    }
    final ImmutableList.Builder<Field> fields = ImmutableList.builder();
    fields.addAll(left.fields);
    fields.addAll(right.fields);
    stack.push(new Frame(join, fields.build()));
    filter(postCondition);
    return this;
}
Also used : ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) ImmutableList(com.google.common.collect.ImmutableList) Join(org.apache.calcite.rel.core.Join) RexCall(org.apache.calcite.rex.RexCall) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) CorrelationId(org.apache.calcite.rel.core.CorrelationId) RexNode(org.apache.calcite.rex.RexNode)

Example 24 with CorrelationId

use of org.apache.calcite.rel.core.CorrelationId in project ignite by apache.

the class RelJson method toRex.

/**
 */
RexNode toRex(RelInput relInput, Object o) {
    RelOptCluster cluster = relInput.getCluster();
    RexBuilder rexBuilder = cluster.getRexBuilder();
    if (o == null)
        return null;
    else if (o instanceof Map) {
        Map map = (Map) o;
        Map<String, Object> opMap = (Map) map.get("op");
        IgniteTypeFactory typeFactory = Commons.typeFactory(cluster);
        if (opMap != null) {
            if (map.containsKey("class"))
                opMap.put("class", map.get("class"));
            List operands = (List) map.get("operands");
            List<RexNode> rexOperands = toRexList(relInput, operands);
            Object jsonType = map.get("type");
            Map window = (Map) map.get("window");
            if (window != null) {
                SqlAggFunction operator = (SqlAggFunction) toOp(opMap);
                RelDataType type = toType(typeFactory, jsonType);
                List<RexNode> partitionKeys = new ArrayList<>();
                if (window.containsKey("partition"))
                    partitionKeys = toRexList(relInput, (List) window.get("partition"));
                List<RexFieldCollation> orderKeys = new ArrayList<>();
                if (window.containsKey("order"))
                    orderKeys = toRexFieldCollationList(relInput, (List) window.get("order"));
                RexWindowBound lowerBound;
                RexWindowBound upperBound;
                boolean physical;
                if (window.get("rows-lower") != null) {
                    lowerBound = toRexWindowBound(relInput, (Map) window.get("rows-lower"));
                    upperBound = toRexWindowBound(relInput, (Map) window.get("rows-upper"));
                    physical = true;
                } else if (window.get("range-lower") != null) {
                    lowerBound = toRexWindowBound(relInput, (Map) window.get("range-lower"));
                    upperBound = toRexWindowBound(relInput, (Map) window.get("range-upper"));
                    physical = false;
                } else {
                    // No ROWS or RANGE clause
                    lowerBound = null;
                    upperBound = null;
                    physical = false;
                }
                boolean distinct = (Boolean) map.get("distinct");
                return rexBuilder.makeOver(type, operator, rexOperands, partitionKeys, ImmutableList.copyOf(orderKeys), lowerBound, upperBound, physical, true, false, distinct, false);
            } else {
                SqlOperator operator = toOp(opMap);
                RelDataType type;
                if (jsonType != null)
                    type = toType(typeFactory, jsonType);
                else
                    type = rexBuilder.deriveReturnType(operator, rexOperands);
                return rexBuilder.makeCall(type, operator, rexOperands);
            }
        }
        Integer input = (Integer) map.get("input");
        if (input != null) {
            // Check if it is a local ref.
            if (map.containsKey("type")) {
                RelDataType type = toType(typeFactory, map.get("type"));
                return map.get("dynamic") == Boolean.TRUE ? rexBuilder.makeDynamicParam(type, input) : rexBuilder.makeLocalRef(type, input);
            }
            List<RelNode> inputNodes = relInput.getInputs();
            int i = input;
            for (RelNode inputNode : inputNodes) {
                RelDataType rowType = inputNode.getRowType();
                if (i < rowType.getFieldCount()) {
                    RelDataTypeField field = rowType.getFieldList().get(i);
                    return rexBuilder.makeInputRef(field.getType(), input);
                }
                i -= rowType.getFieldCount();
            }
            throw new RuntimeException("input field " + input + " is out of range");
        }
        String field = (String) map.get("field");
        if (field != null) {
            Object jsonExpr = map.get("expr");
            RexNode expr = toRex(relInput, jsonExpr);
            return rexBuilder.makeFieldAccess(expr, field, true);
        }
        String correl = (String) map.get("correl");
        if (correl != null) {
            RelDataType type = toType(typeFactory, map.get("type"));
            return rexBuilder.makeCorrel(type, new CorrelationId(correl));
        }
        if (map.containsKey("literal")) {
            Object literal = map.get("literal");
            RelDataType type = toType(typeFactory, map.get("type"));
            if (literal == null)
                return rexBuilder.makeNullLiteral(type);
            if (type.getSqlTypeName() == SqlTypeName.SYMBOL)
                literal = toEnum(literal);
            else if (type.getSqlTypeName().getFamily() == SqlTypeFamily.BINARY)
                literal = toByteString(literal);
            return rexBuilder.makeLiteral(literal, type, false);
        }
        throw new UnsupportedOperationException("cannot convert to rex " + o);
    } else if (o instanceof Boolean)
        return rexBuilder.makeLiteral((Boolean) o);
    else if (o instanceof String)
        return rexBuilder.makeLiteral((String) o);
    else if (o instanceof Number) {
        Number number = (Number) o;
        if (number instanceof Double || number instanceof Float)
            return rexBuilder.makeApproxLiteral(BigDecimal.valueOf(number.doubleValue()));
        else
            return rexBuilder.makeExactLiteral(BigDecimal.valueOf(number.longValue()));
    } else
        throw new UnsupportedOperationException("cannot convert to rex " + o);
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) SqlOperator(org.apache.calcite.sql.SqlOperator) IgniteTypeFactory(org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeFactory) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlAggFunction(org.apache.calcite.sql.SqlAggFunction) ByteString(org.apache.calcite.avatica.util.ByteString) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RexWindowBound(org.apache.calcite.rex.RexWindowBound) RexBuilder(org.apache.calcite.rex.RexBuilder) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) CorrelationId(org.apache.calcite.rel.core.CorrelationId) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) LinkedHashMap(java.util.LinkedHashMap) RexNode(org.apache.calcite.rex.RexNode)

Example 25 with CorrelationId

use of org.apache.calcite.rel.core.CorrelationId in project ignite by apache.

the class IgniteMdCumulativeCost method getCumulativeCost.

/**
 */
public RelOptCost getCumulativeCost(IgniteCorrelatedNestedLoopJoin rel, RelMetadataQuery mq) {
    RelOptCost cost = nonCumulativeCost(rel, mq);
    if (cost.isInfinite())
        return cost;
    RelNode left = rel.getLeft();
    RelNode right = rel.getRight();
    Set<CorrelationId> corIds = rel.getVariablesSet();
    RelOptCost leftCost = mq.getCumulativeCost(left);
    if (leftCost.isInfinite())
        return leftCost;
    RelOptCost rightCost = mq.getCumulativeCost(right);
    if (rightCost.isInfinite())
        return rightCost;
    return cost.plus(leftCost).plus(rightCost.multiplyBy(left.estimateRowCount(mq) / corIds.size()));
}
Also used : RelNode(org.apache.calcite.rel.RelNode) RelOptCost(org.apache.calcite.plan.RelOptCost) CorrelationId(org.apache.calcite.rel.core.CorrelationId)

Aggregations

CorrelationId (org.apache.calcite.rel.core.CorrelationId)74 RelNode (org.apache.calcite.rel.RelNode)39 RexNode (org.apache.calcite.rex.RexNode)33 RelDataType (org.apache.calcite.rel.type.RelDataType)25 ArrayList (java.util.ArrayList)22 RelOptCluster (org.apache.calcite.plan.RelOptCluster)19 RexBuilder (org.apache.calcite.rex.RexBuilder)18 RelBuilder (org.apache.calcite.tools.RelBuilder)17 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)15 ImmutableList (com.google.common.collect.ImmutableList)12 RelTraitSet (org.apache.calcite.plan.RelTraitSet)12 RexCorrelVariable (org.apache.calcite.rex.RexCorrelVariable)11 RexShuttle (org.apache.calcite.rex.RexShuttle)11 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)10 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)10 List (java.util.List)9 RelOptUtil (org.apache.calcite.plan.RelOptUtil)9 JoinRelType (org.apache.calcite.rel.core.JoinRelType)9 ByteString (org.apache.calcite.avatica.util.ByteString)7 SqlOperator (org.apache.calcite.sql.SqlOperator)7