{"record":{"id":"781d75f938ac91fe","repo":"apache/cassandra","slug":"custom-index-expressions-cannot-be-used-in-where-c","errorCode":null,"errorMessage":"Custom index expressions cannot be used in WHERE clauses for UPDATE or DELETE statements","messagePattern":"Custom index expressions cannot be used in WHERE clauses for UPDATE or DELETE statements","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java","lineNumber":1428,"sourceCode":"         * Creates the restrictions.\n         *\n         * @param metadata the table meta data\n         * @param boundNames the bound names\n         * @param operations the column operations\n         * @param where the where clause\n         * @param conditions the conditions\n         * @return the restrictions\n         */\n        protected StatementRestrictions newRestrictions(ClientState state,\n                                                        TableMetadata metadata,\n                                                        VariableSpecifications boundNames,\n                                                        Operations operations,\n                                                        WhereClause where,\n                                                        Conditions conditions,\n                                                        Object owner)\n        {\n            if (where.containsCustomExpressions())\n                throw new InvalidRequestException(CUSTOM_EXPRESSIONS_NOT_ALLOWED);\n\n            boolean applyOnlyToStaticColumns = appliesOnlyToStaticColumns(operations, conditions);\n            return new StatementRestrictions(state, type, metadata, IndexHints.NONE, where, boundNames, Collections.emptyList(), owner, applyOnlyToStaticColumns, false, false);\n        }\n\n        public List<ColumnCondition.Raw> getConditions()\n        {\n            return conditions;\n        }\n    }\n\n    private static final Constants.Value ONE = new Constants.Value(ByteBufferUtil.bytes(1));\n\n    public SelectStatement createSelectForTxn()\n    {\n        // TODO: get working with static-only updates that don't specify any/all primary key columns\n        Preconditions.checkState(getRestrictions().hasAllPrimaryKeyColumnsRestrictedByEqualities());\n        Selection selection = Selection.forColumns(metadata, Lists.newArrayList(requiresRead), false);","sourceCodeStart":1410,"sourceCodeEnd":1446,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java#L1410-L1446","documentation":"In ModificationStatement's restrictions builder, if the WHERE clause of an UPDATE or DELETE contains custom index expressions (e.g. expr(idx, ...)), this InvalidRequestException is thrown. Custom index expressions are only permitted in SELECT statements, never in data-modifying statements.","triggerScenarios":"UPDATE ... WHERE expr(my_index, col) = ... or DELETE with a custom-index expression in the WHERE clause.","commonSituations":"Copying a SELECT's WHERE clause into an UPDATE/DELETE; ORM/query builders emitting index expressions generically.","solutions":["Remove the custom index expression and identify target rows via primary-key columns instead.","Rewrite as a SELECT to find the keys first, then issue an UPDATE/DELETE on those keys.","Reconsider the data model so the target rows are addressable by their primary key."],"exampleFix":"// before\nDELETE FROM t WHERE expr(custom_idx, tags) = 'x';\n// after\nSELECT pk FROM t WHERE expr(custom_idx, tags) = 'x';\nDELETE FROM t WHERE pk = <found key>;","handlingStrategy":"validation","validationCode":"if (statementType != SELECT && whereClause.containsCustomIndexExpression()) throw new IllegalArgumentException(\"custom index expressions only allowed in SELECT\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never reuse SELECT WHERE clauses verbatim for UPDATE/DELETE","Address target rows by primary key in mutations","Audit ORM/query builders for expr() emission in mutations"],"tags":["cql","custom-index","where-clause"],"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"}