Repository navigation
Conversation
deniskuzZ
marked this pull request as draft
October 15, 2026 18:31
- VariantObjectInspector is an interface (category VARIANT, type name variant); standard, constant, struct-encoded and Iceberg flavours - every serde writes today's two-binary bytes, Avro as Iceberg's variant record; vectors keep StructColumnVector(metadata, value) - Hive's Parquet reader finds metadata/value by name, never prunes inside a variant, and rejects shredded variants outside Iceberg - comparisons/hash reproduce the byte-wise struct results; merge join gets a variant comparator (HiveVariantComparator) - CAST(v AS STRING) and string conversions: NULL for a JSON null, bare strings, base64 binary, plain scalars, JSON objects and arrays; v.metadata/v.value and struct-into-variant inserts are rejected - Calcite VARIANT in both directions, including VARIANT-typed NULL constants, which vectorize; SHOW CREATE TABLE/DESCRIBE print variant; stats size it as before - persistent non-Iceberg tables reject VARIANT at any depth; CTAS/CMV into them fails at compile time; views and native temporary tables allowed - Iceberg writes the exact variant bytes (no BytesWritable padding); Variant.from(List) removed - HS2 reports variant result columns as string/JSON until HIVE-30166; the LLAP external client gets type variant with JSON values
|
This branch has not been deployed
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.



Stacked on #6654 (HIVE-29773). The second commit is this change.
What changes were proposed in this pull request?
VARIANT becomes an ObjectInspector category of its own, next to STRUCT/MAP/LIST/UNION, instead of a struct with a
recognised type name.
VariantObjectInspectoris an interface: category VARIANT, type namevariant,Variant getVariant(Object).VariantEncodingdefines the two-binary layout in one place.ObjectInspectorUtils, the converters andSerDeUtilshandle VARIANT explicitly. Compare andhash keep the byte-wise results of the struct path, and merge joins use
HiveVariantComparator.bytesfields tagged"logicalType":"variant", whichIceberg's registered logical type accepts.
metadataandvalueby name, never prunes nested columns inside a variant, andrejects a shredded variant (a
typed_valuechild) outside Iceberg, which rebuilds shredded values itself.StructColumnVector(metadata, value), now wired from the VARIANTcategory. A VARIANT-typed NULL constant vectorizes.
VARIANTin both directions, including VARIANT-typed NULL constants.variant.Views and native temporary tables may hold VARIANT.
parse_json,CAST(x AS VARIANT),variant_getandto_jsonwork on every inspector flavour.CAST(v AS STRING)and implicit string conversions: NULL for a JSON null, a string's characters, base64 forbinary, plain text for other scalars (as
variant_get(v, '$', 'string')), JSON for objects and arrays.to_json(v)and HS2 values stay JSON.collect_set,collect_list,approx_distinct,IN,=and!=accept VARIANT.IcebergVariantObjectInspectorimplements the interface, and the writer stores exactly the encodedbytes.
stringwith JSON values until HIVE-30166.variantwith JSON values.Why are the changes needed?
At the inspector level VARIANT was a
struct<metadata:binary,value:binary>. Plans, result schemas, views, CTAS,DESCRIBE and HS2 all saw the struct, and features had to recognise a variant by the struct's name or shape.
HIVE-30166 (client capability) and HIVE-30171 (semantic equality) need a variant that is a variant everywhere.
Does this PR introduce any user-facing change?
Yes.
struct<metadata:binary,value:binary>variantstructstringwith JSON valuesCAST(v AS STRING), implicit string conversionsIN (constants),collect_set(v)=v.metadata,v.valuenamed_struct('metadata',…,'value',…)into a variant columnarray<variant>)CREATE TEMPORARY TABLE t (v VARIANT)with native storageparse_json('literal')ST_GeomFromJson/ST_GeomFromGeoJsonwith a LIST/MAP/UNION argumentClassCastExceptionat evaluationUnchanged:
=, GROUP BY, DISTINCT, ORDER BY, joins,min/maxandhash(v).Iceberg values written by Hive 4.2.x carry trailing bytes. Hive 4.2.x wrote the whole reused buffer
(
BytesWritable.getBytes()), so each stored value carries trailing zero bytes. This change writes exact bytes, and aHive rewrite of old rows (INSERT … SELECT, compaction, copy-on-write MERGE/UPDATE) drops the tail. Until then, or
until semantic equality (HIVE-30171), byte-wise
=, GROUP BY, DISTINCT, joins andhash(v)treat an old row and anewly written equal value as different.
Compatibility:
VariantObjectInspectoris an interface, so code compiled against 4.2.x getsIncompatibleClassChangeError.VariantObjectInspector.get()andVariant.from(List)are removed.ObjectInspectorFactory.getVariantObjectInspector()is deprecated in favour ofgetStandardVariantObjectInspector(). Its objects are nowVariant, notList<byte[]>.IcebergVariantObjectInspector.get()returnsIcebergVariantObjectInspector;Table.validateColumnshas afourth parameter.
struct<metadata:binary,value:binary>columns created by Iceberg CTAS on 4.2.x or non-Iceberg CTAS on master staystructs. No SQL route converts them to VARIANT (
CAST(x AS VARIANT)rejects structs) until a follow-up adds afunction from the two binaries to a variant.
How was this patch tested?
nested variants, descending keys, high-bit bytes, buffer reuse, and SQL NULL vs JSON null;
HiveVariantComparatoragainst the BinarySortable key order; JSON escaping;and rows;
variant_first_class.q: types, casts, the shuffle,hash(v), ordering, a map join, CTE materialization,temporary tables and a TEXTFILE directory, over values with bytes >= 0x80;
variant_llap_io.q: Iceberg Parquet and Avro and native temporary ORC and TEXTFILE tables on LLAP;variant_parquet_temporary.q: Parquet temporary tables and CTEs with fetch-task conversion;variant_calcite_nulls.qand the existing variant q-tests;TestJdbcDriver2#testVariantType;BaseJdbcWithMiniLlap#testVariantType, whose only subclass is@Ignored (HIVE-23549).OrcMetrics), so there is no Iceberg ORC test.depends on #6890