Skip to content

Commit 438c880

Browse files
pnikic-dbcloud-fan
authored andcommitted
[SPARK-56569] Add WINDOW_FUNCTION_FRAME_NOT_ORDERED error to replace _LEGACY_ERROR_TEMP_1037
### What changes were proposed in this pull request? The error currently reported when an `ORDER BY` is not specified for a window function which requires it belongs in the `_LEGACY_ERROR_TEMP` group. These errors should be replaced with errors with proper error conditions. In addition, the error text was improved, with the primary improvement being the removal of `(value_expr)`. For example: ```sql SELECT lead(t) OVER () FROM VALUES ('A'), ('B'), ('C') AS tbl(t) ``` **Previous Error**: > Window function lead(t#738680, 1, null) requires window to be ordered, please add ORDER BY clause. For example SELECT lead(t#738680, 1, null)(value_expr) OVER (PARTITION BY window_partition ORDER BY window_ordering) from table. **New Error**: > [WINDOW_FUNCTION_FRAME_NOT_ORDERED] Window function lead requires the window to be ordered, please add an ORDER BY clause. For example: SELECT lead(tbl.t, 1, NULL) OVER (PARTITION BY window_partition ORDER BY window_ordering) FROM table. SQLSTATE: 42601 ### Why are the changes needed? Improvement for error conditions. ### Does this PR introduce _any_ user-facing change? The error message changed for when a window function requires and order by and none was provided. ### How was this patch tested? New tests were added and existing tests used to verify the new error class and the new format. ### Was this patch authored or co-authored using generative AI tooling? Generated-by: Claude Code 2.1.117 Closes apache#55478 from pnikic-db/window-frame-not-ordered-error-condition. Authored-by: Petar Nikić <petar.nikic@databricks.com> Signed-off-by: Wenchen Fan <wenchen@databricks.com>
1 parent 55ddfe3 commit 438c880

8 files changed

Lines changed: 68 additions & 19 deletions

File tree

common/utils/src/main/resources/error/error-conditions.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8542,6 +8542,12 @@
85428542
],
85438543
"sqlState" : "42K0E"
85448544
},
8545+
"WINDOW_FUNCTION_FRAME_NOT_ORDERED" : {
8546+
"message" : [
8547+
"Window function <wf_name> requires the window to be ordered. You need to add an ORDER BY clause. For example: SELECT <wf_expr> OVER (PARTITION BY window_partition ORDER BY window_ordering) FROM table."
8548+
],
8549+
"sqlState" : "42601"
8550+
},
85458551
"WINDOW_FUNCTION_NOT_ALLOWED_IN_CLAUSE" : {
85468552
"message" : [
85478553
"It is not allowed to use window functions inside <clauseName> clause."
@@ -8813,11 +8819,6 @@
88138819
"Window Frame <wf> must match the required frame <required>."
88148820
]
88158821
},
8816-
"_LEGACY_ERROR_TEMP_1037" : {
8817-
"message" : [
8818-
"Window function <wf> requires window to be ordered, please add ORDER BY clause. For example SELECT <wf>(value_expr) OVER (PARTITION BY window_partition ORDER BY window_ordering) from table."
8819-
]
8820-
},
88218822
"_LEGACY_ERROR_TEMP_1039" : {
88228823
"message" : [
88238824
"Multiple time/session window expressions would result in a cartesian product of rows, therefore they are currently not supported."

sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryCompilationErrors.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -897,8 +897,10 @@ private[sql] object QueryCompilationErrors extends QueryErrorsBase with Compilat
897897

898898
def windowFunctionWithWindowFrameNotOrderedError(wf: WindowFunction): Throwable = {
899899
new AnalysisException(
900-
errorClass = "_LEGACY_ERROR_TEMP_1037",
901-
messageParameters = Map("wf" -> wf.toString))
900+
errorClass = "WINDOW_FUNCTION_FRAME_NOT_ORDERED",
901+
messageParameters = Map(
902+
"wf_name" -> wf.prettyName,
903+
"wf_expr" -> wf.sql))
902904
}
903905

904906
def multiTimeWindowExpressionsNotSupportedError(t: TreeNode[_]): Throwable = {

sql/core/src/test/resources/sql-tests/analyzer-results/udf/udf-window.sql.out

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -421,9 +421,11 @@ SELECT udf(val), cate, row_number() OVER(PARTITION BY cate) FROM testData ORDER
421421
-- !query analysis
422422
org.apache.spark.sql.AnalysisException
423423
{
424-
"errorClass" : "_LEGACY_ERROR_TEMP_1037",
424+
"errorClass" : "WINDOW_FUNCTION_FRAME_NOT_ORDERED",
425+
"sqlState" : "42601",
425426
"messageParameters" : {
426-
"wf" : "row_number()"
427+
"wf_expr" : "row_number()",
428+
"wf_name" : "row_number"
427429
}
428430
}
429431

sql/core/src/test/resources/sql-tests/analyzer-results/window.sql.out

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,9 +616,26 @@ SELECT val, cate, row_number() OVER(PARTITION BY cate) FROM testData ORDER BY ca
616616
-- !query analysis
617617
org.apache.spark.sql.AnalysisException
618618
{
619-
"errorClass" : "_LEGACY_ERROR_TEMP_1037",
619+
"errorClass" : "WINDOW_FUNCTION_FRAME_NOT_ORDERED",
620+
"sqlState" : "42601",
620621
"messageParameters" : {
621-
"wf" : "row_number()"
622+
"wf_expr" : "row_number()",
623+
"wf_name" : "row_number"
624+
}
625+
}
626+
627+
628+
-- !query
629+
SELECT lead(t) OVER ()
630+
FROM VALUES ('A'), ('B'), ('C') AS tbl(t)
631+
-- !query analysis
632+
org.apache.spark.sql.AnalysisException
633+
{
634+
"errorClass" : "WINDOW_FUNCTION_FRAME_NOT_ORDERED",
635+
"sqlState" : "42601",
636+
"messageParameters" : {
637+
"wf_expr" : "lead(tbl.t, 1, NULL)",
638+
"wf_name" : "lead"
622639
}
623640
}
624641

sql/core/src/test/resources/sql-tests/inputs/window.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@ SELECT val, cate, avg(null) OVER(PARTITION BY cate ORDER BY val) FROM testData O
158158
-- OrderBy not specified
159159
SELECT val, cate, row_number() OVER(PARTITION BY cate) FROM testData ORDER BY cate, val;
160160

161+
-- OrderBy not specified for lead
162+
SELECT lead(t) OVER ()
163+
FROM VALUES ('A'), ('B'), ('C') AS tbl(t);
164+
161165
-- Over clause is empty
162166
SELECT val, cate, sum(val) OVER(), avg(val) OVER() FROM testData ORDER BY cate, val;
163167

sql/core/src/test/resources/sql-tests/results/udf/udf-window.sql.out

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -421,9 +421,11 @@ struct<>
421421
-- !query output
422422
org.apache.spark.sql.AnalysisException
423423
{
424-
"errorClass" : "_LEGACY_ERROR_TEMP_1037",
424+
"errorClass" : "WINDOW_FUNCTION_FRAME_NOT_ORDERED",
425+
"sqlState" : "42601",
425426
"messageParameters" : {
426-
"wf" : "row_number()"
427+
"wf_expr" : "row_number()",
428+
"wf_name" : "row_number"
427429
}
428430
}
429431

sql/core/src/test/resources/sql-tests/results/window.sql.out

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -599,9 +599,28 @@ struct<>
599599
-- !query output
600600
org.apache.spark.sql.AnalysisException
601601
{
602-
"errorClass" : "_LEGACY_ERROR_TEMP_1037",
602+
"errorClass" : "WINDOW_FUNCTION_FRAME_NOT_ORDERED",
603+
"sqlState" : "42601",
603604
"messageParameters" : {
604-
"wf" : "row_number()"
605+
"wf_expr" : "row_number()",
606+
"wf_name" : "row_number"
607+
}
608+
}
609+
610+
611+
-- !query
612+
SELECT lead(t) OVER ()
613+
FROM VALUES ('A'), ('B'), ('C') AS tbl(t)
614+
-- !query schema
615+
struct<>
616+
-- !query output
617+
org.apache.spark.sql.AnalysisException
618+
{
619+
"errorClass" : "WINDOW_FUNCTION_FRAME_NOT_ORDERED",
620+
"sqlState" : "42601",
621+
"messageParameters" : {
622+
"wf_expr" : "lead(tbl.t, 1, NULL)",
623+
"wf_name" : "lead"
605624
}
606625
}
607626

sql/core/src/test/scala/org/apache/spark/sql/DataFrameWindowFunctionsSuite.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,12 @@ class DataFrameWindowFunctionsSuite extends QueryTest
7171

7272
test("window function should fail if order by clause is not specified") {
7373
val df = Seq((1, "1"), (2, "2"), (1, "2"), (2, "2")).toDF("key", "value")
74-
val e = intercept[AnalysisException](
75-
// Here we missed .orderBy("key")!
76-
df.select(row_number().over(Window.partitionBy("value"))).collect())
77-
assert(e.message.contains("requires window to be ordered"))
74+
checkError(
75+
exception = intercept[AnalysisException](
76+
// Here we missed .orderBy("key")!
77+
df.select(row_number().over(Window.partitionBy("value"))).collect()),
78+
condition = "WINDOW_FUNCTION_FRAME_NOT_ORDERED",
79+
parameters = Map("wf_name" -> "row_number", "wf_expr" -> "row_number()"))
7880
}
7981

8082
test("corr, covar_pop, stddev_pop functions in specific window") {

0 commit comments

Comments
 (0)