{"record":{"id":"85449bf607ee9f94","repo":"apache/cassandra","slug":"materialized-views-are-not-supported-on-counter-ta","errorCode":null,"errorMessage":"Materialized views are not supported on counter tables","messagePattern":"Materialized views are not supported on counter tables","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/CreateViewStatement.java","lineNumber":173,"sourceCode":"            throw ire(\"Base table '%s' doesn't exist\", tableName);\n\n        if (keyspace.hasTable(viewName))\n            throw ire(\"Cannot create materialized view '%s' - a table with the same name already exists\", viewName);\n\n        if (keyspace.hasView(viewName))\n        {\n            if (ifNotExists)\n                return schema;\n\n            throw new AlreadyExistsException(keyspaceName, viewName);\n        }\n\n        /*\n         * Base table validation\n         */\n\n        if (table.isCounter())\n            throw ire(\"Materialized views are not supported on counter tables\");\n\n        if (table.isView())\n            throw ire(\"Materialized views cannot be created against other materialized views\");\n\n        // Guardrails on table properties\n        Guardrails.tableProperties.guard(attrs.updatedProperties(), attrs::removeProperty, state);\n\n        // Guardrail to limit number of mvs per table\n        Iterable<ViewMetadata> tableViews = keyspace.views.forTable(table.id);\n        Guardrails.materializedViewsPerTable.guard(Iterables.size(tableViews) + 1,\n                                                   String.format(\"%s on table %s\", viewName, table.name),\n                                                   false,\n                                                   state);\n\n        if (table.params.gcGraceSeconds == 0)\n        {\n            throw ire(\"Cannot create materialized view '%s' for base table \" +\n                      \"'%s' with gc_grace_seconds of 0, since this value is \" +","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/CreateViewStatement.java#L155-L191","documentation":"Base-table validation in CreateViewStatement.apply(): the underlying table of the new materialized view is a counter table. Materialized views cannot reliably mirror counter updates because view row liveness and counter deltas interact badly, so creating a view over a counter table is rejected with InvalidRequestException.","triggerScenarios":"Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateViewStatement.java:173 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Denormalize counter data into a regular table updated by the application instead of using a materialized view; keep counters in a dedicated table and maintain an aggregate table via application logic or a UDF-free write path; redesign the schema so the view is built over a non-counter table."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}