{"record":{"id":"73788973a19574ac","repo":"apache/cassandra","slug":"cannot-use-selection-function-s-on-primary-key-pa","errorCode":null,"errorMessage":"Cannot use selection function %s on PRIMARY KEY part %s","messagePattern":"Cannot use selection function (.+?) on PRIMARY KEY part (.+?)","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/selection/Selectable.java","lineNumber":321,"sourceCode":"        {\n            this.column = column;\n            this.selectable = selectable;\n            this.kind = kind;\n        }\n\n        @Override\n        public String toString()\n        {\n            return kind.name + \"(\" + selectable + \")\";\n        }\n\n        public Selector.Factory newSelectorFactory(TableMetadata table,\n                                                   AbstractType<?> expectedType,\n                                                   List<ColumnMetadata> defs,\n                                                   VariableSpecifications boundNames)\n        {\n            if (column.isPrimaryKeyColumn())\n                throw new InvalidRequestException(\n                        String.format(\"Cannot use selection function %s on PRIMARY KEY part %s\",\n                                      kind.name,\n                                      column.name));\n\n            Selector.Factory factory = selectable.newSelectorFactory(table, expectedType, defs, boundNames);\n            boolean isMultiCell = factory.getColumnSpecification(table).type.isMultiCell();\n\n            return WritetimeOrTTLSelector.newFactory(factory, addAndGetIndex(column, defs), kind, isMultiCell);\n        }\n\n        @Override\n        public AbstractType<?> getExactTypeIfKnown(String keyspace)\n        {\n            AbstractType<?> type = kind.returnType;\n            return column.type.isMultiCell() && !kind.aggregatesMultiCell() ? ListType.getInstance(type, false) : type;\n        }\n\n        @Override","sourceCodeStart":303,"sourceCodeEnd":339,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/selection/Selectable.java#L303-L339","documentation":"Selection functions of certain kinds (e.g. writetime, ttl, ttl-like wrappers) cannot be applied to columns that are part of the primary key, because primary key columns have no per-row writetime/ttl cells to read. The factory refuses to build the selector.","triggerScenarios":"SELECT writetime(pk_col) FROM t or TTL(clustering_col) where the wrapped column belongs to the PRIMARY KEY.","commonSituations":"Users probe write timestamps of partition/clustering keys; Cassandra never stores writetime/ttl for primary key columns, so the query is rejected at prepare time.","solutions":["Remove the selection function from the primary key column","Apply the function to a regular (non-key) column","If you need key write history, model it in a separate table with the key as a value column"],"exampleFix":"// before\nSELECT writetime(pk) FROM t;\n// after\nSELECT writetime(value) FROM t;","handlingStrategy":"validation","validationCode":"Set<String> pkCols = table.primaryKeyColumns().stream().map(ColumnMetadata::getName).collect(toSet());\nif (pkCols.contains(targetColumn)) throw new IllegalArgumentException(\"writetime/ttl not allowed on PK column\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never wrap primary key columns in writetime()/ttl()","Check ColumnMetadata.isPrimaryKeyColumn() when generating queries dynamically","Keep key-vs-value column awareness in query builders"],"tags":["cql","primary-key","writetime"],"backgroundTag":"unsupported-operation","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}