split column expression into separate classes

This commit is contained in:
2026-03-02 16:20:54 +01:00
parent 85c56584be
commit d9eaa2009f
31 changed files with 876 additions and 189 deletions
+27 -14
View File
@@ -17,6 +17,17 @@ add_library(matador-orm STATIC
../../include/matador/query/criteria/like_criteria.hpp
../../include/matador/query/criteria/logical_criteria.hpp
../../include/matador/query/criteria_evaluator.hpp
../../include/matador/query/database.hpp
../../include/matador/query/error_code.hpp
../../include/matador/query/expression/abstract_column_expression.hpp
../../include/matador/query/expression/binary_column_expression.hpp
../../include/matador/query/expression/column_expression.hpp
../../include/matador/query/expression/expression_operators.hpp
../../include/matador/query/expression/expression_visitor.hpp
../../include/matador/query/expression/placeholder_expression.hpp
../../include/matador/query/expression/table_column_expression.hpp
../../include/matador/query/expression/value_expression.hpp
../../include/matador/query/expression_evaluator.hpp
../../include/matador/query/fk_value_extractor.hpp
../../include/matador/query/generator.hpp
../../include/matador/query/insert_query_builder.hpp
@@ -47,6 +58,7 @@ add_library(matador-orm STATIC
../../include/matador/query/intermediates/query_select_intermediate.hpp
../../include/matador/query/intermediates/query_set_intermediate.hpp
../../include/matador/query/intermediates/query_update_intermediate.hpp
../../include/matador/query/intermediates/query_values_intermediate.hpp
../../include/matador/query/intermediates/query_where_intermediate.hpp
../../include/matador/query/internal/basic_type_to_string_visitor.hpp
../../include/matador/query/internal/column_value_pair.hpp
@@ -54,11 +66,13 @@ add_library(matador-orm STATIC
../../include/matador/query/internal/string_builder_utils.hpp
../../include/matador/query/join_data.hpp
../../include/matador/query/key_value_generator.hpp
../../include/matador/query/manual_pk_generator.hpp
../../include/matador/query/meta_table_macro.hpp
../../include/matador/query/meta_table_macro.hpp
../../include/matador/query/query.hpp
../../include/matador/query/query_builder.hpp
../../include/matador/query/query_collection_resolver.hpp
../../include/matador/query/query_column.hpp
../../include/matador/query/query_data.hpp
../../include/matador/query/query_intermediates.hpp
../../include/matador/query/query_object_resolver.hpp
@@ -70,6 +84,7 @@ add_library(matador-orm STATIC
../../include/matador/query/table.hpp
../../include/matador/query/table_column.hpp
../../include/matador/query/table_constraint.hpp
../../include/matador/query/table_pk_generator.hpp
../../include/matador/query/value_extractor.hpp
../../include/matador/sql/abstract_sql_logger.hpp
../../include/matador/sql/backend_provider.hpp
@@ -106,6 +121,7 @@ add_library(matador-orm STATIC
../../include/matador/sql/statement_cache.hpp
orm/error_code.cpp
orm/session.cpp
query/abstract_pk_generator.cpp
query/attribute_string_writer.cpp
query/basic_schema.cpp
query/builder.cpp
@@ -119,6 +135,14 @@ add_library(matador-orm STATIC
query/criteria/logical_criteria.cpp
query/criteria/not_criteria.cpp
query/criteria_evaluator.cpp
query/error_code.cpp
query/expression/binary_column_expression.cpp
query/expression/column_expression.cpp
query/expression/expression_operators.cpp
query/expression/placeholder_expression.cpp
query/expression/table_column_expression.cpp
query/expression/value_expression.cpp
query/expression_evaluator.cpp
query/generator.cpp
query/insert_query_builder.cpp
query/intermediates/executable_query.cpp
@@ -147,6 +171,7 @@ add_library(matador-orm STATIC
query/intermediates/query_select_intermediate.cpp
query/intermediates/query_set_intermediate.cpp
query/intermediates/query_update_intermediate.cpp
query/intermediates/query_values_intermediate.cpp
query/intermediates/query_where_intermediate.cpp
query/internal/basic_type_to_string_visitor.cpp
query/internal/column_value_pair.cpp
@@ -154,6 +179,7 @@ add_library(matador-orm STATIC
query/internal/query_result_impl.cpp
query/internal/string_builder_utils.cpp
query/key_value_generator.cpp
query/manual_pk_generator.cpp
query/query.cpp
query/query_builder.cpp
query/query_builder_exception.cpp
@@ -166,6 +192,7 @@ add_library(matador-orm STATIC
query/table.cpp
query/table_column.cpp
query/table_constraint.cpp
query/table_pk_generator.cpp
query/value_extractor.cpp
sql/backend_provider.cpp
sql/connection.cpp
@@ -192,20 +219,6 @@ add_library(matador-orm STATIC
sql/resolver_service.cpp
sql/statement.cpp
sql/statement_cache.cpp
../../include/matador/query/database.hpp
query/abstract_pk_generator.cpp
../../include/matador/query/manual_pk_generator.hpp
query/manual_pk_generator.cpp
../../include/matador/query/table_pk_generator.hpp
query/table_pk_generator.cpp
../../include/matador/query/intermediates/query_values_intermediate.hpp
query/intermediates/query_values_intermediate.cpp
../../include/matador/query/error_code.hpp
query/error_code.cpp
../../include/matador/query/column_expression.hpp
query/column_expression.cpp
../../include/matador/query/abstract_column_expression.hpp
../../include/matador/query/query_column.hpp
)
target_include_directories(matador-orm
-49
View File
@@ -1,49 +0,0 @@
#include "matador/query/column_expression.hpp"
namespace matador::query {
binary_column_expression::binary_column_expression(column_expression_ptr left_column, binary_expression_operator operand, column_expression_ptr right_column)
: left_column_(std::move(left_column))
, operand_(operand)
, right_column_(std::move(right_column)) {
}
void binary_column_expression::accept(expression_visitor &visitor) const {
visitor.visit(*this);
}
table_column_expression::table_column_expression(table_column col)
: column_(std::move(col)){
}
void table_column_expression::accept(expression_visitor &visitor) const {
visitor.visit(*this);
}
value_expression::value_expression(utils::database_type value)
: value_(std::move(value)) {
}
void value_expression::accept(expression_visitor &visitor) const {
visitor.visit(*this);
}
void placeholder_expression::accept(expression_visitor &visitor) const {
visitor.visit(*this);
}
column_expression_ptr operator+(const table_column &col, utils::placeholder /*placeholder*/) {
return std::make_unique<binary_column_expression>(std::make_unique<table_column_expression>(col), binary_expression_operator::Plus, std::make_unique<placeholder_expression>());
}
column_expression_ptr operator+(utils::placeholder /*placeholder*/, const table_column &col) {
return std::make_unique<binary_column_expression>(std::make_unique<placeholder_expression>(), binary_expression_operator::Plus, std::make_unique<table_column_expression>(col));
}
column_expression_ptr operator-(const table_column &col, utils::placeholder /*placeholder*/) {
return std::make_unique<binary_column_expression>(std::make_unique<table_column_expression>(col), binary_expression_operator::Minus, std::make_unique<placeholder_expression>());
}
column_expression_ptr operator-(utils::placeholder /*placeholder*/, const table_column &col) {
return std::make_unique<binary_column_expression>(std::make_unique<placeholder_expression>(), binary_expression_operator::Minus, std::make_unique<table_column_expression>(col));
}
}
+4 -2
View File
@@ -8,8 +8,10 @@
#include "matador/query/criteria/logical_criteria.hpp"
#include "matador/query/criteria/not_criteria.hpp"
#include "matador/query/query_utils.hpp"
#include "matador/sql/dialect.hpp"
#include "matador/sql/query_context.hpp"
#include "matador/utils/enum_mapper.hpp"
#include "matador/utils/value.hpp"
@@ -26,8 +28,8 @@ static const utils::enum_mapper<binary_operator> BinaryOperatorEnum({
}
criteria_evaluator::criteria_evaluator(const sql::dialect &d, sql::query_context &query)
: dialect_(d)
, query_(query) {
: dialect_(d)
, query_(query) {
}
std::string criteria_evaluator::evaluate(const abstract_criteria &node) {
@@ -0,0 +1,26 @@
#include "matador/query/expression/binary_column_expression.hpp"
#include "matador/query/expression/expression_visitor.hpp"
namespace matador::query {
binary_column_expression::binary_column_expression(column_expression_ptr left_column, const binary_expression_operator operand, column_expression_ptr right_column)
: left_column_(std::move(left_column))
, operand_(operand)
, right_column_(std::move(right_column)) {
}
void binary_column_expression::accept(expression_visitor &visitor) const {
visitor.visit(*this);
}
const column_expression_ptr& binary_column_expression::left_column() const {
return left_column_;
}
binary_expression_operator binary_column_expression::operand() const {
return operand_;
}
const column_expression_ptr& binary_column_expression::right_column() const {
return right_column_;
}
}
@@ -0,0 +1,31 @@
#include "matador/query/expression/column_expression.hpp"
namespace matador::query {
column_expression::column_expression(column_expression_ptr expr) noexcept
: expression_(std::move(expr)) {}
bool column_expression::empty() const noexcept {
return !expression_;
}
const abstract_column_expression* column_expression::get() const noexcept {
return expression_.get();
}
const column_expression_ptr& column_expression::ptr() const noexcept {
return expression_;
}
column_expression_ptr column_expression::release() noexcept {
return std::move(expression_);
}
column_expression::operator std::unique_ptr<abstract_column_expression>() && noexcept {
return std::move(expression_);
}
table_column column_expression::as(const std::string& alias) && {
const table_column col{std::move(expression_)};
return col.as(alias);
}
}
@@ -0,0 +1,90 @@
#include "matador/query/expression/expression_operators.hpp"
#include "matador/query/expression/placeholder_expression.hpp"
namespace matador::query {
column_expression operator+(const table_column &col, utils::placeholder /*placeholder*/) {
return column_expression{std::make_unique<binary_column_expression>(
std::make_unique<table_column_expression>(col),
binary_expression_operator::Plus,
std::make_unique<placeholder_expression>()
)};
}
column_expression operator+(utils::placeholder /*placeholder*/, const table_column &col) {
return column_expression{std::make_unique<binary_column_expression>(
std::make_unique<placeholder_expression>(),
binary_expression_operator::Plus,
std::make_unique<table_column_expression>(col)
)};
}
column_expression operator-(const table_column &col, utils::placeholder /*placeholder*/) {
return column_expression{std::make_unique<binary_column_expression>(
std::make_unique<table_column_expression>(col),
binary_expression_operator::Minus,
std::make_unique<placeholder_expression>()
)};
}
column_expression operator-(utils::placeholder /*placeholder*/, const table_column &col) {
return column_expression{std::make_unique<binary_column_expression>(
std::make_unique<placeholder_expression>(),
binary_expression_operator::Minus,
std::make_unique<table_column_expression>(col)
)};
}
column_expression operator*(const table_column& col, utils::placeholder /*placeholder*/) {
return column_expression{std::make_unique<binary_column_expression>(
std::make_unique<table_column_expression>(col),
binary_expression_operator::Multiply,
std::make_unique<placeholder_expression>()
)};
}
column_expression operator*(utils::placeholder /*placeholder*/, const table_column& col) {
return column_expression{std::make_unique<binary_column_expression>(
std::make_unique<placeholder_expression>(),
binary_expression_operator::Multiply,
std::make_unique<table_column_expression>(col)
)};
}
column_expression operator*(column_expression&& left, column_expression&& right) {
return column_expression{std::make_unique<binary_column_expression>(
left.release(), binary_expression_operator::Multiply, right.release()
)};
}
column_expression operator/(const table_column& col, utils::placeholder /*placeholder*/) {
return column_expression{std::make_unique<binary_column_expression>(
std::make_unique<table_column_expression>(col),
binary_expression_operator::Divide,
std::make_unique<placeholder_expression>()
)};
}
column_expression operator/(utils::placeholder /*placeholder*/, const table_column& col) {
return column_expression{std::make_unique<binary_column_expression>(
std::make_unique<placeholder_expression>(),
binary_expression_operator::Divide,
std::make_unique<table_column_expression>(col)
)};
}
column_expression operator%(const table_column& col, utils::placeholder /*placeholder*/) {
return column_expression{std::make_unique<binary_column_expression>(
std::make_unique<table_column_expression>(col),
binary_expression_operator::Modulo,
std::make_unique<placeholder_expression>()
)};
}
column_expression operator%(utils::placeholder /*placeholder*/, const table_column& col) {
return column_expression{std::make_unique<binary_column_expression>(
std::make_unique<placeholder_expression>(),
binary_expression_operator::Modulo,
std::make_unique<table_column_expression>(col)
)};
}
}
@@ -0,0 +1,9 @@
#include "matador/query/expression/placeholder_expression.hpp"
#include "matador/query/expression/expression_visitor.hpp"
namespace matador::query {
void placeholder_expression::accept(expression_visitor &visitor) const {
visitor.visit(*this);
}
}
@@ -0,0 +1,16 @@
#include "matador/query/expression/table_column_expression.hpp"
#include "matador/query/expression/expression_visitor.hpp"
namespace matador::query {
table_column_expression::table_column_expression(table_column col)
: column_(std::move(col)){
}
void table_column_expression::accept(expression_visitor &visitor) const {
visitor.visit(*this);
}
const table_column& table_column_expression::col() const {
return column_;
}
}
@@ -0,0 +1,16 @@
#include "matador/query/expression/value_expression.hpp"
#include "matador/query/expression/expression_visitor.hpp"
namespace matador::query {
value_expression::value_expression(utils::database_type value)
: value_(std::move(value)) {
}
void value_expression::accept(expression_visitor &visitor) const {
visitor.visit(*this);
}
const utils::database_type& value_expression::value() const {
return value_;
}
}
+57
View File
@@ -0,0 +1,57 @@
#include "matador/query/expression_evaluator.hpp"
#include "matador/query/expression/binary_column_expression.hpp"
#include "matador/query/expression/table_column_expression.hpp"
#include "matador/query/expression/placeholder_expression.hpp"
#include "matador/query/expression/value_expression.hpp"
#include "matador/query/internal/basic_type_to_string_visitor.hpp"
#include "matador/query/internal/string_builder_utils.hpp"
#include "matador/sql/dialect.hpp"
#include "matador/sql/query_context.hpp"
#include "matador/utils/enum_mapper.hpp"
namespace matador::query {
namespace detail {
static const utils::enum_mapper<binary_expression_operator> BinaryExpressionOperatorEnum({
{binary_expression_operator::Plus, "+"},
{binary_expression_operator::Minus, "-"},
{binary_expression_operator::Multiply, "*"},
{binary_expression_operator::Divide, "/"},
{binary_expression_operator::Modulo, "%"},
});
}
expression_evaluator::expression_evaluator(const sql::dialect &d, sql::query_context &query)
: dialect_(d)
, query_(query){
}
void expression_evaluator::visit(const binary_column_expression& node) {
expression_.append("(");
node.left_column()->accept(*this);
expression_.append(" ");
expression_.append(detail::BinaryExpressionOperatorEnum.to_string(node.operand()));
expression_.append(" ");
node.right_column()->accept(*this);
expression_.append(")");
}
void expression_evaluator::visit(const table_column_expression& node) {
prepare_identifier_string_append(expression_, node.col().name(), dialect_);
}
void expression_evaluator::visit(const value_expression& node) {
attribute_string_writer writer(dialect_, std::nullopt);
internal::basic_type_to_string_visitor v(writer, query_);
std::visit(v, node.value());
expression_.append(v.result);
}
void expression_evaluator::visit(const placeholder_expression& node) {
query_.bind_vars.emplace_back(std::string("value_") + std::to_string(query_.bind_vars.size() + 1));
expression_.append(dialect_.next_placeholder(query_.bind_vars));
}
}
@@ -17,7 +17,7 @@ query_update_intermediate::query_update_intermediate(const table& tab) {
// context_->parts.push_back(std::make_unique<internal::query_set_part>(std::move(columns)));
// return {context_};
// }
query_update_intermediate& query_update_intermediate::set(const table_column &col, column_expression_ptr expression) {
query_update_intermediate& query_update_intermediate::set(const table_column &col, column_expression&& expression) {
key_value_pairs_.emplace_back(col, std::move(expression));
return *this;
}
+30
View File
@@ -1,9 +1,39 @@
#include "matador/query/query_utils.hpp"
#include "matador/query/attribute_string_writer.hpp"
#include "matador/query/table.hpp"
#include "matador/query/internal/string_builder_utils.hpp"
#include "matador/query/expression_evaluator.hpp"
#include "matador/sql/dialect.hpp"
#include "matador/sql/query_context.hpp"
namespace matador::query {
void prepare_column(sql::query_context& ctx, const sql::dialect& d, const table_column& col) {
// Expression-backed select item: (<expr>) [AS alias]
if (col.is_expression()) {
// attribute_string_writer writer(d);
expression_evaluator v(d, ctx);
col.expression()->accept(v);
if (col.has_alias()) {
ctx.sql.append(" ").append(d.as()).append(" ").append(col.alias());
}
return;
}
// Existing behavior: plain column or function
if (!col.is_function()) {
prepare_identifier_string_append(ctx.sql, col.name(), d);
} else {
if (col.column_name() == d.asterisk()) {
ctx.sql += d.sql_function_at(col.function()) + "(" + col.column_name() + ")";
} else {
ctx.sql += d.sql_function_at(col.function()) + "(" + col.column_name() + ") " + d.as() + " " + col.alias();
}
}
}
void prepare_column(std::string &out, const sql::dialect &d, const table_column &col) {
if (!col.is_function()) {
prepare_identifier_string_append(out, col.name(), d);
+8
View File
@@ -144,6 +144,14 @@ void table_column::table(const query::table* tab) {
canonical_name_ = build_canonical_name(table_, column_name_);
}
bool table_column::is_expression() const {
return static_cast<bool>(expression_);
}
const column_expression_ptr& table_column::expression() const {
return expression_;
}
table_column::operator const std::string&() const {
return name();
}
+1 -1
View File
@@ -2,7 +2,7 @@
#include "matador/query/query.hpp"
#include "matador/query/criteria.hpp"
#include "matador/query/error_code.hpp"
#include "matador/query/internal/column_value_pair.hpp"
#include "matador/query/expression/expression_operators.hpp"
namespace matador::query {
table_pk_generator::table_pk_generator(const std::string& table_name, const std::string &sequence_name)