[ 
https://issues.apache.org/jira/browse/SPARK-58517?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Szehon Ho resolved SPARK-58517.
-------------------------------
    Fix Version/s: 4.3.0
       Resolution: Fixed

Issue resolved by pull request 57722
[https://github.com/apache/spark/pull/57722]

> SDP schema evolution ignores spark.sql.caseSensitive, corrupting the target 
> schema on case-only column differences
> ------------------------------------------------------------------------------------------------------------------
>
>                 Key: SPARK-58517
>                 URL: https://issues.apache.org/jira/browse/SPARK-58517
>             Project: Spark
>          Issue Type: Bug
>          Components: Declarative Pipelines
>    Affects Versions: 5.0.0
>            Reporter: Andreas Neumann
>            Assignee: Andreas Neumann
>            Priority: Major
>              Labels: pull-request-available
>             Fix For: 4.3.0
>
>
> h3. Summary
> SDP table schema evolution in {{DatasetManager.evolveTable}} is hard-wired to 
> compare schemas case-sensitively, ignoring the session's 
> {{spark.sql.caseSensitive}} setting. Under the default (case-insensitive) 
> session, a target column {{value}} and an incoming column {{Value}} are 
> treated as *distinct*, so the target is evolved to carry *both* columns -- a 
> schema that is internally inconsistent under the resolver the rest of the 
> engine uses.
> h3. Root cause
> Two utilities on the evolution path take the case-sensitive default and never 
> forward the session conf:
> * {{SchemaMergingUtils.mergeSchemas}} calls {{StructType.merge(tableSchema, 
> dataSchema)}} positionally. {{StructType.merge}} has a {{caseSensitive: 
> Boolean = true}} parameter that is left at its default.
> * {{SchemaInferenceUtils.diffSchemas}} builds {{name -> field}} maps and 
> computes {{targetFields.keySet.diff(currentFields.keySet)}} -- an 
> exact-string set difference, also case-sensitive.
> Both are invoked from {{DatasetManager.evolveTable}} (via 
> {{mergeWithExistingSchema}}), so the entire schema-evolution path ignores 
> {{spark.sql.caseSensitive}}.
> h3. Impact
> This is not AutoCDC-specific: {{SchemaMergingUtils}} / 
> {{SchemaInferenceUtils}} are general pipeline-table utilities, so any SDP 
> table that evolves its schema under a case-insensitive session and receives a 
> column differing only in case from an existing one is affected. The corrupt 
> (two-column) target then fails downstream where the case-insensitive resolver 
> runs:
> * AutoCDC SCD2: {{COLUMN_ALREADY_EXISTS}}, raised by 
> {{ResolveUnion.checkColumnNames}} over the {{unionByName}} in 
> {{Scd2ForeachBatchHandler.reconcileMicrobatch}} (the affected-rows union 
> reads the now-two-column target back).
> * AutoCDC SCD1: {{AMBIGUOUS_REFERENCE}}, deeper in the MERGE plan (no 
> reconcile union).
> The same user mistake thus surfaces as two different error conditions 
> depending on SCD type; both are downstream symptoms of the corrupt evolved 
> schema, not the root cause.
> h3. Current test coverage (characterization only)
> These existing SCD2 E2E tests pin the *observed* (buggy) fallout and 
> reference this ticket:
> * {{AutoCdcScd2SchemaEvolutionSuite}} -- "a source DF column whose name 
> differs from the target only by case fails with COLUMN_ALREADY_EXISTS under 
> case-insensitive resolution"
> * {{AutoCdcScd1SchemaEvolutionSuite}} -- the analogous AMBIGUOUS_REFERENCE 
> case
> h3. Proposed fix
> Thread {{caseSensitive}} (from {{conf.caseSensitiveAnalysis}}, or a 
> {{Resolver}}) into both {{mergeSchemas}} and {{diffSchemas}}, forwarding it 
> to {{StructType.merge}}. {{diffSchemas}}'s add/delete/type-change logic all 
> keys off exact names, so a case-insensitive variant must canonicalize 
> consistently to avoid spuriously deleting-then-adding a case-differing 
> column. Add unit coverage at the {{SchemaMergingUtils}} / {{diffSchemas}} 
> level plus a non-AutoCDC {{MaterializeTablesSuite}} case, since the blast 
> radius is all pipeline tables. Once fixed, the two characterization tests 
> above should be updated to assert the merge is a no-op (the incoming column 
> maps onto the existing one).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to