{"record":{"id":"0b4d0367990ec372","repo":"apache/cassandra","slug":"this-table-currently-does-not-support-the-complex","errorCode":null,"errorMessage":"This table currently does not support the complex partial partition key filters implied for the underlying table","messagePattern":"This table currently does not support the complex partial partition key filters implied for the underlying table","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/virtual/RemoteToLocalVirtualTable.java","lineNumber":418,"sourceCode":"            RowFilter commonRowFilter = rowFilter;\n            if (commonPrefixLength > 0)\n            {\n                commonRowFilter = copy(commonRowFilter);\n                for (int i = 0 ; i < commonPrefixLength ; ++i)\n                    commonRowFilter.add(pks.get(i), Operator.EQ, starts[i]);\n            }\n\n            Operator lastStartOp = start.isInclusive() ? Operator.GTE : Operator.GT;\n            Operator lastEndOp = end.isInclusive() ? Operator.LTE : Operator.LT;\n            if (commonPrefixLength == Math.max(minCount, maxCount - 1))\n            {\n                // can simply add our remaining filters and continue on our way\n                addExpressions(commonRowFilter, pks, commonPrefixLength, starts, Operator.GTE, lastStartOp);\n                addExpressions(commonRowFilter, pks, commonPrefixLength, ends, Operator.LTE, lastEndOp);\n                return List.of(new Request(DataRange.allData(local.partitioner), commonRowFilter, columnFilter));\n            }\n\n            throw new InvalidRequestException(\"This table currently does not support the complex partial partition key filters implied for the underlying table\");\n        }\n\n        ByteBuffer[] startBuffers = start.getBufferArray();\n        PartitionPosition startBound;\n        if (start.size() == 0) startBound = local.partitioner.getMinimumToken().minKeyBound();\n        else if (pkCount == 1) startBound = local.partitioner.decorateKey(startBuffers[0]);\n        else startBound = local.partitioner.decorateKey(CompositeType.build(ByteBufferAccessor.instance, Arrays.copyOf(startBuffers, pkCount)));\n\n        ByteBuffer[] endBuffers = end.getBufferArray();\n        PartitionPosition endBound;\n        if (end.size() == 0) endBound = local.partitioner.getMinimumToken().maxKeyBound();\n        else if (pkCount == 1) endBound = local.partitioner.decorateKey(endBuffers[0]);\n        else endBound = local.partitioner.decorateKey(CompositeType.build(ByteBufferAccessor.instance, Arrays.copyOf(endBuffers, pkCount)));\n\n        AbstractBounds<PartitionPosition> bounds = AbstractBounds.bounds(startBound, start.isEmpty() || start.size() > pkCount || start.isInclusive(),\n                                                                         endBound, end.isEmpty() || end.size() > pkCount || end.isInclusive());\n        boolean hasSlices = start.size() > pkCount || end.size() > pkCount;\n        if (!hasSlices)","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/virtual/RemoteToLocalVirtualTable.java#L400-L436","documentation":"Even with partial PK bounds allowed, rebind() can only handle simple cases where start/end bounds share a common prefix and can be lowered into row-filter expressions. Complex interleaved or mismatched partial bounds (e.g. start specifies col1+col2, end only col1 with differing tails) cannot be expressed as a row filter, so it throws InvalidRequestException.","triggerScenarios":"Partial partition key bounds on the underlying table where the start and end bounds have incompatible shapes beyond the common prefix — detected after commonPrefixLength computation when neither the full-prefix nor simple cases apply.","commonSituations":"Range queries over a composite partition key where each bound restricts a different number of PK columns; tooling generating arbitrary clustering/pk bounds; mixed inclusive/exclusive bounds on partial keys.","solutions":["Make both bounds specify the same, full set of partition key columns.","Simplify the query to equality on the partition key so a single remote read partition is produced.","Split the query into several fully-bounded queries covering the desired range.","Filter the extra dimension client-side after fetching full partitions."],"exampleFix":"// before\nSELECT * FROM vt WHERE pk1 > 'a';              -- only one bound, partial\n// after\nSELECT * FROM vt WHERE pk1 >= 'a' AND pk1 <= 'b' AND pk2 >= 0 AND pk2 <= 999;","handlingStrategy":"validation","validationCode":"// Reject mismatched partial bounds up front\nif (startCols != endCols || (startCols > 0 && startCols < pkCount))\n    throw new IllegalArgumentException(\"Use equal, full partition key bounds on both sides\");","typeGuard":null,"tryCatchPattern":"try { session.execute(query); }\ncatch (InvalidRequestException e) {\n    if (e.getMessage().contains(\"complex partial partition key filters\"))\n        // split into fully-bounded queries\n}\n","preventionTips":["Use symmetric bounds: same columns on start and end","Prefer full partition key equality over ranges","Split complex ranges into multiple exact-key queries","Keep composite partition key queries simple"],"tags":["cassandra","virtual-table","partition-key","unsupported-operation"],"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"}