Commit Graph

88 Commits

Author SHA1 Message Date
Avi Kivity
fcb8d040e8 treewide: use Software Package Data Exchange (SPDX) license identifiers
Instead of lengthy blurbs, switch to single-line, machine-readable
standardized (https://spdx.dev) license identifiers. The Linux kernel
switched long ago, so there is strong precedent.

Three cases are handled: AGPL-only, Apache-only, and dual licensed.
For the latter case, I chose (AGPL-3.0-or-later and Apache-2.0),
reasoning that our changes are extensive enough to apply our license.

The changes we applied mechanically with a script, except to
licenses/README.md.

Closes #9937
2022-01-18 12:15:18 +01:00
Jan Ciolek
e458340821 cql3: Remove term
term isn't used anywhere now. We can remove it and all classes that derive from it.

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2021-11-04 15:56:45 +01:00
Jan Ciolek
890c8f4026 cql3: Remove term in operations
Replace term with expression in cql3/operation and its children.

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2021-11-04 15:56:45 +01:00
Jan Ciolek
a82351dc79 cql3: expr: Add constant::view() method
Add a method that returns raw_value_view to expr::constant.

It's added for convenience - without it in many places
we would have to write my_value.value.to_view().

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2021-10-28 15:14:52 +02:00
Jan Ciolek
9c40516071 cql3: expr: Add receiver to expr::bind_variable
bind_variable used to have only the type of bound value.
Now this type is replaced with receiver, which describes information about column corresponding to this value.
A receiver contains type, column name, etc.

Receiver is needed in order to implement fill_prepare_context in the next commit.
It's an argument of prepare_context::add_variable_specification.

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2021-10-28 15:14:52 +02:00
Jan Ciolek
d61b2dbf8a cql3: Implement term::to_expression for collections
Each collection delayed_value can now be converted to expression.

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2021-09-24 11:05:53 +02:00
Jan Ciolek
c40f227c14 cql3: Implement term::to_expression for marker classes
Implement to_expression for non terminals that represent a bind marker.
For now each bind marker has a shape describing where it is used, but hopefully this can be removed in the future.

In order to evaluate a bind_variable we need to know its type.
The type is needed to pass to constant and to validate the value.

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2021-09-24 11:05:53 +02:00
Jan Ciolek
f86a1270b0 cql3: Add term::to_expression method
Add a method that converts given term to the matching expression.
It will be used as an intermediate step when implementing evaluate(expression).
evaluate(term) will convert the term to the expression and then call evaluate(expression).

For terminals this is simply calling get() to serialize the value.
For non-terminals the implementation is more complicated and will be implemeted in the following commits.

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2021-09-24 11:05:53 +02:00
Jan Ciolek
2523c9ba48 cql3: Replace most uses of terminal with expr::constant
constant is now ready to replace terminal as a final value representation.
Replace bind() with evaluate and shared_ptr<terminal> with constant.

We can't get rid of terminal yet. Sometimes terminal is converted back
to term, which constant can't do. This won't be a problem once we
replace term with expression.

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2021-09-21 16:28:15 +02:00
Jan Ciolek
221ed38e94 cql3: Replace all uses of bind_and_get with evaluate_to_raw_view
Start using evaluate_to_raw_value instead of bind_and_get.
This is a step towards using only evaluate.

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2021-09-21 16:20:30 +02:00
Jan Ciolek
2936adc570 cql3: Move data_type to terminal, make get_value_type non-virtual
Every class now has implementation of get_value_type().
We can simply make base class keep the data_type.

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2021-09-21 16:20:28 +02:00
Jan Ciolek
5aae370928 cql3: sets: Implement get_value_type in sets.hh
To convert a terminal to expr::constant we need know the value type.
Implement getting value type for terminals in sets.hh.

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2021-09-21 16:13:36 +02:00
Jan Ciolek
a964827696 cql3: expr: Add expr::evaluate
Adds the functions:
constant evaluate(term*, const query_options&);
raw_value_view evaluate(term*, const query_options&);

These functions take a term, bind it and convert the terminal
to constant or raw_value_view.

In the future these functions will take expression instead of term.
For that to happen bind() has to be implemented on expression,
this will be done later.

Also introduces terminal::get_value_type().
In order to construct a constant from terminal we need to know the type.
It will be implemented in the following commits.

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2021-09-21 16:13:34 +02:00
Jan Ciolek
561e6b0a59 cql3: Make collection term get() use the internal serialization format
A term should always be serialized using the internal cql serialization format.
A term represents a value received from the driver,
but for every use we are going to need it in the internal serialization format.

Other places in the code already do this, for example see list_prepare_term,
it calls value.bind(query_options::DEFAULT) to evaluate a collection_constructor.
query_options::DEFAULT has the latest cql serialization format.

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2021-09-21 16:05:09 +02:00
Avi Kivity
8c0f2f9e3d Revert "Merge 'cql3: Add expr::constant to replace terminal' from Jan Ciołek"
This reverts commit e9343fd382, reversing
changes made to 27138b215b. It causes a
regression in v2 serialization_format support:

collection_serialization_with_protocol_v2_test fails with: marshaling error: read_simple_bytes - not enough bytes (requested 1627390306, got 3)

Fixes #9360
2021-09-20 15:15:09 +03:00
Jan Ciolek
a0ec2113ae cql3: Replace most uses of terminal with expr::constant
constant is now ready to replace terminal as a final value representation.
Replace bind() with evaluate and shared_ptr<terminal> with constant.

We can't get rid of terminal yet. Sometimes terminal is converted back
to term, which constant can't do. This won't be a problem once we
replace term with expression.

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2021-09-13 17:47:17 +02:00
Jan Ciolek
c3fb2f2b57 cql3: Replace all uses of bind_and_get with evaluate_to_raw_view
Start using evaluate_to_raw_value instead of bind_and_get.
This is a step towards using only evaluate.

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2021-09-13 17:44:06 +02:00
Jan Ciolek
9b6b2899ed cql3: Move data_type to terminal, make get_value_type non-virtual
Every class now has implementation of get_value_type().
We can simply make base class keep the data_type.

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2021-09-13 17:03:23 +02:00
Jan Ciolek
5a755cda2b cql3: sets: Implement get_value_type in sets.hh
To convert a terminal to expr::constant we need know the value type.
Implement getting value type for terminals in sets.hh.

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2021-09-13 17:03:23 +02:00
Jan Ciolek
844bf2d472 cql3: expr: Add expr::evaluate
Adds the functions:
constant evaluate(term*, const query_options&);
raw_value_view evaluate(term*, const query_options&);

These functions take a term, bind it and convert the terminal
to constant or raw_value_view.

In the future these functions will take expression instead of term.
For that to happen bind() has to be implemented on expression,
this will be done later.

Also introduces terminal::get_value_type().
In order to construct a constant from terminal we need to know the type.
It will be implemented in the following commits.

Signed-off-by: Jan Ciolek <jan.ciolek@scylladb.com>
2021-09-13 17:03:23 +02:00
Avi Kivity
658cd47d21 cql3: sets, maps, expr: move set and map raw functions around
Move them closer to prepare related functions for modification. Since
sets and maps share some implementation details in the grammar, they
are moved and converted as a unit.
2021-08-26 15:13:07 +03:00
Avi Kivity
51f62d5953 cql3: constants: extricate cql3::constants::null_literal::null_value from null_literal
null_literal (which is in the term::raw domain) will be converted to an
expression, so unnest the nested class null_value (which is in the term
domain and is not converted now).
2021-08-26 14:44:21 +03:00
Avi Kivity
660be97028 cql3: term::raw, multi_column_raw: unify prepare() signatures
In order to replace the term::raw hierarchy with expressions,
we need to unify the signatures of term::raw::prepare() and
term::multi_column_raw::prepare(). This is because we'll only have
one expression type to represent both single values and tuples
(although, different subexpression types will may used).

The difference in the two prepare() signatures is the
`receiver` parameter - which is a (type, name) pair used
to perfom type inference on the expression being prepared,
with the name used to report errors. In a perfect world, this
would just be an expression - a tuple or a singular expression
as the case requires. But we don't have the needed expression
infrastructure yet - general tuples or name-annotated expressions.

Resolve the problem by introducing a variant for the single-value
and tuple. This is more or less creating a mini-expression type
used just for this. Once our expression type grows the needed
capabilities, it can replace this type.

Note that for some cases, this replaces compile-time checks by
runtime checks (which should never trigger). In other cases
the classes really needed both interfaces, so the new variant
is a better fit.
2021-08-26 14:11:42 +03:00
Pavel Solodovnikov
49ddd269ea cql3: rename variable_specifications to prepare_context
The class is repurposed to be more generic and also be able
to hold additional metadata related to function calls within
a CQL statement. Rename all methods appropriately.

Visitor functions in AST nodes (`collect_marker_specification`)
are also renamed to a more generic `fill_prepare_context`.

The name `prepare_context` designates that this metadata
structure is a byproduct of `stmt::raw::prepare()` call and
is needed only for "prepare" step of query execution.

Signed-off-by: Pavel Solodovnikov <pa.solodovnikov@scylladb.com>
2021-07-24 14:33:33 +03:00
Avi Kivity
a55b434a2b treewide: extent copyright statements to present day 2021-06-06 19:18:49 +03:00
Michał Chojnowski
dcbc053ecd cql3: change the internal type of lists::value from std::vector to chunked_vector
Lists can grow very big. Let's use a chunked vector to prevent large contiguous
allocations.
2021-05-17 17:09:55 +02:00
Michał Chojnowski
458878a414 cql3: optimize the deserialization of collections
Before this patch, deserializing a collection from a (prepared) CQL request
involved deserializing every element and serializing it again. Originally this
was a hacky method of validation, and it was also needed to reserialize nested
frozen collections from the CQLv2 format to the CQLv3 format.

But since then we started doing validation separately (before calls to
from_serialized) and CQLv2 became irrelevant, making reserialization of
elements (which, among other things, involves a memory alocation for every
element) pure waste.

This patch adds a faster path for collections in the v3 format, which does not
involve linearizing or reserializing the elements (since v3 is the same as
our internal format).

After this patch, the path from prepared CQL statements to
atomic_cell_or_collection is almost completely linearization-free. The last
remaining place is collection_mutation_description, where map keys are
linearized.
2021-04-01 10:44:21 +02:00
Michał Chojnowski
a0f12b8d63 cql3: maps, sets: switch the element type from bytes to managed_bytes 2021-04-01 10:44:21 +02:00
Michał Chojnowski
8927aaf225 cql3: output managed_bytes instead of bytes in get_with_protocol_version 2021-04-01 10:44:21 +02:00
Michał Chojnowski
c2c6b2abfa cql3: remove operation::make_*cell
The operation::make_*cell functions are useless aliases to methods of
update_parameters, and are used interchangeably with them throughout the code.
Remove them.

Also, remove the now-unused update_parameters::make_cell version for
fragmented_temporary_buffer::view.
2021-04-01 10:42:07 +02:00
Michał Chojnowski
b9322a6b71 cql3: switch users of cql3::raw_value_view to internals-independent API
We want to change the internals of cql3::raw_value{_view}.
However, users of cql3::raw_value and cql3::raw_value_view often
use them by extracting the internal representation, which will be different
after the planned change.

This commit prepares us for the change by making all accesses to the value
inside cql3::raw_value(_view) be done through helper methods which don't expose
the internal representation publicly.

After this commit we are free to change the internal representation of
raw_value_{view} without messing up their users.
2021-04-01 10:42:04 +02:00
Dejan Mircevski
3aa80f47fe abstract_type: Rework unreversal methods
Replace two methods for unreversal (`as` and `self_or_reversed`) with
a new one (`without_reversed`).  More flexible and better named.

Tests: unit (dev)

Signed-off-by: Dejan Mircevski <dejan@scylladb.com>

Closes #7889
2021-01-10 19:30:12 +02:00
Dejan Mircevski
8b2f459622 cql3: Fix crash when removing unset_value from set
Avoid crash described in #7740 by ignoring the update when the
element-to-remove is UNSET_VALUE.

Tests: unit (dev)

Signed-off-by: Dejan Mircevski <dejan@scylladb.com>
2021-01-07 13:22:20 +02:00
Dejan Mircevski
14fa39cfa6 cql3: Fix handling of reverse-order sets
When the clustering order is reversed on a set column, the column type
is reversed_type_impl, not set_type_impl.  Therefore, we have to check
for both reversed type and set type in some places.

To make such checks easier, add convenience methods self_or_reversed()
and as() to abstract_type.  Invoke those methods (instead of is_set()
and casts) enough to make test_clustering_key_reverse_frozen_set pass.
Leave other invocations of is_set() and *_cast<set_type_impl>() as
they are; some are protected by callers from being invoked on reverse
types, but some are quite possibly bugs untriggered by existing tests.

Signed-off-by: Dejan Mircevski <dejan@scylladb.com>
2021-01-07 13:22:20 +02:00
Michał Chojnowski
4f359a7a99 cql3: sets: remove unnecessary use of with_linearized
We can validate directly from fragmented buffers now.
2020-12-11 09:53:07 +01:00
Michał Chojnowski
d731b34d95 cql3: sets: don't linearize in value::from_serialized
We can deserialize directly from fragmented buffers now.
2020-12-03 10:57:07 +01:00
Piotr Jastrzebski
49fd17a4ef cql3: Improve error messages for markers binding
When binding prepared statement it is possible that values being binded
are not correct. Unfortunately before this patch, the error message
was only saying what type got a wrong value. This was not very helpful
because there could be multiple columns with the same type in the table.
We also support collections so sometimes error was saying that there
is a wrong value for a type T but the affected column was actually of
type collection<T>.

This patch adds information about a column name that got the wrong
value so that it's easier to find and fix the problem.

Tests: unit(dev)

Signed-off-by: Piotr Jastrzebski <piotr@scylladb.com>
Message-Id: <90b70a7e5144d7cb3e53876271187e43fd8eee25.1597832048.git.piotr@scylladb.com>
2020-08-20 12:51:36 +03:00
Rafael Ávila de Espíndola
ad6d65dbbd Everywhere: Explicitly instantiate make_shared
seastar::make_shared has a constructor taking a T&&. There is no such
constructor in std::make_shared:

https://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared

This means that we have to move from

    make_shared(T(...)

to

    make_shared<T>(...)

If we don't want to depend on the idiosyncrasies of
seastar::make_shared.

Signed-off-by: Rafael Ávila de Espíndola <espindola@scylladb.com>
2020-07-21 10:33:49 -07:00
Pavel Solodovnikov
c4bbeb80db cql3: pass column_specification by ref to cql3::assignment_testable functions
This patch changes the signatures of `test_assignment` and
`test_all` functions to accept `cql3::column_specification` by
const reference instead of shared pointer.

Mostly a cosmetic change reducing overall shared_ptr bloat in
cql3 code.

Tests: unit(dev, debug)

Signed-off-by: Pavel Solodovnikov <pa.solodovnikov@scylladb.com>
Message-Id: <20200529195249.767346-1-pa.solodovnikov@scylladb.com>
2020-05-30 09:49:29 +03:00
Pavel Solodovnikov
f6e765b70f cql3: pass column_specification via lw_shared_ptr
`column_specification` class is marked as "final": it's safe
to use non-polymorphic pointer "lw_shared_ptr" instead of a
more generic "shared_ptr".

tests: unit(dev, debug)

Signed-off-by: Pavel Solodovnikov <pa.solodovnikov@scylladb.com>
Message-Id: <20200427084016.26068-1-pa.solodovnikov@scylladb.com>
2020-04-27 12:47:42 +03:00
Rafael Ávila de Espíndola
c0072eab30 everywhere: Be more explicit that we don't want std::make_shared
If sstring is made an alias to std::string ADL causes std::make_shared
to be found. Explicitly ask for ::make_shared.

Signed-off-by: Rafael Ávila de Espíndola <espindola@scylladb.com>
2020-03-10 13:13:48 -07:00
Calle Wilund
b6443e44b9 set: Make set_type_impl::serialize_partially_deserialized_form static
Conform with map + does not require any instance info.
2020-03-02 14:43:34 +00:00
Pavel Solodovnikov
8efb02146f cql3: const cleanups and API de-pointerization
* Pass raw::select_statement::parameters as lw_shared_ptr
 * Some more const cleanups here and there
 * lists,maps,sets::equals now accept const-ref to *_type_impl
   instead of shared_ptr
 * Remove unused `get_column_for_condition` from modification_statement.hh
 * More methods now accept const-refs instead of shared_ptr

Every call site where a shared_ptr was required as an argument
has been inspected to be sure that no dangling references are
possible.

Tests: unit(dev, debug)

Signed-off-by: Pavel Solodovnikov <pa.solodovnikov@scylladb.com>
Message-Id: <20200220153204.279940-1-pa.solodovnikov@scylladb.com>
2020-02-20 18:14:49 +02:00
Pavel Solodovnikov
5b6e2d7178 cql3: change some function signatures to accept const references
This patch continues the effort of reducing shared_ptr's count
in the different APIs throughout the cql3 code tree.

These functions now pass cref to column_specification instead of
shared_ptr:
 * multiple variants of `validate_assignable_to`
 * sets::value_spec_of
 * lists::value_spec_of
 * lists::index_spec_of
 * lists::uuid_index_spec_of
 * tuples::component_spec_of
 * user_types::field_spec_of

These functions don't pass the shared_ptr around down the call
hierarchy, also obviously assuming that the column_specification
passed is always non-null.

So it's safe to assume that they don't borrow the ownership of
the pointer or knowingly prolongate lifetime of the object
pointed by.

Signed-off-by: Pavel Solodovnikov <pa.solodovnikov@scylladb.com>
2020-02-16 17:24:14 +03:00
Pavel Solodovnikov
49bf936403 cql3: change signatures of several functions to return crefs instead of pointers
The following functions now accept const reference to
column_specification instead of shared_ptr:
 * lists::index_spec_of
 * lists::value_spec_of
 * lists::uuid_index_spec_of
 * sets::value_spec_of

Changed maps::value_spec_of and maps::key_spec_of signatures
to accept const ref instead of non-const ref to
column_specification.

Signed-off-by: Pavel Solodovnikov <pa.solodovnikov@scylladb.com>
2020-02-16 17:23:56 +03:00
Pavel Solodovnikov
bf95bd0916 cql3: more functions marked as const
The following functions are now "const":
 * `term::collect_marker_specification`
 * `relation::to_term`
 * `multi_item_terminal::get_elements`
 * `raw_update::is_compatible_with`

Signed-off-by: Pavel Solodovnikov <pa.solodovnikov@scylladb.com>
Message-Id: <20200213142445.35312-1-pa.solodovnikov@scylladb.com>
2020-02-16 11:22:30 +02:00
Pavel Solodovnikov
f2feeb4b10 cql3: Propagate "const" to some virtual methods in cql hierarchy
Add "const" attributes to `assignment_testable::test_assignment`
and `term::raw::prepare` methods. These should have been marked as
"const" even before the change but for some reason were missing
these qualifiers.

Mark other supplementary methods with "const" attributes as
necessary.

Tests: unit(dev, debug)

Signed-off-by: Pavel Solodovnikov <pa.solodovnikov@scylladb.com>
Message-Id: <20200127213215.494000-1-pa.solodovnikov@scylladb.com>
2020-01-29 00:23:40 +02:00
Pavel Solodovnikov
e1b22b6a4c cql3: get rid of lw_shared_ptr for variable_specifications
`parsed_statement::get_bound_variables` is assumed to always
return a nonnull pointer to `variable_specifications` instance.

In this case using a pointer is superfluous and can be safely
replaced by a plain reference.

Also add a default ctor and a utility method `set_bound_variables`
to the `variable_specifications` class to actually reset the
contents of the class instance.

Tests: unit(dev, debug)

Signed-off-by: Pavel Solodovnikov <pa.solodovnikov@scylladb.com>
Message-Id: <20200120195839.164296-1-pa.solodovnikov@scylladb.com>
2020-01-22 12:51:02 +02:00
Pavel Solodovnikov
aba9a11ff0 cql: pass variable_specifications via lw_shared_ptr
Instances of `variable_specifications` are passed around as
shared_ptr's, which are redundant in this case since the class
is marked as `final`. Use `lw_shared_ptr` instead since we know
for sure it's not a polymorphic pointer.

Tests: unit(debug)

Signed-off-by: Pavel Solodovnikov <pa.solodovnikov@scylladb.com>
Message-Id: <20191225232853.45395-1-pa.solodovnikov@scylladb.com>
2019-12-29 16:26:26 +02:00
Kamil Braun
393974df3b cql3: make {lists,maps,sets}::value::from_serialized take const {}_type&.
This will simplify the code a bit where from_serialized is used
after switching to visitors. Also reduces the number of shared_ptr
copies.
2019-10-25 10:49:19 +02:00