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;
}
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);
}
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());
}
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))));
}
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);
}
Aggregations