Skip to content

Commit ed62346

Browse files
IGNITE-27700 SQL Calcite: Fix merge filter to scan after trimmed fields
1 parent 9a4ddbf commit ed62346

25 files changed

Lines changed: 144 additions & 178 deletions

modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerHelper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,10 @@ public static IgniteRel optimize(SqlNode sqlNode, IgnitePlanner planner, IgniteL
127127

128128
rel = planner.extractConjunctionOverDisjunctionCommonPart(rel);
129129

130-
rel = planner.trimUnusedFields(root.withRel(rel)).rel;
131-
132130
rel = planner.transform(PlannerPhase.HEP_FILTER_PUSH_DOWN, rel.getTraitSet(), rel);
133131

132+
rel = planner.trimUnusedFields(root.withRel(rel)).rel;
133+
134134
// The following pushed down project can erase top-level hints. We store them to reassign hints for join nodes.
135135
// Clear the inherit pathes to consider the hints as not propogated ones.
136136
List<RelHint> topHints = HintUtils.allRelHints(rel).stream().map(h -> h.inheritPath.isEmpty()

modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerPhase.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ public enum PlannerPhase {
108108
@Override public RuleSet getRules(PlanningContext ctx) {
109109
return ctx.rules(
110110
RuleSets.ofList(
111+
CoreRules.FILTER_REDUCE_EXPRESSIONS,
111112
FilterScanMergeRule.TABLE_SCAN_SKIP_CORRELATED,
112113

113114
CoreRules.FILTER_MERGE,

modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/AbstractIndexScan.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.apache.calcite.rel.RelInput;
2828
import org.apache.calcite.rel.RelWriter;
2929
import org.apache.calcite.rel.metadata.RelMetadataQuery;
30+
import org.apache.calcite.rel.type.RelDataType;
3031
import org.apache.calcite.rex.RexBuilder;
3132
import org.apache.calcite.rex.RexNode;
3233
import org.apache.calcite.rex.RexUtil;
@@ -67,12 +68,13 @@ protected AbstractIndexScan(
6768
RelTraitSet traitSet,
6869
RelOptTable table,
6970
String idxName,
71+
@Nullable RelDataType rowType,
7072
@Nullable List<RexNode> proj,
7173
@Nullable RexNode cond,
7274
@Nullable List<SearchBounds> searchBounds,
7375
@Nullable ImmutableBitSet reqColumns
7476
) {
75-
super(cluster, traitSet, Collections.emptyList(), table, proj, cond, reqColumns);
77+
super(cluster, traitSet, Collections.emptyList(), table, rowType, proj, cond, reqColumns);
7678

7779
this.idxName = idxName;
7880
this.searchBounds = searchBounds;

modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteIndexScan.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.apache.calcite.rel.RelCollation;
2525
import org.apache.calcite.rel.RelInput;
2626
import org.apache.calcite.rel.RelWriter;
27+
import org.apache.calcite.rel.type.RelDataType;
2728
import org.apache.calcite.rex.RexNode;
2829
import org.apache.calcite.util.ImmutableBitSet;
2930
import org.apache.ignite.internal.processors.query.calcite.prepare.bounds.SearchBounds;
@@ -64,6 +65,7 @@ public IgniteIndexScan(RelInput input) {
6465
* @param traits Traits of this relational expression
6566
* @param tbl Table definition.
6667
* @param idxName Index name.
68+
* @param rowType Row type.
6769
* @param proj Projects.
6870
* @param cond Filters.
6971
* @param requiredCols Participating columns.
@@ -74,13 +76,14 @@ public IgniteIndexScan(
7476
RelTraitSet traits,
7577
RelOptTable tbl,
7678
String idxName,
79+
@Nullable RelDataType rowType,
7780
@Nullable List<RexNode> proj,
7881
@Nullable RexNode cond,
7982
@Nullable List<SearchBounds> searchBounds,
8083
@Nullable ImmutableBitSet requiredCols,
8184
RelCollation collation
8285
) {
83-
this(-1L, cluster, traits, tbl, idxName, proj, cond, searchBounds, requiredCols, collation);
86+
this(-1L, cluster, traits, tbl, idxName, rowType, proj, cond, searchBounds, requiredCols, collation);
8487
}
8588

8689
/**
@@ -89,6 +92,7 @@ public IgniteIndexScan(
8992
* @param traits Traits of this relational expression
9093
* @param tbl Table definition.
9194
* @param idxName Index name.
95+
* @param rowType Row type.
9296
* @param proj Projects.
9397
* @param cond Filters.
9498
* @param requiredCols Participating colunms.
@@ -100,13 +104,14 @@ private IgniteIndexScan(
100104
RelTraitSet traits,
101105
RelOptTable tbl,
102106
String idxName,
107+
@Nullable RelDataType rowType,
103108
@Nullable List<RexNode> proj,
104109
@Nullable RexNode cond,
105110
@Nullable List<SearchBounds> searchBounds,
106111
@Nullable ImmutableBitSet requiredCols,
107112
RelCollation collation
108113
) {
109-
super(cluster, traits, tbl, idxName, proj, cond, searchBounds, requiredCols);
114+
super(cluster, traits, tbl, idxName, rowType, proj, cond, searchBounds, requiredCols);
110115

111116
this.sourceId = sourceId;
112117
this.collation = collation;
@@ -132,13 +137,13 @@ private IgniteIndexScan(
132137
/** {@inheritDoc} */
133138
@Override public IgniteRel clone(long sourceId) {
134139
return new IgniteIndexScan(sourceId, getCluster(), getTraitSet(), getTable(),
135-
idxName, projects, condition, searchBounds, requiredColumns, collation);
140+
idxName, rowType, projects, condition, searchBounds, requiredColumns, collation);
136141
}
137142

138143
/** {@inheritDoc} */
139144
@Override public IgniteRel clone(RelOptCluster cluster, List<IgniteRel> inputs) {
140145
return new IgniteIndexScan(sourceId, cluster, getTraitSet(), getTable(),
141-
idxName, projects, condition, searchBounds, requiredColumns, collation);
146+
idxName, rowType, projects, condition, searchBounds, requiredColumns, collation);
142147
}
143148

144149
/** {@inheritDoc} */

modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteTableScan.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.apache.calcite.plan.RelTraitSet;
2525
import org.apache.calcite.rel.RelInput;
2626
import org.apache.calcite.rel.RelWriter;
27+
import org.apache.calcite.rel.type.RelDataType;
2728
import org.apache.calcite.rex.RexNode;
2829
import org.apache.calcite.util.ImmutableBitSet;
2930
import org.jetbrains.annotations.Nullable;
@@ -63,14 +64,15 @@ public IgniteTableScan(
6364
RelTraitSet traits,
6465
RelOptTable tbl
6566
) {
66-
this(cluster, traits, tbl, null, null, null);
67+
this(cluster, traits, tbl, null, null, null, null);
6768
}
6869

6970
/**
7071
* Creates a TableScan.
7172
* @param cluster Cluster that this relational expression belongs to
7273
* @param traits Traits of this relational expression
7374
* @param tbl Table definition.
75+
* @param rowType Row type.
7476
* @param proj Projects.
7577
* @param cond Filters.
7678
* @param requiredColunms Participating colunms.
@@ -79,18 +81,20 @@ public IgniteTableScan(
7981
RelOptCluster cluster,
8082
RelTraitSet traits,
8183
RelOptTable tbl,
84+
@Nullable RelDataType rowType,
8285
@Nullable List<RexNode> proj,
8386
@Nullable RexNode cond,
8487
@Nullable ImmutableBitSet requiredColunms
8588
) {
86-
this(-1L, cluster, traits, tbl, proj, cond, requiredColunms);
89+
this(-1L, cluster, traits, tbl, rowType, proj, cond, requiredColunms);
8790
}
8891

8992
/**
9093
* Creates a TableScan.
9194
* @param cluster Cluster that this relational expression belongs to
9295
* @param traits Traits of this relational expression
9396
* @param tbl Table definition.
97+
* @param rowType Row type.
9498
* @param proj Projects.
9599
* @param cond Filters.
96100
* @param requiredColunms Participating colunms.
@@ -100,11 +104,12 @@ private IgniteTableScan(
100104
RelOptCluster cluster,
101105
RelTraitSet traits,
102106
RelOptTable tbl,
107+
@Nullable RelDataType rowType,
103108
@Nullable List<RexNode> proj,
104109
@Nullable RexNode cond,
105110
@Nullable ImmutableBitSet requiredColunms
106111
) {
107-
super(cluster, traits, ImmutableList.of(), tbl, proj, cond, requiredColunms);
112+
super(cluster, traits, ImmutableList.of(), tbl, rowType, proj, cond, requiredColunms);
108113
this.sourceId = sourceId;
109114
}
110115

@@ -126,11 +131,13 @@ private IgniteTableScan(
126131

127132
/** {@inheritDoc} */
128133
@Override public IgniteRel clone(long sourceId) {
129-
return new IgniteTableScan(sourceId, getCluster(), getTraitSet(), getTable(), projects, condition, requiredColumns);
134+
return new IgniteTableScan(sourceId, getCluster(), getTraitSet(), getTable(), rowType, projects, condition,
135+
requiredColumns);
130136
}
131137

132138
/** {@inheritDoc} */
133139
@Override public IgniteRel clone(RelOptCluster cluster, List<IgniteRel> inputs) {
134-
return new IgniteTableScan(sourceId, cluster, getTraitSet(), getTable(), projects, condition, requiredColumns);
140+
return new IgniteTableScan(sourceId, cluster, getTraitSet(), getTable(), rowType, projects, condition,
141+
requiredColumns);
135142
}
136143
}

modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/ProjectableFilterableTableScan.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,16 @@ protected ProjectableFilterableTableScan(
7575
RelTraitSet traitSet,
7676
List<RelHint> hints,
7777
RelOptTable table,
78+
@Nullable RelDataType rowType,
7879
@Nullable List<RexNode> proj,
7980
@Nullable RexNode cond,
8081
@Nullable ImmutableBitSet reqColumns
8182
) {
8283
super(cluster, traitSet, hints, table);
8384

85+
assert proj == null || rowType != null : "rowType should be provided if project != null";
86+
87+
this.rowType = rowType;
8488
projects = proj;
8589
condition = cond;
8690
requiredColumns = reqColumns;
@@ -90,6 +94,7 @@ protected ProjectableFilterableTableScan(
9094
protected ProjectableFilterableTableScan(RelInput input) {
9195
super(input);
9296
condition = input.getExpression("filters");
97+
rowType = input.get("rowType") == null ? null : input.getRowType("rowType");
9398
projects = input.get("projects") == null ? null : input.getExpressionList("projects");
9499
requiredColumns = input.get("requiredColumns") == null ? null : input.getBitSet("requiredColumns");
95100
}
@@ -129,6 +134,7 @@ protected RelWriter explainTerms0(RelWriter pw) {
129134
}
130135

131136
return pw
137+
.itemIf("rowType", rowType, projects != null) // Intentional project check here.
132138
.itemIf("projects", projects, projects != null)
133139
.itemIf("requiredColumns", requiredColumns, requiredColumns != null);
134140
}
@@ -151,10 +157,9 @@ protected RelWriter explainTerms0(RelWriter pw) {
151157

152158
/** {@inheritDoc} */
153159
@Override public RelDataType deriveRowType() {
154-
if (projects != null)
155-
return RexUtil.createStructType(Commons.typeFactory(getCluster()), projects);
156-
else
157-
return table.unwrap(IgniteTable.class).getRowType(Commons.typeFactory(getCluster()), requiredColumns);
160+
assert projects == null : "For merged projects rowType should be provided explicetely";
161+
162+
return table.unwrap(IgniteTable.class).getRowType(Commons.typeFactory(getCluster()), requiredColumns);
158163
}
159164

160165
/** */

modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/logical/IgniteLogicalIndexScan.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.apache.calcite.plan.RelOptCluster;
2222
import org.apache.calcite.plan.RelOptTable;
2323
import org.apache.calcite.plan.RelTraitSet;
24+
import org.apache.calcite.rel.type.RelDataType;
2425
import org.apache.calcite.rex.RexNode;
2526
import org.apache.calcite.util.ImmutableBitSet;
2627
import org.apache.ignite.internal.processors.query.calcite.prepare.bounds.SearchBounds;
@@ -37,6 +38,7 @@ public static IgniteLogicalIndexScan create(
3738
RelTraitSet traits,
3839
RelOptTable table,
3940
String idxName,
41+
@Nullable RelDataType rowType,
4042
@Nullable List<RexNode> proj,
4143
@Nullable RexNode cond,
4244
@Nullable ImmutableBitSet requiredColumns
@@ -51,6 +53,7 @@ public static IgniteLogicalIndexScan create(
5153
traits,
5254
table,
5355
idxName,
56+
rowType,
5457
proj,
5558
cond,
5659
searchBounds,
@@ -63,6 +66,7 @@ public static IgniteLogicalIndexScan create(
6366
* @param traits Traits of this relational expression
6467
* @param tbl Table definition.
6568
* @param idxName Index name.
69+
* @param rowType Row type.
6670
* @param proj Projects.
6771
* @param cond Filters.
6872
* @param searchBounds Index search bounds.
@@ -73,11 +77,12 @@ private IgniteLogicalIndexScan(
7377
RelTraitSet traits,
7478
RelOptTable tbl,
7579
String idxName,
80+
@Nullable RelDataType rowType,
7681
@Nullable List<RexNode> proj,
7782
@Nullable RexNode cond,
7883
@Nullable List<SearchBounds> searchBounds,
7984
@Nullable ImmutableBitSet requiredCols
8085
) {
81-
super(cluster, traits, tbl, idxName, proj, cond, searchBounds, requiredCols);
86+
super(cluster, traits, tbl, idxName, rowType, proj, cond, searchBounds, requiredCols);
8287
}
8388
}

modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/logical/IgniteLogicalTableScan.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.apache.calcite.plan.RelOptTable;
2525
import org.apache.calcite.plan.RelTraitSet;
2626
import org.apache.calcite.rel.hint.RelHint;
27+
import org.apache.calcite.rel.type.RelDataType;
2728
import org.apache.calcite.rex.RexNode;
2829
import org.apache.calcite.util.ImmutableBitSet;
2930
import org.apache.ignite.internal.processors.query.calcite.rel.ProjectableFilterableTableScan;
@@ -37,12 +38,13 @@ public static IgniteLogicalTableScan create(
3738
RelTraitSet traits,
3839
RelOptTable tbl,
3940
@Nullable List<RelHint> hints,
41+
@Nullable RelDataType rowType,
4042
@Nullable List<RexNode> proj,
4143
@Nullable RexNode cond,
4244
@Nullable ImmutableBitSet requiredColumns
4345
) {
44-
return new IgniteLogicalTableScan(cluster, traits, tbl, hints == null ? ImmutableList.of() : hints, proj, cond,
45-
requiredColumns);
46+
return new IgniteLogicalTableScan(cluster, traits, tbl, hints == null ? ImmutableList.of() : hints,
47+
rowType, proj, cond, requiredColumns);
4648
}
4749

4850
/**
@@ -51,6 +53,7 @@ public static IgniteLogicalTableScan create(
5153
* @param traits Traits of this relational expression.
5254
* @param tbl Table definition.
5355
* @param hints Hints.
56+
* @param rowType Row type.
5457
* @param proj Projects.
5558
* @param cond Filters.
5659
* @param requiredColunms Participating colunms.
@@ -60,16 +63,17 @@ private IgniteLogicalTableScan(
6063
RelTraitSet traits,
6164
RelOptTable tbl,
6265
List<RelHint> hints,
66+
@Nullable RelDataType rowType,
6367
@Nullable List<RexNode> proj,
6468
@Nullable RexNode cond,
6569
@Nullable ImmutableBitSet requiredColunms
6670
) {
67-
super(cluster, traits, hints, tbl, proj, cond, requiredColunms);
71+
super(cluster, traits, hints, tbl, rowType, proj, cond, requiredColunms);
6872
}
6973

7074
/** {@inheritDoc} */
7175
@Override public IgniteLogicalTableScan withHints(List<RelHint> hints) {
72-
return new IgniteLogicalTableScan(getCluster(), getTraitSet(), getTable(), hints, projects(), condition(),
73-
requiredColumns());
76+
return new IgniteLogicalTableScan(getCluster(), getTraitSet(), getTable(), hints,
77+
rowType, projects(), condition(), requiredColumns());
7478
}
7579
}

modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/LogicalScanConverterRule.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ public abstract class LogicalScanConverterRule<T extends ProjectableFilterableTa
111111
traits,
112112
rel.getTable(),
113113
rel.indexName(),
114+
rel.getRowType(),
114115
rel.projects(),
115116
rel.condition(),
116117
rel.searchBounds(),
@@ -163,8 +164,8 @@ public abstract class LogicalScanConverterRule<T extends ProjectableFilterableTa
163164
if (!corrIds.isEmpty())
164165
traits = traits.replace(CorrelationTrait.correlations(corrIds));
165166

166-
return new IgniteTableScan(rel.getCluster(), traits,
167-
rel.getTable(), rel.projects(), rel.condition(), rel.requiredColumns());
167+
return new IgniteTableScan(rel.getCluster(), traits, rel.getTable(),
168+
rel.getRowType(), rel.projects(), rel.condition(), rel.requiredColumns());
168169
}
169170
};
170171

modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/logical/ExposeIndexRule.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.apache.calcite.rel.RelNode;
3333
import org.apache.calcite.rel.core.TableScan;
3434
import org.apache.calcite.rel.hint.RelHint;
35+
import org.apache.calcite.rel.type.RelDataType;
3536
import org.apache.calcite.rex.RexNode;
3637
import org.apache.calcite.util.ImmutableBitSet;
3738
import org.apache.ignite.internal.processors.query.calcite.hint.HintDefinition;
@@ -75,6 +76,7 @@ private static boolean preMatch(IgniteLogicalTableScan scan) {
7576

7677
RelOptTable optTable = scan.getTable();
7778
IgniteTable igniteTable = optTable.unwrap(IgniteTable.class);
79+
RelDataType rowType = scan.getRowType();
7880
List<RexNode> proj = scan.projects();
7981
RexNode condition = scan.condition();
8082
ImmutableBitSet requiredCols = scan.requiredColumns();
@@ -83,7 +85,7 @@ private static boolean preMatch(IgniteLogicalTableScan scan) {
8385
return;
8486

8587
List<IgniteLogicalIndexScan> indexes = igniteTable.indexes().values().stream()
86-
.map(idx -> idx.toRel(cluster, optTable, proj, condition, requiredCols))
88+
.map(idx -> idx.toRel(cluster, optTable, rowType, proj, condition, requiredCols))
8789
.collect(Collectors.toList());
8890

8991
assert !indexes.isEmpty();

0 commit comments

Comments
 (0)