15 static uint64_t
id(0);
16 std::ostringstream oss;
19 return C.
pool(oss.str().c_str());
29 for (
auto &f :
from) {
30 if (
Stmt **stmt = std::get_if<Stmt*>(&f.source))
43 auto h = hash<ThreadSafePooledOptionalString>{}(
attr_name.
text);
45 return std::rotl(hash<ThreadSafePooledString>{}(
get_table_name()), 17) xor h;
53 return hash<ThreadSafePooledOptionalString>{}(
tok.
text);
58 uint64_t
hash =
fn->hash();
59 for (
auto &arg :
args)
60 hash ^= std::rotl(
hash, 31) xor arg->hash();
66 return std::rotl(
expr->hash(), 13) xor uint64_t(
op().
type);
71 const auto hl =
lhs->hash();
72 const auto hr =
rhs->hash();
73 return std::rotl(hl, 41) xor std::rotl(hr, 17) xor uint64_t(
op().
type);
79 return h(
query.get());
91 if (
auto other = cast<const Designator>(&o)) {
92 if (this->
has_table_name() != other->has_table_name())
return false;
100 if (
auto other = cast<const Constant>(&o))
101 return this->
tok.
text == other->tok.text;
107 if (
auto other = cast<const FnApplicationExpr>(&o)) {
108 if (*this->
fn != *other->fn)
return false;
109 if (this->
args.size() != other->args.size())
return false;
110 for (std::size_t i = 0, end = this->
args.size(); i != end; ++i) {
111 if (*this->
args[i] != *other->args[i])
121 if (
auto other = cast<const UnaryExpr>(&o))
122 return this->
op().
text == other->op().text
and *this->
expr == *other->expr;
128 if (
auto other = cast<const BinaryExpr>(&o))
129 return this->
op().
text == other->op().text
and *this->
lhs == *other->lhs
and *this->
rhs == *other->rhs;
135 if (
auto other = cast<const QueryExpr>(&e))
136 return this->
query.get() == other->query.get();
151 if (d.type()->is_primitive()) {
153 if (not schema.
has(
id))
154 schema.
add(std::move(
id), d.type());
158 if (fn.get_function().is_aggregate()) {
160 static std::ostringstream oss;
164 if (not schema.
has(
id))
165 schema.
add(std::move(
id), fn.type());
179std::ostream & m::ast::operator<<(std::ostream &out,
const Expr &e) {
181 p.expand_nested_queries(
false);
186std::ostream & m::ast::operator<<(std::ostream &out,
const Clause &c) {
188 p.expand_nested_queries(
false);
193std::ostream & m::ast::operator<<(std::ostream &out,
const Command &cmd) {
195 p.expand_nested_queries(
false);
261 auto &stmt = as<const SelectStmt>(*
query);
262 if (stmt.from)
return false;
263 auto &select = as<const SelectClause>(*stmt.select);
264 M_insist(select.select.size() == 1);
265 if (not select.select[0].first->is_constant())
272 auto &stmt = as<const SelectStmt>(*
query);
273 auto &select = as<const SelectClause>(*stmt.select);
274 M_insist(select.select.size() == 1);
275 if (select.select[0].first->can_be_null())
287#define ACCEPT(CLASS) \
288 void CLASS::accept(ASTExprVisitor &v) { v(*this); } \
289 void CLASS::accept(ConstASTExprVisitor &v) const { v(*this); }
300template<
bool C,
bool PreOrder>
304 template<
typename T>
using Const =
typename super::template Const<T>;
305 using callback_t = std::conditional_t<C, ConstASTExprVisitor, ASTExprVisitor>;
308 callback_t &callback_;
311 recursive_expr_visitor(callback_t &callback) : callback_(callback) { }
313 using super::operator();
314 void operator()(Const<ErrorExpr> &e)
override { callback_(e); }
315 void operator()(Const<Designator> &e)
override { callback_(e); }
316 void operator()(Const<Constant> &e)
override { callback_(e); }
317 void operator()(Const<QueryExpr> &e)
override { callback_(e); }
319 void operator()(Const<FnApplicationExpr> &e)
override {
321 super::operator()(e);
322 if constexpr (not PreOrder) callback_(e);
325 void operator()(Const<UnaryExpr> &e)
override {
327 super::operator()(e);
328 if constexpr (not PreOrder) callback_(e);
331 void operator()(Const<BinaryExpr> &e)
override {
333 super::operator()(e);
334 if constexpr (not PreOrder) callback_(e);
343 recursive_expr_visitor<C,
true>{*
this}(e);
349 recursive_expr_visitor<C,
false>{*
this}(e);
361#define ACCEPT(CLASS) \
362 void CLASS::accept(ASTClauseVisitor &v) { v(*this); } \
363 void CLASS::accept(ConstASTClauseVisitor &v) const { v(*this); }
369#define ACCEPT(CLASS) \
370 void CLASS::accept(ASTConstraintVisitor &v) { v(*this); } \
371 void CLASS::accept(ConstASTConstraintVisitor &v) const { v(*this); }
377#define ACCEPT(CLASS) \
378 void CLASS::accept(ASTCommandVisitor &v) { v(*this); } \
379 void CLASS::accept(ConstASTCommandVisitor &v) const { v(*this); }
#define M_AST_EXPR_LIST(X)
#define M_AST_CONSTRAINT_LIST(X)
#define M_AST_COMMAND_LIST(X)
#define M_AST_CLAUSE_LIST(X)
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.
The catalog contains all Databases and keeps track of all meta information of the database system.
ThreadSafePooledString pool(const char *str) const
Creates an internalized copy of the string str by adding it to the internal StringPool.
static Catalog & Get()
Return a reference to the single Catalog instance.
A data type representing a pooled (or internalized) object.
An Identifier is composed of a name and an optional prefix.
A Schema represents a sequence of identifiers, optionally with a prefix, and their associated types.
void add(entry_type e)
Adds the entry e to this Schema.
bool has(const Identifier &id) const
Returns true iff this Schema contains an entry with Identifier id.
Implements printing the AST in dot language.
Dumps a textual representation of the AST to an output stream.
Pretty-prints the AST in SQL.
std::unique_ptr< Expr > lhs
uint64_t hash() const override
Computes a hash of this, considering only syntactic properties.
bool operator==(const Expr &other) const override
Returns true iff other is syntactically equal to this.
std::unique_ptr< Expr > rhs
void dot(std::ostream &out) const
bool operator==(const Expr &other) const override
Returns true iff other is syntactically equal to this.
uint64_t hash() const override
Computes a hash of this, considering only syntactic properties.
ThreadSafePooledString get_table_name() const
uint64_t hash() const override
Computes a hash of this, considering only syntactic properties.
bool has_table_name() const
bool operator==(const Expr &other) const override
Returns true iff other is syntactically equal to this.
bool operator==(const Expr &other) const override
Returns true iff other is syntactically equal to this.
void dot(std::ostream &out) const
Writes a Graphivz dot representation of this Expr to out.
const Type * type() const
Returns the Type of this Expr.
Schema get_required() const
Returns a Schema instance containing all required definitions.
Token tok
the token of the expression; serves as an anchor to locate the expression in the source
uint64_t hash() const override
Computes a hash of this, considering only syntactic properties.
std::vector< std::unique_ptr< Expr > > args
bool operator==(const Expr &other) const override
Returns true iff other is syntactically equal to this.
std::unique_ptr< Expr > fn
std::vector< from_type > from
bool operator==(const Expr &other) const override
Returns true iff other is syntactically equal to this.
uint64_t hash() const override
Computes a hash of this, considering only syntactic properties.
std::unique_ptr< Stmt > query
bool can_be_null() const override
Returns true iff this Expr is nullable, i.e.
static ThreadSafePooledString make_unique_alias()
bool is_constant() const override
Returns true iff this Expr is constant, i.e.
void dot(std::ostream &out) const
Writes a Graphivz dot representation of this Stmt to out.
void operator()(Const< Expr > &e)
typename super::template Const< T > Const
void operator()(Const< Expr > &e)
typename super::template Const< T > Const
A generic base class for implementing recursive ast::Expr visitors.
ThreadSafePooledOptionalString text
declared as optional for dummy tokens
uint64_t hash() const override
Computes a hash of this, considering only syntactic properties.
bool operator==(const Expr &other) const override
Returns true iff other is syntactically equal to this.
std::unique_ptr< Expr > expr
Exception class which can be thrown to skip recursion of the subtree in pre-order visitors.