Files
scylladb/cql3/selection/selectable.cc
Nadav Har'El b026aea6f7 cql3/expr: add NEG unary operator for numeric negation
This patch adds a new expression type, unary_operator, analogous to
the existing binary_operator but takes just one operand instead of
two.

This patch also implements the first and only unary operator type,
unary_oper_t::NEG, implementing negation (unary minus) for all numeric
types.

For fixed-width integer types overflow or underflow results in an error.
If the operand is NULL, the result is a NULL as well.

The new operator is not yet used by the CQL syntax - our parser doesn't
parse arithmetic expressions yet. We also do not plan to use it in the
following patch which uses the separate SUB (subtraction) operation,
not the new NEG. But since I already implemented a unary minus operator,
and we'll surely need it in the future for general arithmentic operations,
I thought I might as well include this patch as well.

Refs #22918 ("Support arithmetic operators")
2026-05-25 10:08:11 +03:00

93 lines
3.2 KiB
C++

/*
* Copyright (C) 2015-present ScyllaDB
*/
/*
* SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.1
*/
#include "cql3/query_options.hh"
#include "cql3/functions/functions.hh"
#include "cql3/functions/castas_fcts.hh"
#include "cql3/functions/aggregate_fcts.hh"
#include "cql3/expr/expression.hh"
#include "cql3/expr/expr-utils.hh"
namespace cql3 {
namespace selection {
seastar::logger slogger("cql3_selection");
expr::expression
make_count_rows_function_expression() {
return expr::function_call{
cql3::functions::function_name::native_function(cql3::functions::aggregate_fcts::COUNT_ROWS_FUNCTION_NAME),
std::vector<cql3::expr::expression>()};
}
bool
selectable_processes_selection(const expr::expression& selectable) {
return expr::visit(overloaded_functor{
[&] (const expr::constant&) -> bool {
return true;
},
[&] (const expr::conjunction& conj) -> bool {
on_internal_error(slogger, "no way to express 'SELECT a AND b' in the grammar yet");
},
[&] (const expr::binary_operator& conj) -> bool {
on_internal_error(slogger, "no way to express 'SELECT a binop b' in the grammar yet");
},
[&] (const expr::unary_operator&) -> bool {
on_internal_error(slogger, "no way to express 'SELECT unop a' in the grammar yet");
},
[] (const expr::subscript&) -> bool {
return true;
},
[&] (const expr::column_value& column) -> bool {
return false;
},
[&] (const expr::unresolved_identifier& ui) -> bool {
on_internal_error(slogger, "selectable_processes_selection saw an unprepared column_identifier");
},
[&] (const expr::column_mutation_attribute& cma) -> bool {
return true;
},
[&] (const expr::function_call& fc) -> bool {
return true;
},
[&] (const expr::cast& c) -> bool {
return true;
},
[&] (const expr::field_selection& fs) -> bool {
return true;
},
[&] (const expr::bind_variable&) -> bool {
on_internal_error(slogger, "bind_variable found its way to selector context");
},
[&] (const expr::untyped_constant&) -> bool {
on_internal_error(slogger, "untyped_constant found its way to selector context");
},
[&] (const expr::tuple_constructor&) -> bool {
on_internal_error(slogger, "tuple_constructor found its way to selector context");
},
[&] (const expr::collection_constructor&) -> bool {
on_internal_error(slogger, "collection_constructor found its way to selector context");
},
[&] (const expr::usertype_constructor&) -> bool {
on_internal_error(slogger, "collection_constructor found its way to selector context");
},
[&] (const expr::temporary& t) -> bool {
// Well it doesn't process the selection, but it's not bypasses the selection completely
// so we can't use the fast path. In any case it won't be seen.
return true;
},
}, selectable);
};
}
}