You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Cassandra: paging a Query on a GSI with two HASH attributes reads the second HASH attribute as the sort key #673
On the Cassandra backend, a Query with an ExclusiveStartKey on a GSI whose key schema has two HASH attributes and one RANGE attribute reads the cursor's sort key value from the wrong attribute. crates/storage-cassandra/src/data/query.rs takes query_key_schema[1] as the sort key (line 234 on main, line 264 on #429). For HASH h1, h2 and RANGE r that is h2, so page 2 starts from h2's value instead of r's.
Reproduction
main at 3051e50, dev build with the Cassandra backend, cassandra:4.1 with PasswordAuthenticator. Table key PK (S). GSI two-hash with HASH h1 (S) and h2, RANGE r (N), projection ALL. Five items, p1 to p5, all with h1 = "1", and r = 1, 2, 3, 3, 3. Each request sets Limit: 2 and passes the previous page's LastEvaluatedKey as ExclusiveStartKey. All five items were in the index before the first page.
h2 defined as N, every item at h2 = 0:
key condition
page 1
page 2
later pages
h1 = :x AND h2 = :y
p1, p2
p1, p2
pages 3 to 5 return p1, p2 again
h1 = :x AND h2 = :y AND r > :z (:z = 0)
p1, p2
500
h1 = :x AND h2 = :y AND r = :z (:z = 3)
p3, p4
500
Page 1's LastEvaluatedKey for the first query is {"PK": {"S": "p2"}, "h1": {"S": "1"}, "h2": {"N": "0"}, "r": {"N": "2"}}. Page 2 repeats p1 and p2 because the cursor compares r with 0, the value of h2.
h2 defined as S, every item at h2 = "2": page 2 of each of the three queries answers 500, and the server logs storage internal error internal_error=sort key type mismatch, because the S value of h2 is parsed as the N sort key.
SQLite and PostgreSQL on the same commit page the h2 N table correctly: p1, p2, then p3, p4, then p5, and p3, p4 then p5 for r = :z.
The 500 with a condition on r also happens with one HASH attribute
The same items on a GSI with HASH h1 and RANGE r page correctly for h1 = :x (p1, p2, then p3, p4, then p5). Page 2 still answers 500 for h1 = :x AND r > :z and for h1 = :x AND r = :z. The server logs these Cassandra errors from the cursor's same_sk query:
r > :z: Column "sk_n" cannot be restricted by both an equality and an inequality relation
r = :z: sk_n cannot be restricted by more than one relation if it includes an Equal
So on Cassandra, a key condition on the RANGE attribute of a GSI cannot be combined with an ExclusiveStartKey, whatever the number of HASH attributes. That part may need its own issue.
Expected
Page 2 continues after the last item of page 1, as on SQLite and PostgreSQL: the cursor reads the RANGE attribute's value from the ExclusiveStartKey, and a key condition on the RANGE attribute and the cursor are applied together.
Activity