You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by zh...@apache.org on 2025/09/24 12:54:53 UTC
(calcite) 01/02: [CALCITE-7190] FETCH and OFFSET in SortMergeRule only supports BIGINT
This is an automated email from the ASF dual-hosted git repository.
zhenchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
commit d8fcc4077ddf74f05994f24edc8997f8889dd7b5
Author: Zhen Chen <cz...@163.com>
AuthorDate: Sat Sep 20 18:12:31 2025 +0800
[CALCITE-7190] FETCH and OFFSET in SortMergeRule only supports BIGINT
---
.../org/apache/calcite/rel/rules/MeasureRules.java | 4 ++--
.../apache/calcite/rel/rules/SortMergeRule.java | 14 ++++++------
.../java/org/apache/calcite/tools/RelBuilder.java | 25 +++++++++++++++-------
3 files changed, 27 insertions(+), 16 deletions(-)
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/MeasureRules.java b/core/src/main/java/org/apache/calcite/rel/rules/MeasureRules.java
index 707c7b2f5f..037a4d6054 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/MeasureRules.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/MeasureRules.java
@@ -508,8 +508,8 @@ protected ProjectSortMeasureRule(ProjectSortMeasureRuleConfig config) {
relBuilder.push(sort.getInput())
.projectPlus(map.keySet())
- .sortLimit(sort.offset == null ? 0 : RexLiteral.longValue(sort.offset),
- sort.fetch == null ? -1 : RexLiteral.longValue(sort.fetch),
+ .sortLimit(sort.offset == null ? 0 : RexLiteral.numberValue(sort.offset),
+ sort.fetch == null ? -1 : RexLiteral.numberValue(sort.fetch),
sort.getSortExps())
.project(newProjects);
call.transformTo(relBuilder.build());
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/SortMergeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/SortMergeRule.java
index 797b7e354a..1622864329 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/SortMergeRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/SortMergeRule.java
@@ -28,6 +28,8 @@
import org.immutables.value.Value;
+import java.math.BigDecimal;
+
/**
* This rule try to merge the double {@link Sort},one is Limit semantics,
* another sort is Limit or TOPN semantics.
@@ -92,18 +94,18 @@ private static void limitMerge(SortMergeRule rule,
final RelBuilder builder = call.builder();
- final long topFetch = topSort.fetch instanceof RexLiteral
- ? RexLiteral.longValue(topSort.fetch) : -1;
+ final Number topFetch = topSort.fetch instanceof RexLiteral
+ ? RexLiteral.numberValue(topSort.fetch) : null;
- final long bottomFetch = bottomSort.fetch instanceof RexLiteral
- ? RexLiteral.longValue(bottomSort.fetch) : -1;
+ final Number bottomFetch = bottomSort.fetch instanceof RexLiteral
+ ? RexLiteral.numberValue(bottomSort.fetch) : null;
- if (topFetch == -1 || bottomFetch == -1) {
+ if (topFetch == null || bottomFetch == null) {
return;
}
// Get the minimum limit value from parent and child sort RelNode
- final long minFetch = Math.min(topFetch, bottomFetch);
+ final Number minFetch = ((BigDecimal) topFetch).min((BigDecimal) bottomFetch);
builder.push(bottomSort.getInput());
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 b9b9c25a42..e653d72d54 100644
--- a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
+++ b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
@@ -3674,7 +3674,7 @@ private static <E> ImmutableList<ImmutableList<E>> copy(
* @param offset Number of rows to skip; non-positive means don't skip any
* @param fetch Maximum number of rows to fetch; negative means no limit
*/
- public RelBuilder limit(int offset, int fetch) {
+ public RelBuilder limit(Number offset, Number fetch) {
return sortLimit(offset, fetch, ImmutableList.of());
}
@@ -3720,7 +3720,7 @@ public RelBuilder sort(Iterable<? extends RexNode> nodes) {
}
/** Creates a {@link Sort} by expressions, with limit and offset. */
- public RelBuilder sortLimit(long offset, long fetch, RexNode... nodes) {
+ public RelBuilder sortLimit(Number offset, Number fetch, RexNode... nodes) {
return sortLimit(offset, fetch, ImmutableList.copyOf(nodes));
}
@@ -3739,10 +3739,16 @@ public RelBuilder sort(RelCollation collation) {
* @param fetch Maximum number of rows to fetch; negative means no limit
* @param nodes Sort expressions
*/
- public RelBuilder sortLimit(long offset, long fetch,
+ public RelBuilder sortLimit(Number offset, Number fetch,
Iterable<? extends RexNode> nodes) {
- final @Nullable RexNode offsetNode = offset <= 0 ? null : literal(offset);
- final @Nullable RexNode fetchNode = fetch < 0 ? null : literal(fetch);
+ final @Nullable RexNode offsetNode =
+ new BigDecimal(offset.toString()).compareTo(BigDecimal.ZERO) <= 0
+ ? null
+ : literal(offset);
+ final @Nullable RexNode fetchNode =
+ new BigDecimal(fetch.toString()).compareTo(BigDecimal.ZERO) < 0
+ ? null
+ : literal(fetch);
return sortLimit(offsetNode, fetchNode, nodes);
}
@@ -3770,9 +3776,12 @@ public RelBuilder sortLimit(@Nullable RexNode offsetNode, @Nullable RexNode fetc
final Registrar registrar = new Registrar(fields(), ImmutableList.of());
final List<RelFieldCollation> fieldCollations =
registrar.registerFieldCollations(nodes);
- final long fetch = fetchNode instanceof RexLiteral
- ? RexLiteral.longValue(fetchNode) : -1;
- if (offsetNode == null && fetch == 0 && config.simplifyLimit()) {
+ final Number fetch = fetchNode instanceof RexLiteral
+ ? RexLiteral.numberValue(fetchNode) : null;
+ if (offsetNode == null
+ && fetch != null
+ && ((BigDecimal) fetch).compareTo(BigDecimal.ZERO) == 0
+ && config.simplifyLimit()) {
return empty();
}
if (offsetNode == null && fetchNode == null && fieldCollations.isEmpty()) {