/* * Copyright (c) 2021, Tim Flynn * Copyright (c) 2021, Mahmoud Mandour * Copyright (c) 2022, the SerenityOS developers. * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include namespace SQL::AST { template static inline NonnullRefPtr create_ast_node(Args&&... args) { return adopt_ref(*new T(forward(args)...)); } class ASTNode : public RefCounted { public: virtual ~ASTNode() = default; 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(DeprecatedString name, Vector> signed_numbers) : m_name(move(name)) , m_signed_numbers(move(signed_numbers)) { VERIFY(m_signed_numbers.size() <= 2); } DeprecatedString const& name() const { return m_name; } Vector> const& signed_numbers() const { return m_signed_numbers; } private: DeprecatedString m_name; Vector> m_signed_numbers; }; class ColumnDefinition : public ASTNode { public: ColumnDefinition(DeprecatedString name, NonnullRefPtr type_name) : m_name(move(name)) , m_type_name(move(type_name)) { } DeprecatedString const& name() const { return m_name; } NonnullRefPtr const& type_name() const { return m_type_name; } private: DeprecatedString m_name; NonnullRefPtr m_type_name; }; class CommonTableExpression : public ASTNode { public: CommonTableExpression(DeprecatedString table_name, Vector column_names, NonnullRefPtr const& select_statement() const { return m_select_statement; } private: DeprecatedString m_table_name; Vector m_column_names; NonnullRefPtr select_statement, bool invert_expression) : m_select_statement(move(select_statement)) , m_invert_expression(invert_expression) { } NonnullRefPtr m_select_statement; bool m_invert_expression; }; class CollateExpression : public NestedExpression { public: CollateExpression(NonnullRefPtr expression, DeprecatedString collation_name) : NestedExpression(move(expression)) , m_collation_name(move(collation_name)) { } DeprecatedString const& collation_name() const { return m_collation_name; } private: DeprecatedString 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; } RefPtr const& escape() const { return m_escape; } virtual ResultOr evaluate(ExecutionContext&) const override; 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)) { } NonnullRefPtr const& expression() const { return m_expression; } private: NonnullRefPtr m_expression; }; class InSelectionExpression : public InvertibleNestedExpression { public: InSelectionExpression(NonnullRefPtr expression, NonnullRefPtr const& select_statement() const { return m_select_statement; } private: NonnullRefPtr select_statement, bool is_temporary, bool is_error_if_table_exists) : m_schema_name(move(schema_name)) , m_table_name(move(table_name)) , m_select_statement(move(select_statement)) , m_is_temporary(is_temporary) , m_is_error_if_table_exists(is_error_if_table_exists) { } CreateTable(DeprecatedString schema_name, DeprecatedString table_name, Vector> columns, bool is_temporary, bool is_error_if_table_exists) : m_schema_name(move(schema_name)) , m_table_name(move(table_name)) , m_columns(move(columns)) , m_is_temporary(is_temporary) , m_is_error_if_table_exists(is_error_if_table_exists) { } DeprecatedString const& schema_name() const { return m_schema_name; } DeprecatedString const& table_name() const { return m_table_name; } bool has_selection() const { return !m_select_statement.is_null(); } RefPtr m_select_statement; Vector> m_columns; bool m_is_temporary; bool m_is_error_if_table_exists; }; class AlterTable : public Statement { public: DeprecatedString const& schema_name() const { return m_schema_name; } DeprecatedString const& table_name() const { return m_table_name; } protected: AlterTable(DeprecatedString schema_name, DeprecatedString table_name) : m_schema_name(move(schema_name)) , m_table_name(move(table_name)) { } private: DeprecatedString m_schema_name; DeprecatedString m_table_name; }; class RenameTable : public AlterTable { public: RenameTable(DeprecatedString schema_name, DeprecatedString table_name, DeprecatedString new_table_name) : AlterTable(move(schema_name), move(table_name)) , m_new_table_name(move(new_table_name)) { } DeprecatedString const& new_table_name() const { return m_new_table_name; } private: DeprecatedString m_new_table_name; }; class RenameColumn : public AlterTable { public: RenameColumn(DeprecatedString schema_name, DeprecatedString table_name, DeprecatedString column_name, DeprecatedString new_column_name) : AlterTable(move(schema_name), move(table_name)) , m_column_name(move(column_name)) , m_new_column_name(move(new_column_name)) { } DeprecatedString const& column_name() const { return m_column_name; } DeprecatedString const& new_column_name() const { return m_new_column_name; } private: DeprecatedString m_column_name; DeprecatedString m_new_column_name; }; class AddColumn : public AlterTable { public: AddColumn(DeprecatedString schema_name, DeprecatedString table_name, NonnullRefPtr column) : AlterTable(move(schema_name), move(table_name)) , m_column(move(column)) { } NonnullRefPtr const& column() const { return m_column; } private: NonnullRefPtr m_column; }; class DropColumn : public AlterTable { public: DropColumn(DeprecatedString schema_name, DeprecatedString table_name, DeprecatedString column_name) : AlterTable(move(schema_name), move(table_name)) , m_column_name(move(column_name)) { } DeprecatedString const& column_name() const { return m_column_name; } private: DeprecatedString m_column_name; }; class DropTable : public Statement { public: DropTable(DeprecatedString schema_name, DeprecatedString table_name, bool is_error_if_table_does_not_exist) : m_schema_name(move(schema_name)) , m_table_name(move(table_name)) , m_is_error_if_table_does_not_exist(is_error_if_table_does_not_exist) { } DeprecatedString const& schema_name() const { return m_schema_name; } DeprecatedString const& table_name() const { return m_table_name; } bool is_error_if_table_does_not_exist() const { return m_is_error_if_table_does_not_exist; } private: DeprecatedString m_schema_name; DeprecatedString m_table_name; bool m_is_error_if_table_does_not_exist; }; enum class ConflictResolution { Abort, Fail, Ignore, Replace, Rollback, }; class Insert : public Statement { public: Insert(RefPtr common_table_expression_list, ConflictResolution conflict_resolution, DeprecatedString schema_name, DeprecatedString table_name, DeprecatedString alias, Vector column_names, Vector> chained_expressions) : m_common_table_expression_list(move(common_table_expression_list)) , m_conflict_resolution(conflict_resolution) , m_schema_name(move(schema_name)) , m_table_name(move(table_name)) , m_alias(move(alias)) , m_column_names(move(column_names)) , m_chained_expressions(move(chained_expressions)) { } Insert(RefPtr common_table_expression_list, ConflictResolution conflict_resolution, DeprecatedString schema_name, DeprecatedString table_name, DeprecatedString alias, Vector column_names, RefPtr const& select_statement() const { return m_select_statement; } virtual ResultOr execute(ExecutionContext&) const override; private: RefPtr m_common_table_expression_list; ConflictResolution m_conflict_resolution; DeprecatedString m_schema_name; DeprecatedString m_table_name; DeprecatedString m_alias; Vector m_column_names; Vector> m_chained_expressions; RefPtr