Skip to content

Commit adddd4c

Browse files
authored
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.
1 parent 5c47d6d commit adddd4c

File tree

3 files changed

+56
-44
lines changed

3 files changed

+56
-44
lines changed

datafusion/functions-table/src/generate_series.rs

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -433,30 +433,11 @@ fn reach_end_int64(val: i64, end: i64, step: i64, include_end: bool) -> bool {
433433
}
434434
}
435435

436-
fn validate_interval_step(
437-
step: IntervalMonthDayNano,
438-
start: i64,
439-
end: i64,
440-
) -> Result<()> {
436+
fn validate_interval_step(step: IntervalMonthDayNano) -> Result<()> {
441437
if step.months == 0 && step.days == 0 && step.nanoseconds == 0 {
442438
return plan_err!("Step interval cannot be zero");
443439
}
444440

445-
let step_is_positive = step.months > 0 || step.days > 0 || step.nanoseconds > 0;
446-
let step_is_negative = step.months < 0 || step.days < 0 || step.nanoseconds < 0;
447-
448-
if start > end && step_is_positive {
449-
return plan_err!(
450-
"Start is bigger than end, but increment is positive: Cannot generate infinite series"
451-
);
452-
}
453-
454-
if start < end && step_is_negative {
455-
return plan_err!(
456-
"Start is smaller than end, but increment is negative: Cannot generate infinite series"
457-
);
458-
}
459-
460441
Ok(())
461442
}
462443

@@ -567,18 +548,6 @@ impl GenerateSeriesFuncImpl {
567548
}
568549
};
569550

570-
if start > end && step > 0 {
571-
return plan_err!(
572-
"Start is bigger than end, but increment is positive: Cannot generate infinite series"
573-
);
574-
}
575-
576-
if start < end && step < 0 {
577-
return plan_err!(
578-
"Start is smaller than end, but increment is negative: Cannot generate infinite series"
579-
);
580-
}
581-
582551
if step == 0 {
583552
return plan_err!("Step cannot be zero");
584553
}
@@ -656,7 +625,7 @@ impl GenerateSeriesFuncImpl {
656625
};
657626

658627
// Validate step interval
659-
validate_interval_step(step, start, end)?;
628+
validate_interval_step(step)?;
660629

661630
Ok(Arc::new(GenerateSeriesTable {
662631
schema,
@@ -749,7 +718,7 @@ impl GenerateSeriesFuncImpl {
749718
let end_ts = end_date as i64 * NANOS_PER_DAY;
750719

751720
// Validate step interval
752-
validate_interval_step(step_interval, start_ts, end_ts)?;
721+
validate_interval_step(step_interval)?;
753722

754723
Ok(Arc::new(GenerateSeriesTable {
755724
schema,

datafusion/sqllogictest/test_files/table_functions.slt

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,17 +160,20 @@ physical_plan LazyMemoryExec: partitions=1, batch_generators=[generate_series: s
160160
# Test generate_series with invalid arguments
161161
#
162162

163-
query error DataFusion error: Error during planning: Start is bigger than end, but increment is positive: Cannot generate infinite series
163+
query I
164164
SELECT * FROM generate_series(5, 1)
165+
----
165166

166-
query error DataFusion error: Error during planning: Start is smaller than end, but increment is negative: Cannot generate infinite series
167+
query I
167168
SELECT * FROM generate_series(-6, 6, -1)
169+
----
168170

169171
query error DataFusion error: Error during planning: Step cannot be zero
170172
SELECT * FROM generate_series(-6, 6, 0)
171173

172-
query error DataFusion error: Error during planning: Start is bigger than end, but increment is positive: Cannot generate infinite series
174+
query I
173175
SELECT * FROM generate_series(6, -6, 1)
176+
----
174177

175178

176179
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
298301
# Test range with invalid arguments
299302
#
300303

301-
query error DataFusion error: Error during planning: Start is bigger than end, but increment is positive: Cannot generate infinite series
304+
query I
302305
SELECT * FROM range(5, 1)
306+
----
303307

304-
query error DataFusion error: Error during planning: Start is smaller than end, but increment is negative: Cannot generate infinite series
308+
query I
305309
SELECT * FROM range(-6, 6, -1)
310+
----
306311

307312
query error DataFusion error: Error during planning: Step cannot be zero
308313
SELECT * FROM range(-6, 6, 0)
309314

310-
query error DataFusion error: Error during planning: Start is bigger than end, but increment is positive: Cannot generate infinite series
315+
query I
311316
SELECT * FROM range(6, -6, 1)
317+
----
312318

313319

314320
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
378384
2023-01-03T00:00:00
379385
2023-01-02T00:00:00
380386

381-
query error DataFusion error: Error during planning: Start is bigger than end, but increment is positive: Cannot generate infinite series
387+
query P
382388
SELECT * FROM range(TIMESTAMP '2023-01-03T00:00:00', TIMESTAMP '2023-01-01T00:00:00', INTERVAL '1' DAY)
389+
----
383390

384-
query error DataFusion error: Error during planning: Start is smaller than end, but increment is negative: Cannot generate infinite series
391+
query P
385392
SELECT * FROM range(TIMESTAMP '2023-01-01T00:00:00', TIMESTAMP '2023-01-02T00:00:00', INTERVAL '-1' DAY)
393+
----
386394

387395
query error DataFusion error: Error during planning: range function with timestamps requires exactly 3 arguments
388396
SELECT * FROM range(TIMESTAMP '2023-01-03T00:00:00', TIMESTAMP '2023-01-01T00:00:00')
@@ -489,11 +497,13 @@ query P
489497
SELECT * FROM range(DATE '1992-09-01', DATE '1992-10-01', NULL::INTERVAL)
490498
----
491499

492-
query error DataFusion error: Error during planning: Start is bigger than end, but increment is positive: Cannot generate infinite series
500+
query P
493501
SELECT * FROM range(DATE '2023-01-03', DATE '2023-01-01', INTERVAL '1' DAY)
502+
----
494503

495-
query error DataFusion error: Error during planning: Start is smaller than end, but increment is negative: Cannot generate infinite series
504+
query P
496505
SELECT * FROM range(DATE '2023-01-01', DATE '2023-01-02', INTERVAL '-1' DAY)
506+
----
497507

498508
query error DataFusion error: Error during planning: range function with dates requires exactly 3 arguments
499509
SELECT * FROM range(DATE '2023-01-01', DATE '2023-01-03')

docs/source/library-user-guide/upgrading.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,39 @@ The builder pattern is more efficient as it computes properties once during `bui
154154

155155
Note: `with_default_selectivity()` is not deprecated as it simply updates a field value and does not require the overhead of the builder pattern.
156156

157+
### `generate_series` and `range` table functions changed
158+
159+
The `generate_series` and `range` table functions now return an empty set when the interval is invalid, instead of an error.
160+
This behavior is consistent with systems like PostgreSQL.
161+
162+
Before:
163+
164+
```sql
165+
> select * from generate_series(0, -1);
166+
Error during planning: Start is bigger than end, but increment is positive: Cannot generate infinite series
167+
168+
> select * from range(0, -1);
169+
Error during planning: Start is bigger than end, but increment is positive: Cannot generate infinite series
170+
```
171+
172+
Now:
173+
174+
```sql
175+
> select * from generate_series(0, -1);
176+
+-------+
177+
| value |
178+
+-------+
179+
+-------+
180+
0 row(s) fetched.
181+
182+
> select * from range(0, -1);
183+
+-------+
184+
| value |
185+
+-------+
186+
+-------+
187+
0 row(s) fetched.
188+
```
189+
157190
## DataFusion `52.0.0`
158191

159192
### Changes to DFSchema API

0 commit comments

Comments
 (0)