Skip to content

Commit 801acdf

Browse files
IGNITE-24664 SQL Calcite: Use PK index scan instead of hash index scan - Fixes #11900.
Signed-off-by: Aleksey Plekhanov <plehanov.alex@gmail.com>
1 parent e29db88 commit 801acdf

File tree

6 files changed

+33
-15
lines changed

6 files changed

+33
-15
lines changed

modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/IndexFirstLastScan.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,11 @@ public IndexFirstLastScan(
6767
@Override protected IndexQueryContext indexQueryContext() {
6868
IndexQueryContext res = super.indexQueryContext();
6969

70+
boolean checkExpired = !cctx.config().isEagerTtl();
71+
7072
return new IndexQueryContext(
7173
res.cacheFilter(),
72-
createNotNullRowFilter(idx, true)
74+
createNotNullRowFilter(idx, checkExpired)
7375
);
7476
}
7577

modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/IndexScan.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,9 @@ protected IndexQueryContext indexQueryContext() {
255255
? new InlineIndexRowFactory(rowHnd.inlineIndexKeyTypes().toArray(new InlineIndexKeyType[0]), rowHnd)
256256
: null;
257257

258-
BPlusTree.TreeRowClosure<IndexRow, IndexRow> rowFilter = isInlineScan() ? null : createNotExpiredRowFilter();
258+
boolean checkExpired = !cctx.config().isEagerTtl();
259+
260+
BPlusTree.TreeRowClosure<IndexRow, IndexRow> rowFilter = checkExpired ? createNotExpiredRowFilter() : null;
259261

260262
return new IndexQueryContext(filter, rowFilter, rowFactory);
261263
}

modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementor.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.apache.calcite.rex.RexNode;
3939
import org.apache.calcite.util.ImmutableBitSet;
4040
import org.apache.ignite.internal.processors.failure.FailureProcessor;
41+
import org.apache.ignite.internal.processors.query.QueryUtils;
4142
import org.apache.ignite.internal.processors.query.calcite.exec.RowHandler.RowFactory;
4243
import org.apache.ignite.internal.processors.query.calcite.exec.exp.ExpressionFactory;
4344
import org.apache.ignite.internal.processors.query.calcite.exec.exp.RangeIterable;
@@ -512,21 +513,30 @@ private boolean hasExchange(RelNode rel) {
512513
@Override public Node<Row> visit(IgniteTableScan rel) {
513514
RexNode condition = rel.condition();
514515
List<RexNode> projects = rel.projects();
515-
ImmutableBitSet requiredColunms = rel.requiredColumns();
516+
ImmutableBitSet requiredColumns = rel.requiredColumns();
516517

517518
IgniteTable tbl = rel.getTable().unwrap(IgniteTable.class);
518519
IgniteTypeFactory typeFactory = ctx.getTypeFactory();
519520

520-
RelDataType rowType = tbl.getRowType(typeFactory, requiredColunms);
521+
RelDataType rowType = tbl.getRowType(typeFactory, requiredColumns);
521522

522523
Predicate<Row> filters = condition == null ? null : expressionFactory.predicate(condition, rowType);
523524
Function<Row, Row> prj = projects == null ? null : expressionFactory.project(projects, rowType);
524525

525526
ColocationGroup grp = ctx.group(rel.sourceId());
526527

527-
Iterable<Row> rowsIter = tbl.scan(ctx, grp, requiredColunms);
528+
IgniteIndex idx = tbl.getIndex(QueryUtils.PRIMARY_KEY_INDEX);
528529

529-
return new ScanStorageNode<>(tbl.name(), ctx, rowType, rowsIter, filters, prj);
530+
if (idx != null && !tbl.isIndexRebuildInProgress()) {
531+
Iterable<Row> rowsIter = idx.scan(ctx, grp, null, requiredColumns);
532+
533+
return new ScanStorageNode<>(idx.name(), ctx, rowType, rowsIter, filters, prj);
534+
}
535+
else {
536+
Iterable<Row> rowsIter = tbl.scan(ctx, grp, requiredColumns);
537+
538+
return new ScanStorageNode<>(tbl.name(), ctx, rowType, rowsIter, filters, prj);
539+
}
530540
}
531541

532542
/** {@inheritDoc} */

modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/ExpressionFactoryImpl.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ public class ExpressionFactoryImpl<Row> implements ExpressionFactory<Row> {
109109
/** */
110110
private final RelDataType nullType;
111111

112+
/** */
113+
private final RelDataType booleanType;
114+
112115
/** */
113116
private final ExecutionContext<Row> ctx;
114117

@@ -126,6 +129,7 @@ public ExpressionFactoryImpl(
126129

127130
emptyType = new RelDataTypeFactory.Builder(this.typeFactory).build();
128131
nullType = typeFactory.createSqlType(SqlTypeName.NULL);
132+
booleanType = typeFactory.createJavaType(Boolean.class);
129133
}
130134

131135
/** {@inheritDoc} */
@@ -624,7 +628,7 @@ private abstract class AbstractScalarPredicate<T extends Scalar> {
624628
private AbstractScalarPredicate(T scalar) {
625629
this.scalar = scalar;
626630
hnd = ctx.rowHandler();
627-
out = hnd.factory(typeFactory, typeFactory.createJavaType(Boolean.class)).create();
631+
out = hnd.factory(typeFactory, booleanType).create();
628632
}
629633
}
630634

modules/core/src/main/java/org/apache/ignite/spi/indexing/IndexingQueryCacheFilter.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
package org.apache.ignite.spi.indexing;
1919

20-
import java.util.Set;
20+
import java.util.BitSet;
2121
import org.apache.ignite.cluster.ClusterNode;
2222
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
2323
import org.apache.ignite.internal.processors.cache.GridCacheAffinityManager;
@@ -30,7 +30,7 @@ public class IndexingQueryCacheFilter {
3030
private final GridCacheAffinityManager aff;
3131

3232
/** Partitions. */
33-
private final Set<Integer> parts;
33+
private final BitSet parts;
3434

3535
/** Topology version. */
3636
private final AffinityTopologyVersion topVer;
@@ -46,7 +46,7 @@ public class IndexingQueryCacheFilter {
4646
* @param topVer Topology version.
4747
* @param locNode Local node.
4848
*/
49-
public IndexingQueryCacheFilter(GridCacheAffinityManager aff, Set<Integer> parts,
49+
public IndexingQueryCacheFilter(GridCacheAffinityManager aff, BitSet parts,
5050
AffinityTopologyVersion topVer, ClusterNode locNode) {
5151
this.aff = aff;
5252
this.parts = parts;
@@ -76,6 +76,6 @@ public boolean applyPartition(int part) {
7676
if (parts == null)
7777
return aff.primaryByPartition(locNode, part, topVer);
7878
else
79-
return parts.contains(part);
79+
return parts.get(part);
8080
}
8181
}

modules/core/src/main/java/org/apache/ignite/spi/indexing/IndexingQueryFilterImpl.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
package org.apache.ignite.spi.indexing;
1919

20-
import java.util.HashSet;
20+
import java.util.BitSet;
2121
import org.apache.ignite.internal.GridKernalContext;
2222
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
2323
import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
@@ -37,7 +37,7 @@ public class IndexingQueryFilterImpl implements IndexingQueryFilter {
3737
private final AffinityTopologyVersion topVer;
3838

3939
/** Partitions. */
40-
private final HashSet<Integer> parts;
40+
private final BitSet parts;
4141

4242
/**
4343
* Treat replicated as partitioned.
@@ -71,10 +71,10 @@ public IndexingQueryFilterImpl(GridKernalContext ctx, @Nullable AffinityTopology
7171
if (F.isEmpty(partsArr))
7272
parts = null;
7373
else {
74-
parts = new HashSet<>();
74+
parts = new BitSet();
7575

7676
for (int part : partsArr)
77-
parts.add(part);
77+
parts.set(part);
7878
}
7979

8080
this.treatReplicatedAsPartitioned = treatReplicatedAsPartitioned;

0 commit comments

Comments
 (0)