apache/cassandra · error · InvalidRequestException

Cannot use token relation when defining a materialized view

Error message

Cannot use token relation when defining a materialized view

What it means

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.

Source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateViewStatement.java:300

        if (!missingPrimaryKeyColumns.isEmpty())
        {
            throw ire("Cannot create materialized view '%s' without primary key columns %s from base table '%s'",
                      viewName, join(", ", transform(missingPrimaryKeyColumns, ColumnIdentifier::toString)), tableName);
        }

        Set<ColumnIdentifier> regularBaseTableColumnsInViewPrimaryKey = new HashSet<>(primaryKeyColumns);
        transform(table.primaryKeyColumns(), c -> c.name).forEach(regularBaseTableColumnsInViewPrimaryKey::remove);
        if (regularBaseTableColumnsInViewPrimaryKey.size() > 1)
        {
            throw ire("Cannot include more than one non-primary key column in materialized view primary key (got %s)",
                      join(", ", transform(regularBaseTableColumnsInViewPrimaryKey, ColumnIdentifier::toString)));
        }

        /*
         * Process WHERE clause
         */
        if (whereClause.containsTokenRelations())
            throw new InvalidRequestException("Cannot use token relation when defining a materialized view");

        if (whereClause.containsCustomExpressions())
            throw ire("WHERE clause for materialized view '%s' cannot contain custom index expressions", viewName);

        StatementRestrictions restrictions =
            new StatementRestrictions(state,
                                      StatementType.SELECT,
                                      table,
                                      IndexHints.NONE,
                                      whereClause,
                                      VariableSpecifications.empty(),
                                      Collections.emptyList(),
                                      null,
                                      false,
                                      false,
                                      true,
                                      true);

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. 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).
  2. Restrict view partitions by a real column value (e.g. `WHERE region = 'us'`) rather than by token range.
  3. Do token-range filtering in the application when querying, not in the view definition.

Example fix

-- before
CREATE MATERIALIZED VIEW ks.v AS SELECT * FROM ks.t WHERE TOKEN(pk) > -9223372036854775808 AND x IS NOT NULL PRIMARY KEY (x, pk);

-- after
CREATE MATERIALIZED VIEW ks.v AS SELECT * FROM ks.t WHERE x IS NOT NULL PRIMARY KEY (x, pk);
Defensive patterns

Strategy: validation

Validate before calling

if (viewWhereClause.toUpperCase().contains("TOKEN("))
    throw new IllegalArgumentException("TOKEN() relations are not allowed in MV WHERE clauses");

Try / catch

try { session.execute(viewDdl); }
catch (InvalidQueryException e) {
  if (e.getMessage().contains("token relation"))
      throw new IllegalArgumentException("rewrite the view WHERE clause without TOKEN()", e);
  throw e;
}

Prevention

When it happens

Trigger: `CREATE MATERIALIZED VIEW ... FROM base WHERE TOKEN(pk) >= ...` — any WHERE clause calling TOKEN() when defining a view.

Common situations: Copying partition-scan filters (used in SELECTs for paging) into a view definition; generated DDL that includes token-based shard filters.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/832064bad22dd38e. Report an issue: GitHub.