{"record":{"id":"7cc59402c84353e1","repo":"apache/iceberg","slug":"cannot-create-view-s-s-that-references-temporary-7cc594","errorCode":null,"errorMessage":"Cannot create view %s.%s that references temporary %s: %s","messagePattern":"Cannot create view (.+?)\\.(.+?) that references temporary (.+?): (.+?)","errorType":"exception","errorClass":"IcebergAnalysisException","httpStatus":null,"severity":"error","filePath":"spark/v4.1/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/analysis/RewriteViewCommands.scala","lineNumber":135,"sourceCode":"\n      case UnresolvedIdentifier(CatalogAndIdentifier(catalog, ident), _)\n          if ViewUtil.isViewCatalog(catalog) =>\n        Some(ResolvedIdentifier(catalog, ident))\n\n      case _ =>\n        None\n    }\n  }\n\n  /**\n   * Permanent views are not allowed to reference temp objects\n   */\n  private def verifyTemporaryObjectsDontExist(\n      identifier: ResolvedIdentifier,\n      child: LogicalPlan): Unit = {\n    val tempViews = collectTemporaryViews(child)\n    if (tempViews.nonEmpty) {\n      throw invalidRefToTempObject(\n        identifier,\n        tempViews.map(v => v.quoted).mkString(\"[\", \", \", \"]\"),\n        \"view\")\n    }\n\n    val tempFunctions = collectTemporaryFunctions(child)\n    if (tempFunctions.nonEmpty) {\n      throw invalidRefToTempObject(identifier, tempFunctions.mkString(\"[\", \", \", \"]\"), \"function\")\n    }\n  }\n\n  private def invalidRefToTempObject(\n      ident: ResolvedIdentifier,\n      tempObjectNames: String,\n      tempObjectType: String) = {\n    new IcebergAnalysisException(\n      String.format(\n        \"Cannot create view %s.%s that references temporary %s: %s\",","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.1/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/analysis/RewriteViewCommands.scala#L117-L153","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","solutions":["Persist the base data first (CREATE TABLE or a permanent view), then define the new view over the persisted object.","Inline the temp view's query text into the new view definition.","Move shared definitions into the Iceberg/REST view catalog as permanent views.","Use CREATE TEMPORARY VIEW for the target if session scope is actually desired."],"exampleFix":"// before (fails)\nCREATE TEMPORARY VIEW cur AS SELECT * FROM events WHERE day = current_date();\nCREATE VIEW iceberg.db.today AS SELECT * FROM cur;\n\n// after (works)\nCREATE VIEW iceberg.db.today AS SELECT * FROM iceberg.db.events WHERE day = current_date();","handlingStrategy":"validation","validationCode":"// Spark 4.1: pre-check that the CREATE VIEW body has no temp view references\nval analyzed = spark.sessionState.executePlan(df.queryExecution.logical).analyzed\nval tempRefs = analyzed.flatMap {\n  case r: org.apache.spark.sql.catalyst.analysis.UnresolvedRelation\n    if spark.sessionState.catalog.isTempView(r.multipartIdentifier) => Seq(r.multipartIdentifier.quoted)\n  case _ => Seq.empty\n}\nif (tempRefs.nonEmpty) throw new IllegalStateException(s\"persist these first: $tempRefs\")","typeGuard":"def isCatalogQualified(nameParts: Seq[String]): Boolean = nameParts.length >= 2","tryCatchPattern":null,"preventionTips":["Never mix CREATE TEMPORARY VIEW staging with CREATE VIEW <catalog>.db.<name> in the same pipeline without persisting staging first.","Use CREATE TABLE for intermediate results that permanent views depend on.","Keep permanent view SQL fully catalog/database qualified.","Add a lint rule or CI test that creates all permanent views in a fresh session.","Document the temp-vs-permanent view policy for the team."],"tags":["spark","view","temporary-object","analysis-exception","spark4-1"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}