{"record":{"id":"ec4d33121b5b936f","repo":"apache/cassandra","slug":"ann-ordering-does-not-support-any-other-ordering","errorCode":null,"errorMessage":"ANN ordering does not support any other ordering","messagePattern":"ANN ordering does not support any other ordering","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java","lineNumber":553,"sourceCode":"\n    /**\n     * This is a hack to push ordering down to indexes.\n     * Indexes are selected based on RowFilter only, so we need to turn orderings into restrictions\n     * so they end up in the row filter.\n     *\n     * @param orderings orderings from the select statement\n     * @return the {@link RestrictionSet} with the added orderings\n     */\n    private RestrictionSet addOrderingRestrictions(List<Ordering> orderings, RestrictionSet restrictionSet)\n    {\n        List<Ordering> annOrderings = orderings.stream().filter(o -> o.expression.hasNonClusteredOrdering()).collect(Collectors.toList());\n\n        if (annOrderings.size() > 1)\n            throw new InvalidRequestException(\"Cannot specify more than one ANN ordering\");\n        else if (annOrderings.size() == 1)\n        {\n            if (orderings.size() > 1)\n                throw new InvalidRequestException(\"ANN ordering does not support any other ordering\");\n            Ordering annOrdering = annOrderings.get(0);\n            if (annOrdering.direction != Ordering.Direction.ASC)\n                throw new InvalidRequestException(\"Descending ANN ordering is not supported\");\n            SingleRestriction restriction = annOrdering.expression.toRestriction();\n            return restrictionSet.addRestriction(restriction);\n        }\n        return restrictionSet;\n    }\n\n    private void processPartitionKeyRestrictions(ClientState state, boolean hasQueriableIndex, boolean allowFiltering, boolean forView)\n    {\n        if (!type.allowPartitionKeyRanges())\n        {\n            checkFalse(partitionKeyRestrictions.isOnToken(),\n                       \"The token function cannot be used in WHERE clauses for %s statements\", type);\n\n            if (partitionKeyRestrictions.hasUnrestrictedPartitionKeyComponents())\n                throw invalidRequest(\"Some partition key parts are missing: %s\",","sourceCodeStart":535,"sourceCodeEnd":571,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java#L535-L571","documentation":"A single ANN ordering cannot be combined with any other ORDER BY expression (clustering order or another column ordering). When one non-clustered (ANN) ordering exists alongside other orderings, the statement is rejected.","triggerScenarios":"SELECT ... FROM table WHERE ... ORDER BY ann_of(v) : [...], some_clustering_col ASC — an ANN ordering plus any additional ordering in the same query.","commonSituations":"Users expect vector search results sorted first by similarity then by clustering column (tie-breaking) and add both orderings; vector search in Cassandra does not support secondary sort within the ANN scan.","solutions":["Remove the extra ORDER BY column and sort/tie-break results in the application.","Issue the ANN-only query and post-process client-side with the secondary sort.","If secondary sort semantics are required, restrict the result set first and sort in memory."],"exampleFix":"// before\nSELECT * FROM items ORDER BY ann_of(vec) : [0.1,0.2], created_at DESC;\n// after\nSELECT * FROM items ORDER BY ann_of(vec) : [0.1,0.2]; // sort by created_at client-side","handlingStrategy":"validation","validationCode":"if (hasAnnOrdering(orderings) && orderings.size() > 1)\n    throw new IllegalArgumentException(\"ANN ordering cannot be combined with other orderings\");","typeGuard":null,"tryCatchPattern":"try { session.execute(stmt); }\ncatch (InvalidRequestException e) {\n    if (e.getMessage().equals(\"ANN ordering does not support any other ordering\")) { /* strip secondary ORDER BY, sort client-side */ }\n    else throw e;\n}","preventionTips":["When adding an ANN ORDER BY, emit no other ordering terms.","Implement tie-breaking/sorting after fetching results.","Wrap query builders so ANN queries bypass generic ordering injection."],"tags":["cassandra","cql","ann","vector-search","ordering"],"backgroundTag":"conflicting-config-options","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"}