Repository navigation
Conversation
Natural stored views over an in-memory metastore of already existing views whose base tables evolved. A view whose fuzzy UNION fails only because the generic_project branch has lowercase Calcite names while the other branch carries the source's camelCase Avro names must be repaired with the source spelling (non-strict, forceLowercase=false): nested records, aliases, deeper records, arrays/maps, metadata siblings, ordinary access above the UNION, an aliased nested-struct operand, an ordinal-return wrapper operand, and adjacent UNION chains. Every other outcome is frozen byte for byte from the unchanged baseline: working views (direct/direct, generated/generated, lowercase, fallback and derived branches, both orders, chains), strict and forceLowercase modes, standalone generated branches, and preserved failures (ambiguous, missing or container provenance, inconsistent source casing, opaque unions, and the Project-between-UNIONs limitation) with exact exception class and message. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
NT1: the hand-derived v_n8_outer oracle is now Avro's own serialization of the same schema (unchanged expectations), and every repaired oracle must equal its own reserialization. NT2: v_n12_latent (pv_evolved2 UNION pv_pascal_evolved UNION pv_small) is a preserved-failure control: its working inner generated/generated UNION has disagreeing source spellings, so the outer UNION must keep its own original exception, not the inner one. Shape U(U(G,G),D) and all four baseline outcomes frozen. NT3: the ordinal-return wrapper is li_groot_cast_nullability(id, requestheader), so its operands $0/$1 distinguish the selected ordinal 1. All its frozen and repaired oracles are unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…EM-25474) A fuzzy UNION projects an evolved struct with generic_project, whose Avro schema is derived from lowercase Calcite names, while a pass-through branch keeps the source's camelCase names, so the exact-name UNION merge rejects the view. The baseline merge always runs first. Only after its plain RuntimeException (with forceLowercase=false, and when a generic_project recipe exists below the UNION) is the merge retried once, with the generated fields spelled like the source Avro fields they project (names only: the generated record identities, nullability, defaults and docs are kept). Recipes are lazy, per conversion, and cover input columns, a field of a column and an ordinal-return argument. Any failure of the attempt rethrows the original exception. SchemaUtilities, the Rex shuttle and every successful conversion are unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.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 are proposed in this pull request, and why are they necessary?
This is a deliberately narrow alternative to the closed #620, which is superseded and was not reopened.
Problem. When a stored view
UNIONs tables whose structs evolved differently, the fuzzy-union rewriter wraps the evolved branch in an internalgeneric_projectcall so both branches share one struct shape.coral-schemaderives that branch's Avro schema from Calcite's lower-cased type names, while the other, pass-through branch keeps the case-preserved Avro names of its source (for examplerequestHeader.pageKey). The exact-name Avro UNION merge then fails withrequestHeader is in schema ... but not in schema ..., so Avro schema inference fails for the view withforceLowercase=false.Change. Only
RelToAvroSchemaConverterchanges, and only the UNION visitor's failure path:RuntimeException(exact class), withforceLowercase=false, ageneric_projectproject below the UNION, and an actual source-backed name difference, the merge is retried once with the generated fields respelled like the source Avro fields they project. The retry uses the same, unchangedSchemaUtilities.mergeUnionRecordSchema.Scope. One production file (+194/-3, 197 lines); the rest is two new test files and two new test resources (5 files total). No existing file, golden resource, or
SchemaUtilitiesmethod is modified, and noSchemaRexShuttlemethod changes. Every conversion that succeeded before still returns a byte-identical schema, and every unrelated failure keeps its exception class and message.Deliberately not changed (pre-existing behavior, out of scope here): default/nullability/alias/logical-type handling of generated schemas, ordinary UNION matching of differently spelled physical fields, namespace handling, and anything with
forceLowercase=true.Known limitations
How was this patch tested?
New
FuzzyUnionAvroCasingTests(6 tests) with an in-memory metastore/CoralCatalogfixture; every conversion runs through bothViewToAvroSchemaConverter.create(HiveMetastoreClient)andcreate(CoralCatalog). Views are existingVIRTUAL_VIEWs so the real fuzzy rewriter runs, with lower-cased Hive columns and case-preservedavro.schema.literal.forceLowercasecombinations) asserts that every other outcome is unchanged: working views (direct/direct, generated/generated stays lower-case, lower-case and fallback/derived branches in both orders) return byte-identical schemas, and unrepaired failures (ambiguous, missing or container provenance, inconsistent source casing, opaque unions, strict namespace, intervening Project) keep their exact exception class and message.Commands (JDK 17, Gradle
cleanTest), run on the head commit::coral-schema:test: 187 tests, 0 failures, 0 skipped (181 existing + 6 new).:coral-hive:testand:coral-spark:test: pass, includingFuzzyUnionTest(13/13) andFuzzyUnionViewTest(11/11).:coral-schema:spotlessJavaCheck: passes (run in a temporary clone because the worktree cannot run the ratcheted check).Not run:
./gradlew clean build,:coral-spark:spark3Test, and:coral-spark-catalog:test. The saved original-view Spark 3.1/3.5 acceptance described above has also not been run.🤖 Generated with GitHub Copilot CLI