/* * Copyright (c) 2021, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include namespace SQL { template static inline NonnullRefPtr create_ast_node(Args&&... args) { return adopt_ref(*new T(forward(args)...)); } class ASTNode : public RefCounted { public: virtual ~ASTNode() { } protected: ASTNode() = default; }; //================================================================================================== // Language types //================================================================================================== class SignedNumber final : public ASTNode { public: explicit SignedNumber(double value) : m_value(value) { } double value() const { return m_value; } private: double m_value; }; class TypeName : public ASTNode { public: TypeName(String name, NonnullRefPtrVector signed_numbers) : m_name(move(name)) , m_signed_numbers(move(signed_numbers)) { VERIFY(m_signed_numbers.size() <= 2); } const String& name() const { return m_name; } const NonnullRefPtrVector signed_numbers() const { return m_signed_numbers; } private: String m_name; NonnullRefPtrVector m_signed_numbers; }; class ColumnDefinition : public ASTNode { public: ColumnDefinition(String name, NonnullRefPtr type_name) : m_name(move(name)) , m_type_name(move(type_name)) { } const String& name() const { return m_name; } const NonnullRefPtr& type_name() const { return m_type_name; } private: String m_name; NonnullRefPtr m_type_name; }; class CommonTableExpression : public ASTNode { public: CommonTableExpression(String table_name, Vector column_names, NonnullRefPtr& select_statement() const { return m_select_statement; } private: String m_table_name; Vector m_column_names; NonnullRefPtr select_statement, bool invert_expression) : m_select_statement(move(select_statement)) , m_invert_expression(invert_expression) { } const NonnullRefPtr m_select_statement; bool m_invert_expression; }; class CollateExpression : public NestedExpression { public: CollateExpression(NonnullRefPtr expression, String collation_name) : NestedExpression(move(expression)) , m_collation_name(move(collation_name)) { } const String& collation_name() const { return m_collation_name; } private: String m_collation_name; }; enum class MatchOperator { Like, Glob, Match, Regexp, }; class MatchExpression : public InvertibleNestedDoubleExpression { public: MatchExpression(MatchOperator type, NonnullRefPtr lhs, NonnullRefPtr rhs, RefPtr escape, bool invert_expression) : InvertibleNestedDoubleExpression(move(lhs), move(rhs), invert_expression) , m_type(type) , m_escape(move(escape)) { } MatchOperator type() const { return m_type; } const RefPtr& escape() const { return m_escape; } private: MatchOperator m_type; RefPtr m_escape; }; class NullExpression : public InvertibleNestedExpression { public: NullExpression(NonnullRefPtr expression, bool invert_expression) : InvertibleNestedExpression(move(expression), invert_expression) { } }; class IsExpression : public InvertibleNestedDoubleExpression { public: IsExpression(NonnullRefPtr lhs, NonnullRefPtr rhs, bool invert_expression) : InvertibleNestedDoubleExpression(move(lhs), move(rhs), invert_expression) { } }; class BetweenExpression : public InvertibleNestedDoubleExpression { public: BetweenExpression(NonnullRefPtr expression, NonnullRefPtr lhs, NonnullRefPtr rhs, bool invert_expression) : InvertibleNestedDoubleExpression(move(lhs), move(rhs), invert_expression) , m_expression(move(expression)) { } const NonnullRefPtr& expression() const { return m_expression; } private: NonnullRefPtr m_expression; }; class InChainedExpression : public InvertibleNestedExpression { public: InChainedExpression(NonnullRefPtr expression, NonnullRefPtr expression_chain, bool invert_expression) : InvertibleNestedExpression(move(expression), invert_expression) , m_expression_chain(move(expression_chain)) { } const NonnullRefPtr& expression_chain() const { return m_expression_chain; } private: NonnullRefPtr m_expression_chain; }; class InTableExpression : public InvertibleNestedExpression { public: InTableExpression(NonnullRefPtr expression, String schema_name, String table_name, bool invert_expression) : InvertibleNestedExpression(move(expression), invert_expression) , m_schema_name(move(schema_name)) , m_table_name(move(table_name)) { } const String& schema_name() const { return m_schema_name; } const String& table_name() const { return m_table_name; } private: String m_schema_name; String m_table_name; }; //================================================================================================== // Statements //================================================================================================== class Statement : public ASTNode { }; class ErrorStatement final : public Statement { }; class CreateTable : public Statement { public: CreateTable(String schema_name, String table_name, RefPtr& select_statement() const { return m_select_statement; } bool has_columns() const { return !m_columns.is_empty(); } const NonnullRefPtrVector columns() const { return m_columns; } bool is_temporary() const { return m_is_temporary; } bool is_error_if_table_exists() const { return m_is_error_if_table_exists; } private: String m_schema_name; String m_table_name; RefPtr