{"record":{"id":"b3e17ce338cdb62b","repo":"apache/iceberg","slug":"replacing-a-view-is-not-supported-by-catalog-cata-b3e17c","errorCode":null,"errorMessage":"Replacing a view is not supported by catalog: catalogName","messagePattern":"Replacing a view is not supported by catalog: catalogName","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkSessionCatalog.java","lineNumber":525,"sourceCode":"      String[] columnAliases,\n      String[] columnComments,\n      Map<String, String> properties)\n      throws NoSuchNamespaceException, NoSuchViewException {\n    if (asViewCatalog instanceof SupportsReplaceView) {\n      return ((SupportsReplaceView) asViewCatalog)\n          .replaceView(\n              ident,\n              sql,\n              currentCatalog,\n              currentNamespace,\n              schema,\n              queryColumnNames,\n              columnAliases,\n              columnComments,\n              properties);\n    }\n\n    throw new UnsupportedOperationException(\n        \"Replacing a view is not supported by catalog: \" + catalogName);\n  }\n\n  @Override\n  public View alterView(Identifier ident, ViewChange... changes)\n      throws NoSuchViewException, IllegalArgumentException {\n    if (null != asViewCatalog && asViewCatalog.viewExists(ident)) {\n      return asViewCatalog.alterView(ident, changes);\n    } else if (isViewCatalog()) {\n      return getSessionCatalog().alterView(ident, changes);\n    }\n\n    throw new UnsupportedOperationException(\n        \"Altering a view is not supported by catalog: \" + catalogName);\n  }\n\n  @Override\n  public boolean dropView(Identifier ident) {","sourceCodeStart":507,"sourceCodeEnd":543,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkSessionCatalog.java#L507-L543","documentation":"SparkSessionCatalog delegates view operations to an underlying view catalog when one is configured; otherwise it only handles tables. This UnsupportedOperationException is thrown from replaceView when the wrapped catalog neither implements ViewCatalog nor is configured as a session view catalog, so replacing (CREATE OR REPLACE VIEW) a view cannot be performed.","triggerScenarios":"Calling SparkCatalog/SparkSessionCatalog.replaceView(ident, ...) (e.g. via CREATE OR REPLACE VIEW SQL) when asViewCatalog is null, the ident does not exist as a view in a delegate view catalog, and isViewCatalog() is false for catalogName.","commonSituations":"Using CREATE OR REPLACE VIEW against a catalog (e.g. HadoopCatalog, Hive Metastore without view support in the configured delegate, or a third-party catalog) that does not implement the Iceberg ViewCatalog interface; running against a session catalog whose underlying implementation only supports tables.","solutions":["Configure the catalog so its underlying implementation supports views (a catalog implementing org.apache.iceberg.view.ViewCatalog), e.g. use a REST/Hive/JDBC catalog with view support.","Drop the existing view and re-create it instead of replacing: DROP VIEW ident; CREATE VIEW ident AS ...","If the delegate catalog does support views, ensure the view actually exists there (viewExists(ident) path) so the delegation branch is taken.","Manage views in a different catalog that supports replace, or use engine-native (non-Iceberg) views for this metadata location."],"exampleFix":"// before\nspark.sql(\"CREATE OR REPLACE VIEW my_view AS SELECT * FROM t\") // throws UnsupportedOperationException\n// after\nspark.sql(\"DROP VIEW IF EXISTS my_view\")\nspark.sql(\"CREATE VIEW my_view AS SELECT * FROM t\")","handlingStrategy":"try-catch","validationCode":"// before replace\nViewCatalog vc = ((SparkCatalog) sparkCatalog).asViewCatalog();\nif (vc == null) { /* catalog does not support views: use drop+create */ }","typeGuard":"boolean supportsViewReplace = sparkCatalog instanceof SparkCatalog\n    && ((SparkCatalog) sparkCatalog).asViewCatalog() != null;","tryCatchPattern":"try {\n  catalog.replaceView(ident, schema, spec, location, props);\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage().contains(\"Replacing a view\")) { catalog.dropView(ident); catalog.createView(ident, ...); }\n  else throw e;\n}","preventionTips":["Choose a catalog implementation that implements ViewCatalog before defining views in it.","Check asViewCatalog()/ViewCatalog support at session setup time, not at first write.","Avoid CREATE OR REPLACE VIEW in migrations targeting view-less catalogs."],"tags":["unsupported-operation","view","catalog","spark"],"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"}