use of org.apache.ignite.internal.sql.engine.rel.IgniteCorrelatedNestedLoopJoin in project ignite-3 by apache.
the class CorrelateToNestedLoopRule method convert.
/**
* {@inheritDoc}
*/
@Override
public 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.sql.engine.rel.IgniteCorrelatedNestedLoopJoin in project ignite-3 by apache.
the class CorrelatedNestedLoopJoinRule method convert.
@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<>();
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);
}
use of org.apache.ignite.internal.sql.engine.rel.IgniteCorrelatedNestedLoopJoin in project ignite-3 by apache.
the class CorrelatedSubqueryPlannerTest method test.
/**
* Test verifies the row type is consistent for correlation variable and
* node that actually puts this variable into a context.
*
* <p>In this particular test the row type of the left input of CNLJ node should
* match the row type correlated variable in the filter was created with.
*
* @throws Exception In case of any unexpected error.
*/
@Test
public void test() throws Exception {
IgniteSchema schema = createSchema(createTable("T1", IgniteDistributions.single(), "A", Integer.class, "B", Integer.class, "C", Integer.class, "D", Integer.class, "E", Integer.class));
String sql = "" + "SELECT (SELECT count(*) FROM t1 AS x WHERE x.b<t1.b)\n" + " FROM t1\n" + " WHERE (a>e-2 AND a<e+2)\n" + " OR c>d\n" + " ORDER BY 1;";
IgniteRel rel = physicalPlan(sql, schema, "FilterTableScanMergeRule");
IgniteFilter filter = findFirstNode(rel, byClass(IgniteFilter.class).and(f -> RexUtils.hasCorrelation(((Filter) f).getCondition())));
RexFieldAccess fieldAccess = findFirst(filter.getCondition(), RexFieldAccess.class);
assertNotNull(fieldAccess);
assertEquals(RexCorrelVariable.class, fieldAccess.getReferenceExpr().getClass());
IgniteCorrelatedNestedLoopJoin join = findFirstNode(rel, byClass(IgniteCorrelatedNestedLoopJoin.class));
assertEquals(fieldAccess.getReferenceExpr().getType(), join.getLeft().getRowType());
}
Aggregations