{"record":{"id":"a1ef0b7ae7b2ffa2","repo":"apache/cassandra","slug":"cannot-be-used-in-comparisons-so-cannot-be-used-a","errorCode":null,"errorMessage":"cannot be used in comparisons, so cannot be used as a clustering column","messagePattern":"cannot be used in comparisons, so cannot be used as a clustering column","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/marshal/AbstractType.java","lineNumber":827,"sourceCode":"    /**\n     * This must be overriden by subclasses if necessary so that for any\n     * AbstractType, this == TypeParser.parse(toString()).\n     *\n     * Note that for backwards compatibility this includes the full classname.\n     * For CQL purposes the short name is fine.\n     */\n    @Override\n    public String toString()\n    {\n        return getClass().getName();\n    }\n\n    public void checkComparable()\n    {\n        switch (comparisonType)\n        {\n            case NOT_COMPARABLE:\n                throw new IllegalArgumentException(this + \" cannot be used in comparisons, so cannot be used as a clustering column\");\n        }\n    }\n\n    public final AssignmentTestable.TestResult testAssignment(String keyspace, ColumnSpecification receiver)\n    {\n        return testAssignment(receiver.type);\n    }\n\n    @Override\n    public AbstractType<?> getCompatibleTypeIfKnown(String keyspace)\n    {\n        return this;\n    }\n\n    /**\n     * @return A fixed, serialized value to be used when the column is masked, to be returned instead of the real value.\n     */\n    public ByteBuffer getMaskedValue()","sourceCodeStart":809,"sourceCodeEnd":845,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/marshal/AbstractType.java#L809-L845","documentation":"checkComparable throws IllegalArgumentException when the type's comparisonType is NOT_COMPARABLE, because clustering columns require an orderable (comparable) type. This is a schema-time sanity check, not a runtime data error.","triggerScenarios":"Declaring a CREATE TABLE whose clustering column (or a partition key component validated via this path) uses a non-comparable type — e.g. a custom type with ComparisonType.NOT_COMPARABLE.","commonSituations":"Custom AbstractType implementations that never set a comparisonType; schema migration attempts to add such a type as a clustering key; copy-pasted type definitions from dynamic composite usage.","solutions":["Use a comparable type (text, int, uuid, etc.) for the clustering column.","If using a custom type, implement/declare a proper ComparisonType (e.g. ComparisonType.CUSTOM with a valid compareCustom).","Move the non-comparable data into a regular column instead of the clustering key."],"exampleFix":"-- before\nCREATE TABLE t (k int, c SomeNonComparableType, PRIMARY KEY (k, c));\n-- after\nCREATE TABLE t (k int, c text, PRIMARY KEY (k, c));","handlingStrategy":"try-catch","validationCode":"AbstractType<?> t = ...;\nt.checkComparable(); // call at startup/schema-load time, not at CREATE TABLE time","typeGuard":"boolean isClusteringSafe(AbstractType<?> t) { try { t.checkComparable(); return true; } catch (IllegalArgumentException e) { return false; } }","tryCatchPattern":"catch (IllegalArgumentException e) { throw new SchemaException(\"clustering column type not comparable: \" + e.getMessage()); }","preventionTips":["Call checkComparable() in custom AbstractType tests before shipping.","Restrict clustering columns to built-in comparable types.","For custom types, always set a proper ComparisonType in the constructor."],"tags":["schema","validation","clustering-column"],"backgroundTag":"schema-validation-failed","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"}