apache/iceberg · error · IcebergAnalysisException

Cannot create view %s.%s that references temporary %s: %s

Error message

Cannot create view %s.%s that references temporary %s: %s

What it means

Iceberg's Spark 4.1 RewriteViewCommands rule throws this AnalysisException when creating a permanent view on a view catalog whose plan references session temporary views. Permanent views must resolve without the creating session, so temporary views in the body are rejected by verifyTemporaryObjectsDontExist during analysis.

Source

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

      case UnresolvedIdentifier(CatalogAndIdentifier(catalog, ident), _)
          if ViewUtil.isViewCatalog(catalog) =>
        Some(ResolvedIdentifier(catalog, ident))

      case _ =>
        None
    }
  }

  /**
   * Permanent views are not allowed to reference temp objects
   */
  private def verifyTemporaryObjectsDontExist(
      identifier: ResolvedIdentifier,
      child: LogicalPlan): Unit = {
    val tempViews = collectTemporaryViews(child)
    if (tempViews.nonEmpty) {
      throw invalidRefToTempObject(
        identifier,
        tempViews.map(v => v.quoted).mkString("[", ", ", "]"),
        "view")
    }

    val tempFunctions = collectTemporaryFunctions(child)
    if (tempFunctions.nonEmpty) {
      throw invalidRefToTempObject(identifier, tempFunctions.mkString("[", ", ", "]"), "function")
    }
  }

  private def invalidRefToTempObject(
      ident: ResolvedIdentifier,
      tempObjectNames: String,
      tempObjectType: String) = {
    new IcebergAnalysisException(
      String.format(
        "Cannot create view %s.%s that references temporary %s: %s",

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Persist the base data first (CREATE TABLE or a permanent view), then define the new view over the persisted object.
  2. Inline the temp view's query text into the new view definition.
  3. Move shared definitions into the Iceberg/REST view catalog as permanent views.
  4. Use CREATE TEMPORARY VIEW for the target if session scope is actually desired.

Example fix

// before (fails)
CREATE TEMPORARY VIEW cur AS SELECT * FROM events WHERE day = current_date();
CREATE VIEW iceberg.db.today AS SELECT * FROM cur;

// after (works)
CREATE VIEW iceberg.db.today AS SELECT * FROM iceberg.db.events WHERE day = current_date();
Defensive patterns

Strategy: validation

Validate before calling

// Spark 4.1: pre-check that the CREATE VIEW body has no temp view references
val analyzed = spark.sessionState.executePlan(df.queryExecution.logical).analyzed
val tempRefs = analyzed.flatMap {
  case r: org.apache.spark.sql.catalyst.analysis.UnresolvedRelation
    if spark.sessionState.catalog.isTempView(r.multipartIdentifier) => Seq(r.multipartIdentifier.quoted)
  case _ => Seq.empty
}
if (tempRefs.nonEmpty) throw new IllegalStateException(s"persist these first: $tempRefs")

Type guard

def isCatalogQualified(nameParts: Seq[String]): Boolean = nameParts.length >= 2

Prevention

When it happens

Trigger: `CREATE VIEW iceberg.db.v AS SELECT ... FROM temp_view` where temp_view exists only in the session (CREATE TEMPORARY VIEW). Message reports the target view catalog.name and the quoted temp view names.

Common situations: Session-staged transformations (temp views) being persisted as Iceberg views; SQL migration scripts that mix temp views and permanent catalog views; applications that rebuild temp views on startup and then define permanent views over them, failing on fresh sessions.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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