Files
scylladb/cql3/column_condition.hh
Avi Kivity bfa8a8efb7 cql3: column_condition: deinline constructor
It will be easier to mangle it later out of the header.
2022-06-02 13:11:05 +03:00

130 lines
5.5 KiB
C++

/*
* Copyright (C) 2015-present ScyllaDB
*
* Modified by ScyllaDB
*/
/*
* SPDX-License-Identifier: (AGPL-3.0-or-later and Apache-2.0)
*/
#pragma once
#include "cql3/abstract_marker.hh"
#include "cql3/expr/expression.hh"
#include "utils/like_matcher.hh"
namespace cql3 {
/**
* A CQL3 condition on the value of a column or collection element. For example, "UPDATE .. IF a = 0".
*/
class column_condition final {
public:
// If _collection_element is not zero, this defines the receiver cell, not the entire receiver
// column.
// E.g. if column type is list<string> and expression is "a = ['test']", then the type of the
// column definition below is list<string>. If expression is "a[0] = 'test'", then the column
// object stands for the string cell. See column_condition::raw::prepare() for details.
const column_definition& _column;
private:
// For collection, when testing the equality of a specific element, nullopt otherwise.
std::optional<expr::expression> _collection_element;
// A literal value for comparison predicates or a multi item terminal for "a IN ?"
std::optional<expr::expression> _value;
// List of terminals for "a IN (value, value, ...)"
std::vector<expr::expression> _in_values;
const std::unique_ptr<like_matcher> _matcher;
expr::oper_t _op;
public:
column_condition(const column_definition& column, std::optional<expr::expression> collection_element,
std::optional<expr::expression> value, std::vector<expr::expression> in_values,
std::unique_ptr<like_matcher> matcher, expr::oper_t op);
/**
* Collects the column specification for the bind variables of this operation.
*
* @param boundNames the list of column specification where to collect the
* bind variables of this term in.
*/
void collect_marker_specificaton(prepare_context& ctx);
// Retrieve parameter marker values, if any, find the appropriate collection
// element if the cell is a collection and an element access is used in the expression,
// and evaluate the condition.
bool applies_to(const data_value* cell_value, const query_options& options) const;
/**
* Helper constructor wrapper for
* "IF col['key'] = 'foo'"
* "IF col = 'foo'"
* "IF col LIKE <pattern>"
*/
static lw_shared_ptr<column_condition> condition(const column_definition& def, std::optional<expr::expression> collection_element,
expr::expression value, std::unique_ptr<like_matcher> matcher, expr::oper_t op) {
return make_lw_shared<column_condition>(def, std::move(collection_element), std::move(value),
std::vector<expr::expression>{}, std::move(matcher), op);
}
// Helper constructor wrapper for "IF col IN ... and IF col['key'] IN ... */
static lw_shared_ptr<column_condition> in_condition(const column_definition& def, std::optional<expr::expression> collection_element,
std::optional<expr::expression> in_marker, std::vector<expr::expression> in_values) {
return make_lw_shared<column_condition>(def, std::move(collection_element), std::move(in_marker),
std::move(in_values), nullptr, expr::oper_t::IN);
}
class raw final {
private:
std::optional<cql3::expr::expression> _value;
std::vector<cql3::expr::expression> _in_values;
std::optional<cql3::expr::expression> _in_marker;
// Can be nullopt, used with the syntax "IF m[e] = ..." (in which case it's 'e')
std::optional<cql3::expr::expression> _collection_element;
expr::oper_t _op;
public:
raw(std::optional<cql3::expr::expression> value,
std::vector<cql3::expr::expression> in_values,
std::optional<cql3::expr::expression> in_marker,
std::optional<cql3::expr::expression> collection_element,
expr::oper_t op)
: _value(std::move(value))
, _in_values(std::move(in_values))
, _in_marker(std::move(in_marker))
, _collection_element(std::move(collection_element))
, _op(op)
{ }
/**
* A condition on a column or collection element.
* For example:
* "IF col['key'] = 'foo'"
* "IF col = 'foo'"
* "IF col LIKE 'foo%'"
*/
static lw_shared_ptr<raw> simple_condition(cql3::expr::expression value, std::optional<cql3::expr::expression> collection_element,
expr::oper_t op) {
return make_lw_shared<raw>(std::move(value), std::vector<cql3::expr::expression>{},
std::nullopt, std::move(collection_element), op);
}
/**
* An IN condition on a column or a collection element. IN may contain a list of values or a single marker.
* For example:
* "IF col IN ('foo', 'bar', ...)"
* "IF col IN ?"
* "IF col['key'] IN * ('foo', 'bar', ...)"
* "IF col['key'] IN ?"
*/
static lw_shared_ptr<raw> in_condition(std::optional<cql3::expr::expression> collection_element,
std::optional<cql3::expr::expression> in_marker, std::vector<cql3::expr::expression> in_values) {
return make_lw_shared<raw>(std::nullopt, std::move(in_values), std::move(in_marker),
std::move(collection_element), expr::oper_t::IN);
}
lw_shared_ptr<column_condition> prepare(data_dictionary::database db, const sstring& keyspace, const column_definition& receiver) const;
};
};
} // end of namespace cql3