LuciferYang opened a new pull request, #9265:
URL: https://github.com/apache/paimon/pull/9265

   ### Purpose
   
   Raises the `spark4` profile baseline from 4.1.2 to 4.2.0, adds a 
`paimon-spark-4.2` module, and keeps Spark 4.0 and 4.1 working under the new 
baseline. Same shape as #7648, which did this for 4.1. Related to #8901.
   
   `paimon-spark-common` and `paimon-spark4-common` are compiled once, against 
the newest supported Spark, and the resulting classfiles ship to every 4.x 
runtime. Raising the baseline therefore changes bytecode that 4.0 and 4.1 have 
to load, and Spark 4.2 made several source-compatible but binary-incompatible 
changes: `CatalogManager` became an interface (a 4.2-built call site emits 
`invokeinterface` and dies with `IncompatibleClassChangeError` on 4.0/4.1); 
case classes gained fields (`CatalogStorageFormat`, `AppendData`, 
`DataSourceV2ScanRelation`), so positional patterns and named-argument `copy` 
calls no longer link across versions; `RewriteRowLevelCommand`'s 
`DELTA_OPERATIONS_WITH_*` constants were renamed; `V2WriteCommand` gained a 
`WriteWithSchemaEvolution` supertype; and `DESCRIBE ... PARTITION` moved out of 
`DescribeRelation` into its own `DescribeTablePartition` plan (SPARK-39660).
   
   Four mechanisms are used, in order of preference:
   
   1. **Version-neutral construction** — match by type with named accessors 
instead of positional patterns, and build placeholders through factory methods 
(`CatalogStorageFormat.empty`) rather than arity-sensitive constructors.
   2. **`SparkShim` methods** where only the arity differs, so each per-version 
module supplies its own call.
   3. **`SparkVersionCompat`** reflective accessors where the *signature* is 
incompatible. Reflection is immune to the class/interface flip, since only 
invoke opcodes carry that distinction.
   4. **Same-FQCN forks** in `paimon-spark-4.0` / `-4.1` where a supertype or a 
parameter type differs and no accessor can paper over it. Shade writes the 
module's own classes first, so the fork wins.
   
   `paimon-spark-ut-4.0` and `-4.1` recompile the shared test sources against 
their own baseline. They produce test-jars only and are deliberately left out 
of publish and release, unlike `paimon-spark-ut`.
   
   One behaviour fix is included because the baseline bump caused it. 
`qualifyIdentifier` has to carry the catalog so Spark 4.2's 
`SimpleFunctionRegistryBase.normalizeFuncName` sees a 3-part identifier, but 
the same identifier reached the expression builder, which renamed the default 
output column of an unaliased v1 function call from `db.udf(...)` to 
`catalog.db.udf(...)` on every version from 3.4 up. The builder name now drops 
the catalog; the registry key keeps it.
   
   ### Tests
   
   CI, plus locally:
   
   - `mvn -Pspark4 clean install` over `paimon-spark-common`, 
`paimon-spark4-common`, `paimon-spark-4.0`, `-4.1`, `-4.2` and the three ut 
modules — success.
   - `mvn -Pspark3 clean compile` over `paimon-spark-common` + 
`paimon-spark3-common` — success.
   - `spotless:check` clean on all six touched modules.
   - `PaimonV1FunctionTest` 13/13 on 4.2, 4.1 and 4.0; `DescribeTableTest` 4/4 
on 4.2, 4.1 and 4.0; `SparkVersionCompatTest` 14/14.
   - The column-name fix was verified in both directions — reverting it turns 
the new case red with `ArraySeq("paimon.test.udf_add2(3, 4)") did not equal 
List("test.udf_add2(3, 4)")`.
   
   The new `PaimonV1FunctionTestBase` case asserts the column name rather than 
the row values, which is why the existing cases could not catch the regression: 
they all compare rows with `checkAnswer` and spell out `AS` wherever a name is 
involved.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to