This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git
The following commit(s) were added to refs/heads/main by this push:
new adddd4c32b fix: Make `generate_series` return an empty set with
invalid ranges (#19999)
adddd4c32b is described below
commit adddd4c32b504f482d23dd2e0767e65292353f85
Author: Nuno Faria <[email protected]>
AuthorDate: Tue Jan 27 05:21:36 2026 +0000
fix: Make `generate_series` return an empty set with invalid ranges (#19999)
## Which issue does this PR close?
- Closes #19998.
## Rationale for this change
Make the `generate_series` table function follow the Postgres's
convention.
## What changes are included in this PR?
- Removed the error when the range is invalid.
- Updated existing tests.
## Are these changes tested?
Yes.
## Are there any user-facing changes?
`generate_series`/`range` return an empty set with invalid ranges.
---
datafusion/functions-table/src/generate_series.rs | 37 ++--------------------
.../sqllogictest/test_files/table_functions.slt | 30 ++++++++++++------
docs/source/library-user-guide/upgrading.md | 33 +++++++++++++++++++
3 files changed, 56 insertions(+), 44 deletions(-)
diff --git a/datafusion/functions-table/src/generate_series.rs
b/datafusion/functions-table/src/generate_series.rs
index b806798bce..342269fbc2 100644
--- a/datafusion/functions-table/src/generate_series.rs
+++ b/datafusion/functions-table/src/generate_series.rs
@@ -433,30 +433,11 @@ fn reach_end_int64(val: i64, end: i64, step: i64,
include_end: bool) -> bool {
}
}
-fn validate_interval_step(
- step: IntervalMonthDayNano,
- start: i64,
- end: i64,
-) -> Result<()> {
+fn validate_interval_step(step: IntervalMonthDayNano) -> Result<()> {
if step.months == 0 && step.days == 0 && step.nanoseconds == 0 {
return plan_err!("Step interval cannot be zero");
}
- let step_is_positive = step.months > 0 || step.days > 0 ||
step.nanoseconds > 0;
- let step_is_negative = step.months < 0 || step.days < 0 ||
step.nanoseconds < 0;
-
- if start > end && step_is_positive {
- return plan_err!(
- "Start is bigger than end, but increment is positive: Cannot
generate infinite series"
- );
- }
-
- if start < end && step_is_negative {
- return plan_err!(
- "Start is smaller than end, but increment is negative: Cannot
generate infinite series"
- );
- }
-
Ok(())
}
@@ -567,18 +548,6 @@ impl GenerateSeriesFuncImpl {
}
};
- if start > end && step > 0 {
- return plan_err!(
- "Start is bigger than end, but increment is positive: Cannot
generate infinite series"
- );
- }
-
- if start < end && step < 0 {
- return plan_err!(
- "Start is smaller than end, but increment is negative: Cannot
generate infinite series"
- );
- }
-
if step == 0 {
return plan_err!("Step cannot be zero");
}
@@ -656,7 +625,7 @@ impl GenerateSeriesFuncImpl {
};
// Validate step interval
- validate_interval_step(step, start, end)?;
+ validate_interval_step(step)?;
Ok(Arc::new(GenerateSeriesTable {
schema,
@@ -749,7 +718,7 @@ impl GenerateSeriesFuncImpl {
let end_ts = end_date as i64 * NANOS_PER_DAY;
// Validate step interval
- validate_interval_step(step_interval, start_ts, end_ts)?;
+ validate_interval_step(step_interval)?;
Ok(Arc::new(GenerateSeriesTable {
schema,
diff --git a/datafusion/sqllogictest/test_files/table_functions.slt
b/datafusion/sqllogictest/test_files/table_functions.slt
index cf8a091880..f0e00ffc69 100644
--- a/datafusion/sqllogictest/test_files/table_functions.slt
+++ b/datafusion/sqllogictest/test_files/table_functions.slt
@@ -160,17 +160,20 @@ physical_plan LazyMemoryExec: partitions=1,
batch_generators=[generate_series: s
# Test generate_series with invalid arguments
#
-query error DataFusion error: Error during planning: Start is bigger than end,
but increment is positive: Cannot generate infinite series
+query I
SELECT * FROM generate_series(5, 1)
+----
-query error DataFusion error: Error during planning: Start is smaller than
end, but increment is negative: Cannot generate infinite series
+query I
SELECT * FROM generate_series(-6, 6, -1)
+----
query error DataFusion error: Error during planning: Step cannot be zero
SELECT * FROM generate_series(-6, 6, 0)
-query error DataFusion error: Error during planning: Start is bigger than end,
but increment is positive: Cannot generate infinite series
+query I
SELECT * FROM generate_series(6, -6, 1)
+----
statement error DataFusion error: Error during planning: generate_series
function requires 1 to 3 arguments
@@ -298,17 +301,20 @@ physical_plan LazyMemoryExec: partitions=1,
batch_generators=[range: start=1, en
# Test range with invalid arguments
#
-query error DataFusion error: Error during planning: Start is bigger than end,
but increment is positive: Cannot generate infinite series
+query I
SELECT * FROM range(5, 1)
+----
-query error DataFusion error: Error during planning: Start is smaller than
end, but increment is negative: Cannot generate infinite series
+query I
SELECT * FROM range(-6, 6, -1)
+----
query error DataFusion error: Error during planning: Step cannot be zero
SELECT * FROM range(-6, 6, 0)
-query error DataFusion error: Error during planning: Start is bigger than end,
but increment is positive: Cannot generate infinite series
+query I
SELECT * FROM range(6, -6, 1)
+----
statement error DataFusion error: Error during planning: range function
requires 1 to 3 arguments
@@ -378,11 +384,13 @@ SELECT * FROM range(TIMESTAMP '2023-01-03T00:00:00',
TIMESTAMP '2023-01-01T00:00
2023-01-03T00:00:00
2023-01-02T00:00:00
-query error DataFusion error: Error during planning: Start is bigger than end,
but increment is positive: Cannot generate infinite series
+query P
SELECT * FROM range(TIMESTAMP '2023-01-03T00:00:00', TIMESTAMP
'2023-01-01T00:00:00', INTERVAL '1' DAY)
+----
-query error DataFusion error: Error during planning: Start is smaller than
end, but increment is negative: Cannot generate infinite series
+query P
SELECT * FROM range(TIMESTAMP '2023-01-01T00:00:00', TIMESTAMP
'2023-01-02T00:00:00', INTERVAL '-1' DAY)
+----
query error DataFusion error: Error during planning: range function with
timestamps requires exactly 3 arguments
SELECT * FROM range(TIMESTAMP '2023-01-03T00:00:00', TIMESTAMP
'2023-01-01T00:00:00')
@@ -489,11 +497,13 @@ query P
SELECT * FROM range(DATE '1992-09-01', DATE '1992-10-01', NULL::INTERVAL)
----
-query error DataFusion error: Error during planning: Start is bigger than end,
but increment is positive: Cannot generate infinite series
+query P
SELECT * FROM range(DATE '2023-01-03', DATE '2023-01-01', INTERVAL '1' DAY)
+----
-query error DataFusion error: Error during planning: Start is smaller than
end, but increment is negative: Cannot generate infinite series
+query P
SELECT * FROM range(DATE '2023-01-01', DATE '2023-01-02', INTERVAL '-1' DAY)
+----
query error DataFusion error: Error during planning: range function with dates
requires exactly 3 arguments
SELECT * FROM range(DATE '2023-01-01', DATE '2023-01-03')
diff --git a/docs/source/library-user-guide/upgrading.md
b/docs/source/library-user-guide/upgrading.md
index 916ff4a82b..6043c81d14 100644
--- a/docs/source/library-user-guide/upgrading.md
+++ b/docs/source/library-user-guide/upgrading.md
@@ -154,6 +154,39 @@ The builder pattern is more efficient as it computes
properties once during `bui
Note: `with_default_selectivity()` is not deprecated as it simply updates a
field value and does not require the overhead of the builder pattern.
+### `generate_series` and `range` table functions changed
+
+The `generate_series` and `range` table functions now return an empty set when
the interval is invalid, instead of an error.
+This behavior is consistent with systems like PostgreSQL.
+
+Before:
+
+```sql
+> select * from generate_series(0, -1);
+Error during planning: Start is bigger than end, but increment is positive:
Cannot generate infinite series
+
+> select * from range(0, -1);
+Error during planning: Start is bigger than end, but increment is positive:
Cannot generate infinite series
+```
+
+Now:
+
+```sql
+> select * from generate_series(0, -1);
++-------+
+| value |
++-------+
++-------+
+0 row(s) fetched.
+
+> select * from range(0, -1);
++-------+
+| value |
++-------+
++-------+
+0 row(s) fetched.
+```
+
## DataFusion `52.0.0`
### Changes to DFSchema API
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]