Commit Graph

3228 Commits

Author SHA1 Message Date
Kamil Braun
e6942d31d3 Merge 'query processor code cleanup' from Gleb
The series contains mostly cleanups for query processor and no functional
change. The last patch is a small cleanup for the storage_proxy.

* 'qp-cleanup' of https://github.com/gleb-cloudius/scylla:
  storage_proxy: remove unused variable
  client_state: co-routinise has_column_family_access function
  query_processor: get rid of internal_state and create individual query_satate for each request
  cql3: move validation::validate_column_family from client_state::has_column_family_access
  client_state: drop unneeded argument from has.*access functions
  cql3: move check for dropping cdc tables from auth to the drop statement code itself
  query_processor: co-routinise execute_prepared_without_checking_exception_message function
  query_processor: co-routinize execute_direct_without_checking_exception_message function
  cql3: remove empty statement::validate functions
  cql3: remove empty function validate_cluster_support
  cql3/statements: fix indentation and spurious white spaces
  query_processor: move statement::validate call into execute_with_params function
  query_processor: co-routinise execute_with_params function
  query_processor: execute statement::validate before each execution of internal query instead of only during prepare
  query_processor: get rid of shared internal_query_state
  query_processor: co-routinize execute_paged_internal function
  query_processor: co_routinize execute_batch_without_checking_exception_message function
  query_processor: co-routinize process_authorized_statement function
2023-06-23 10:32:57 +02:00
Kamil Braun
be5b61b870 Merge 'cql3: expr: break up expression.hh header' from Avi Kivity
It's very annoying to add a declaration to expression.hh and watch
the whole world get recompiled. Improve that by moving less-common
functions to a new header expr-utils.hh. Move the evaluation machinery
to a new header evaluate.hh. The remaining definitions in expression.hh
should not change as often, and thus cause less frequent recompiles.

Closes #14346

* github.com:scylladb/scylladb:
  cql3: expr: break up expression.hh header
  cql3: expr: restrictions.hh: protect against double inclusions
  cql3: constants: deinline
  cql3: statement_restrictions: deinline
  cql3: deinline operation::fill_prepare_context()
2023-06-23 10:19:28 +02:00
Nadav Har'El
0a1283c813 Merge 'cql3:statements:describe_statement: check pointer after casting to UDF/UDA' from Michał Jadwiszczak
There was a bug in describe_statement. If executing `DESC FUNCTION  <uda name>` or ` DESC AGGREGATE <udf name>`, Scylla was crashing because the function was found (`functions::find()` searches both UDFs and UDAs) but the function was bad and the pointer wasn't checked after cast.

Added a test for this.

Fixes: #14360

Closes #14332

* github.com:scylladb/scylladb:
  cql-pytest:test_describe: add test for filtering UDF and UDA
  cql3:statements:describe_statement: check pointer to UDF/UDA
2023-06-22 20:54:25 +03:00
Michał Jadwiszczak
d498451cdf cql3:statements:describe_statement: check pointer to UDF/UDA
While looking for specific UDF/UDA, result of
`functions::functions::find()` needs to be filtered out based on
function's type.

Fixes: #14360
2023-06-22 18:08:16 +02:00
Gleb Natapov
28f31bcbb1 query_processor: get rid of internal_state and create individual query_satate for each request
We want to put per-request field in query_satate, so make it unique for
each internal execution (it is unique for non internal once).
2023-06-22 15:26:20 +03:00
Avi Kivity
b858a4669d cql3: expr: break up expression.hh header
Adding a function declaration to expression.hh causes many
recompilations. Reduce that by:

 - moving some restrictions-related definitions to
   the existing expr/restrictions.hh
 - moving evaluation related names to a new header
   expr/evaluate.hh
 - move utilities to a new header
   expr/expr-utilities.hh

expression.hh contains only expression definitions and the most
basic and common helpers, like printing.
2023-06-22 14:21:03 +03:00
Avi Kivity
25c351a4f6 cql3: expr: restrictions.hh: protect against double inclusions
Add #pragma once. Right now it's safe as it only has declarations
(which can be repeated), but soon it will have a definition.
2023-06-22 14:19:43 +03:00
Avi Kivity
7302088274 cql3: constants: deinline
To reduce future header fan-in, deinline all non-trivial functions.
While these aer on the hot path, they can't be inlined anyway as they're
virtual, and they're quite heavy anyway.
2023-06-22 14:19:43 +03:00
Avi Kivity
6c0f8a73c5 cql3: statement_restrictions: deinline
Reduce future header fan-in by deinlining functions. These are
all on the prepare path.
2023-06-22 14:19:43 +03:00
Avi Kivity
3834a1fd7c cql3: deinline operation::fill_prepare_context()
To reduce operation.hh include fan-in, deinline fill_prepare_context().
It's not performance sensitive has it's on the prepare phase.
2023-06-22 14:19:43 +03:00
Gleb Natapov
4bad482e4b cql3: move validation::validate_column_family from client_state::has_column_family_access
Checking keyspace/table presence should not be part of authorization code
and it is not done consistently today.  For instance keyspace presence
is not checked in "alter keyspace" during authorization, but during
statement execution. Make it consistent.
2023-06-22 13:57:36 +03:00
Gleb Natapov
31bddb65c7 client_state: drop unneeded argument from has.*access functions
After previous patch we can drop db argument to most of has.*access
functions in the client_state.
2023-06-22 13:57:36 +03:00
Gleb Natapov
06bcce53b5 cql3: move check for dropping cdc tables from auth to the drop statement code itself
Checking if a table is CDC log and cannot be dropped should not be done
as part of authentication (this has nothing to do with auth), but in the
drop statement itself. Throwing unauthorized_exception is wrong as well,
but unfortunately it is enshrined with a test. Not sure if it is a good
idea to change it now.
2023-06-22 13:57:36 +03:00
Gleb Natapov
0820309c14 query_processor: co-routinise execute_prepared_without_checking_exception_message function 2023-06-22 13:57:36 +03:00
Gleb Natapov
818e72c029 query_processor: co-routinize execute_direct_without_checking_exception_message function 2023-06-22 13:57:36 +03:00
Gleb Natapov
45ce608117 cql3: remove empty statement::validate functions
There are a lot of empty overloads for the function so lets remove them
and use the one in the parent class instead.
2023-06-22 13:57:33 +03:00
Gleb Natapov
3cd9b8548d cql3: remove empty function validate_cluster_support 2023-06-22 13:52:52 +03:00
Gleb Natapov
8c2c4a6a78 cql3/statements: fix indentation and spurious white spaces 2023-06-22 13:49:11 +03:00
Gleb Natapov
d75a41ba30 query_processor: move statement::validate call into execute_with_params function
It is called before any call to the function anyway, so lets do it once instead.
2023-06-22 13:49:11 +03:00
Gleb Natapov
24e78059a5 query_processor: co-routinise execute_with_params function 2023-06-22 13:49:11 +03:00
Gleb Natapov
725fa5e0f3 query_processor: execute statement::validate before each execution of internal query instead of only during prepare
There is a discrepancy on how statement::validate is used. On a regular
path it is called before each execution, but on internal execution
path it is called only once during prepare. Such discrepancy make it
hard to reason what can and cannot be done during the call. Call it
uniformly before each execution. This allow validate to check a state that
can change after prepare.
2023-06-22 13:49:11 +03:00
Gleb Natapov
ce12a18135 query_processor: get rid of shared internal_query_state
internal_query_state was passed in shared_ptr from the java
translation times. It may be a regular c++ type with a lifetime
bound by the function execution it was created in.
2023-06-22 13:49:11 +03:00
Gleb Natapov
aabd05e2ef query_processor: co-routinize execute_paged_internal function 2023-06-22 13:49:11 +03:00
Gleb Natapov
64a67a59d6 query_processor: co_routinize execute_batch_without_checking_exception_message function 2023-06-22 13:49:11 +03:00
Gleb Natapov
c4ca24e636 query_processor: co-routinize process_authorized_statement function 2023-06-22 13:49:11 +03:00
Kamil Braun
23a60df92d Merge 'cql3: expr: simplify evaluate()' from Avi Kivity
Make evaluate()'s body more regular, then exploit it by
replacing the long list of branches with a lambda template.

Closes #14306

* github.com:scylladb/scylladb:
  cql3: expr: simplify evaluate()
  cql3: expr: standardize evaluate() branches to call do_evaluate()
  cql3: expr: rename evaluate(ExpressionElement) to do_evaluate()
2023-06-22 12:18:36 +02:00
Kamil Braun
563d466de1 Merge 'cql3: select_statement: coroutinize indexed statement's do_execute()' from Avi Kivity
Improves readability, and probably a little faster too.

Closes #14311

* github.com:scylladb/scylladb:
  cql3: select_statement: reindent indexed_table_select_statement::do_execute
  cql3: select_statement: simplify inner lambda in indexed_table_select_statement::do_execute()
  cql3: select_statement: coroutinize indexed_table_select_statement::do_execute()
2023-06-22 12:10:45 +02:00
Avi Kivity
32b27d6a08 cql3: expr: change evaluation_input vector components to take spans
Spans are slightly cleaner, slightly faster (as they avoid an indirection),
and allow for replacing some of the arguments with small_vector:s.

Closes #14313
2023-06-22 11:28:01 +02:00
Tomasz Grabiec
21198e8470 treewide: Replace dht::shard_of() uses with table::shard_of() / erm::shard_of()
dht::shard_of() does not use the correct sharder for tablet-based tables.
Code which is supposed to work with all kinds of tables should use erm::get_sharder().
2023-06-21 00:58:24 +02:00
Avi Kivity
453bbc1115 cql3: expr: improve error message when rejecting aggregation functions in illegal contexts
Fix a small grammatical error, and capitalize WHERE in accordance
with SQL tradition.

Closes #14288
2023-06-20 17:52:53 +03:00
Avi Kivity
77ff78328b cql3: select_statement: reindent indexed_table_select_statement::do_execute 2023-06-20 14:12:58 +03:00
Avi Kivity
218d9fe384 cql3: select_statement: simplify inner lambda in indexed_table_select_statement::do_execute()
The lambda is defined to return a coordinator_result<stop_iteration>,
but in fact only returns successful outcomes, never failures.

Change it to return a plain stop_iteration, so its callers don't have
to check for failure.
2023-06-20 14:11:36 +03:00
Avi Kivity
e5ed07e3e1 cql3: select_statement: coroutinize indexed_table_select_statement::do_execute()
Will lead to more readable code after a bit more prettifying. Also
has fewer allocations, though this isn't a hot path.
2023-06-20 13:51:50 +03:00
Botond Dénes
9e9636ef15 Merge 'cql3: select_statement: coroutinize and simplify do_execute()' from Avi Kivity
Split off do_execute() into a fast path and slow(ish) path, and
coroutinize the latter.

perf-simple-query shows no change in performance (which is
unsurprising since it picks the fast path which is essentially unchanged).

Closes #14246

* github.com:scylladb/scylladb:
  cql3: select_statement: reindent execute_without_checking_exception_message_aggregate_or_paged()
  cql3: select_statement: coroutinize execute_without_checking_exception_message_aggregate_or_paged()
  cql3: select_statement: split do_execute into fast-path and slow/slower paths
  cql3: select_statement: disambiguate execute() overloads
2023-06-20 08:02:07 +03:00
Avi Kivity
792c46c0f8 cql3: expr: simplify evaluate()
Now that all branches in the visitor are uniform and consist
of a single call to do_evaluate() overloads, we can simplify
by calling a lambda template that does just that.
2023-06-20 02:33:10 +03:00
Avi Kivity
66e0326385 cql3: expr: standardize evaluate() branches to call do_evaluate()
Extract the various snippets into do_evaluate() overloads. We'll
exploit this in the next patch.
2023-06-20 02:19:33 +03:00
Avi Kivity
b64eeefa35 cql3: expr: rename evaluate(ExpressionElement) to do_evaluate()
evaluate(expression) calls the various evaluate(ExpressionElement)
overloads to perform its work. However, if we add an ExpressionElement
and forget to implement its evaluate() overload, we'll end up in
with infinite recursion. It will be caught immediately, but better to
avoid it.

Also sprinkle static:s on do_evaluate() where missing.
2023-06-20 02:10:18 +03:00
Avi Kivity
7090f4c43b cql3: expr: evaluate() column_mutation_attribute
Enhance evaluation_inputs with timestamps and ttls, and use
them to evaluate writetime/ttl.

The data structure is compatible with the current way of doing
things (see result_set_builder::_timestamps, result_set_build::_ttls).
We use std::span<> instead of std::vector<> as it is more general
and a tiny bit faster.

The algorithm is taken from writetime_or_ttl_selector::add_input().
2023-06-18 22:41:09 +03:00
Nadav Har'El
97d444bbf7 Merge 'cql3/expression: implement evaluate(field_selection) ' from Jan Ciołek
Implement `expr:valuate()` for `expr::field_selection`.

`field_selection` is used to represent access to a struct field.
For example, with a UDT value:
```
CREATE TYPE my_type (a int, b int);
```
The expression `my_type_value.a` would be represented as a `field_selection`, which selects the field `a`.

Evaluating such an expression consists of finding the right element's value in a serialized UDT value and returning it.

Note that it's still not possible to use `field_selection` inside the `WHERE` clause. Enabling it would require changes to the grammar, as well as query planning, Current `statement_restrictions` just reacts with `on_internal_error` when it encounters a `field_selection`.
Nonetheless it's a step towards relaxing the grammar, and now it's finally possible to evaluate all kinds of prepared expressions (#12906)

Fixes: https://github.com/scylladb/scylladb/issues/12906

Closes #14235

* github.com:scylladb/scylladb:
  boost/expr_test: test evaluate(field_selection)
  cql3/expr: fix printing of field_selection
  cql3/expression: implement evaluate(field_selection)
  types/user: modify idx_of_field to use bytes_view
  column_identifer: add column_identifier_raw::text()
  types: add read_nth_user_type_field()
  types: add read_nth_tuple_element()
2023-06-18 11:08:25 +03:00
Pavel Emelyanov
900c609269 Merge 'Initialize query_processor early, without messaging_service or gossiper' from Kamil Braun
In https://github.com/scylladb/scylladb/pull/14231 we split `storage_proxy` initialization into two phases: for local and remote parts. Here we do the same with `query_processor`. This allows performing queries for local tables early in the Scylla startup procedure, before we initialize services used for cluster communication such as `messaging_service` or `gossiper`.

Fixes: #14202

As a follow-up we will simplify `system_keyspace` initialization, making it available earlier as well.

Closes #14256

* github.com:scylladb/scylladb:
  main, cql_test_env: start `query_processor` early
  cql3: query_processor: split `remote` initialization step
  cql3: query_processor: move `migration_manager&`, `forwarder&`, `group0_client&` to a `remote` object
  cql3: query_processor: make `forwarder()` private
  cql3: query_processor: make `get_group0_client()` private
  cql3: strongly_consistent_modification_statement: fix indentation
  cql3: query_processor: make `get_migration_manager` private
  tracing: remove `qp.get_migration_manager()` calls
  table_helper: remove `qp.get_migration_manager()` calls
  thrift: handler: move implementation of `execute_schema_command` to `query_processor`
  data_dictionary: add `get_version`
  cql3: statements: schema_altering_statement: move `execute0` to `query_processor`
  cql3: statements: pass `migration_manager&` explicitly to `prepare_schema_mutations`
  main: add missing `supervisor::notify` message
2023-06-16 17:41:08 +03:00
Kamil Braun
c212370cf1 cql3: query_processor: split remote initialization step
Pass `migration_manager&`, `forward_service&` and `raft_group0_client&`
in the remote init step which happens after the constructor.

Add a corresponding uninit remote step.
Make sure that any use of the `remote` services is finished before we
destroy the `remote` object by using a gate.

Thanks to this in a later commit we'll be able to move the construction
of `query_processor` earlier in the Scylla initialization procedure.
2023-06-16 14:29:59 +02:00
Kamil Braun
ec5b831c13 cql3: query_processor: move migration_manager&, forwarder&, group0_client& to a remote object
These services are used for performing distributed queries, which
require remote calls. As a preparation for 2-phase initialization of
`query_processor` (for local queries vs for distributed queries), move
them to a separate `remote` object which will be constructed in the
second phase.

Replace the getters for the different services with a single `remote()`
getter. Once we split the initialization into two phases, `remote()`
will include a safety protection.
2023-06-16 14:08:21 +02:00
Kamil Braun
c2fa6406ad cql3: query_processor: make forwarder() private 2023-06-16 13:45:59 +02:00
Kamil Braun
f616408a87 cql3: query_processor: make get_group0_client() private 2023-06-16 13:45:19 +02:00
Kamil Braun
db769c8eb3 cql3: strongly_consistent_modification_statement: fix indentation 2023-06-16 13:44:59 +02:00
Kamil Braun
2e441e17cf cql3: query_processor: make get_migration_manager private
After previous commits it's no longer used outside `query_processor`.
Also remove the `const` version - not needed for anything.

Use the getter instead of directly accessing `_mm` in `query_processor`
methods. Later we will put `_mm` in a separate object.
2023-06-16 13:44:14 +02:00
Jan Ciolek
ee660f2d61 cql3/expr: fix printing of field_selection
expression printing has two modes: debug and user.
The user mode should output standard CQL that can be
parsed back to an expression.
In debug mode there can be some additional information
that helps with debugging stuff.

The code for printing `field_selection` didn't distinguish
between user mode and debug mode. It just always printed
in debug mode, with extra parenthesis around the field selection.

Let's change it so that it emits valid CQL in user mdoe.

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2023-06-16 01:21:02 +02:00
Jan Ciolek
f79f3ea3ae cql3/expression: implement evaluate(field_selection)
Implement expr:valuate() for expr::field_selection.

`field_selection` is used to represent access to a struct field.
For example, with a UDT value:
```
CREATE TYPE my_type (a int, b int);
```
The expression `my_type_value.a` would be represented as
a field_selection, which selects the field 'a'.

Evaluating such an expression consists of finding the
right element's value in a serialized UDT value
and returning it.

Fixes: https://github.com/scylladb/scylladb/issues/12906

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2023-06-16 01:21:00 +02:00
Jan Ciolek
d8d5442db8 column_identifer: add column_identifier_raw::text()
I would like to be able to get a reference to the
string inside `column_identifer_raw`, but there was
no such function. There was only `to_string()`, which
copies the entire string, which is wasteful.

Let's add the method `text()`, which returns a reference
instead of a copy. `column_identifier` already has
such method, so `column_identifier_raw` can have one
as well.

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2023-06-16 01:11:30 +02:00
Kamil Braun
9e25a3cbed thrift: handler: move implementation of execute_schema_command to query_processor
It's now named `execute_thrift_schema_command` in `query_processor`.

This allows us to remove yet another
`query_processor::get_migration_manager()` call.

Now that `execute_thrift_schema_command` sits near
`execute_schema_statement` (the latter used for CQL), we can see a
certain similarity. The Thrift version should also in theory get a retry
loop like the one CQL has, so the similarity would become even stronger.
Perhaps the two functions could be refactored to deduplicate some logic
later.
2023-06-15 09:48:54 +02:00