[CALCITE-7190] FETCH and OFFSET in SortMergeRule only supports BIGINT
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 707c7b2..037a4d6 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 797b7e3..1622864 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 b9b9c25..d84c031 100644
--- a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
+++ b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
@@ -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()) {