Repository navigation
Conversation
Report first-class CHAR/VARCHAR types and lengths through HiveServer2 and Spark Connect JDBC metadata so clients can describe result and catalog columns.
89977ef to
9a499ce
Compare
srielau
left a comment
There was a problem hiding this comment.
SQL Language review
Client-metadata review (Connect JDBC + HiveServer2 getColumns). Not Analyzer/Parser.
The Connect JDBC mapping is the real fix: CharType / VarcharType are StringType subclasses, so case StringType => missed them and threw SQLFeatureNotSupportedException. Mapping them to Types.CHAR / VARCHAR with precision n, and widening the other matchers to _: StringType, is the right split.
HS2 getColumns already mapped VARCHAR to Types.VARCHAR; only COLUMN_SIZE was missing. Execute-path CHAR/VARCHAR on HS2 was already wired (TTypeId + CHARACTER_MAXIMUM_LENGTH via defaultSize, which equals length).
Findings
-
Medium -- Connect
getColumnsstill reportsCHAR_OCTET_LENGTH = 0. Catalog metadata will pick upCOLUMN_SIZE = nviagetDisplaySize->getPrecision, but octet length is hardcoded to 0. HS2 leaves it null as well. Clients that size buffers fromCHAR_OCTET_LENGTHstill see unknown width. -
Medium --
getTypeInfostill has no CHAR / VARCHAR(n). OnlySTRINGis listed asTypes.VARCHAR. Tools that discover types fromgetTypeInfowill not see CHAR. -
Medium -- HS2
getColumnstest assertsdefaultSizeinstead of.length. VARCHAR now falls through tocolSize === o.defaultSize. That equals length today, butdefaultSizeis the wrong contract (STRINGis 20). This test also does not enablestandardSemantics, unlike the new result-metadata test. -
Low -- HS2 result-metadata test does not exercise this diff. Execute-path CHAR/VARCHAR was already implemented. It pins Hive names
char/varchar(no length) vs ConnectCHAR(4)/VARCHAR(6), and does not prove the VARCHARCOLUMN_SIZEfix. -
Medium -- tests were not run. The PR says Connect and HS2 suites were blocked locally. Please run them (or wait on CI) before merge; Hive type-name assertions are easy to get wrong.
-
Low -- two metadata mappers stay in lockstep. Connect
getColumnsuses display size forCOLUMN_SIZE; HS2 uses length. They agree for CHAR/VARCHAR only because display size delegates to precision.
Suggested order
- Add Connect
getColumnscoverage for table CHAR/VARCHAR (COLUMN_SIZE, type code, type name). - Decide on
CHAR_OCTET_LENGTHandgetTypeInfo(fix or explicitly out of scope). - Assert HS2 VARCHAR size as
.length, notdefaultSize. - Run the two suites before merge.
Fill JDBC CHAR_OCTET_LENGTH and Connect getTypeInfo for CHAR/VARCHAR, and assert catalog COLUMN_SIZE from declared length rather than defaultSize.
srielau
left a comment
There was a problem hiding this comment.
SQL Language re-review (4673559)
Previous findings are addressed in this commit.
| # | Original | Status |
|---|---|---|
| 1 | Connect CHAR_OCTET_LENGTH hardcoded 0; no table getColumns test |
Fixed -- JdbcTypeUtils.getCharOctetLength, table getColumns test |
| 2 | getTypeInfo missing CHAR / VARCHAR(n) |
Fixed -- CHAR + VARCHAR with CREATE_PARAMS = length, ordered by DATA_TYPE then TYPE_NAME |
| 3 | HS2 test asserted defaultSize |
Fixed -- match .length, explicit 255 / 1024, standardSemantics on |
| 4 | HS2 result-metadata test did not prove getColumnSize |
Fixed -- size/octet asserted on c17/c18; CAST test kept as Hive name pin |
| 5 | Tests not run | Open (environment) -- still blocked locally; relying on CI |
| 6 | Dual mappers / display-size vs length | Acceptable -- CHAR/VARCHAR length and octet helpers agree; Connect COLUMN_SIZE still display size, which equals precision for these types |
HS2 scaladoc and CHAR_OCTET_LENGTH are updated. Connect table getColumns covers type code, CHAR(4) / VARCHAR(6) names, COLUMN_SIZE, and octet length.
Remaining
-
Medium -- still no local run of the Connect/HS2 suites. The new
getColumns/getTypeInfoassertions are the kind that fail on type-name casing. Please confirm GitHub CI forSparkConnectJdbcDataTypeSuite,SparkConnectDatabaseMetaDataSuite, andSparkMetadataOperationSuiteis green before merge. -
Low -- PR description is stale. It still describes only CAST result metadata and "tests blocked", and does not mention
CHAR_OCTET_LENGTHorgetTypeInfo. Please refresh What/Why/How-tested. -
Low --
CHAR_OCTET_LENGTHis character lengthn, not UTF-8 octets. Documented in the helper; JDBC's name says octets. Fine if called out; some clients will allocatenbytes forCHAR(n)and truncate multibyte text.
The production mapping looks correct. Not blocking on (2)/(3).
|
Re-review remaining items:
|
A Connect client has no SQLConf, so it always sees DefaultSqlApiConf, where CHAR/VARCHAR are not first class types. A result schema produced by a server running with standard semantics was therefore undecodable: RowEncoder refused to build an encoder for CHAR(n)/VARCHAR(n), and the Arrow layer neither recognized CharEncoder/VarcharEncoder nor accepted the constrained type as a read target. Whether CHAR/VARCHAR are first class is decided by the session that produced the schema, so accept them when building an encoder for an engine-produced schema, while user-supplied schemas (UDF return types, Encoders.row) keep honoring the local configuration.
srielau
left a comment
There was a problem hiding this comment.
SQL Language re-review (b798e6a)
Metadata follow-ups from 4673559 still look in place. The new commit is the right split: engine-produced schemas accept CHAR/VARCHAR (encoderForResultSchema); user-supplied schemas (UDF, Encoders.row, createDataFrame) still honor local charVarcharFirstClassTypes. Arrow treats CHAR/VARCHAR as string vectors and reads via plainStringType, which matches how the server encodes them.
SparkResult only swaps UnboundRowEncoder; typed as[String] keeps StringEncoder and already matched the string-vector case. Nested struct/array CHAR is covered by the recursive flag and the ArrowEncoderSuite round trip.
This decode path is also what makes the existing JDBC CAST getString test runnable on a client with default conf.
Remaining
-
Medium -- PR description is stale. It still talks only about JDBC/HS2 metadata and local test blockage. Please add the Connect result-decode problem (client
DefaultSqlApiConfcannot see serverstandardSemantics) andencoderForResultSchema. -
Medium -- missing negative test on the user encoder path. Please assert
RowEncoder.encoderFor(StructType().add("c", CharType(4)))still throwsUNSUPPORTED_DATA_TYPE_FOR_ENCODERwhen first-class types are off, so the newtrueoverride cannot leak into UDF /createDataFrame. -
Low -- Python Connect is not covered. This is JVM
RowEncoder/ Arrow. If Python already maps proto CHAR to string, say so in the PR; otherwise it is a follow-up. -
Low (from last review) --
CHAR_OCTET_LENGTHis charactern, not UTF-8 octets; still documented. Confirm CI for JDBC,ArrowEncoderSuite, and HS2.
Architecture of the new entry point looks sound. Not blocking on (3)/(4).
cloud-fan
left a comment
There was a problem hiding this comment.
1 blocking, 0 non-blocking, 2 nits.
The result-schema decoding split is sound, but the new octet-length metadata underreports multibyte values and should be corrected before merge.
Correctness (1)
- Blocking: sql/connect/client/jdbc/src/main/scala/org/apache/spark/sql/connect/client/jdbc/util/JdbcTypeUtils.scala:181: Report byte capacity, not character count, in
CHAR_OCTET_LENGTH. -- see inline
Nits: 2 minor items (see inline comments).
Verification
I traced engine-produced schemas from SparkResult.createEncoder through RowEncoder.encoderForResultSchema into the Arrow string reader, while the ordinary encoderFor path still consults the local configuration. I also traced both JDBC getColumns implementations: each now returns the declared character count for CHAR_OCTET_LENGTH, even though the added comments identify byte-buffer sizing clients, so a multibyte UTF-8 value can require more bytes than reported.
JDBC CHAR_OCTET_LENGTH is a byte capacity. Spark CHAR/VARCHAR n is in characters, so report 4 * n (UTF-8 max), saturating at Int.MaxValue.
cloud-fan
left a comment
There was a problem hiding this comment.
3 addressed, 0 remaining, 1 new to this AI review. (0 newly introduced, 1 late catch, 0 previously raised.)
0 blocking, 0 non-blocking, 1 nit.
The prior correctness issue is fixed; one small Scaladoc clarity nit remains.
Nits: 1 minor item (see inline comments).
Verification
I traced Connect result schemas from SparkResult.createEncoder through RowEncoder.encoderForResultSchema into Arrow deserialization, confirming that ordinary encoderFor remains configuration-gated. I also traced both JDBC getColumns paths and verified that their current helpers report saturated 4 * n byte capacity, with focused tests asserting the corresponding metadata.
…/thriftserver/SparkGetColumnsOperation.scala Co-authored-by: Wenchen Fan <cloud0fan@gmail.com>
…esult schemas ### What changes were proposed in this pull request? Covers Connect JDBC mapping ([SPARK-58806](https://issues.apache.org/jira/browse/SPARK-58806)), plus HiveServer2 / JDBC result metadata ([SPARK-58804](https://issues.apache.org/jira/browse/SPARK-58804)) and `DatabaseMetaData.getColumns` `COLUMN_SIZE` ([SPARK-58805](https://issues.apache.org/jira/browse/SPARK-58805)). Parent: [SPARK-58794](https://issues.apache.org/jira/browse/SPARK-58794). Independent of the remaining CHAR/VARCHAR follow-ups. Rebased onto `master` after #58033; can merge without #58080 / #58087 / #58130. Unique vs master: srielau/spark@master...serge-rielau_data/SPARK-58794-clients Expose first-class `CHAR(n)` and `VARCHAR(n)` to SQL clients when `spark.sql.charVarchar.standardSemantics.enabled` is on, and let those clients decode result rows that carry the types. Metadata: - Spark Connect JDBC maps `CharType` / `VarcharType` to `java.sql.Types.CHAR` / `VARCHAR`, with Java string values and precision / display size `n`. - Connect `DatabaseMetaData.getColumns` reports `COLUMN_SIZE` as the declared character length `n`. `CHAR_OCTET_LENGTH` is the UTF-8 maximum byte capacity `4 * n` (saturating at `Int.MaxValue`); unbounded STRING stays 0. - Connect `DatabaseMetaData.getTypeInfo` lists `CHAR` and `VARCHAR` with `CREATE_PARAMS = length`. Unbounded `STRING` remains a `Types.VARCHAR` row without create params. - HiveServer2 `getColumns` reports `COLUMN_SIZE = n` for `VARCHAR(n)` as well as `CHAR(n)`, and `CHAR_OCTET_LENGTH = 4 * n` for both (null for unbounded STRING). - HiveServer2 result metadata coverage pins Hive JDBC names (`char` / `varchar`, no length) and precision `n` for CAST results. Decode (JVM Connect client): - The Connect client process has no engine `SQLConf`, so `RowEncoder.encoderFor` still follows the local `charVarcharFirstClassTypes` flag and rejects CHAR/VARCHAR when first-class types are off. - `RowEncoder.encoderForResultSchema` always accepts CHAR/VARCHAR. `SparkResult.createEncoder` uses it only for `UnboundRowEncoder` (engine-produced result schemas). Other encoder bindings keep `encoderFor`. - Arrow serializer / deserializer treat `CharEncoder` / `VarcharEncoder` like `StringEncoder`, and deserialize via `StringHelper.plainStringType` so STRING Arrow vectors up-cast to CHAR/VARCHAR. - JDBC CAST `ResultSet.next` / `collect` needs this path; metadata-only mapping is not enough. Python Connect already maps proto `char` / `var_char` in `pyspark.sql.connect.types`; a mixed classic vs Connect test covers schema and `collect()`. The existing Connect proto already carries CHAR/VARCHAR and their lengths. ### Why are the changes needed? Spark Connect JDBC rejected first-class `CharType` and `VarcharType` as unsupported because its metadata mapping only recognized the `StringType` singleton. `getColumns` hardcoded `CHAR_OCTET_LENGTH` to 0, and `getTypeInfo` listed only unbounded STRING. HiveServer2 already identified VARCHAR catalog columns but reported `COLUMN_SIZE` as unknown. Clients therefore cannot reliably describe or size CHAR/VARCHAR columns even though Catalyst retains the type and length. Separately, a server with standard semantics sends CHAR/VARCHAR in the result schema. The JVM Connect client then failed at row decode (`UNSUPPORTED_DATA_TYPE_FOR_ENCODER`) because `RowEncoder.encoderFor` read the client's default conf (`charVarcharFirstClassTypes = false`). JDBC CAST collect and Spark Connect `SparkResult` both hit that path. ### Does this PR introduce _any_ user-facing change? Yes, when first-class CHAR/VARCHAR types are present: JDBC and HiveServer2 metadata now report the corresponding JDBC type and declared character length instead of rejecting the type or reporting an unknown size. `CHAR_OCTET_LENGTH` is the UTF-8 maximum byte capacity (`4 * n`), not the character length. Connect clients can also collect CHAR/VARCHAR result columns instead of failing to decode the schema. ### How was this patch tested? - `RowEncoderSuite`: `encoderFor` still raises `UNSUPPORTED_DATA_TYPE_FOR_ENCODER` for CHAR/VARCHAR when both first-class flags are off; `encoderForResultSchema` accepts the same schema. - `ArrowEncoderSuite`: CHAR/VARCHAR Arrow round-trip (top-level, nested struct, array). - `SparkConnectJdbcDataTypeSuite`: CAST result metadata and table `getColumns` (`CHAR(4)` / `VARCHAR(6)`, `COLUMN_SIZE`, `CHAR_OCTET_LENGTH` = 16 / 24); CAST collect after decode. - `SparkConnectDatabaseMetaDataSuite`: `getTypeInfo` rows for CHAR / VARCHAR. - `SparkMetadataOperationSuite`: HiveServer2 `getColumns` / CAST result metadata (`CHAR_OCTET_LENGTH` = `4 * n`). - `pyspark.sql.tests.connect.test_connect_basic.SparkConnectBasicTests.test_char_varchar_result_schema`: classic vs Connect schema and `collect()`. Local compile of `sql-api`, `connect-client-jdbc`, and `hive-thriftserver` passed. HiveServer2 / full Connect JDBC in this environment remain blocked (`CheckReturnValue` while compiling `connect-common`; FIPS Python multiprocessing). Please treat the suites above as the merge gate. ### Was this patch authored or co-authored using generative AI tooling? Yes (Cursor). Closes #58132 from srielau/serge-rielau_data/SPARK-58794-clients. Authored-by: Serge Rielau <serge@rielau.com> Signed-off-by: Wenchen Fan <wenchen@databricks.com> (cherry picked from commit 6af294e) Signed-off-by: Wenchen Fan <wenchen@databricks.com>
…tandardSemantics ### What changes were proposed in this pull request? Parent epic: [SPARK-58794](https://issues.apache.org/jira/browse/SPARK-58794). Unique ticket: [SPARK-58807](https://issues.apache.org/jira/browse/SPARK-58807) (CTAS/CREATE VIEW/CTE inherit CHAR/VARCHAR). Also covers [SPARK-58808](https://issues.apache.org/jira/browse/SPARK-58808) (SQL FUNCTION assignment), [SPARK-58809](https://issues.apache.org/jira/browse/SPARK-58809) (session variables), and [SPARK-58811](https://issues.apache.org/jira/browse/SPARK-58811) (ALTER/temp/external). #58080 (SPARK-58798 LCT) is on master. Clients (JDBC / HS2 / Connect) landed in #58132 / SPARK-58806. Language-surface hardening under `spark.sql.charVarchar.standardSemantics.enabled`: **Bug fixes (format write)** - **ORC:** `CharType`/`VarcharType` extend `StringType`, so write used to stamp `spark.sql.catalyst.type=string` and file-only inference lost the constraint. Stamp `char(n)` / `varchar(n)` via `CharVarcharUtils.charVarcharTypeName`. Write stays on ORC `STRING` plus that attribute (not native ORC CHAR/VARCHAR), so ORC `maxLength` does not fight Spark store assignment. Unbounded STRING, including collated STRING, still stamps `string` (same as Avro: collation is not a file-only round-trip in this PR). - **Avro:** same subclass trap on leaves, map keys, and ser/de. Stamp `spark.sql.catalyst.type` on STRING and `spark.sql.catalyst.mapKey.type` on maps. Restore only `StringType` subtypes; a non-string stamp is `IncompatibleSchemaException`. sql/core has no avro data source; ser/de is covered with `DataFileWriter`. **Coverage** - CTAS / CREATE VIEW (CHAR and VARCHAR) / CTE inherit CHAR/VARCHAR - ALTER COLUMN equal-length CHAR/VARCHAR; V2 VARCHAR widen / CHAR to VARCHAR - Session / script variables, FETCH INTO, SQL FUNCTION params and RETURNS - EXTERNAL TABLE scan pad / overflow - CHAR/VARCHAR vs non-string compare and COALESCE - JSON / CSV with a user-specified CHAR/VARCHAR schema - ORC catalog + file-only round-trip, including cross-flag (`standardSemantics` on then off, first-class types off, `preserveCharVarcharTypeInfo` only) - Avro schema conversion, nested struct, CHAR map keys, and serializer/deserializer values ### Why are the changes needed? Without ORC/Avro catalyst-type stamping, Spark-written files cannot re-infer CHAR/VARCHAR under the flag. Language surfaces (CTAS/VIEW/CTE/vars/functions/user schemas) need explicit coverage so schema fidelity does not regress. ### Does this PR introduce _any_ user-facing change? Yes, when the flag is on: ORC and Avro preserve CHAR/VARCHAR logical types across write/read instead of collapsing to STRING. CTAS/VIEW/CTE/vars/functions behavior matches the foundation rules and is now tested. ### How was this patch tested? - `BasicCharVarcharTestSuite` / language surfaces (including Avro ser/de and ORC cross-flag) - Regenerated `charvarchar-standard-semantics.sql` goldens Closes #58087 from srielau/SPARK-58794-surfaces. Authored-by: Serge Rielau <serge@rielau.com> Signed-off-by: Wenchen Fan <wenchen@databricks.com>
…tandardSemantics ### What changes were proposed in this pull request? Parent epic: [SPARK-58794](https://issues.apache.org/jira/browse/SPARK-58794). Unique ticket: [SPARK-58807](https://issues.apache.org/jira/browse/SPARK-58807) (CTAS/CREATE VIEW/CTE inherit CHAR/VARCHAR). Also covers [SPARK-58808](https://issues.apache.org/jira/browse/SPARK-58808) (SQL FUNCTION assignment), [SPARK-58809](https://issues.apache.org/jira/browse/SPARK-58809) (session variables), and [SPARK-58811](https://issues.apache.org/jira/browse/SPARK-58811) (ALTER/temp/external). #58080 (SPARK-58798 LCT) is on master. Clients (JDBC / HS2 / Connect) landed in #58132 / SPARK-58806. Language-surface hardening under `spark.sql.charVarchar.standardSemantics.enabled`: **Bug fixes (format write)** - **ORC:** `CharType`/`VarcharType` extend `StringType`, so write used to stamp `spark.sql.catalyst.type=string` and file-only inference lost the constraint. Stamp `char(n)` / `varchar(n)` via `CharVarcharUtils.charVarcharTypeName`. Write stays on ORC `STRING` plus that attribute (not native ORC CHAR/VARCHAR), so ORC `maxLength` does not fight Spark store assignment. Unbounded STRING, including collated STRING, still stamps `string` (same as Avro: collation is not a file-only round-trip in this PR). - **Avro:** same subclass trap on leaves, map keys, and ser/de. Stamp `spark.sql.catalyst.type` on STRING and `spark.sql.catalyst.mapKey.type` on maps. Restore only `StringType` subtypes; a non-string stamp is `IncompatibleSchemaException`. sql/core has no avro data source; ser/de is covered with `DataFileWriter`. **Coverage** - CTAS / CREATE VIEW (CHAR and VARCHAR) / CTE inherit CHAR/VARCHAR - ALTER COLUMN equal-length CHAR/VARCHAR; V2 VARCHAR widen / CHAR to VARCHAR - Session / script variables, FETCH INTO, SQL FUNCTION params and RETURNS - EXTERNAL TABLE scan pad / overflow - CHAR/VARCHAR vs non-string compare and COALESCE - JSON / CSV with a user-specified CHAR/VARCHAR schema - ORC catalog + file-only round-trip, including cross-flag (`standardSemantics` on then off, first-class types off, `preserveCharVarcharTypeInfo` only) - Avro schema conversion, nested struct, CHAR map keys, and serializer/deserializer values ### Why are the changes needed? Without ORC/Avro catalyst-type stamping, Spark-written files cannot re-infer CHAR/VARCHAR under the flag. Language surfaces (CTAS/VIEW/CTE/vars/functions/user schemas) need explicit coverage so schema fidelity does not regress. ### Does this PR introduce _any_ user-facing change? Yes, when the flag is on: ORC and Avro preserve CHAR/VARCHAR logical types across write/read instead of collapsing to STRING. CTAS/VIEW/CTE/vars/functions behavior matches the foundation rules and is now tested. ### How was this patch tested? - `BasicCharVarcharTestSuite` / language surfaces (including Avro ser/de and ORC cross-flag) - Regenerated `charvarchar-standard-semantics.sql` goldens Closes #58087 from srielau/SPARK-58794-surfaces. Authored-by: Serge Rielau <serge@rielau.com> Signed-off-by: Wenchen Fan <wenchen@databricks.com> (cherry picked from commit db6fc3a) Signed-off-by: Wenchen Fan <wenchen@databricks.com>
What changes were proposed in this pull request?
Covers Connect JDBC mapping (SPARK-58806), plus HiveServer2 / JDBC result metadata (SPARK-58804) and
DatabaseMetaData.getColumnsCOLUMN_SIZE(SPARK-58805). Parent: SPARK-58794.Independent of the remaining CHAR/VARCHAR follow-ups. Rebased onto
masterafter #58033; can merge without #58080 / #58087 / #58130. Unique vs master: srielau/spark@master...serge-rielau_data/SPARK-58794-clientsExpose first-class
CHAR(n)andVARCHAR(n)to SQL clients whenspark.sql.charVarchar.standardSemantics.enabledis on, and let those clients decode result rows that carry the types.Metadata:
CharType/VarcharTypetojava.sql.Types.CHAR/VARCHAR, with Java string values and precision / display sizen.DatabaseMetaData.getColumnsreportsCOLUMN_SIZEas the declared character lengthn.CHAR_OCTET_LENGTHis the UTF-8 maximum byte capacity4 * n(saturating atInt.MaxValue); unbounded STRING stays 0.DatabaseMetaData.getTypeInfolistsCHARandVARCHARwithCREATE_PARAMS = length. UnboundedSTRINGremains aTypes.VARCHARrow without create params.getColumnsreportsCOLUMN_SIZE = nforVARCHAR(n)as well asCHAR(n), andCHAR_OCTET_LENGTH = 4 * nfor both (null for unbounded STRING).char/varchar, no length) and precisionnfor CAST results.Decode (JVM Connect client):
SQLConf, soRowEncoder.encoderForstill follows the localcharVarcharFirstClassTypesflag and rejects CHAR/VARCHAR when first-class types are off.RowEncoder.encoderForResultSchemaalways accepts CHAR/VARCHAR.SparkResult.createEncoderuses it only forUnboundRowEncoder(engine-produced result schemas). Other encoder bindings keepencoderFor.CharEncoder/VarcharEncoderlikeStringEncoder, and deserialize viaStringHelper.plainStringTypeso STRING Arrow vectors up-cast to CHAR/VARCHAR.ResultSet.next/collectneeds this path; metadata-only mapping is not enough.Python Connect already maps proto
char/var_charinpyspark.sql.connect.types; a mixed classic vs Connect test covers schema andcollect().The existing Connect proto already carries CHAR/VARCHAR and their lengths.
Why are the changes needed?
Spark Connect JDBC rejected first-class
CharTypeandVarcharTypeas unsupported because its metadata mapping only recognized theStringTypesingleton.getColumnshardcodedCHAR_OCTET_LENGTHto 0, andgetTypeInfolisted only unbounded STRING. HiveServer2 already identified VARCHAR catalog columns but reportedCOLUMN_SIZEas unknown. Clients therefore cannot reliably describe or size CHAR/VARCHAR columns even though Catalyst retains the type and length.Separately, a server with standard semantics sends CHAR/VARCHAR in the result schema. The JVM Connect client then failed at row decode (
UNSUPPORTED_DATA_TYPE_FOR_ENCODER) becauseRowEncoder.encoderForread the client's default conf (charVarcharFirstClassTypes = false). JDBC CAST collect and Spark ConnectSparkResultboth hit that path.Does this PR introduce any user-facing change?
Yes, when first-class CHAR/VARCHAR types are present: JDBC and HiveServer2 metadata now report the corresponding JDBC type and declared character length instead of rejecting the type or reporting an unknown size.
CHAR_OCTET_LENGTHis the UTF-8 maximum byte capacity (4 * n), not the character length. Connect clients can also collect CHAR/VARCHAR result columns instead of failing to decode the schema.How was this patch tested?
RowEncoderSuite:encoderForstill raisesUNSUPPORTED_DATA_TYPE_FOR_ENCODERfor CHAR/VARCHAR when both first-class flags are off;encoderForResultSchemaaccepts the same schema.ArrowEncoderSuite: CHAR/VARCHAR Arrow round-trip (top-level, nested struct, array).SparkConnectJdbcDataTypeSuite: CAST result metadata and tablegetColumns(CHAR(4)/VARCHAR(6),COLUMN_SIZE,CHAR_OCTET_LENGTH= 16 / 24); CAST collect after decode.SparkConnectDatabaseMetaDataSuite:getTypeInforows for CHAR / VARCHAR.SparkMetadataOperationSuite: HiveServer2getColumns/ CAST result metadata (CHAR_OCTET_LENGTH=4 * n).pyspark.sql.tests.connect.test_connect_basic.SparkConnectBasicTests.test_char_varchar_result_schema: classic vs Connect schema andcollect().Local compile of
sql-api,connect-client-jdbc, andhive-thriftserverpassed. HiveServer2 / full Connect JDBC in this environment remain blocked (CheckReturnValuewhile compilingconnect-common; FIPS Python multiprocessing). Please treat the suites above as the merge gate.Was this patch authored or co-authored using generative AI tooling?
Yes (Cursor).