split column expression into separate classes
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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_;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user