This is an automated email from the ASF dual-hosted git repository.
rubenql pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push:
new 34ae30c7c6 [CALCITE-7222] SortRemoveDuplicateKeysRule miss fetch and
offset information
34ae30c7c6 is described below
commit 34ae30c7c6db7cf2172e1dd81a6023e6866ae215
Author: Zhen Chen <[email protected]>
AuthorDate: Sat Oct 11 17:36:58 2025 +0800
[CALCITE-7222] SortRemoveDuplicateKeysRule miss fetch and offset information
---
.../calcite/rel/metadata/RelMetadataQuery.java | 6 ++--
.../rel/rules/SortRemoveDuplicateKeysRule.java | 4 +--
.../java/org/apache/calcite/tools/RelBuilder.java | 8 ++++-
.../org/apache/calcite/test/RelOptRulesTest.java | 22 +++++++++++++
.../org/apache/calcite/test/RelOptRulesTest.xml | 38 ++++++++++++++++++++++
5 files changed, 72 insertions(+), 6 deletions(-)
diff --git
a/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
b/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
index 4a5d8ddff0..8044846254 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
@@ -994,12 +994,12 @@ public Boolean isVisibleInExplain(RelNode rel,
}
/**
- * Determines whether key is functionally dependent on column.
+ * Determines whether one column functionally determines another.
*/
- public @Nullable Boolean determines(RelNode rel, int key, int column) {
+ public @Nullable Boolean determines(RelNode rel, int determinant, int
dependent) {
for (;;) {
try {
- return functionalDependencyHandler.determines(rel, this, key, column);
+ return functionalDependencyHandler.determines(rel, this, determinant,
dependent);
} catch (MetadataHandlerProvider.NoHandler e) {
functionalDependencyHandler =
revise(BuiltInMetadata.FunctionalDependency.Handler.class);
}
diff --git
a/core/src/main/java/org/apache/calcite/rel/rules/SortRemoveDuplicateKeysRule.java
b/core/src/main/java/org/apache/calcite/rel/rules/SortRemoveDuplicateKeysRule.java
index 525bece4c8..6574aa9f59 100644
---
a/core/src/main/java/org/apache/calcite/rel/rules/SortRemoveDuplicateKeysRule.java
+++
b/core/src/main/java/org/apache/calcite/rel/rules/SortRemoveDuplicateKeysRule.java
@@ -78,7 +78,7 @@ protected SortRemoveDuplicateKeysRule(Config config) {
boolean dup = false;
for (RelFieldCollation existed : newCollations) {
if (Boolean.TRUE.equals(
- mq.determines(sort, field.getFieldIndex(),
existed.getFieldIndex()))) {
+ mq.determines(sort, existed.getFieldIndex(),
field.getFieldIndex()))) {
dup = true;
break;
}
@@ -93,7 +93,7 @@ protected SortRemoveDuplicateKeysRule(Config config) {
}
relBuilder.push(sort.getInput())
- .sort(RelCollations.of(newCollations));
+ .sortLimit(sort.offset, sort.fetch, RelCollations.of(newCollations));
call.transformTo(relBuilder.build());
}
diff --git a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
index d84c031458..90df447ebc 100644
--- a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
+++ b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
@@ -3727,8 +3727,14 @@ public RelBuilder sortLimit(long offset, long fetch,
RexNode... nodes) {
/** Creates a {@link Sort} by specifying collations.
*/
public RelBuilder sort(RelCollation collation) {
+ return sortLimit(null, null, collation);
+ }
+
+ /** Creates a {@link Sort} by specifying collations, with offset node and
fetch node. */
+ public RelBuilder sortLimit(@Nullable RexNode offsetNode, @Nullable RexNode
fetchNode,
+ RelCollation collation) {
final RelNode sort =
- struct.sortFactory.createSort(peek(), collation, null, null);
+ struct.sortFactory.createSort(peek(), collation, offsetNode,
fetchNode);
replaceTop(sort);
return this;
}
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
index 32225bf803..3a4fb184c5 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -11334,6 +11334,28 @@ private void
checkLoptOptimizeJoinRule(LoptOptimizeJoinRule rule) {
.check();
}
+ /** Test case of
+ * <a
href="https://issues.apache.org/jira/browse/CALCITE-7222">[CALCITE-7222]
+ * SortRemoveDuplicateKeysRule miss fetch and offset infomation</a>. */
+ @Test void testSortRemoveDuplicateKeysWithPK() {
+ final String query = "select * from (select empno as a, deptno as b from
emp) t"
+ + " order by a, b limit 1 offset 2";
+ sql(query)
+ .withRule(CoreRules.SORT_REMOVE_DUPLICATE_KEYS)
+ .check();
+ }
+
+ /** Test case of
+ * <a
href="https://issues.apache.org/jira/browse/CALCITE-7222">[CALCITE-7222]
+ * SortRemoveDuplicateKeysRule miss fetch and offset infomation</a>. */
+ @Test void testSortRemoveDuplicateKeysWithLimit() {
+ final String query = "select * from (select empno as a, empno as b from
emp) t"
+ + " order by a, b limit 1 offset 2";
+ sql(query)
+ .withRule(CoreRules.SORT_REMOVE_DUPLICATE_KEYS)
+ .check();
+ }
+
/** Test case of
* <a
href="https://issues.apache.org/jira/browse/CALCITE-7116">[CALCITE-7116]
* Optimize queries with GROUPING SETS by converting them
diff --git
a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
index 3c85ef747a..ac3a626d81 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -18259,6 +18259,44 @@ LogicalSort(sort0=[$0], dir0=[ASC])
LogicalProject(D1=[$7], D2=[$7])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ </TestCase>
+ <TestCase name="testSortRemoveDuplicateKeysWithLimit">
+ <Resource name="sql">
+ <![CDATA[select * from (select empno as a, empno as b from emp) t order
by a, b limit 1 offset 2]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalSort(sort0=[$0], sort1=[$1], dir0=[ASC], dir1=[ASC], offset=[2],
fetch=[1])
+ LogicalProject(A=[$0], B=[$0])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ <Resource name="planAfter">
+ <![CDATA[
+LogicalSort(sort0=[$0], dir0=[ASC], offset=[2], fetch=[1])
+ LogicalProject(A=[$0], B=[$0])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ </TestCase>
+ <TestCase name="testSortRemoveDuplicateKeysWithPK">
+ <Resource name="sql">
+ <![CDATA[select * from (select empno as a, deptno as b from emp) t order
by a, b limit 1 offset 2]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalSort(sort0=[$0], sort1=[$1], dir0=[ASC], dir1=[ASC], offset=[2],
fetch=[1])
+ LogicalProject(A=[$0], B=[$7])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ <Resource name="planAfter">
+ <![CDATA[
+LogicalSort(sort0=[$0], dir0=[ASC], offset=[2], fetch=[1])
+ LogicalProject(A=[$0], B=[$7])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
</TestCase>