{"record":{"id":"832064bad22dd38e","repo":"apache/cassandra","slug":"cannot-use-token-relation-when-defining-a-material","errorCode":null,"errorMessage":"Cannot use token relation when defining a materialized view","messagePattern":"Cannot use token relation when defining a materialized view","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/CreateViewStatement.java","lineNumber":300,"sourceCode":"        if (!missingPrimaryKeyColumns.isEmpty())\n        {\n            throw ire(\"Cannot create materialized view '%s' without primary key columns %s from base table '%s'\",\n                      viewName, join(\", \", transform(missingPrimaryKeyColumns, ColumnIdentifier::toString)), tableName);\n        }\n\n        Set<ColumnIdentifier> regularBaseTableColumnsInViewPrimaryKey = new HashSet<>(primaryKeyColumns);\n        transform(table.primaryKeyColumns(), c -> c.name).forEach(regularBaseTableColumnsInViewPrimaryKey::remove);\n        if (regularBaseTableColumnsInViewPrimaryKey.size() > 1)\n        {\n            throw ire(\"Cannot include more than one non-primary key column in materialized view primary key (got %s)\",\n                      join(\", \", transform(regularBaseTableColumnsInViewPrimaryKey, ColumnIdentifier::toString)));\n        }\n\n        /*\n         * Process WHERE clause\n         */\n        if (whereClause.containsTokenRelations())\n            throw new InvalidRequestException(\"Cannot use token relation when defining a materialized view\");\n\n        if (whereClause.containsCustomExpressions())\n            throw ire(\"WHERE clause for materialized view '%s' cannot contain custom index expressions\", viewName);\n\n        StatementRestrictions restrictions =\n            new StatementRestrictions(state,\n                                      StatementType.SELECT,\n                                      table,\n                                      IndexHints.NONE,\n                                      whereClause,\n                                      VariableSpecifications.empty(),\n                                      Collections.emptyList(),\n                                      null,\n                                      false,\n                                      false,\n                                      true,\n                                      true);\n","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/CreateViewStatement.java#L282-L318","documentation":"Materialized view WHERE clauses cannot contain token relations (`TOKEN(...)` comparisons). The MV base-table filter must translate to normal column restrictions, and token expressions are not supported in view definitions, so `whereClause.containsTokenRelations()` triggers InvalidRequestException.","triggerScenarios":"`CREATE MATERIALIZED VIEW ... FROM base WHERE TOKEN(pk) >= ...` — any WHERE clause calling TOKEN() when defining a view.","commonSituations":"Copying partition-scan filters (used in SELECTs for paging) into a view definition; generated DDL that includes token-based shard filters.","solutions":["Remove the TOKEN(...) relation from the view WHERE clause and filter on actual columns instead (e.g. `col IS NOT NULL` or column value predicates).","Restrict view partitions by a real column value (e.g. `WHERE region = 'us'`) rather than by token range.","Do token-range filtering in the application when querying, not in the view definition."],"exampleFix":"-- before\nCREATE MATERIALIZED VIEW ks.v AS SELECT * FROM ks.t WHERE TOKEN(pk) > -9223372036854775808 AND x IS NOT NULL PRIMARY KEY (x, pk);\n\n-- after\nCREATE MATERIALIZED VIEW ks.v AS SELECT * FROM ks.t WHERE x IS NOT NULL PRIMARY KEY (x, pk);","handlingStrategy":"validation","validationCode":"if (viewWhereClause.toUpperCase().contains(\"TOKEN(\"))\n    throw new IllegalArgumentException(\"TOKEN() relations are not allowed in MV WHERE clauses\");","typeGuard":null,"tryCatchPattern":"try { session.execute(viewDdl); }\ncatch (InvalidQueryException e) {\n  if (e.getMessage().contains(\"token relation\"))\n      throw new IllegalArgumentException(\"rewrite the view WHERE clause without TOKEN()\", e);\n  throw e;\n}","preventionTips":["Validate MV WHERE clauses in app-side DDL builders: reject TOKEN( substrings","Filter views by real column predicates only","Move token-range filtering to query time, not schema time"],"tags":["cassandra","materialized-view","where-clause","token"],"backgroundTag":"invalid-argument-value","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"}