Skip to content

Conversation

Jefffrey
Copy link
Contributor

Which issue does this PR close?

Rationale for this change

Range and GenSeries are essentially the same except for whether they include upper bounds or not; unify their function code to reduce duplication, making future changes easier.

What changes are included in this PR?

Remove GenSeries struct, folding it into Range. Do some more minor refactoring to their code.

Are these changes tested?

Existing tests (updated some error messages).

Are there any user-facing changes?

Not really (updated some error messages).

@github-actions github-actions bot added the sqllogictest SQL Logic Tests (.slt) label Oct 21, 2025
@github-actions github-actions bot added the documentation Improvements or additions to documentation label Oct 21, 2025
Comment on lines +49 to +52
($UDF:ident, $EXPR_FN:ident, $($arg:ident)*, $DOC:expr, $SCALAR_UDF_FN:ident) => {
make_udf_expr_and_func!($UDF, $EXPR_FN, $($arg)*, $DOC, $SCALAR_UDF_FN, $UDF::new);
};
($UDF:ident, $EXPR_FN:ident, $($arg:ident)*, $DOC:expr, $SCALAR_UDF_FN:ident, $CTOR:path) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just like what window functions do:

macro_rules! get_or_init_udwf {
($UDWF:ident, $OUT_FN_NAME:ident, $DOC:expr) => {
get_or_init_udwf!($UDWF, $OUT_FN_NAME, $DOC, $UDWF::default);
};
($UDWF:ident, $OUT_FN_NAME:ident, $DOC:expr, $CTOR:path) => {
paste::paste! {
#[doc = concat!(" Returns a [`WindowUDF`](datafusion_expr::WindowUDF) for [`", stringify!($OUT_FN_NAME), "`].")]
#[doc = ""]
#[doc = concat!(" ", $DOC)]

So we can use same Range struct with different constructor methods

start stop step,
"create a list of values in the range between start and stop, include upper bound",
gen_series_udf,
Range::generate_series
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Custom constructor here

"create a list of values in the range between start and stop, include upper bound",
gen_series_udf
);
struct RangeDoc {}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty struct just so I can use the user_doc attribute; I was going to do it like this:

static RANK_DOCUMENTATION: LazyLock<Documentation> = LazyLock::new(|| {
Documentation::builder(
DOC_SECTION_RANKING,
"Returns the rank of the current row within its partition, allowing \
gaps between ranks. This function provides a ranking similar to `row_number`, but \
skips ranks for identical values.",
"rank()")
.with_sql_example(r#"
```sql
-- Example usage of the rank window function:
SELECT department,
salary,
rank() OVER (PARTITION BY department ORDER BY salary DESC) AS rank
FROM employees;
+-------------+--------+------+
| department | salary | rank |
+-------------+--------+------+
| Sales | 70000 | 1 |
| Sales | 50000 | 2 |
| Sales | 50000 | 2 |
| Sales | 30000 | 4 |
| Engineering | 90000 | 1 |
| Engineering | 80000 | 2 |
+-------------+--------+------+
```
"#)
.build()
});
fn get_rank_doc() -> &'static Documentation {
&RANK_DOCUMENTATION
}

But I prefer using the user_doc attribute as it looks nicer imo; happy to switch if this isn't recommended

/// gen_range(3) => [0, 1, 2]
/// gen_range(1, 4) => [1, 2, 3]
/// gen_range(1, 7, 2) => [1, 3, 5]
pub(super) fn gen_range_inner(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pulled these into the impl Range so they can easily access self.name() and self.include_upper_bound

let [start, stop, step] = take_function_args(self.name(), args)?;

// coerce_types fn should coerce all types to Timestamp(Nanosecond, tz)
// TODO: remove these map_err once the signature is robust enough to guard against this
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking to do this for #15881 itself

@Jefffrey Jefffrey marked this pull request as ready for review October 21, 2025 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation sqllogictest SQL Logic Tests (.slt)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant