mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-24 10:30:38 +00:00
" `function_call` AST nodes are created for each function with side effects in a CQL query, i.e. non-deterministic functions (`uuid()`, `now()` and some others timeuuid-related). These nodes are evaluated either when a query itself is executed or query restrictions are computed (e.g. partition/clustering key ranges for LWT requests). We need to cache the calls since otherwise when handling a `bounce_to_shard` request for an LWT query, we can possibly enter an infinite bouncing loop (in case a function is used to calculate partition key ranges for a query), since the results can be different each time. Furthermore, we don't support bouncing more than one time. Returning `bounce_to_shard` message more than one time will result in a crash. Caching works only for LWT statements and only for the function calls that affect partition key range computation for the query. `variable_specifications` class is renamed to `prepare_context` and generalized to record information about each `function_call` AST node and modify them, as needed: * Check whether a given function call is a part of partition key statement restriction. * Assign ids for caching if above is true and the call is a part of an LWT statement. There is no need to include any kind of statement identifier in the cache key since `query_options` (which holds the cache) is limited to a single statement, anyway. Function calls are indexed by the order in which they appear within a statement while parsing. There is no need to include any kind of statement identifier to the cache key since `query_options` (which holds the cache) is limited to a single statement, anyway. Note that `function_call::raw` AST nodes are not created for selection clauses of a SELECT statement hence they can only accept only one of the following things as parameters: * Other function calls. * Literal values. * Parameter markers. In other words, only parameters that can be immediately reduced to a byte buffer are allowed and we don't need to handle database inputs to non-pure functions separately since they are not possible in this context. Anyhow, we don't even have a single non-pure function that accepts arguments, so precautions are not needed at the moment. Add a test written in `cql-pytest` framework to verify that both prepared and unprepared lwt statements handle `bounce_to_shard` messages correctly in such scenario. Fixes: #8604 Tests: unit(dev, debug) NOTE: the patchset uses `query_options` as a container for cached values. This doesn't look clean and `service::query_state` seems to be a better place to store them. But it's not forwarded to most of the CQL code and would mean that a huge number of places would have to be amended. The series presents a trade-off to avoid forwarding `query_state` everywhere (but maybe it's the thing that needs to be done, nonetheless). " * 'lwt_bounce_to_shard_cached_fn_v6' of https://github.com/ManManson/scylla: cql-pytest: add a test for non-pure CQL functions cql3: cache function calls evaluation for non-deterministic functions cql3: rename `variable_specifications` to `prepare_context`