Repository navigation
fix: preserve CASE WHEN struct field names from the first THEN branch #6827
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+163
−44
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
04f328c
fix: preserve CASE WHEN struct field names from the first THEN branch
pingzh 4012483
test: keep CASE WHEN tests inline for focused review
pingzh 9092911
test: cover COALESCE struct field names
pingzh fb8f705
test: cover nested and null CASE WHEN struct branches
pingzh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
spark/src/test/resources/sql-tests/expressions/conditional/case_when_field_names.sql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| -- Licensed to the Apache Software Foundation (ASF) under one | ||
| -- or more contributor license agreements. See the NOTICE file | ||
| -- distributed with this work for additional information | ||
| -- regarding copyright ownership. The ASF licenses this file | ||
| -- to you under the Apache License, Version 2.0 (the | ||
| -- "License"); you may not use this file except in compliance | ||
| -- with the License. You may obtain a copy of the License at | ||
| -- | ||
| -- http://www.apache.org/licenses/LICENSE-2.0 | ||
| -- | ||
| -- Unless required by applicable law or agreed to in writing, | ||
| -- software distributed under the License is distributed on an | ||
| -- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| -- KIND, either express or implied. See the License for the | ||
| -- specific language governing permissions and limitations | ||
| -- under the License. | ||
|
|
||
| -- Spark preserves the first THEN's struct field names when branches differ only in case. | ||
| -- Native to_json exposes Arrow field names that the row comparison would otherwise ignore. | ||
| -- https://github.com/apache/datafusion-comet/issues/6482 | ||
| -- Config: spark.sql.caseSensitive=false | ||
| -- Config: spark.comet.expression.StructsToJson.allowIncompatible=true | ||
|
|
||
| statement | ||
| CREATE TABLE test_case_field_names(p boolean, q boolean, i int, d double) USING parquet | ||
|
|
||
| statement | ||
| INSERT INTO test_case_field_names VALUES | ||
| (true, false, 1, 1.5), (false, true, 2, 2.5), | ||
| (NULL, false, 3, 3.5), (false, NULL, NULL, NULL) | ||
|
|
||
| -- The result keeps the THEN name for both selected branches, in either name order. | ||
| query expect_native(casewhen) | ||
| SELECT | ||
| to_json(CASE WHEN p THEN named_struct('x', i) ELSE named_struct('X', i) END), | ||
| to_json(CASE WHEN p THEN named_struct('X', i) ELSE named_struct('x', i) END) | ||
| FROM test_case_field_names | ||
|
|
||
| -- Preserve the first THEN's names at both levels of a nested struct, in either branch order. | ||
| query expect_native(casewhen) | ||
| SELECT | ||
| to_json(CASE WHEN p THEN named_struct('a', named_struct('x', i)) | ||
| ELSE named_struct('A', named_struct('X', i)) END), | ||
| to_json(CASE WHEN p THEN named_struct('A', named_struct('X', i)) | ||
| ELSE named_struct('a', named_struct('x', i)) END) | ||
| FROM test_case_field_names | ||
|
|
||
| -- Later THEN branches and an omitted ELSE must also preserve the first THEN's name. | ||
| query expect_native(casewhen) | ||
| SELECT | ||
| to_json(CASE WHEN p THEN named_struct('x', i) | ||
| WHEN q THEN named_struct('X', i + 10) ELSE named_struct('X', i + 20) END), | ||
| to_json(CASE WHEN p THEN named_struct('x', i) | ||
| WHEN q THEN named_struct('X', i + 10) END) | ||
| FROM test_case_field_names | ||
|
|
||
| -- A typed NULL in the first THEN still determines the result's struct field name. | ||
| query expect_native(casewhen) | ||
| SELECT to_json(CASE WHEN p THEN CAST(NULL AS STRUCT<x: INT>) | ||
| WHEN q THEN named_struct('x', i) ELSE named_struct('X', i) END) | ||
| FROM test_case_field_names | ||
|
|
||
| -- Fields align by position. Matching these names would incorrectly combine INT with DOUBLE. | ||
| query expect_native(casewhen) | ||
| SELECT to_json(CASE WHEN p THEN named_struct('x', i, 'X', CAST(5.5 AS DOUBLE)) | ||
| ELSE named_struct('X', 0, 'x', d) END) | ||
| FROM test_case_field_names | ||
|
pingzh marked this conversation as resolved.
|
||
36 changes: 36 additions & 0 deletions
36
spark/src/test/resources/sql-tests/expressions/conditional/coalesce_field_names.sql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| -- Licensed to the Apache Software Foundation (ASF) under one | ||
| -- or more contributor license agreements. See the NOTICE file | ||
| -- distributed with this work for additional information | ||
| -- regarding copyright ownership. The ASF licenses this file | ||
| -- to you under the Apache License, Version 2.0 (the | ||
| -- "License"); you may not use this file except in compliance | ||
| -- with the License. You may obtain a copy of the License at | ||
| -- | ||
| -- http://www.apache.org/licenses/LICENSE-2.0 | ||
| -- | ||
| -- Unless required by applicable law or agreed to in writing, | ||
| -- software distributed under the License is distributed on an | ||
| -- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| -- KIND, either express or implied. See the License for the | ||
| -- specific language governing permissions and limitations | ||
| -- under the License. | ||
|
|
||
| -- COALESCE lowers to CASE WHEN with its last argument as ELSE, but must retain the first | ||
| -- argument's struct field names. Native to_json exposes names that row comparison ignores. | ||
| -- https://github.com/apache/datafusion-comet/issues/6482 | ||
| -- Config: spark.sql.caseSensitive=false | ||
| -- Config: spark.comet.expression.StructsToJson.allowIncompatible=true | ||
|
|
||
| statement | ||
| CREATE TABLE test_coalesce_field_names(p boolean, q boolean, i int) USING parquet | ||
|
|
||
| statement | ||
| INSERT INTO test_coalesce_field_names VALUES | ||
| (true, false, 1), (false, true, 2), (NULL, false, 3), (false, NULL, NULL) | ||
|
|
||
| query expect_native(coalesce) | ||
| SELECT to_json(coalesce( | ||
| CASE WHEN p THEN named_struct('x', i) END, | ||
| CASE WHEN q THEN named_struct('X', i + 100) END, | ||
| named_struct('X', 7))) | ||
| FROM test_coalesce_field_names |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.