{"record":{"id":"acaa467c1400329d","repo":"apache/iceberg","slug":"variant-column-only-supports-getvariant-acaa46","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.2/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.2/spark/src/main/java/org/apache/iceberg/spark/data/vectorized/VariantColumnVector.java#L62-L98","documentation":"In Spark 4.2's VariantColumnVector, getBoolean(rowId) throws UnsupportedOperationException('Variant column only supports getVariant()'). Variant data must be decoded through the Variant API; boolean is just one of many accessor methods stubbed out to prevent misinterpretation of variant buffers.","triggerScenarios":"Calling getBoolean(rowId) on a variant-backed column, e.g. a reader whose expected schema declares BooleanType for a field that is variant, or generic vectorized code reading scalar columns positionally.","commonSituations":"Projection schema mismatched with table schema (boolean vs variant); custom data source readers predating variant support; queries casting variant to boolean in engines without variant-aware evaluation.","solutions":["Call getVariant(rowId) and extract the boolean via the Variant API after checking its type","Make the read schema use VariantType for variant fields","Remove or adjust casts of variant columns to boolean in the query","Upgrade the consuming reader/connector to a variant-capable version"],"exampleFix":"// before\nboolean b = columnVector.getBoolean(rowId);\n// after\nVariant v = ((VariantColumnVector) columnVector).getVariant(rowId);\nboolean b = v.getType() == VariantUtil.Type.BOOLEAN ? ((VariantBoolean) v).get() : false;","handlingStrategy":"type-guard","validationCode":"import org.apache.spark.sql.types.VariantType;\nif (columnVector instanceof VariantColumnVector) { /* use getVariant */ }","typeGuard":"boolean isVariantColumn(ColumnVector v) { return v instanceof VariantColumnVector; }","tryCatchPattern":"try { b = vector.getBoolean(rowId); } catch (UnsupportedOperationException e) { if (e.getMessage().contains(\"getVariant()\")) { b = extractBoolean(((VariantColumnVector) vector).getVariant(rowId)); } else throw e; }","preventionTips":["Match read schema types to table schema (VariantType for variant)","Use variant-aware access paths for variant columns","Avoid implicit casts of variant columns in engines lacking variant support","Test readers against tables with variant columns"],"tags":["spark","variant","vectorized-reader","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"}