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>. */