{"record":{"id":"ac4cfec2c76bccfd","repo":"apache/iceberg","slug":"cannot-move-view-between-catalogs-from-oldcatal-ac4cfe","errorCode":null,"errorMessage":"Cannot move view between catalogs: from=${oldCatalog.name} and to=${newIdent.catalog().name()}","messagePattern":"Cannot move view between catalogs: from=(.+?) and to=(.+?)","errorType":"exception","errorClass":"IcebergAnalysisException","httpStatus":null,"severity":"error","filePath":"spark/v4.2/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/ExtendedDataSourceV2Strategy.scala","lineNumber":130,"sourceCode":"    case DropIdentifierFields(IcebergCatalogAndIdentifier(catalog, ident), fields) =>\n      DropIdentifierFieldsExec(catalog, ident, fields) :: Nil\n\n    case SetWriteDistributionAndOrdering(\n          IcebergCatalogAndIdentifier(catalog, ident),\n          distributionMode,\n          ordering) =>\n      SetWriteDistributionAndOrderingExec(catalog, ident, distributionMode, ordering) :: Nil\n\n    case OrderAwareCoalesce(numPartitions, coalescer, child) =>\n      OrderAwareCoalesceExec(numPartitions, coalescer, planLater(child)) :: Nil\n\n    case RenameTable(\n          ResolvedV2View(oldCatalog: ViewCatalog, oldIdent, _),\n          newName,\n          isView @ true) =>\n      val newIdent = Spark3Util.catalogAndIdentifier(spark, newName.toList.asJava)\n      if (oldCatalog.name != newIdent.catalog().name()) {\n        throw new IcebergAnalysisException(\n          s\"Cannot move view between catalogs: from=${oldCatalog.name} and to=${newIdent.catalog().name()}\")\n      }\n      IcebergRenameV2ViewExec(oldCatalog, oldIdent, newIdent.identifier()) :: Nil\n\n    case DropIcebergView(ResolvedIdentifier(viewCatalog: ViewCatalog, ident), ifExists) =>\n      DropV2ViewExec(viewCatalog, ident, ifExists) :: Nil\n\n    case CreateIcebergView(\n          ResolvedIdentifier(viewCatalog: ViewCatalog, ident),\n          queryText,\n          query,\n          columnAliases,\n          columnComments,\n          comment,\n          collation,\n          properties,\n          allowExisting,\n          replace,","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.2/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/ExtendedDataSourceV2Strategy.scala#L112-L148","documentation":"This IcebergAnalysisException is thrown by ExtendedDataSourceV2Strategy during RENAME VIEW resolution when the source view's catalog differs from the catalog parsed from the new name. Spark's ViewCatalog rename semantics do not support moving a view across catalogs, so the strategy rejects it up front.","triggerScenarios":"Running 'ALTER VIEW old_catalog.db.v RENAME TO other_catalog.db.v2' where the new identifier's catalog name differs from the old catalog's name.","commonSituations":"Unqualified rename targets defaulting to a different session catalog; typos in the target catalog name; attempting to migrate views between catalogs with a single rename.","solutions":["Rename within the same catalog: keep the target name in the same catalog as the source","Drop the view from the source catalog and recreate it in the target catalog to move it","Check the session's current catalog so an unqualified target resolves to the intended one","Use Spark3Util.catalogAndIdentifier output to confirm which catalog the new name resolves to"],"exampleFix":"// before: cross-catalog move\nALTER VIEW iceberg_cat.db.v RENAME TO spark_catalog.db.v2;\n// after: rename within one catalog\nALTER VIEW iceberg_cat.db.v RENAME TO iceberg_cat.db.v2;","handlingStrategy":"validation","validationCode":"val (newCat, newIdent) = Spark3Util.catalogAndIdentifier(spark, newNameParts.asJava)\nrequire(newCat.name() == oldCatalog.name,\n  \"View rename must stay within the same catalog; drop and recreate to move across catalogs\")","typeGuard":null,"tryCatchPattern":"try { spark.sql(\"ALTER VIEW ... RENAME TO ...\") } catch {\n  case e: org.apache.iceberg.spark.IcebergAnalysisException =>\n    logError(\"rename crosses catalogs; drop + recreate instead\", e)\n}","preventionTips":["Keep rename targets in the same catalog as the source view","Set the session catalog explicitly (USE catalog) before unqualified renames","For cross-catalog moves, script drop + create with the view's SQL definition"],"tags":["spark","iceberg","view","rename","catalog"],"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"}