CQL arithmetic makes operand types part of the query
Cassandra 4.0 supports arithmetic in CQL, but return types and prepared-parameter inference affect the result. A compaction-progress query shows why an explicit decimal operand matters.
A percentage expression can return zero for most of an operation's lifetime even when the database is calculating exactly what its type rules require. Cassandra 4.0's arithmetic support makes that problem visible in CQL. The order of operations matters, and so does the type selected for each intermediate result. Changing the final expression cannot recover a fraction already discarded by integer division.
Benjamin Lerer's December 21 explanation describes arithmetic introduced in 4.0. The event is an explanation of existing release behavior, not the introduction of a new December database version. CQL supports addition, subtraction, multiplication, division and remainder for numbers, as well as negation. It also supports adding or subtracting durations for dates and timestamps.
I appreciate query-level arithmetic when it makes an operational result easier to inspect. Cassandra's value for demanding distributed applications does not require moving every calculation into the database. A small expression is useful when its type and meaning are clear, especially in the operational views added with 4.0.
Integer division changes a progress calculation
The release's virtual-table documentation describes system_views.sstable_tasks. It exposes currently running work, including progress and total values with a unit. This view remains node-local. The arithmetic article uses those values to calculate compaction completion. Multiplying progress by one hundred before dividing preserves more information than dividing first when both operands are integers.
The expression (progress / total) * 100 performs the division before multiplication. Both task columns are bigint, so the division produces a bigint. For positive progress below total, the fractional quotient is lost. Multiplying the resulting zero by one hundred still returns zero. At completion, a quotient of one becomes one hundred after multiplication.
That distinction is worth stating because the article's description of the complete expression as zero or one compresses two separate steps. Zero or one describes the integer quotient in the completion example. The final multiplication changes the one to one hundred. The practical lesson follows from the documented type rule and expression evaluation order.
The arithmetic article shows how a decimal operand changes the calculation. A query using that technique is:
SELECT keyspace_name, table_name,
(progress * (decimal) 100) / total AS percentage_of_completion
FROM system_views.sstable_tasks
WHERE kind = 'compaction'
ALLOW FILTERING;
The decimal type hint applies to the literal before multiplication. Under the documented numeric rules, Cassandra makes operations between decimal and bigint produce decimal results. The expression therefore avoids the integer quotient responsible for the earlier loss of a fraction. Its result is still a percentage derived from reported progress, not an estimate of time remaining.
Literals and bind parameters need types
An unadorned integer literal does not always force arbitrary-precision arithmetic. Cassandra considers int, bigint or varint according to which can hold the literal's value. The article identifies 100 as an int in the progress calculation. A floating literal such as 100.0 can lead to a double result in that context.
Prepared statements introduce another source of uncertainty. A bind marker has no concrete value at preparation time, so Cassandra must infer a compatible type from the surrounding expression. The article uses a table with an integer partition key and a tinyint clustering column to show why the result type sometimes identifies the operands and sometimes does not.
For the tinyint column, a sum with a literal and bind marker can resolve because the required result constrains the operand types. For an integer partition key, several operand types can lead to an integer result. The preparation can fail with an ambiguous-operation error even though a human has a particular parameter type in mind.
The documented solution is a type hint on the bind marker. The same approach applies to literal selection. A hint provides information before overload selection, while CAST converts a typed expression. The article demonstrates casting the progress column to decimal as another way to make the calculation use decimal arithmetic.
Arithmetic preserves the scope of the underlying query
The operators have conventional precedence groups. Multiplication, division and remainder precede addition and subtraction. Within the same precedence group, evaluation proceeds left to right. Parentheses can override that ordering. These rules explain why a mathematical rearrangement that appears equivalent may produce a different integer result.
Date arithmetic supplies another concise use. The article queries a sensor table by its partition key and a day calculated as currentdate() - 1d. Its schema groups readings by sensor and day, so the expression computes a concrete value for the day component of the key. It does not provide an unrestricted scan across every time-series partition.
I find the examples strongest when the query's meaning stays explicit. A decimal percentage describes current reported task progress. A date expression selects the day used in the partition restriction. Arithmetic reduces application-side calculation for these cases while leaving the database's query scope and operand-type rules in force.