mutable
A Database System for Research and Fast Prototyping
Loading...
Searching...
No Matches
Sema.hpp
Go to the documentation of this file.
1#pragma once
2
7#include <sstream>
8#include <unordered_map>
9#include <vector>
10
11
12namespace m {
13
14namespace ast {
15
16struct M_EXPORT Sema : ASTVisitor
17{
20 {
23
26 enum stage_t {
34 } stage = S_From;
35
36 bool needs_grouping = false;
37
38 struct result_t
39 {
40 std::reference_wrapper<Expr> expr_;
42 unsigned order;
45
46 result_t(Expr &expr, unsigned order) : expr_(expr), order(order) { }
47 result_t(Expr &expr, unsigned order, ThreadSafePooledOptionalString alias)
48 : expr_(expr), order(order), alias(std::move(alias))
49 { }
50
51 Expr & expr() { return expr_.get(); }
52 const Expr & expr() const { return expr_.get(); }
53 };
54
56 using named_expr_table = std::unordered_multimap<ThreadSafePooledString,
57 std::pair<std::reference_wrapper<Expr>, unsigned>>;
59 using source_type = std::variant<std::monostate, std::reference_wrapper<const Table>, named_expr_table>;
61 using source_table = std::unordered_map<ThreadSafePooledString, std::pair<source_type, unsigned>>;
65 std::unordered_multimap<ThreadSafePooledString, result_t> results;
67 std::unordered_multimap<ThreadSafePooledString, std::reference_wrapper<Expr>> grouping_keys;
68
69 SemaContext(Stmt &stmt) : stmt(stmt) { }
70 };
71
72 private:
76 {
77 private:
79 bool needs_context_ = false;
80
81 public:
82 RequireContext(Sema *sema, Stmt &stmt)
83 : sema_(*M_notnull(sema))
84 , needs_context_(sema_.contexts_.empty())
85 {
86 if (needs_context_)
87 sema_.push_context(stmt);
88 }
89
91 if (needs_context_)
92 sema_.pop_context();
93 }
94 };
95
96 public:
98 private:
100 using context_stack_t = std::vector<SemaContext*>;
103 std::ostringstream oss;
105 std::unique_ptr<DatabaseCommand> command_;
106
107 public:
108 Sema(Diagnostic &diag) : diag(diag) { }
109
112 std::unique_ptr<DatabaseCommand> analyze(std::unique_ptr<ast::Command> ast);
113
114 using ASTExprVisitor::operator();
115 using ASTClauseVisitor::operator();
116 using ASTCommandVisitor::operator();
117#define DECLARE(CLASS) void operator()(CLASS&) override;
121#undef DECLARE
122
123 private:
124 SemaContext & push_context(Stmt &stmt, ThreadSafePooledOptionalString alias = {}) {
125 auto &ref = contexts_.emplace_back(new SemaContext(stmt));
126 ref->alias = std::move(alias);
127 return *ref;
128 }
130 auto ctx = *contexts_.back();
131 delete contexts_.back();
132 contexts_.pop_back();
133 return ctx;
134 }
136 M_insist(not contexts_.empty());
137 return *contexts_.back();
138 }
139 const SemaContext & get_context() const {
140 M_insist(not contexts_.empty());
141 return *contexts_.back();
142 }
143
145 bool is_nested() const;
146
147
148 /*------------------------------------------------------------------------------------------------------------------
149 * Sema Designator Helpers
150 *----------------------------------------------------------------------------------------------------------------*/
151
153 std::unique_ptr<Designator> create_designator(ThreadSafePooledString name, Token tok, const Expr &target);
154
157 std::unique_ptr<Designator> create_designator(const Expr &name, const Expr &target, bool drop_table_name = false);
158
161 std::unique_ptr<Designator> create_designator(Position pos, ThreadSafePooledString table_name,
162 ThreadSafePooledString attr_name,
163 typename Designator::target_type target, const Type *type)
164 {
165 auto &C = Catalog::Get();
166 Token dot(pos, C.pool("."), TK_DOT);
167 Token table(pos, std::move(table_name), TK_IDENTIFIER);
168 Token attr(pos, std::move(attr_name), TK_IDENTIFIER);
169 auto d = std::make_unique<Designator>(std::move(dot), std::move(table), std::move(attr));
170 d->type_ = type;
171 d->target_ = target;
172 return d;
173 }
174
177 void replace_by_fresh_designator_to(std::unique_ptr<Expr> &to_replace, const Expr &target);
178
179
180 /*------------------------------------------------------------------------------------------------------------------
181 * Other Sema Helpers
182 *----------------------------------------------------------------------------------------------------------------*/
183
185 bool is_composable_of(const ast::Expr &expr, const std::vector<std::reference_wrapper<ast::Expr>> components);
186
189 void compose_of(std::unique_ptr<ast::Expr> &ptr, const std::vector<std::reference_wrapper<ast::Expr>> components);
190
192 ThreadSafePooledOptionalString make_unique_id_from_binding_path(context_stack_t::reverse_iterator current_ctx,
193 context_stack_t::reverse_iterator binding_ctx);
194};
195
196}
197
198}
#define M_AST_COMMAND_LIST(X)
Definition: AST.hpp:1042
#define M_AST_CLAUSE_LIST(X)
Definition: AST.hpp:642
#define DECLARE(CLASS)
bool is_composable_of(const ast::Expr &expr, const std::vector< std::reference_wrapper< const ast::Expr > > components)
Computes whether the bound parts of expr are composable of elements in components.
Definition: QueryGraph.cpp:383
#define M_notnull(ARG)
Definition: macro.hpp:182
#define M_insist(...)
Definition: macro.hpp:129
‍mutable namespace
Definition: Backend.hpp:10
ThreadSafeStringPool::proxy_type ThreadSafePooledString
Definition: Pool.hpp:464
STL namespace.
A data type representing a pooled (or internalized) object.
Definition: Pool.hpp:168
This class represents types in the SQL type system.
Definition: Type.hpp:46
std::variant< std::monostate, const Expr *, const Attribute * > target_type
Definition: AST.hpp:137
An expression.
Definition: AST.hpp:39
Helper class to create a context when one is required but does not yet exist.
Definition: Sema.hpp:76
RequireContext(Sema *sema, Stmt &stmt)
Definition: Sema.hpp:82
const Expr & expr() const
Definition: Sema.hpp:52
result_t(Expr &expr, unsigned order)
Definition: Sema.hpp:46
result_t(Expr &expr, unsigned order, ThreadSafePooledOptionalString alias)
Definition: Sema.hpp:47
ThreadSafePooledOptionalString alias
‍alias of the expression; may not have a value
Definition: Sema.hpp:44
unsigned order
‍the order of this result column in the result set
Definition: Sema.hpp:42
std::reference_wrapper< Expr > expr_
Definition: Sema.hpp:40
Holds context information used by semantic analysis of a single statement.
Definition: Sema.hpp:20
source_table sources
‍list of all sources along with their order
Definition: Sema.hpp:63
std::unordered_multimap< ThreadSafePooledString, std::pair< std::reference_wrapper< Expr >, unsigned > > named_expr_table
‍list of all computed expressions along with their order
Definition: Sema.hpp:57
std::unordered_multimap< ThreadSafePooledString, result_t > results
‍list of all results computed by this statement along with their order
Definition: Sema.hpp:65
SemaContext(Stmt &stmt)
Definition: Sema.hpp:69
std::variant< std::monostate, std::reference_wrapper< const Table >, named_expr_table > source_type
‍the type of a source of data: either a database table or a nested query with named results
Definition: Sema.hpp:59
Stmt & stmt
‍the statement that is currently being analyzed and for which this SemaContext is used
Definition: Sema.hpp:25
ThreadSafePooledOptionalString alias
‍if the statement that is being analyzed is a nested query, this is its alias in the outer statement
Definition: Sema.hpp:22
std::unordered_map< ThreadSafePooledString, std::pair< source_type, unsigned > > source_table
‍associative container mapping source name to data source and its order
Definition: Sema.hpp:61
std::unordered_multimap< ThreadSafePooledString, std::reference_wrapper< Expr > > grouping_keys
‍list of grouping keys
Definition: Sema.hpp:67
std::ostringstream oss
‍used to create textual representation of complex AST objects, e.g. expressions
Definition: Sema.hpp:103
const SemaContext & get_context() const
Definition: Sema.hpp:139
Diagnostic & diag
Definition: Sema.hpp:97
context_stack_t contexts_
Definition: Sema.hpp:101
std::unique_ptr< Designator > create_designator(Position pos, ThreadSafePooledString table_name, ThreadSafePooledString attr_name, typename Designator::target_type target, const Type *type)
Creates an entirely new Designator.
Definition: Sema.hpp:161
std::vector< SemaContext * > context_stack_t
‍a stack of sema contexts; one per statement; grows by nesting statements
Definition: Sema.hpp:100
SemaContext pop_context()
Definition: Sema.hpp:129
Sema(Diagnostic &diag)
Definition: Sema.hpp:108
SemaContext & get_context()
Definition: Sema.hpp:135
std::unique_ptr< DatabaseCommand > command_
‍the command to execute when semantic analysis completes without errors
Definition: Sema.hpp:105
M_AST_EXPR_LIST(DECLARE) M_AST_CLAUSE_LIST(DECLARE) M_AST_COMMAND_LIST(DECLARE) private
Definition: Sema.hpp:118
A SQL statement.
Definition: AST.hpp:794