apache/iceberg · error · AnalysisException

CREATE_VIEW_COLUMN_ARITY_MISMATCH.NOT_ENOUGH_DATA_COLUMNS

CREATE_VIEW_COLUMN_ARITY_MISMATCH.NOT_ENOUGH_DATA_COLUMNS

Error message

CREATE_VIEW_COLUMN_ARITY_MISMATCH.NOT_ENOUGH_DATA_COLUMNS

What it means

When creating an Iceberg view, the declared column list has MORE names than the view's query produces. Iceberg's CheckViews throws Spark's standard CREATE_VIEW_COLUMN_ARITY_MISMATCH.NOT_ENOUGH_DATA_COLUMNS AnalysisException, naming the view, its declared columns, and the query's actual output columns.

Source

Thrown at spark/v4.1/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/analysis/CheckViews.scala:77

            resolvedIdent.catalog.name() +: resolvedIdent.identifier.asMultipartIdentifier
          checkCyclicViewReference(viewIdent, query, Seq(viewIdent))
        }

      case AlterViewAs(ResolvedV2View(_, _), _, _) =>
        throw new IcebergAnalysisException(
          "ALTER VIEW <viewName> AS is not supported. Use CREATE OR REPLACE VIEW instead")

      case _ => // OK
    }
  }

  private def verifyColumnCount(
      ident: ResolvedIdentifier,
      columns: Seq[String],
      query: LogicalPlan): Unit = {
    if (columns.nonEmpty) {
      if (columns.length > query.output.length) {
        throw new AnalysisException(
          errorClass = "CREATE_VIEW_COLUMN_ARITY_MISMATCH.NOT_ENOUGH_DATA_COLUMNS",
          messageParameters = Map(
            "viewName" -> String.format("%s.%s", ident.catalog.name(), ident.identifier),
            "viewColumns" -> columns.mkString(", "),
            "dataColumns" -> query.output.map(c => c.name).mkString(", ")))
      } else if (columns.length < query.output.length) {
        throw new AnalysisException(
          errorClass = "CREATE_VIEW_COLUMN_ARITY_MISMATCH.TOO_MANY_DATA_COLUMNS",
          messageParameters = Map(
            "viewName" -> String.format("%s.%s", ident.catalog.name(), ident.identifier),
            "viewColumns" -> columns.mkString(", "),
            "dataColumns" -> query.output.map(c => c.name).mkString(", ")))
      }
    }
  }

  private def checkCyclicViewReference(
      viewIdent: Seq[String],

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Match the column list length to the query output: reduce the declared column names to the number of query columns
  2. Add/adjust expressions in the SELECT so it returns exactly as many columns as declared
  3. Drop the explicit column list entirely and rely on query output names, optionally using aliases in the SELECT

Example fix

// before
CREATE VIEW v (a, b, c) AS SELECT id, name FROM t
// after
CREATE VIEW v (a, b) AS SELECT id, name FROM t
Defensive patterns

Strategy: validation

Validate before calling

val q = spark.sql(viewQuery); require(declaredCols.length == q.schema.length, s"view declares ${declaredCols.length} columns but query outputs ${q.schema.length}")

Try / catch

try { spark.sql(createViewDdl) } catch { case e: AnalysisException if e.getErrorClass.exists(_.startsWith("CREATE_VIEW_COLUMN_ARITY_MISMATCH")) => /* fix column list and retry */ }

Prevention

When it happens

Trigger: `CREATE VIEW v (a, b, c) AS SELECT x, y FROM ...` — the explicit column list length exceeds the number of columns output by the SELECT query on an Iceberg view (v2 view path in CheckViews.verifyColumnCount).

Common situations: Hand-written CREATE VIEW where the column list was edited without updating the query; schema drift where the source query lost columns after a refactor.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/79079d1a5e39acbe. Report an issue: GitHub.