mutable
A Database System for Research and Fast Prototyping
Loading...
Searching...
No Matches
mutable.cpp
Go to the documentation of this file.
1#include <mutable/mutable.hpp>
2
5#include "backend/WebAssembly.hpp"
7#include "lex/Lexer.hpp"
8#include "parse/Parser.hpp"
9#include "parse/Sema.hpp"
10#include <cerrno>
11#include <fstream>
13#include <mutable/io/Reader.hpp>
14#include <mutable/IR/Tuple.hpp>
15#include <mutable/Options.hpp>
17
18
19using namespace m;
20using namespace m::ast;
21
22
23bool m::init() { return streq(m::version::GIT_REV, m::version::get().GIT_REV); }
24
25std::unique_ptr<Stmt> m::statement_from_string(Diagnostic &diag, const std::string &str)
26{
27 Catalog &C = Catalog::Get();
28
29 std::istringstream in(str);
30 Lexer lexer(diag, C.get_pool(), "-", in);
31 Parser parser(lexer);
32 auto stmt = M_TIME_EXPR(std::unique_ptr<Stmt>(parser.parse_Stmt()), "Parse the statement", C.timer());
33 if (diag.num_errors() != 0)
34 throw frontend_exception("syntactic error in statement");
35 M_insist(diag.num_errors() == 0);
36
37 Sema sema(diag);
38 M_TIME_EXPR(sema(*stmt), "Semantic analysis", C.timer());
39 if (diag.num_errors() != 0)
40 throw frontend_exception("semantic error in statement");
41 M_insist(diag.num_errors() == 0);
42
43 return stmt;
44}
45
46std::unique_ptr<DatabaseCommand> m::command_from_string(Diagnostic &diag, const std::string &str)
47{
48 Catalog &C = Catalog::Get();
49
50 std::istringstream in(str);
51 Lexer lexer(diag, C.get_pool(), "-", in);
52 Parser parser(lexer);
53 auto stmt = M_TIME_EXPR(std::unique_ptr<Stmt>(parser.parse_Stmt()), "Parse the statement", C.timer());
54 if (diag.num_errors() != 0)
55 throw frontend_exception("syntactic error in statement");
56 M_insist(diag.num_errors() == 0);
57
58 Sema sema(diag);
59 auto cmd = M_TIME_EXPR(sema.analyze(std::move(stmt)), "Semantic analysis", C.timer());
60 if (diag.num_errors() != 0)
61 throw frontend_exception("semantic error in statement");
62 M_insist(diag.num_errors() == 0);
63
64 return cmd;
65}
66
67void m::process_stream(std::istream &in, const char *filename, Diagnostic diag)
68{
69 Catalog &C = Catalog::Get();
70
71 /*----- Process the input stream. --------------------------------------------------------------------------------*/
72 ast::Lexer lexer(diag, C.get_pool(), filename, in);
73 ast::Parser parser(lexer);
74
75 while (parser.token()) {
76 bool err = false;
77 diag.clear();
78 Timer &timer = C.timer();
79 auto ast = parser.parse();
80 C.scheduler().autocommit(std::move(ast), diag);
81
82 if (Options::Get().times) {
83 using namespace std::chrono;
84 for (const auto &M : timer) {
85 if (M.is_finished())
86 std::cout << M.name << ": " << duration_cast<microseconds>(M.duration()).count() / 1e3 << '\n';
87 }
88 std::cout.flush();
89 timer.clear();
90 }
91 }
92
93 std::cout.flush();
94 std::cerr.flush();
95}
96
97std::unique_ptr<Instruction> m::instruction_from_string(Diagnostic &diag, const std::string &str)
98{
99 Catalog &C = Catalog::Get();
100
101 std::istringstream in(str);
102 Lexer lexer(diag, C.get_pool(), "-", in);
103 Parser parser(lexer);
104 auto instruction = M_TIME_EXPR(parser.parse_Instruction(), "Parse the instruction", C.timer());
105 if (diag.num_errors() != 0)
106 throw frontend_exception("syntactic error in instruction");
107 M_insist(diag.num_errors() == 0);
108
109 return instruction;
110}
111
112void m::execute_statement(Diagnostic &diag, const ast::Stmt &stmt, const bool is_stdin)
113{
114 diag.clear();
115 Catalog &C = Catalog::Get();
116 auto timer = C.timer();
117
118 if (is<const ast::SelectStmt>(stmt)) {
119 auto query_graph = M_TIME_EXPR(QueryGraph::Build(stmt), "Construct the query graph", timer);
120 if (Options::Get().graph) query_graph->dump(std::cout);
121 if (Options::Get().graphdot) {
122 DotTool dot(diag);
123 query_graph->dot(dot.stream());
124 dot.show("graph", is_stdin, "fdp");
125 }
126 if (Options::Get().graph2sql) {
127 query_graph->sql(std::cout);
128 std::cout.flush();
129 }
131 std::unique_ptr<Producer> optree;
132 if (Options::Get().output_partial_plans_file) {
133 auto res = M_TIME_EXPR(
135 "Compute the logical query plan",
136 timer
137 );
138 optree = std::move(res.first);
139
140 std::filesystem::path JSON_path(Options::Get().output_partial_plans_file);
141 errno = 0;
142 std::ofstream JSON_file(JSON_path);
143 if (not JSON_file or errno) {
144 const auto errsv = errno;
145 if (errsv) {
146 diag.err() << "Failed to open output file for partial plans " << JSON_path << ": "
147 << strerror(errsv) << std::endl;
148 } else {
149 diag.err() << "Failed to open output file for partial plans " << JSON_path << std::endl;
150 }
151 } else {
152 auto for_each = [&res](PartialPlanGenerator::callback_type callback) {
154 };
155 PartialPlanGenerator{}.write_partial_plans_JSON(JSON_file, *query_graph, res.second, for_each);
156 }
157 } else {
158 optree = M_TIME_EXPR(Opt(*query_graph), "Compute the logical query plan", timer);
159 }
160 M_insist(bool(optree), "optree must have been computed");
161 if (Options::Get().plan) optree->dump(std::cout);
162 if (Options::Get().plandot) {
163 DotTool dot(diag);
164 optree->dot(dot.stream());
165 dot.show("logical_plan", is_stdin);
166 }
167
168 std::unique_ptr<Consumer> logical_plan;
169 if (Options::Get().benchmark)
170 logical_plan = std::make_unique<NoOpOperator>(std::cout);
171 else
172 logical_plan = std::make_unique<PrintOperator>(std::cout);
173 logical_plan->add_child(optree.release());
174
175 static thread_local std::unique_ptr<Backend> backend;
176 if (not backend)
177 backend = M_TIME_EXPR(C.create_backend(), "Create backend", timer);
178
180 backend->register_operators(PhysOpt);
181 M_TIME_EXPR(PhysOpt.cover(*logical_plan), "Compute the physical query plan", timer);
182 auto physical_plan = PhysOpt.extract_plan();
183
184 if (Options::Get().physplan)
185 physical_plan->dump(std::cout);
186
187 if (not Options::Get().dryrun)
188 M_TIME_EXPR(backend->execute(*physical_plan), "Execute query", timer);
189 } else if (auto I = cast<const ast::InsertStmt>(&stmt)) {
190 auto &DB = C.get_database_in_use();
191 auto &T = DB.get_table(I->table_name.text.assert_not_none());
192 auto &store = T.store();
193 StoreWriter W(store);
194 auto &S = W.schema();
195 Tuple tup(S);
196
197 /* Write all tuples to the store. */
198 for (auto &t : I->tuples) {
199 StackMachine get_tuple(Schema{});
200 for (std::size_t i = 0; i != t.size(); ++i) {
201 auto &v = t[i];
202 switch (v.first) {
204 get_tuple.emit_St_Tup_Null(0, i);
205 break;
206
208 /* nothing to be done, Tuples are initialized to default values */
209 break;
210
212 get_tuple.emit(*v.second);
213 get_tuple.emit_Cast(S[i].type, v.second->type());
214 get_tuple.emit_St_Tup(0, i, S[i].type);
215 break;
216 }
217 }
218 Tuple *args[] = { &tup };
219 get_tuple(args);
220 W.append(tup);
221 }
222 } else if (auto S = cast<const ast::CreateDatabaseStmt>(&stmt)) {
223 C.add_database(S->database_name.text.assert_not_none());
224 } else if (auto S = cast<const ast::DropDatabaseStmt>(&stmt)) {
225 M_unreachable("not implemented");
226 } else if (auto S = cast<const ast::UseDatabaseStmt>(&stmt)) {
227 auto &DB = C.get_database(S->database_name.text.assert_not_none());
229 } else if (auto S = cast<const ast::CreateTableStmt>(&stmt)) {
230 auto &DB = C.get_database_in_use();
231 auto &T = DB.add_table(S->table_name.text.assert_not_none());
232
233 for (auto &attr : S->attributes) {
234 const PrimitiveType *ty = cast<const PrimitiveType>(attr->type);
235 auto attribute_name = attr->name.text.assert_not_none();
236
237 T.push_back(attribute_name, ty->as_vectorial());
238 for (auto &c : attr->constraints) {
240 [&](const PrimaryKeyConstraint&) {
241 T.add_primary_key(attribute_name);
242 },
243 [&](const UniqueConstraint&) {
244 T.at(attribute_name).unique = true;
245 },
246 [&](const NotNullConstraint&) {
247 T.at(attribute_name).not_nullable = true;
248 },
249 [&](const ReferenceConstraint &ref) {
250 auto &ref_table = DB.get_table(ref.table_name.text.assert_not_none());
251 auto &ref_attr = ref_table.at(ref.attr_name.text.assert_not_none());
252 T.at(attribute_name).reference = &ref_attr;
253 },
254 [](auto&&) { M_unreachable("constraint not implemented"); },
256 }
257 }
258
259 T.layout(C.data_layout());
260 T.store(C.create_store(T));
261 } else if (auto S = cast<const ast::DropTableStmt>(&stmt)) {
262 M_unreachable("not implemented");
263 } else if (auto S = cast<const ast::DSVImportStmt>(&stmt)) {
264 auto &DB = C.get_database_in_use();
265 auto &T = DB.get_table(S->table_name.text.assert_not_none());
266
268 if (S->rows) cfg.num_rows = strtol(*S->rows.text, nullptr, 10);
269 if (S->delimiter) cfg.delimiter = unescape(*S->delimiter.text)[1];
270 if (S->escape) cfg.escape = unescape(*S->escape.text)[1];
271 if (S->quote) cfg.quote = unescape(*S->quote.text)[1];
272 cfg.has_header = S->has_header;
273 cfg.skip_header = S->skip_header;
274
275 try {
276 DSVReader R(T, std::move(cfg), diag);
277
278 std::string filename(*S->path.text, 1, strlen(*S->path.text) - 2);
279 errno = 0;
280 std::ifstream file(filename);
281 if (not file) {
282 const auto errsv = errno;
283 diag.e(S->path.pos) << "Could not open file '" << S->path.text << '\'';
284 if (errsv)
285 diag.err() << ": " << strerror(errsv);
286 diag.err() << std::endl;
287 } else {
288 M_TIME_EXPR(R(file, *S->path.text), "Read DSV file", timer);
289 }
290 } catch (m::invalid_argument e) {
291 diag.err() << "Error reading DSV file: " << e.what() << "\n";
292 }
293 }
294
295 if (Options::Get().times) {
296 using namespace std::chrono;
297 for (const auto &M : timer) {
298 if (M.is_finished())
299 std::cout << M.name << ": " << duration_cast<microseconds>(M.duration()).count() / 1e3 << '\n';
300 }
301 std::cout.flush();
302 timer.clear();
303 }
304
305 std::cout.flush();
306 std::cerr.flush();
307}
308
309void m::execute_instruction(Diagnostic &diag, const Instruction &instruction)
310{
311 diag.clear();
312 Catalog &C = Catalog::Get();
313
314 try {
315 auto I = C.create_instruction(instruction.name, instruction.args);
316 I->execute(diag);
317 } catch (const std::exception &e) {
318 diag.e(instruction.tok.pos) << "Instruction " << instruction.name << " does not exist.\n";
319 }
320}
321
322std::unique_ptr<Consumer> m::logical_plan_from_statement(Diagnostic&, const SelectStmt &stmt,
323 std::unique_ptr<Consumer> consumer)
324{
325 Catalog &C = Catalog::Get();
326 auto query_graph = M_TIME_EXPR(QueryGraph::Build(stmt), "Construct the query graph", C.timer());
327
329 auto optree = M_TIME_EXPR(Opt(*query_graph), "Compute the logical query plan", C.timer());
330
331 consumer->add_child(optree.release());
332
333 return consumer;
334}
335
336std::unique_ptr<MatchBase> m::physical_plan_from_logical_plan(Diagnostic &diag, const Consumer &logical_plan)
337{
338 auto &C = Catalog::Get();
339 static thread_local std::unique_ptr<Backend> backend;
340 if (not backend)
341 backend = M_TIME_EXPR(C.create_backend(), "Create backend", C.timer());
342 return physical_plan_from_logical_plan(diag, logical_plan, *backend);
343}
344
345std::unique_ptr<MatchBase> m::physical_plan_from_logical_plan(Diagnostic&, const Consumer &logical_plan,
346 const Backend &backend)
347{
349 backend.register_operators(PhysOpt);
350 M_TIME_EXPR(PhysOpt.cover(logical_plan), "Compute the physical query plan", Catalog::Get().timer());
351 return PhysOpt.extract_plan();
352}
353
354void m::execute_physical_plan(Diagnostic &diag, const MatchBase &physical_plan)
355{
356 auto &C = Catalog::Get();
357 static thread_local std::unique_ptr<Backend> backend;
358 if (not backend)
359 backend = M_TIME_EXPR(C.create_backend(), "Create backend", C.timer());
360 execute_physical_plan(diag, physical_plan, *backend);
361}
362
363void m::execute_physical_plan(Diagnostic&, const MatchBase &physical_plan, const Backend &backend)
364{
365 M_TIME_EXPR(backend.execute(physical_plan), "Execute query", Catalog::Get().timer());
366}
367
368void m::execute_query(Diagnostic &diag, const SelectStmt &stmt, std::unique_ptr<Consumer> consumer)
369{
370 auto &C = Catalog::Get();
371 static thread_local std::unique_ptr<Backend> backend;
372 if (not backend)
373 backend = M_TIME_EXPR(C.create_backend(), "Create backend", C.timer());
374 execute_query(diag, stmt, std::move(consumer), *backend);
375}
376
377void m::execute_query(Diagnostic &diag, const SelectStmt &stmt, std::unique_ptr<Consumer> consumer,
378 const Backend &backend)
379{
380 auto logical_plan = logical_plan_from_statement(diag, stmt, std::move(consumer));
381 auto physical_plan = physical_plan_from_logical_plan(diag, *logical_plan, backend);
382 execute_physical_plan(diag, *physical_plan, backend);
383}
384
385void m::load_from_CSV(Diagnostic &diag, Table &table, const std::filesystem::path &path, std::size_t num_rows,
386 bool has_header, bool skip_header)
387{
388 diag.clear();
389 auto cfg = DSVReader::Config::CSV();
390 cfg.num_rows = num_rows;
391 cfg.has_header = has_header;
392 cfg.skip_header = skip_header;
393 DSVReader R(table, std::move(cfg), diag);
394
395 errno = 0;
396 std::ifstream file(path);
397 if (not file) {
398 diag.e(Position(path.c_str())) << "Could not open file '" << path << '\'';
399 if (errno)
400 diag.err() << ": " << strerror(errno);
401 diag.err() << std::endl;
402 } else {
403 R(file, path.c_str()); // read the file
404 }
405
406 if (diag.num_errors() != 0)
407 throw runtime_error("error while reading CSV file");
408}
409
410void m::execute_file(Diagnostic &diag, const std::filesystem::path &path)
411{
412 diag.clear();
413 auto &C = Catalog::Get();
414
415 errno = 0;
416 std::ifstream in(path);
417 if (not in) {
418 auto errsv = errno;
419 std::cerr << "Could not open '" << path << "'";
420 if (errno)
421 std::cerr << ": " << std::strerror(errsv);
422 std::cerr << std::endl;
423 exit(EXIT_FAILURE);
424 }
425
426 Lexer lexer(diag, C.get_pool(), path.c_str(), in);
427 Parser parser(lexer);
428 Sema sema(diag);
429
430 while (parser.token()) {
431 std::unique_ptr<Command> command(parser.parse());
432 if (diag.num_errors()) return;
433 if (auto inst = cast<Instruction>(command)) {
434 execute_instruction(diag, *inst);
435 } else {
436 auto stmt = as<Stmt>(std::move(command));
437 sema(*stmt);
438 if (diag.num_errors()) return;
439 execute_statement(diag, *stmt);
440 }
441 }
442}
443
444m::StoreWriter::StoreWriter(Store &store) : store_(store), S(store.table().schema()) { }
445
447
448void m::StoreWriter::append(const Tuple &tup) const
449{
450 store_.append();
451 if (layout_ != &store_.table().layout()) {
452 layout_ = &store_.table().layout();
453 writer_ = std::make_unique<m::StackMachine>(m::Interpreter::compile_store(S, store_.memory().addr(), *layout_,
454 S, store_.num_rows() - 1));
455 }
456
457 Tuple *args[] = { const_cast<Tuple*>(&tup) };
458 (*writer_)(args);
459}
#define M_TIME_EXPR(EXPR, DESCR, TIMER)
Definition: Timer.hpp:177
struct @5 args
#define M_unreachable(MSG)
Definition: macro.hpp:146
#define M_insist(...)
Definition: macro.hpp:129
M_EXPORT const version_info & get()
Definition: version.cpp:4
‍mutable namespace
Definition: Backend.hpp:10
void M_EXPORT load_from_CSV(Diagnostic &diag, Table &table, const std::filesystem::path &path, std::size_t num_rows=std::numeric_limits< std::size_t >::max(), bool has_header=false, bool skip_header=false)
Loads a CSV file into a Table.
Definition: mutable.cpp:385
std::unique_ptr< Consumer > M_EXPORT logical_plan_from_statement(Diagnostic &diag, const ast::SelectStmt &stmt, std::unique_ptr< Consumer > consumer)
Optimizes the given SelectStmt.
Definition: mutable.cpp:322
void M_EXPORT process_stream(std::istream &in, const char *filename, Diagnostic diag)
Extracts and executes statements from given stream.
Definition: mutable.cpp:67
std::unique_ptr< DatabaseCommand > M_EXPORT command_from_string(Diagnostic &diag, const std::string &str)
Create a DatabaseCommand from str.
Definition: mutable.cpp:46
void M_EXPORT execute_statement(Diagnostic &diag, const ast::Stmt &stmt, bool is_stdin=false)
Optimizes and executes the given Stmt.
Definition: mutable.cpp:112
std::unique_ptr< ast::Instruction > M_EXPORT instruction_from_string(Diagnostic &diag, const std::string &str)
Use lexer and parser to create an Instruction from str.
Definition: mutable.cpp:97
bool streq(const char *first, const char *second)
Definition: fn.hpp:29
std::string M_EXPORT unescape(const std::string &str, char esc='\\', char quote='"')
Definition: fn.cpp:35
void M_EXPORT execute_instruction(Diagnostic &diag, const ast::Instruction &instruction)
Executes the given Instruction.
Definition: mutable.cpp:309
void M_EXPORT execute_physical_plan(Diagnostic &diag, const MatchBase &physical_plan)
Executes the given physical plan.
Definition: mutable.cpp:354
T(x)
void M_EXPORT execute_file(Diagnostic &diag, const std::filesystem::path &path)
Execute the SQL file at path.
Definition: mutable.cpp:410
std::unique_ptr< ast::Stmt > M_EXPORT statement_from_string(Diagnostic &diag, const std::string &str)
Use lexer, parser, and semantic analysis to create a Stmt from str.
Definition: mutable.cpp:25
void M_EXPORT execute_query(Diagnostic &diag, const ast::SelectStmt &stmt, std::unique_ptr< Consumer > consumer)
Optimizes and executes the given SelectStmt.
Definition: mutable.cpp:368
bool M_EXPORT init(void)
Initializes the mu*t*able library.
Definition: mutable.cpp:23
auto visit(Callable &&callable, Base &obj, m::tag< Callable > &&=m::tag< Callable >())
Generic implementation to visit a class hierarchy, with similar syntax as std::visit.
Definition: Visitor.hpp:138
std::unique_ptr< MatchBase > M_EXPORT physical_plan_from_logical_plan(Diagnostic &diag, const Consumer &logical_plan)
Computes a physical plan from the given logical plan.
Definition: mutable.cpp:336
Defines the interface of all execution Backends.
Definition: Backend.hpp:17
virtual void register_operators(PhysicalOptimizer &phys_opt) const =0
Registers all physical operators of this Backend in phys_opt.
virtual void execute(const MatchBase &plan) const =0
Executes the already computed physical covering represented by plan using this Backend.
The catalog contains all Databases and keeps track of all meta information of the database system.
Definition: Catalog.hpp:215
CostFunction & cost_function() const
Returns a reference to the default CostFunction.
Definition: Catalog.hpp:502
ThreadSafeStringPool & get_pool()
Returns a reference to the StringPool.
Definition: Catalog.hpp:259
Database & get_database_in_use()
Returns a reference to the Database that is currently in use, if any.
Definition: Catalog.hpp:295
Database & get_database(const ThreadSafePooledString &name) const
Returns the Database with the given name.
Definition: Catalog.hpp:283
std::unique_ptr< Store > create_store(const Table &tbl) const
Creates a new Store for the given Table tbl.
Definition: Catalog.hpp:352
Database & add_database(ThreadSafePooledString name)
Creates a new Database with the given name.
Definition: Catalog.cpp:58
static Catalog & Get()
Return a reference to the single Catalog instance.
std::unique_ptr< DatabaseInstruction > create_instruction(const ThreadSafePooledString &name, const std::vector< std::string > &args) const
Returns a reference to the DatabaseInstruction with the given name.
Definition: Catalog.hpp:528
Timer & timer()
Returns the global Timer instance.
Definition: Catalog.hpp:264
Scheduler & scheduler() const
Returns a reference to the default Scheduler.
Definition: Catalog.hpp:553
void set_database_in_use(Database &db)
Sets the Database db as the Database that is currently in use.
Definition: Catalog.hpp:303
storage::DataLayoutFactory & data_layout() const
Returns a reference to the default DataLayoutFactory.
Definition: Catalog.hpp:379
pe::PlanEnumerator & plan_enumerator() const
Returns a reference to the default PlanEnumerator.
Definition: Catalog.hpp:441
std::unique_ptr< Backend > create_backend() const
Returns a new Backend.
Definition: Catalog.hpp:477
A Consumer is an Operator that can be evaluated on a sequence of tuples.
Definition: Operator.hpp:133
Configuration parameters for importing a DSV file.
Definition: Reader.hpp:45
static Config CSV()
Creates a Config for CSV files, with delimiter, escape, and quote set accordingly to RFC 4180 (see ht...
Definition: Reader.hpp:61
char delimiter
‍the delimiter separating cells
Definition: Reader.hpp:47
char quote
‍the quotation mark for strings
Definition: Reader.hpp:49
bool skip_header
‍whether to ignore the headline (requires has_header = true)
Definition: Reader.hpp:55
char escape
‍the character to escape special characters within strings, e.g. \n
Definition: Reader.hpp:51
bool has_header
‍whether the first line of the file is a headline describing the columns
Definition: Reader.hpp:53
std::size_t num_rows
‍the maximum number of rows to read from the file (may exceed actual number of rows)
Definition: Reader.hpp:57
A reader for delimiter separated value (DSV) files.
Definition: Reader.hpp:30
std::ostream & e(const Position pos)
Definition: Diagnostic.hpp:41
void clear()
Resets the error counter.
Definition: Diagnostic.hpp:50
unsigned num_errors() const
Returns the number of errors emitted since the last call to clear().
Definition: Diagnostic.hpp:48
std::ostream & err()
Definition: Diagnostic.hpp:53
This class enables direct rendering of dot output (e.g.
Definition: DotTool.hpp:14
std::ostream & stream()
Definition: DotTool.hpp:27
void show(const char *name, bool interactive, const char *algo=DEFAULT_LAYOUT_ALGORITHM)
Present the graph to the user.
Definition: DotTool.cpp:84
static StackMachine compile_store(const Schema &tuple_schema, void *address, const storage::DataLayout &layout, const Schema &layout_schema, std::size_t row_id=0, std::size_t tuple_id=0)
Compile a StackMachine to store a tuple of Schema tuple_schema using a given memory address and a giv...
The optimizer interface.
Definition: Optimizer.hpp:19
std::pair< std::unique_ptr< Producer >, PlanTable > optimize_with_plantable(QueryGraph &G) const
Recursively computes and constructs an optimal logical plan for the given query graph G,...
Definition: Optimizer.cpp:185
static Options & Get()
Return a reference to the single Options instance.
Definition: Options.cpp:9
A partial plan is a set of (potentially incomplete) pairwise disjoint plans.
void for_each_complete_partial_plan(const PlanTable &PT, callback_type callback)
Given a PlanTable with a final plan, enumerate all complete partial plans of this final plan and invo...
void write_partial_plans_JSON(std::ostream &out, const QueryGraph &G, const PlanTable &PT, std::function< void(callback_type)> for_each_partial_plan)
std::function< void(const partial_plan_type &)> callback_type
Concrete PhysicalOptimizer implementation using a concrete statically-typed.
void cover(const Operator &plan) override
Finds an optimal physical operator covering for the logical plan rooted in plan.
std::unique_ptr< MatchBase > extract_plan() override
Extracts the found physical operator covering by moving it out of the underlying physical plan table.
This table represents all explored plans with their sub-plans, estimated size, cost,...
Definition: PlanTable.hpp:284
PrimitiveTypes represent Types of values.
Definition: Type.hpp:159
virtual const PrimitiveType * as_vectorial() const =0
Convert this PrimitiveType to its vectorial equivalent.
static std::unique_ptr< QueryGraph > Build(const ast::Stmt &stmt)
bool autocommit(std::unique_ptr< ast::Command > command, Diagnostic &diag)
Schedule a ast::Command for execution and automatically commits its changes.
Definition: Scheduler.cpp:9
A Schema represents a sequence of identifiers, optionally with a prefix, and their associated types.
Definition: Schema.hpp:39
A stack machine that evaluates an expression.
This class provides direct write access to the contents of a Store.
Definition: mutable.hpp:116
void append(const Tuple &tup) const
Appends tup to the store.
Definition: mutable.cpp:448
const Schema & schema() const
Returns the Schema of Tuples to write.
Definition: mutable.hpp:128
StoreWriter(Store &store)
Definition: mutable.cpp:444
Defines a generic store interface.
Definition: Store.hpp:22
A table is a sorted set of attributes.
Definition: Schema.hpp:388
Collect timings of events.
Definition: Timer.hpp:17
Token tok
‍the token of the Instruction; starts with \
Definition: AST.hpp:771
ThreadSafePooledString name
‍the name of the Instruction (without leading \‍)
Definition: AST.hpp:773
std::vector< std::string > args
‍the arguments to the Instruction; may be empty
Definition: AST.hpp:775
const Token & token()
Definition: Parser.hpp:38
std::unique_ptr< Stmt > parse_Stmt()
Definition: Parser.cpp:133
std::unique_ptr< Command > parse()
Definition: Parser.cpp:98
std::unique_ptr< Instruction > parse_Instruction()
Definition: Parser.cpp:106
A SQL select statement.
Definition: AST.hpp:936
std::unique_ptr< DatabaseCommand > analyze(std::unique_ptr< ast::Command > ast)
Perform semantic analysis of an ast::Command.
Definition: Sema.cpp:15
A SQL statement.
Definition: AST.hpp:794
Position pos
Definition: Token.hpp:15
const char * what() const noexcept override
Definition: exception.hpp:17
Signals that an argument to a function of method was invalid.
Definition: exception.hpp:37
Signals a runtime error that mu*t*able is not responsible for and that mu*t*able was not able to reco...
Definition: exception.hpp:49
Definition: tag.hpp:8