mirror of
https://github.com/scylladb/scylladb.git
synced 2026-05-31 03:56:42 +00:00
ScyllaDB has special counter columns for which atomic add/subtract operations like `SET a = a + 1` are allowed. Such operations have not been allowed on ordinary non-counter columns, as they would not be properly atomic - the read an the write are separate, and concurrent operations can have incorrect results. This patch makes it allowed to use such atomic add/subtract operations in **LWT** statements. For example UPDATE ... SET a = a - 7 IF a > 0 or UPDATE ... SET a = a + 1 IF a != NULL The row updated in the operation, and the updated column (`a`) should be initialized before the update. The example `SET a = a + 1 IF a != NULL` will fail the condition if `a` is not set. A different request `SET a = a + 1 IF EXISTS` will just leave `a` unset if it's unset (NULL + 1 is NULL, this is SQL's null propagation rules). This add/subtract operations is allowed on any numeric (integer or floating point) column. The ability of LWT to fetch the old values of a column and use it to calculate the new value has long been available in our internal CAS implementation - and has been in use for years in Alternator - but until this patch it was not exposed in CQL's LWT. This series does not add new syntax to CQL - the "SET a = a + b" and "SET a = a - b" syntax already existed for counters, and we just allow the same syntax for non- counters. However, the series does add a bit of machinery that will allow us to easily support more general expressions in the future. In particular, this series implements the addition, subtraction, and unary-minus operators for expressions, and adds the machinery needed to run **any** expression in "SET a = expr()", using existing row values fetched by LWT. This is a new Scylla-only feature that does not exist in Cassandra. Fixes #10568 Refs #22918 ("Support arithmetic operators"), SCYLLADB-1576 ("Decimal arithmetic operations OOM") This is is a new feature, so normally would not be backported. Closes scylladb/scylladb#29939 * github.com:scylladb/scylladb: cql: atomic add/subtract operations with LWT cql3: let constants::setter evaluate expressions using prefetched row data cql3/expr: add NEG unary operator for numeric negation cql3/expr: add SUB binary operator for numeric subtraction cql3/expr: add ADD binary operator for numeric addition types: add is_arithmetic() method for types