This is an automated email from the ASF dual-hosted git repository.

mbudiu 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 ff103d885c [CALCITE-7154] When the offset or limit of a SORT operation 
is of type BIGINT row count calculation overflows
ff103d885c is described below

commit ff103d885cc4344a45ea01a522a825e528000355
Author: Zhen Chen <[email protected]>
AuthorDate: Sun Aug 31 21:31:51 2025 +0800

    [CALCITE-7154] When the offset or limit of a SORT operation is of type 
BIGINT row count calculation overflows
---
 .../java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java | 10 +++++-----
 .../java/org/apache/calcite/rel/metadata/RelMdMinRowCount.java | 10 +++++-----
 .../java/org/apache/calcite/rel/metadata/RelMdRowCount.java    |  8 ++++----
 core/src/main/java/org/apache/calcite/rex/RexLiteral.java      |  7 +++++++
 .../src/test/java/org/apache/calcite/test/RelMetadataTest.java |  9 +++++++++
 5 files changed, 30 insertions(+), 14 deletions(-)

diff --git 
a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java 
b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java
index 2858fd908b..8f666051ab 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMaxRowCount.java
@@ -115,11 +115,11 @@ public Double getMaxRowCount(Sort rel, RelMetadataQuery 
mq) {
       rowCount = Double.POSITIVE_INFINITY;
     }
 
-    final int offset = rel.offset instanceof RexLiteral ? 
RexLiteral.intValue(rel.offset) : 0;
+    final long offset = rel.offset instanceof RexLiteral ? 
RexLiteral.longValue(rel.offset) : 0;
     rowCount = Math.max(rowCount - offset, 0D);
 
     final double limit =
-        rel.fetch instanceof RexLiteral ? RexLiteral.intValue(rel.fetch) : 
rowCount;
+        rel.fetch instanceof RexLiteral ? RexLiteral.longValue(rel.fetch) : 
rowCount;
     return limit < rowCount ? limit : rowCount;
   }
 
@@ -129,11 +129,11 @@ public Double getMaxRowCount(EnumerableLimit rel, 
RelMetadataQuery mq) {
       rowCount = Double.POSITIVE_INFINITY;
     }
 
-    final int offset = rel.offset instanceof RexLiteral ? 
RexLiteral.intValue(rel.offset) : 0;
+    final long offset = rel.offset instanceof RexLiteral ? 
RexLiteral.longValue(rel.offset) : 0;
     rowCount = Math.max(rowCount - offset, 0D);
 
     final double limit =
-        rel.fetch instanceof RexLiteral ? RexLiteral.intValue(rel.fetch) : 
rowCount;
+        rel.fetch instanceof RexLiteral ? RexLiteral.longValue(rel.fetch) : 
rowCount;
     return limit < rowCount ? limit : rowCount;
   }
 
@@ -214,7 +214,7 @@ public Double getMaxRowCount(RelSubset rel, 
RelMetadataQuery mq) {
       if (node instanceof Sort) {
         Sort sort = (Sort) node;
         if (sort.fetch instanceof RexLiteral) {
-          return (double) RexLiteral.intValue(sort.fetch);
+          return (double) RexLiteral.longValue(sort.fetch);
         }
       }
     }
diff --git 
a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMinRowCount.java 
b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMinRowCount.java
index 88c0aab97b..f4280ee719 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMinRowCount.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdMinRowCount.java
@@ -114,11 +114,11 @@ public Double getMinRowCount(Sort rel, RelMetadataQuery 
mq) {
       rowCount = 0D;
     }
 
-    final int offset = rel.offset instanceof RexLiteral ? 
RexLiteral.intValue(rel.offset) : 0;
+    final long offset = rel.offset instanceof RexLiteral ? 
RexLiteral.longValue(rel.offset) : 0;
     rowCount = Math.max(rowCount - offset, 0D);
 
     final double limit =
-        rel.fetch instanceof RexLiteral ? RexLiteral.intValue(rel.fetch) : 
rowCount;
+        rel.fetch instanceof RexLiteral ? RexLiteral.longValue(rel.fetch) : 
rowCount;
     return limit < rowCount ? limit : rowCount;
   }
 
@@ -128,11 +128,11 @@ public Double getMinRowCount(EnumerableLimit rel, 
RelMetadataQuery mq) {
       rowCount = 0D;
     }
 
-    final int offset = rel.offset instanceof RexLiteral ? 
RexLiteral.intValue(rel.offset) : 0;
+    final long offset = rel.offset instanceof RexLiteral ? 
RexLiteral.longValue(rel.offset) : 0;
     rowCount = Math.max(rowCount - offset, 0D);
 
     final double limit =
-        rel.fetch instanceof RexLiteral ? RexLiteral.intValue(rel.fetch) : 
rowCount;
+        rel.fetch instanceof RexLiteral ? RexLiteral.longValue(rel.fetch) : 
rowCount;
     return limit < rowCount ? limit : rowCount;
   }
 
@@ -174,7 +174,7 @@ public Double getMinRowCount(RelSubset rel, 
RelMetadataQuery mq) {
       if (node instanceof Sort) {
         Sort sort = (Sort) node;
         if (sort.fetch instanceof RexLiteral) {
-          return (double) RexLiteral.intValue(sort.fetch);
+          return (double) RexLiteral.longValue(sort.fetch);
         }
       }
     }
diff --git 
a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdRowCount.java 
b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdRowCount.java
index 8da6caa894..eeb8cc9adc 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdRowCount.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdRowCount.java
@@ -149,11 +149,11 @@ public Double getRowCount(Calc rel, RelMetadataQuery mq) {
       return null;
     }
 
-    final int offset = rel.offset instanceof RexLiteral ? 
RexLiteral.intValue(rel.offset) : 0;
+    final long offset = rel.offset instanceof RexLiteral ? 
RexLiteral.longValue(rel.offset) : 0;
     rowCount = Math.max(rowCount - offset, 0D);
 
     final double limit =
-        rel.fetch instanceof RexLiteral ? RexLiteral.intValue(rel.fetch) : 
rowCount;
+        rel.fetch instanceof RexLiteral ? RexLiteral.longValue(rel.fetch) : 
rowCount;
     return limit < rowCount ? limit : rowCount;
   }
 
@@ -163,11 +163,11 @@ public Double getRowCount(Calc rel, RelMetadataQuery mq) {
       return null;
     }
 
-    final int offset = rel.offset instanceof RexLiteral ? 
RexLiteral.intValue(rel.offset) : 0;
+    final long offset = rel.offset instanceof RexLiteral ? 
RexLiteral.longValue(rel.offset) : 0;
     rowCount = Math.max(rowCount - offset, 0D);
 
     final double limit =
-        rel.fetch instanceof RexLiteral ? RexLiteral.intValue(rel.fetch) : 
rowCount;
+        rel.fetch instanceof RexLiteral ? RexLiteral.longValue(rel.fetch) : 
rowCount;
     return limit < rowCount ? limit : rowCount;
   }
 
diff --git a/core/src/main/java/org/apache/calcite/rex/RexLiteral.java 
b/core/src/main/java/org/apache/calcite/rex/RexLiteral.java
index b83aa512a5..a79e108006 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexLiteral.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexLiteral.java
@@ -1278,6 +1278,13 @@ public static int intValue(RexNode node) {
     return number.intValue();
   }
 
+  /** Returns the value of a literal, cast, or unary minus, as a long;
+   * never null. */
+  public static long longValue(RexNode node) {
+    final Number number = numberValue(node);
+    return number.longValue();
+  }
+
   public static @Nullable String stringValue(RexNode node) {
     final Comparable value = findValue(node);
     return (value == null) ? null : ((NlsString) value).getValue();
diff --git a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java 
b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
index 10d7abac62..38f8ac587f 100644
--- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
@@ -957,6 +957,15 @@ void testColumnOriginsUnion() {
     sql(sql).assertThatRowCount(is(7d), is(0D), is(7d));
   }
 
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-7154";>[CALCITE-7154]
+   * When the offset or limit of a SORT operation is of type BIGINT row count
+   * calculation overflows</a>. */
+  @Test void testRowCountSortLimitOffsetOnFiniteBigint() {
+    final String sql = "select * from emp limit 3000000000 offset 2500000000";
+    sql(sql).assertThatRowCount(is(1d), is(0d), is(3000000000d));
+  }
+
   /** Test case for
    * <a 
href="https://issues.apache.org/jira/browse/CALCITE-5944";>[CALCITE-5944]
    * Add metadata for Sample</a>. */

Reply via email to