{"record":{"id":"81ae2eb4e6a87368","repo":"apache/cassandra","slug":"counter-type-is-not-supported-for-primary-key-colu-81ae2e","errorCode":null,"errorMessage":"counter type is not supported for PRIMARY KEY column '%s'","messagePattern":"counter type is not supported for PRIMARY KEY column '(.+?)'","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/CreateViewStatement.java","lineNumber":262,"sourceCode":"            ColumnMetadata column = table.getColumn(name);\n            if (null == column || !selectedColumns.contains(name))\n                throw ire(\"Unknown column '%s' referenced in PRIMARY KEY for materialized view '%s'\", name, viewName);\n\n            if (!primaryKeyColumns.add(name))\n                throw ire(\"Duplicate column '%s' in PRIMARY KEY clause for materialized view '%s'\", name, viewName);\n\n            AbstractType<?> type = column.type;\n\n            if (type.isMultiCell())\n            {\n                if (type.isCollection())\n                    throw ire(\"Invalid non-frozen collection type '%s' for PRIMARY KEY column '%s'\", type, name);\n                else\n                    throw ire(\"Invalid non-frozen user-defined type '%s' for PRIMARY KEY column '%s'\", type, name);\n            }\n\n            if (type.isCounter())\n                throw ire(\"counter type is not supported for PRIMARY KEY column '%s'\", name);\n\n            if (type.referencesDuration())\n                throw ire(\"duration type is not supported for PRIMARY KEY column '%s'\", name);\n        });\n\n        // If we give a clustering order, we must explicitly do so for all aliases and in the order of the PK\n        if (!clusteringOrder.isEmpty() && !clusteringColumns.equals(new ArrayList<>(clusteringOrder.keySet())))\n            throw ire(\"Clustering key columns must exactly match columns in CLUSTERING ORDER BY directive\");\n\n        /*\n         * We need to include all of the primary key columns from the base table in order to make sure that we do not\n         * overwrite values in the view. We cannot support \"collapsing\" the base table into a smaller number of rows in\n         * the view because if we need to generate a tombstone, we have no way of knowing which value is currently being\n         * used in the view and whether or not to generate a tombstone. In order to not surprise our users, we require\n         * that they include all of the columns. We provide them with a list of all of the columns left to include.\n         */\n        List<ColumnIdentifier> missingPrimaryKeyColumns =\n            Lists.newArrayList(filter(transform(table.primaryKeyColumns(), c -> c.name), c -> !primaryKeyColumns.contains(c)));","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/CreateViewStatement.java#L244-L280","documentation":"Counter columns cannot be part of a materialized view's primary key. Counter values are stored specially (only-increment cells) and cannot act as unique key components, so validation rejects them explicitly.","triggerScenarios":"CREATE MATERIALIZED VIEW ... PRIMARY KEY (pk, hits) where hits is a counter column.","commonSituations":"Trying to index/aggregate by counter values in a view; schema where a counter column was mistaken for a regular bigint.","solutions":["Remove the counter column from the PRIMARY KEY and key the view on regular columns","Maintain the count in a separate non-counter bigint column (updated transactionally by the application) if it must be a key","Query counters from the base table and filter in application code"],"exampleFix":"// before\nCREATE MATERIALIZED VIEW mv AS SELECT pk, hits FROM counters_base WHERE pk IS NOT NULL AND hits IS NOT NULL PRIMARY KEY (pk, hits);\n// after\nCREATE MATERIALIZED VIEW mv AS SELECT pk, day, hits FROM counters_base WHERE pk IS NOT NULL AND day IS NOT NULL PRIMARY KEY (pk, day);","handlingStrategy":"validation","validationCode":"for (String c : primaryKeyCols) if (baseTable.getColumn(c).type.isCounter()) throw new IllegalArgumentException(\"Counter column in MV primary key: \" + c);","typeGuard":null,"tryCatchPattern":"try { session.execute(createMvStmt); } catch (InvalidQueryException e) { if (e.getMessage().contains(\"counter type is not supported\")) { /* remove counter from PRIMARY KEY */ } }","preventionTips":["Never include counter columns in view keys; key on regular columns","Separate counter tables from indexed/denormalized designs"],"tags":["cql","materialized-view","counter","primary-key"],"backgroundTag":"unsupported-operation","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"}