Branimir Lambov created CASSANDRA-21856:
-------------------------------------------

             Summary: Decimal type has inconsistent behaviour when used as a key
                 Key: CASSANDRA-21856
                 URL: https://issues.apache.org/jira/browse/CASSANDRA-21856
             Project: Apache Cassandra
          Issue Type: Bug
          Components: CQL/Semantics
            Reporter: Branimir Lambov


Decimals may have different representations that compare equal, e.g. 1.5 and 
1.500. Cassandra's treatment of these values is very inconsistent. When we 
write both, depending on what kind of key they are, we can see:

Partition keys
 * 1.5 and 1.500 are two separate partitions, because the token is computed 
from the raw bytes.
 * = and IN only match the exact bytes, so pk = 1.50 finds nothing.
 * pk >= 1.50 AND pk <= 1.50 ALLOW FILTERING returns both partitions.
 * DELETE ... WHERE pk = 1.500 leaves the 1.5 partition in place.

Clustering keys
 * The two writes are one row, and every query finds it with any of the three 
forms (=, IN, slices, ALLOW FILTERING). Deleting 1.500, by point or by range, 
deletes the row.
 * Which form comes back depends on history.
 * In the memtable or after one flush, it’s the first-written form, 1.5.
 * In the split state it’s 1.500 for most queries. The >= 1.50 AND <= 1.50 
slice and the ALLOW FILTERING queries return 1.5.
 * After compaction the version ends up chosen randomly.

Map keys
 * The second write overwrites the first, leaving one entry. m[x], slices, 
CONTAINS KEY and m[x] = v filtering all find it with any form. Deleting 
m[1.500] deletes m[1.5].
 * The last-written form is returned, which is the opposite of clustering keys.

Legacy secondary index on regular column
 * v = 1.5 finds only the 1.5 row, v = 1.500 only the 1.500 row, and v = 1.50 
finds nothing, even with pk = 0.
 * Range queries need ALLOW FILTERING and then find both rows.
 * Without the index, v = 1.50 ALLOW FILTERING finds both, so adding the index 
changes the results.

SAI
 * SAI compares values, so any form finds every equal row, for exact and range 
queries alike.
 * This holds for regular columns, clustering columns and map keys.
 * Returned values come back as written.

 

These inconsistencies cause additional problems for trie memtables, where keys 
are normalized by the conversion to and from {{{}ByteComparable{}}}.

We need to find a way to make the behaviour consistent, e.g. by converting data 
in the CQL layer to its normalized form with no trailing 0s.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to