{"record":{"id":"2947f683a38a1cf1","repo":"apache/cassandra","slug":"cannot-drop-a-table-when-materialized-views-still","errorCode":null,"errorMessage":"Cannot drop a table when materialized views still depend on it (%s)","messagePattern":"Cannot drop a table when materialized views still depend on it \\((.+?)\\)","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/DropTableStatement.java","lineNumber":111,"sourceCode":"\n        if (null == table)\n        {\n            if (ifExists)\n                return schema;\n\n            throw ire(\"Table '%s.%s' doesn't exist\", keyspaceName, tableName);\n        }\n\n        if (table.isView())\n            throw ire(\"Cannot use DROP TABLE on a materialized view. Please use DROP MATERIALIZED VIEW instead.\");\n\n        if (table.requiresAccordSupport() && table.params.pendingDrop)\n            throw ire(\"Table '%s.%s' is already being dropped\", keyspaceName, tableName);\n\n        Iterable<ViewMetadata> views = keyspace.views.forTable(table.id);\n        if (!isEmpty(views))\n        {\n            throw ire(\"Cannot drop a table when materialized views still depend on it (%s)\",\n                      keyspaceName,\n                      join(\", \", transform(views, ViewMetadata::name)));\n        }\n\n        return schema.withAddedOrUpdated(keyspace.withSwapped(keyspace.tables.without(table)));\n    }\n\n    SchemaChange schemaChangeEvent(KeyspacesDiff diff)\n    {\n        return new SchemaChange(Change.DROPPED, Target.TABLE, keyspaceName, tableName);\n    }\n\n    public void authorize(ClientState client)\n    {\n        client.ensureTablePermission(keyspaceName, tableName, Permission.DROP);\n    }\n\n    @Override","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/DropTableStatement.java#L93-L129","documentation":"DROP TABLE was attempted on a base table that has materialized views defined over it. Cassandra requires views to be dropped first because a table cannot be removed while dependent views reference it.","triggerScenarios":"Running DROP TABLE on a keyspace table that still has at least one ViewMetadata in keyspace.views forTable(table.id).","commonSituations":"Developers forgetting which materialized views were created on a base table; migrations that create views but later drop the base table first; inherited schemas with undocumented views.","solutions":["List the dependent views from the error message and run DROP MATERIALIZED VIEW for each","Then reissue DROP TABLE","Use system_schema.views to discover all views on the base table before dropping"],"exampleFix":"// before\nDROP TABLE ks.metrics;\n// after\nDROP MATERIALIZED VIEW ks.metrics_by_day;\nDROP TABLE ks.metrics;","handlingStrategy":"validation","validationCode":"var views = session.execute(\"SELECT view_name FROM system_schema.views WHERE keyspace_name=? AND base_table_name=?\", ks, table);\nfor (var v : views) session.execute(\"DROP MATERIALIZED VIEW IF EXISTS \" + ks + \".\" + v.getString(\"view_name\"));","typeGuard":null,"tryCatchPattern":"try { dropTable(); } catch (InvalidRequest e) { if (e.getMessage().contains(\"materialized views still depend\")) dropDependentViewsThenRetry(); else throw e; }","preventionTips":["Query system_schema.views for base_table_name before dropping any table","Document view dependencies alongside table schemas","Generate drop scripts in dependency order (views first, base tables last)"],"tags":["cassandra","cql","ddl","materialized-views"],"backgroundTag":"schema-validation-failed","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}