Repository navigation
[SPARK-61177][CONNECT] Quote the field names of DataType::to_ddl, and canonicalize the collation name of DataType::from_ddl, in the Rust client - #374
Closed
HyukjinKwon wants to merge 1 commit into
Conversation
… canonicalize the collation name of DataType::from_ddl, in the Rust client DataType::to_ddl wrote the field names unquoted and the nested types with simple_string, so a name with a space, a backtick or a dot gave DDL that the server cannot parse. It now quotes names as Spark's quoteIfNeeded does and writes the types as DataType.sql. DataType::from_ddl lowercased the whole input, so the collation of "STRING COLLATE UTF8_LCASE" became "utf8_lcase". The collation name is now canonicalized as the server does it: upper case for UTF8_ and UNICODE names, and for ICU locale names a lower-case language, a title-case script and upper-case other parts, such as sr_CI_AI and sr_Cyrl_SRB_CI_AI. Co-authored-by: Isaac <no-reply@databricks.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
What changes were proposed in this pull request?
SPARK-61177:
StructType.toDDL()quotes each field name withquoteIfNeeded, which wraps the name in backticks, doubles the backticks in it, and leaves a name alone only when it matches[a-zA-Z_][a-zA-Z0-9_]*. The types are written asDataType.sql, so a nested struct isSTRUCT<`my col`: INT NOT NULL COMMENT 'c'>.DataType.fromDDLcanonicalizes the collation name, as the server does.The Rust client now does the same in
DataType::to_ddland in itsfrom_ddlparser:to_ddlquotes the top-level names and the names of nested struct fields. It writes the types in theDataType.sqlform:STRUCT<...>,ARRAY<...>,MAP<K, V>, andSTRING COLLATE <NAME>for a non-default collation.from_ddltakes the collation name from the input, not from the lowercased copy, and canonicalizes it withcanonical_collation_name. AUTF8_*orUNICODE*name is in upper case. An ICU locale name,language[_Script][_COUNTRY][_SPECIFIERS], has a lower-case language, a title-case four-letter script and upper-case other parts. The server gives these names for the input in the first column:utf8_lcaseUTF8_LCASEUnicode_Ci_AiUNICODE_CI_AIunicode_rtrimUNICODE_RTRIMutf8_lcase_rtrimUTF8_LCASE_RTRIMsr_ci_ai,SR_CI_AI,sr_CI_AIsr_CI_AIENende_cide_CIzh_hant_hkgzh_Hant_HKGSR_CYRL_SRB_CI_AIsr_Cyrl_SRB_CI_AIThe server rejects
en_uswith COLLATION_INVALID_NAME.from_ddldoes not validate names, so it givesen_US.Why are the changes needed?
With the old code,
to_ddlwrote the names as they were. The server cannot parse the result for a name that needs quoting:The strings are what the old
to_ddlwrote for a struct with a fieldmy colof typeINT, a fielda`bof typeINT, and a struct fieldsof typestruct<my col:int>.from_ddl("a STRING COLLATE UTF8_LCASE")gave the collationutf8_lcase. Spark givesUTF8_LCASE.Does this PR introduce any user-facing change?
Yes.
DataType::to_ddlnow returns the Spark DDL form, for example`my col` INT,`abINT `` in place of ``my col int,ab int``. A nested struct, array or map is written with the SQL type names.DataType::from_ddlcanonicalizes the collation name, for example `UTF8_LCASE` for `STRING COLLATE utf8_lcase` and `sr_CI_AI` for `STRING COLLATE SR_CI_AI`, as the server does.How was this patch tested?
struct_to_ddl_quotes_names_and_writes_sql_typesincrates/spark-connect/tests/types_behavior.rscovers quoted and unquoted names (spaces, backticks, dots, leading digits, all digits, leading underscore, unicode),NOT NULL, comments with a single quote, nested struct fields, arrays and maps of structs, atomic types, and collations. The expected strings are the output ofStructType.toDDL()on the server of PySpark 4.3.0. This test fails without the change.from_ddl_canonicalizes_the_collation_nameincrates/spark-connect/tests/types_behavior.rschecks the twelve names of the table above, with the canonical name the server gives for each (en_usasen_US), and ato_ddlround trip. It fails without the change (utf8_lcasebefore the change).struct_to_ddl_tree_and_nullablewas updated to the new outputa INT,b STRING NOT NULL.createDataFrame([], "c STRING COLLATE <name>")gives the canonical names of the table above, which the new test checks.to_ddlparse back (createDataFrame([], ddl).schema) to the expected types, for the names, the nested structs, the arrays and maps, and the collations in the cases above. The CHAR and VARCHAR case fails increateDataFramewith an internal check on the local relation. This is not a parse error.wasm-udf, the offline Python suites (2227 passed, 8 skipped), and the live drop-in and Arrow suites (210 passed) and live cases (10 passed) against a local Spark 4.3.0 server. Clippy reports no diagnostics in the changed lines.Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude Opus 5.5
This pull request and its description were written by Isaac.