This is an automated email from the ASF dual-hosted git repository.
rubenql pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/master by this push:
new dcbc493 [CALCITE-5019] Avoid multiple scans when table is
ProjectableFilterableTable and projections and filters act on different columns
dcbc493 is described below
commit dcbc493bf699d961427952c5efc047b76d859096
Author: IceMimosa <[email protected]>
AuthorDate: Wed Feb 23 18:06:10 2022 +0800
[CALCITE-5019] Avoid multiple scans when table is
ProjectableFilterableTable and projections and filters act on different columns
---
.../apache/calcite/interpreter/TableScanNode.java | 4 +--
.../apache/calcite/test/ScannableTableTest.java | 29 ++++++++++++++++++++--
2 files changed, 29 insertions(+), 4 deletions(-)
diff --git
a/core/src/main/java/org/apache/calcite/interpreter/TableScanNode.java
b/core/src/main/java/org/apache/calcite/interpreter/TableScanNode.java
index 2f552f1..ece2008 100644
--- a/core/src/main/java/org/apache/calcite/interpreter/TableScanNode.java
+++ b/core/src/main/java/org/apache/calcite/interpreter/TableScanNode.java
@@ -200,8 +200,6 @@ public class TableScanNode implements Node {
} else {
projectInts = projects.toIntArray();
}
- final Enumerable<@Nullable Object[]> enumerable1 =
- pfTable.scan(root, mutableFilters, projectInts);
for (RexNode filter : mutableFilters) {
if (!filters.contains(filter)) {
throw RESOURCE.filterableTableInventedFilter(filter.toString())
@@ -227,6 +225,8 @@ public class TableScanNode implements Node {
continue;
}
}
+ final Enumerable<@Nullable Object[]> enumerable1 =
+ pfTable.scan(root, mutableFilters, projectInts);
final Enumerable<Row> rowEnumerable = Enumerables.toRow(enumerable1);
final ImmutableIntList rejectedProjects;
if (originalProjects == null || originalProjects.equals(projects)) {
diff --git a/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java
b/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java
index 2a64d97..0339cd4 100644
--- a/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java
+++ b/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java
@@ -155,7 +155,7 @@ public class ScannableTableTest {
"j=Paul");
// Only 2 rows came out of the table. If the value is 4, it means that the
// planner did not pass the filter down.
- assertThat(buf.toString(), is("returnCount=2, filter=<0, 4>,
projects=[1]"));
+ assertThat(buf.toString(), is("returnCount=2, filter=<0, 4>, projects=[1,
0]"));
}
@Test void testProjectableFilterableNonCooperative() throws Exception {
@@ -188,7 +188,7 @@ public class ScannableTableTest {
.returnsUnordered("k=1940; j=John",
"k=1942; j=Paul");
assertThat(buf.toString(),
- is("returnCount=2, filter=<0, 4>, projects=[2, 1]"));
+ is("returnCount=2, filter=<0, 4>, projects=[2, 1, 0]"));
}
/** A filter on a {@link
org.apache.calcite.schema.ProjectableFilterableTable}
@@ -397,6 +397,25 @@ public class ScannableTableTest {
}
/** Test case for
+ * <a
href="https://issues.apache.org/jira/browse/CALCITE-5019">[CALCITE-5019]
+ * Avoid multiple scans when table is ProjectableFilterableTable</a>.*/
+ @Test void testProjectableFilterableWithScanCounter() throws Exception {
+ final StringBuilder buf = new StringBuilder();
+ final BeatlesProjectableFilterableTable table =
+ new BeatlesProjectableFilterableTable(buf, false);
+ final String explain = "PLAN="
+ + "EnumerableInterpreter\n"
+ + " BindableTableScan(table=[[s, beatles]], filters=[[=($0, 4)]],
projects=[[1]]";
+ CalciteAssert.that()
+ .with(newSchema("s", Pair.of("beatles", table)))
+ .query("select \"j\" from \"s\".\"beatles\" where \"i\" = 4")
+ .explainContains(explain)
+ .returnsUnordered("j=John", "j=Paul");
+ assertThat(table.getScanCount(), is(1));
+ assertThat(buf.toString(), is("returnCount=4, projects=[1, 0]"));
+ }
+
+ /** Test case for
* <a
href="https://issues.apache.org/jira/browse/CALCITE-1031">[CALCITE-1031]
* In prepared statement, CsvScannableTable.scan is called twice</a>. */
@Test void testPrepared2() throws SQLException {
@@ -558,6 +577,7 @@ public class ScannableTableTest {
* interface. */
public static class BeatlesProjectableFilterableTable
extends AbstractTable implements ProjectableFilterableTable {
+ private final AtomicInteger scanCounter = new AtomicInteger();
private final StringBuilder buf;
private final boolean cooperative;
@@ -577,6 +597,7 @@ public class ScannableTableTest {
public Enumerable<@Nullable Object[]> scan(DataContext root, List<RexNode>
filters,
final int @Nullable [] projects) {
+ scanCounter.incrementAndGet();
final Pair<Integer, Object> filter = getFilter(cooperative, filters);
return new AbstractEnumerable<Object[]>() {
public Enumerator<Object[]> enumerator() {
@@ -584,6 +605,10 @@ public class ScannableTableTest {
}
};
}
+
+ public int getScanCount() {
+ return this.scanCounter.get();
+ }
}
private static Enumerator<Object[]> tens() {