From 11b7b860355b31111e98c5d569d5fbb4d6f8ccf3 Mon Sep 17 00:00:00 2001 From: YongChul Kwon Date: Sun, 14 Jun 2026 23:04:52 -0700 Subject: [PATCH 1/3] feat: support expression in preceding and following window bound --- proto/substrait/algebra.proto | 28 ++++++++++++++++++----- site/docs/expressions/window_functions.md | 6 +++-- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/proto/substrait/algebra.proto b/proto/substrait/algebra.proto index 253094aa2..a1269ca42 100644 --- a/proto/substrait/algebra.proto +++ b/proto/substrait/algebra.proto @@ -1402,17 +1402,33 @@ message Expression { // Defines that the bound extends this far back from the current record. message Preceding { // A strictly positive integer specifying the number of records that - // the window extends back from the current record. Required. Use - // CurrentRow for offset zero and Following for negative offsets. - int64 offset = 1; + // the window extends back from the current record. Required. + // Use CurrentRow for offset zero and Following for negative offsets. + oneof offset_mode { + int64 offset = 1; + + // Expression evaluated into a strictly positive integer specifying + // the offset from the current record. Evaluating to null, zero, or + // a negative integer should result in an error. + // Recommended type for offset is int64. + Expression offset_expr = 2; + } } // Defines that the bound extends this far ahead of the current record. message Following { // A strictly positive integer specifying the number of records that - // the window extends ahead of the current record. Required. Use - // CurrentRow for offset zero and Preceding for negative offsets. - int64 offset = 1; + // the window extends ahead of the current record. Required. + // Use CurrentRow for offset zero and Preceding for negative offsets. + oneof offset_mode { + int64 offset = 1; + + // Expression evaluated into a strictly positive integer specifying + // the offset from the current record. Evaluating to null, zero, or + // a negative integer should result in an error. + // Recommended type for offset is int64. + Expression offset_expr = 2; + } } // Defines that the bound extends to or from the current record. diff --git a/site/docs/expressions/window_functions.md b/site/docs/expressions/window_functions.md index 260118062..b9f3c4f11 100644 --- a/site/docs/expressions/window_functions.md +++ b/site/docs/expressions/window_functions.md @@ -18,8 +18,10 @@ When binding a window function, the binding must include the following additiona | Property | Description | Required | | ----------- | ------------------------------------------------------------ | ------------------------------------------------------------ | | Partition | A list of partitioning expressions. | False, defaults to a single partition for the entire dataset | -| Lower Bound | Bound Following(int64), Bound Trailing(int64) or CurrentRow. | False, defaults to start of partition | -| Upper Bound | Bound Following(int64), Bound Trailing(int64) or CurrentRow. | False, defaults to end of partition | +| Lower Bound | Preceding, Following, CurrentRow, or Unbounded. | False, defaults to start of partition | +| Upper Bound | Preceding, Following, CurrentRow, or Unbounded. | False, defaults to end of partition | + +`Preceding` and `Following` define offsets relative to the current record. Exactly one offset mode must be provided: a literal integer (`offset`) or an expression that evaluates to a strictly positive integer (`offset_expr`). `offset_expr` should use type `int64`; evaluating to null, zero, or a negative integer should result in an error. Use `CurrentRow` for offset zero, and use the opposite bound direction for negative offsets. ## Aggregate Functions as Window Functions From e37509b60d0992d7ac161be02053618ea9fff992 Mon Sep 17 00:00:00 2001 From: YongChul Kwon Date: Sun, 14 Jun 2026 23:17:31 -0700 Subject: [PATCH 2/3] add dialect change --- dialects/tests/expressions_test.yaml | 2 ++ text/dialect_schema.yaml | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/dialects/tests/expressions_test.yaml b/dialects/tests/expressions_test.yaml index de48f4f66..ca012e700 100644 --- a/dialects/tests/expressions_test.yaml +++ b/dialects/tests/expressions_test.yaml @@ -21,3 +21,5 @@ supported_expressions: - CURRENT_DATE - CURRENT_TIMESTAMP - CURRENT_TIMEZONE + - expression: WINDOW_FUNCTION + supports_offset_expr: false diff --git a/text/dialect_schema.yaml b/text/dialect_schema.yaml index 3dbf0deec..c00bb7fc7 100644 --- a/text/dialect_schema.yaml +++ b/text/dialect_schema.yaml @@ -1100,6 +1100,13 @@ definitions: metadata: type: object description: Arbitrary data created by the dialect author. + supports_offset_expr: + type: boolean + default: false + description: > + Whether this dialect supports expression-based offsets for window + function bounds. If false, only literal offsets are supported for + Preceding and Following bounds. Defaults to false. required: [expression] if_then_expression: type: object From 4032b4336ffc214fd57a76a06d59fc5498876aa0 Mon Sep 17 00:00:00 2001 From: YongChul Kwon Date: Wed, 15 Jul 2026 11:28:50 -0700 Subject: [PATCH 3/3] remove oneof and deprecated the explicit offset --- proto/substrait/algebra.proto | 34 +++++++++++------------ site/docs/expressions/window_functions.md | 2 +- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/proto/substrait/algebra.proto b/proto/substrait/algebra.proto index a1269ca42..df6306040 100644 --- a/proto/substrait/algebra.proto +++ b/proto/substrait/algebra.proto @@ -1404,15 +1404,14 @@ message Expression { // A strictly positive integer specifying the number of records that // the window extends back from the current record. Required. // Use CurrentRow for offset zero and Following for negative offsets. - oneof offset_mode { - int64 offset = 1; - - // Expression evaluated into a strictly positive integer specifying - // the offset from the current record. Evaluating to null, zero, or - // a negative integer should result in an error. - // Recommended type for offset is int64. - Expression offset_expr = 2; - } + // Deprecated: use `offset_expr` instead. + int64 offset = 1 [deprecated = true]; + + // Expression evaluated into a strictly positive integer specifying + // the offset from the current record. Evaluating to null, zero, or + // a negative integer should result in an error. + // Recommended type for offset is int64. + Expression offset_expr = 2; } // Defines that the bound extends this far ahead of the current record. @@ -1420,15 +1419,14 @@ message Expression { // A strictly positive integer specifying the number of records that // the window extends ahead of the current record. Required. // Use CurrentRow for offset zero and Preceding for negative offsets. - oneof offset_mode { - int64 offset = 1; - - // Expression evaluated into a strictly positive integer specifying - // the offset from the current record. Evaluating to null, zero, or - // a negative integer should result in an error. - // Recommended type for offset is int64. - Expression offset_expr = 2; - } + // Deprecated: use `offset_expr` instead. + int64 offset = 1 [deprecated = true]; + + // Expression evaluated into a strictly positive integer specifying + // the offset from the current record. Evaluating to null, zero, or + // a negative integer should result in an error. + // Recommended type for offset is int64. + Expression offset_expr = 2; } // Defines that the bound extends to or from the current record. diff --git a/site/docs/expressions/window_functions.md b/site/docs/expressions/window_functions.md index b9f3c4f11..95dd2fc68 100644 --- a/site/docs/expressions/window_functions.md +++ b/site/docs/expressions/window_functions.md @@ -21,7 +21,7 @@ When binding a window function, the binding must include the following additiona | Lower Bound | Preceding, Following, CurrentRow, or Unbounded. | False, defaults to start of partition | | Upper Bound | Preceding, Following, CurrentRow, or Unbounded. | False, defaults to end of partition | -`Preceding` and `Following` define offsets relative to the current record. Exactly one offset mode must be provided: a literal integer (`offset`) or an expression that evaluates to a strictly positive integer (`offset_expr`). `offset_expr` should use type `int64`; evaluating to null, zero, or a negative integer should result in an error. Use `CurrentRow` for offset zero, and use the opposite bound direction for negative offsets. +`Preceding` and `Following` define offsets relative to the current record. `offset_expr` is the recommended way to specify the offset; it should evaluate to a strictly positive integer and should use type `int64`. A literal integer `offset` is still accepted for compatibility but is deprecated. Evaluating `offset_expr` to null, zero, or a negative integer should result in an error. Use `CurrentRow` for offset zero, and use the opposite bound direction for negative offsets. ## Aggregate Functions as Window Functions