Search in sources :

Example 1 with CorrelationTrait

use of org.apache.ignite.internal.processors.query.calcite.trait.CorrelationTrait in project ignite by apache.

the class IgniteFilter method passThroughCorrelation.

/**
 */
@Override
public Pair<RelTraitSet, List<RelTraitSet>> passThroughCorrelation(RelTraitSet nodeTraits, List<RelTraitSet> inTraits) {
    Set<CorrelationId> corrSet = RexUtils.extractCorrelationIds(getCondition());
    CorrelationTrait correlation = TraitUtils.correlation(nodeTraits);
    if (corrSet.isEmpty() || correlation.correlationIds().containsAll(corrSet))
        return Pair.of(nodeTraits, ImmutableList.of(inTraits.get(0).replace(correlation)));
    return null;
}
Also used : CorrelationTrait(org.apache.ignite.internal.processors.query.calcite.trait.CorrelationTrait) CorrelationId(org.apache.calcite.rel.core.CorrelationId)

Example 2 with CorrelationTrait

use of org.apache.ignite.internal.processors.query.calcite.trait.CorrelationTrait in project ignite by apache.

the class FilterSpoolMergeToSortedIndexSpoolRule method onMatch.

/**
 * {@inheritDoc}
 */
@Override
public void onMatch(RelOptRuleCall call) {
    final IgniteFilter filter = call.rel(0);
    final IgniteTableSpool spool = call.rel(1);
    RelOptCluster cluster = spool.getCluster();
    RelTraitSet trait = spool.getTraitSet();
    CorrelationTrait filterCorr = TraitUtils.correlation(filter);
    if (filterCorr.correlated())
        trait = trait.replace(filterCorr);
    RelNode input = spool.getInput();
    RelCollation inCollation = TraitUtils.collation(input);
    IndexConditions idxCond = RexUtils.buildSortedIndexConditions(cluster, inCollation, filter.getCondition(), spool.getRowType(), null);
    if (F.isEmpty(idxCond.lowerCondition()) && F.isEmpty(idxCond.upperCondition()))
        return;
    RelCollation traitCollation;
    RelCollation searchCollation;
    if (inCollation == null || inCollation.isDefault()) {
        // Create collation by index condition.
        List<RexNode> lowerBound = idxCond.lowerBound();
        List<RexNode> upperBound = idxCond.upperBound();
        assert lowerBound == null || upperBound == null || lowerBound.size() == upperBound.size();
        int cardinality = lowerBound != null ? lowerBound.size() : upperBound.size();
        List<Integer> equalsFields = new ArrayList<>(cardinality);
        List<Integer> otherFields = new ArrayList<>(cardinality);
        // First, add all equality filters to collation, then add other fields.
        for (int i = 0; i < cardinality; i++) {
            RexNode lowerNode = lowerBound != null ? lowerBound.get(i) : null;
            RexNode upperNode = upperBound != null ? upperBound.get(i) : null;
            if (RexUtils.isNotNull(lowerNode) || RexUtils.isNotNull(upperNode))
                (F.eq(lowerNode, upperNode) ? equalsFields : otherFields).add(i);
        }
        searchCollation = traitCollation = TraitUtils.createCollation(F.concat(true, equalsFields, otherFields));
    } else {
        // Create search collation as a prefix of input collation.
        traitCollation = inCollation;
        Set<Integer> searchKeys = idxCond.keys();
        List<RelFieldCollation> collationFields = inCollation.getFieldCollations().subList(0, searchKeys.size());
        assert searchKeys.containsAll(collationFields.stream().map(RelFieldCollation::getFieldIndex).collect(Collectors.toSet())) : "Search condition should be a prefix of collation [searchKeys=" + searchKeys + ", collation=" + inCollation + ']';
        searchCollation = RelCollations.of(collationFields);
    }
    RelNode res = new IgniteSortedIndexSpool(cluster, trait.replace(traitCollation), convert(input, input.getTraitSet().replace(traitCollation)), searchCollation, filter.getCondition(), idxCond);
    call.transformTo(res);
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) IgniteSortedIndexSpool(org.apache.ignite.internal.processors.query.calcite.rel.IgniteSortedIndexSpool) CorrelationTrait(org.apache.ignite.internal.processors.query.calcite.trait.CorrelationTrait) IndexConditions(org.apache.ignite.internal.processors.query.calcite.util.IndexConditions) ArrayList(java.util.ArrayList) RelTraitSet(org.apache.calcite.plan.RelTraitSet) RelCollation(org.apache.calcite.rel.RelCollation) RelNode(org.apache.calcite.rel.RelNode) IgniteFilter(org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter) IgniteTableSpool(org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableSpool) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) RexNode(org.apache.calcite.rex.RexNode)

Example 3 with CorrelationTrait

use of org.apache.ignite.internal.processors.query.calcite.trait.CorrelationTrait in project ignite by apache.

the class CorrelateToNestedLoopRule method convert.

/**
 * {@inheritDoc}
 */
@Override
protected PhysicalNode convert(RelOptPlanner planner, RelMetadataQuery mq, LogicalCorrelate rel) {
    final RelOptCluster cluster = rel.getCluster();
    final Set<CorrelationId> correlationIds = Collections.singleton(rel.getCorrelationId());
    CorrelationTrait corrTrait = CorrelationTrait.correlations(correlationIds);
    RelTraitSet outTraits = cluster.traitSetOf(IgniteConvention.INSTANCE);
    RelTraitSet leftInTraits = cluster.traitSetOf(IgniteConvention.INSTANCE);
    RelTraitSet rightInTraits = cluster.traitSetOf(IgniteConvention.INSTANCE).replace(RewindabilityTrait.REWINDABLE).replace(corrTrait);
    RelNode left = convert(rel.getLeft(), leftInTraits);
    RelNode right = convert(rel.getRight(), rightInTraits);
    return new IgniteCorrelatedNestedLoopJoin(cluster, outTraits, left, right, cluster.getRexBuilder().makeLiteral(true), correlationIds, rel.getJoinType());
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) CorrelationTrait(org.apache.ignite.internal.processors.query.calcite.trait.CorrelationTrait) RelNode(org.apache.calcite.rel.RelNode) CorrelationId(org.apache.calcite.rel.core.CorrelationId) RelTraitSet(org.apache.calcite.plan.RelTraitSet) IgniteCorrelatedNestedLoopJoin(org.apache.ignite.internal.processors.query.calcite.rel.IgniteCorrelatedNestedLoopJoin)

Example 4 with CorrelationTrait

use of org.apache.ignite.internal.processors.query.calcite.trait.CorrelationTrait in project ignite by apache.

the class IgniteCorrelatedNestedLoopJoin method passThroughCorrelation.

/**
 * {@inheritDoc}
 */
@Override
public Pair<RelTraitSet, List<RelTraitSet>> passThroughCorrelation(RelTraitSet nodeTraits, List<RelTraitSet> inTraits) {
    CorrelationTrait nodeCorr = TraitUtils.correlation(nodeTraits);
    Set<CorrelationId> selfCorrIds = U.newHashSet(variablesSet.size() + nodeCorr.correlationIds().size());
    selfCorrIds.addAll(variablesSet);
    selfCorrIds.addAll(nodeCorr.correlationIds());
    return Pair.of(nodeTraits, ImmutableList.of(inTraits.get(0).replace(nodeCorr), inTraits.get(1).replace(CorrelationTrait.correlations(selfCorrIds))));
}
Also used : CorrelationTrait(org.apache.ignite.internal.processors.query.calcite.trait.CorrelationTrait) CorrelationId(org.apache.calcite.rel.core.CorrelationId)

Example 5 with CorrelationTrait

use of org.apache.ignite.internal.processors.query.calcite.trait.CorrelationTrait in project ignite by apache.

the class CorrelatedNestedLoopJoinRule method convert.

/**
 * {@inheritDoc}
 */
@Override
protected PhysicalNode convert(RelOptPlanner planner, RelMetadataQuery mq, LogicalJoin rel) {
    final int leftFieldCount = rel.getLeft().getRowType().getFieldCount();
    final RelOptCluster cluster = rel.getCluster();
    final RexBuilder rexBuilder = cluster.getRexBuilder();
    final RelBuilder relBuilder = relBuilderFactory.create(rel.getCluster(), null);
    final Set<CorrelationId> correlationIds = new HashSet<>();
    final ArrayList<RexNode> corrVar = new ArrayList<>();
    if (corrVar.isEmpty()) {
        for (int i = 0; i < batchSize; i++) {
            CorrelationId correlationId = cluster.createCorrel();
            correlationIds.add(correlationId);
            corrVar.add(rexBuilder.makeCorrel(rel.getLeft().getRowType(), correlationId));
        }
    }
    // Generate first condition
    final RexNode condition = rel.getCondition().accept(new RexShuttle() {

        @Override
        public RexNode visitInputRef(RexInputRef input) {
            int field = input.getIndex();
            if (field >= leftFieldCount)
                return rexBuilder.makeInputRef(input.getType(), input.getIndex() - leftFieldCount);
            return rexBuilder.makeFieldAccess(corrVar.get(0), field);
        }
    });
    List<RexNode> conditionList = new ArrayList<>();
    conditionList.add(condition);
    // Add batchSize-1 other conditions
    for (int i = 1; i < batchSize; i++) {
        final int corrIndex = i;
        final RexNode condition2 = condition.accept(new RexShuttle() {

            @Override
            public RexNode visitCorrelVariable(RexCorrelVariable variable) {
                return corrVar.get(corrIndex);
            }
        });
        conditionList.add(condition2);
    }
    RelTraitSet filterInTraits = rel.getRight().getTraitSet();
    // Push a filter with batchSize disjunctions
    relBuilder.push(rel.getRight().copy(filterInTraits, rel.getRight().getInputs())).filter(relBuilder.or(conditionList));
    RelNode right = relBuilder.build();
    JoinRelType joinType = rel.getJoinType();
    RelTraitSet outTraits = cluster.traitSetOf(IgniteConvention.INSTANCE);
    RelTraitSet leftInTraits = cluster.traitSetOf(IgniteConvention.INSTANCE);
    CorrelationTrait corrTrait = CorrelationTrait.correlations(correlationIds);
    RelTraitSet rightInTraits = cluster.traitSetOf(IgniteConvention.INSTANCE).replace(RewindabilityTrait.REWINDABLE).replace(corrTrait);
    RelNode left = convert(rel.getLeft(), leftInTraits);
    right = convert(right, rightInTraits);
    return new IgniteCorrelatedNestedLoopJoin(cluster, outTraits, left, right, rel.getCondition(), correlationIds, joinType);
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) RexCorrelVariable(org.apache.calcite.rex.RexCorrelVariable) CorrelationTrait(org.apache.ignite.internal.processors.query.calcite.trait.CorrelationTrait) RelBuilder(org.apache.calcite.tools.RelBuilder) RexShuttle(org.apache.calcite.rex.RexShuttle) ArrayList(java.util.ArrayList) RelTraitSet(org.apache.calcite.plan.RelTraitSet) IgniteCorrelatedNestedLoopJoin(org.apache.ignite.internal.processors.query.calcite.rel.IgniteCorrelatedNestedLoopJoin) JoinRelType(org.apache.calcite.rel.core.JoinRelType) RelNode(org.apache.calcite.rel.RelNode) RexBuilder(org.apache.calcite.rex.RexBuilder) RexInputRef(org.apache.calcite.rex.RexInputRef) CorrelationId(org.apache.calcite.rel.core.CorrelationId) HashSet(java.util.HashSet) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

CorrelationTrait (org.apache.ignite.internal.processors.query.calcite.trait.CorrelationTrait)6 RelOptCluster (org.apache.calcite.plan.RelOptCluster)4 RelTraitSet (org.apache.calcite.plan.RelTraitSet)4 RelNode (org.apache.calcite.rel.RelNode)4 CorrelationId (org.apache.calcite.rel.core.CorrelationId)4 RexNode (org.apache.calcite.rex.RexNode)3 ArrayList (java.util.ArrayList)2 IgniteCorrelatedNestedLoopJoin (org.apache.ignite.internal.processors.query.calcite.rel.IgniteCorrelatedNestedLoopJoin)2 IgniteFilter (org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter)2 IgniteTableSpool (org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableSpool)2 HashSet (java.util.HashSet)1 RelCollation (org.apache.calcite.rel.RelCollation)1 RelFieldCollation (org.apache.calcite.rel.RelFieldCollation)1 JoinRelType (org.apache.calcite.rel.core.JoinRelType)1 RexBuilder (org.apache.calcite.rex.RexBuilder)1 RexCorrelVariable (org.apache.calcite.rex.RexCorrelVariable)1 RexInputRef (org.apache.calcite.rex.RexInputRef)1 RexShuttle (org.apache.calcite.rex.RexShuttle)1 RelBuilder (org.apache.calcite.tools.RelBuilder)1 IgniteHashIndexSpool (org.apache.ignite.internal.processors.query.calcite.rel.IgniteHashIndexSpool)1