{"record":{"id":"00cbad89ff60413b","repo":"apache/iceberg","slug":"variant-column-only-supports-getvariant","errorCode":null,"errorMessage":"Variant column only supports getVariant()","messagePattern":"Variant column only supports getVariant\\(\\)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/data/vectorized/VariantColumnVector.java","lineNumber":80,"sourceCode":"    return valueChild.isNullAt(rowId);\n  }\n\n  // getChild is what getVariant() calls: child(0) = value, child(1) = metadata\n  @Override\n  public ColumnVector getChild(int ordinal) {\n    if (ordinal == 0) {\n      return valueChild;\n    } else if (ordinal == 1) {\n      return metadataChild;\n    }\n\n    throw new IllegalArgumentException(\n        \"Variant column has only 2 children, got ordinal: \" + ordinal);\n  }\n\n  @Override\n  public boolean getBoolean(int rowId) {\n    throw unsupported();\n  }\n\n  @Override\n  public byte getByte(int rowId) {\n    throw unsupported();\n  }\n\n  @Override\n  public short getShort(int rowId) {\n    throw unsupported();\n  }\n\n  @Override\n  public int getInt(int rowId) {\n    throw unsupported();\n  }\n\n  @Override","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/data/vectorized/VariantColumnVector.java#L62-L98","documentation":"VariantColumnVector wraps an Iceberg variant column for Spark's vectorized reader. Variants are not scalar values, so all typed scalar accessors (getBoolean, getByte, ...) are hard-wired to throw UnsupportedOperationException with 'Variant column only supports getVariant()'. Only getVariant()/getChild (value and metadata children) are meaningful. This error means Spark or user code tried to read a variant column as a plain boolean.","triggerScenarios":"Spark's vectorized Parquet reader invokes getBoolean(rowId) on a ColumnVector whose dataType is VariantType — e.g. an expression or cast attempts to read the variant column as boolean instead of going through getVariant()/variant_get.","commonSituations":"Casting a variant column directly to boolean in Spark SQL; custom Spark data-source or expression code that reads columns generically by primitive type without handling VariantType; running an older Spark build whose vectorized reader does not know about variant columns.","solutions":["Access the value via getVariant()/variant_get(...) or cast the variant result in Spark SQL (e.g. CAST(col AS BOOLEAN) through variant_get) rather than reading the column as a scalar.","If you own the calling code, check vector.dataType() instanceof VariantType and route to the variant child vectors (getChild(0)=value, getChild(1)=metadata) instead of calling getBoolean.","Disable the vectorized reader for such reads (read.parquet.vectorization.enabled=false) as a workaround if a Spark expression incorrectly hits the scalar path.","Upgrade Spark/Iceberg to versions with full variant expression support so plans never read variant columns as primitives."],"exampleFix":"// before\nboolean v = columnVector.getBoolean(rowId); // throws for variant columns\n// after\nColumnVector variantVal = columnVector.getChild(0);\n// decode variant value via variant metadata, or in SQL: variant_get(col, '$.field')","handlingStrategy":"type-guard","validationCode":"boolean isVariant = columnVector.dataType() instanceof org.apache.spark.sql.types.VariantType;","typeGuard":"boolean isVariantVector(ColumnVector cv) {\n  return cv.dataType() instanceof org.apache.spark.sql.types.VariantType;\n}","tryCatchPattern":"try {\n  v = vector.getBoolean(rowId);\n} catch (UnsupportedOperationException e) {\n  // column is a variant: decode via getChild(0)/(1) or variant_get in SQL\n}","preventionTips":["Check dataType() for VariantType before calling any scalar getter on a ColumnVector","Use variant_get()/typed casts in Spark SQL rather than reading variant columns directly","Keep Spark and Iceberg versions aligned on variant vectorized-read support"],"tags":["spark","vectorized-reader","variant","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}