mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-24 02:20:37 +00:00
No one seems to call them except for other uses_function methods. Tests: unit (dev) Signed-off-by: Dejan Mircevski <dejan@scylladb.com>
172 lines
7.1 KiB
C++
172 lines
7.1 KiB
C++
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2015 ScyllaDB
|
|
*
|
|
* Modified by ScyllaDB
|
|
*/
|
|
|
|
/*
|
|
* This file is part of Scylla.
|
|
*
|
|
* Scylla is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Scylla is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Scylla. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "cql3/term.hh"
|
|
#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, nullptr otherwise.
|
|
::shared_ptr<term> _collection_element;
|
|
// A literal value for comparison predicates or a multi item terminal for "a IN ?"
|
|
::shared_ptr<term> _value;
|
|
// List of terminals for "a IN (value, value, ...)"
|
|
std::vector<::shared_ptr<term>> _in_values;
|
|
const std::unique_ptr<like_matcher> _matcher;
|
|
expr::oper_t _op;
|
|
public:
|
|
column_condition(const column_definition& column, ::shared_ptr<term> collection_element,
|
|
::shared_ptr<term> value, std::vector<::shared_ptr<term>> in_values,
|
|
std::unique_ptr<like_matcher> matcher, expr::oper_t op)
|
|
: column(column)
|
|
, _collection_element(std::move(collection_element))
|
|
, _value(std::move(value))
|
|
, _in_values(std::move(in_values))
|
|
, _matcher(std::move(matcher))
|
|
, _op(op)
|
|
{
|
|
if (op != expr::oper_t::IN) {
|
|
assert(_in_values.empty());
|
|
}
|
|
}
|
|
/**
|
|
* 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(variable_specifications& bound_names) const;
|
|
|
|
// 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, ::shared_ptr<term> collection_element,
|
|
::shared_ptr<term> 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<::shared_ptr<term>>{}, 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, ::shared_ptr<term> collection_element,
|
|
::shared_ptr<term> in_marker, std::vector<::shared_ptr<term>> 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:
|
|
::shared_ptr<term::raw> _value;
|
|
std::vector<::shared_ptr<term::raw>> _in_values;
|
|
::shared_ptr<abstract_marker::in_raw> _in_marker;
|
|
|
|
// Can be nullptr, used with the syntax "IF m[e] = ..." (in which case it's 'e')
|
|
::shared_ptr<term::raw> _collection_element;
|
|
expr::oper_t _op;
|
|
public:
|
|
raw(::shared_ptr<term::raw> value,
|
|
std::vector<::shared_ptr<term::raw>> in_values,
|
|
::shared_ptr<abstract_marker::in_raw> in_marker,
|
|
::shared_ptr<term::raw> 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(::shared_ptr<term::raw> value, ::shared_ptr<term::raw> collection_element,
|
|
expr::oper_t op) {
|
|
return make_lw_shared<raw>(std::move(value), std::vector<::shared_ptr<term::raw>>{},
|
|
::shared_ptr<abstract_marker::in_raw>{}, 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(::shared_ptr<term::raw> collection_element,
|
|
::shared_ptr<abstract_marker::in_raw> in_marker, std::vector<::shared_ptr<term::raw>> in_values) {
|
|
return make_lw_shared<raw>(::shared_ptr<term::raw>{}, std::move(in_values), std::move(in_marker),
|
|
std::move(collection_element), expr::oper_t::IN);
|
|
}
|
|
|
|
lw_shared_ptr<column_condition> prepare(database& db, const sstring& keyspace, const column_definition& receiver) const;
|
|
};
|
|
};
|
|
|
|
} // end of namespace cql3
|