mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-24 02:12:09 -05:00
1037d6b0eb
This patch introduces the ability execute parsed SQL statements. The abstract AST Statement node now has a virtual 'execute' method. This method takes a Database object as parameter and returns a SQLResult object. Also introduced here is the CREATE SCHEMA statement. Tables live in a schema, and if no schema is present in a table reference the 'default' schema is implied. This schema is created if it doesn't yet exist when a Database object is created. Finally, as a proof of concept, the CREATE SCHEMA and CREATE TABLE statements received an 'execute' implementation. The CREATE TABLE method is not able to create tables created from SQL queries yet.
992 lines
31 KiB
C++
992 lines
31 KiB
C++
/*
|
|
* Copyright (c) 2021, Tim Flynn <trflynn89@pm.me>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/NonnullRefPtr.h>
|
|
#include <AK/NonnullRefPtrVector.h>
|
|
#include <AK/RefCounted.h>
|
|
#include <AK/RefPtr.h>
|
|
#include <AK/String.h>
|
|
#include <LibSQL/AST/Token.h>
|
|
#include <LibSQL/Forward.h>
|
|
#include <LibSQL/SQLResult.h>
|
|
#include <LibSQL/Type.h>
|
|
|
|
namespace SQL::AST {
|
|
|
|
template<class T, class... Args>
|
|
static inline NonnullRefPtr<T>
|
|
create_ast_node(Args&&... args)
|
|
{
|
|
return adopt_ref(*new T(forward<Args>(args)...));
|
|
}
|
|
|
|
class ASTNode : public RefCounted<ASTNode> {
|
|
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<SignedNumber> 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<SignedNumber>& signed_numbers() const { return m_signed_numbers; }
|
|
|
|
private:
|
|
String m_name;
|
|
NonnullRefPtrVector<SignedNumber> m_signed_numbers;
|
|
};
|
|
|
|
class ColumnDefinition : public ASTNode {
|
|
public:
|
|
ColumnDefinition(String name, NonnullRefPtr<TypeName> type_name)
|
|
: m_name(move(name))
|
|
, m_type_name(move(type_name))
|
|
{
|
|
}
|
|
|
|
const String& name() const { return m_name; }
|
|
const NonnullRefPtr<TypeName>& type_name() const { return m_type_name; }
|
|
|
|
private:
|
|
String m_name;
|
|
NonnullRefPtr<TypeName> m_type_name;
|
|
};
|
|
|
|
class CommonTableExpression : public ASTNode {
|
|
public:
|
|
CommonTableExpression(String table_name, Vector<String> column_names, NonnullRefPtr<Select> select_statement)
|
|
: m_table_name(move(table_name))
|
|
, m_column_names(move(column_names))
|
|
, m_select_statement(move(select_statement))
|
|
{
|
|
}
|
|
|
|
const String& table_name() const { return m_table_name; }
|
|
const Vector<String>& column_names() const { return m_column_names; }
|
|
const NonnullRefPtr<Select>& select_statement() const { return m_select_statement; }
|
|
|
|
private:
|
|
String m_table_name;
|
|
Vector<String> m_column_names;
|
|
NonnullRefPtr<Select> m_select_statement;
|
|
};
|
|
|
|
class CommonTableExpressionList : public ASTNode {
|
|
public:
|
|
CommonTableExpressionList(bool recursive, NonnullRefPtrVector<CommonTableExpression> common_table_expressions)
|
|
: m_recursive(recursive)
|
|
, m_common_table_expressions(move(common_table_expressions))
|
|
{
|
|
VERIFY(!m_common_table_expressions.is_empty());
|
|
}
|
|
|
|
bool recursive() const { return m_recursive; }
|
|
const NonnullRefPtrVector<CommonTableExpression>& common_table_expressions() const { return m_common_table_expressions; }
|
|
|
|
private:
|
|
bool m_recursive;
|
|
NonnullRefPtrVector<CommonTableExpression> m_common_table_expressions;
|
|
};
|
|
|
|
class QualifiedTableName : public ASTNode {
|
|
public:
|
|
QualifiedTableName(String schema_name, String table_name, String alias)
|
|
: m_schema_name(move(schema_name))
|
|
, m_table_name(move(table_name))
|
|
, m_alias(move(alias))
|
|
{
|
|
}
|
|
|
|
const String& schema_name() const { return m_schema_name; }
|
|
const String& table_name() const { return m_table_name; }
|
|
const String& alias() const { return m_alias; }
|
|
|
|
private:
|
|
String m_schema_name;
|
|
String m_table_name;
|
|
String m_alias;
|
|
};
|
|
|
|
class ReturningClause : public ASTNode {
|
|
public:
|
|
struct ColumnClause {
|
|
NonnullRefPtr<Expression> expression;
|
|
String column_alias;
|
|
};
|
|
|
|
ReturningClause() = default;
|
|
|
|
explicit ReturningClause(Vector<ColumnClause> columns)
|
|
: m_columns(move(columns))
|
|
{
|
|
}
|
|
|
|
bool return_all_columns() const { return m_columns.is_empty(); };
|
|
const Vector<ColumnClause>& columns() const { return m_columns; }
|
|
|
|
private:
|
|
Vector<ColumnClause> m_columns;
|
|
};
|
|
|
|
enum class ResultType {
|
|
All,
|
|
Table,
|
|
Expression,
|
|
};
|
|
|
|
class ResultColumn : public ASTNode {
|
|
public:
|
|
ResultColumn() = default;
|
|
|
|
explicit ResultColumn(String table_name)
|
|
: m_type(ResultType::Table)
|
|
, m_table_name(move(table_name))
|
|
{
|
|
}
|
|
|
|
ResultColumn(NonnullRefPtr<Expression> expression, String column_alias)
|
|
: m_type(ResultType::Expression)
|
|
, m_expression(move(expression))
|
|
, m_column_alias(move(column_alias))
|
|
{
|
|
}
|
|
|
|
ResultType type() const { return m_type; }
|
|
|
|
bool select_from_table() const { return !m_table_name.is_null(); }
|
|
const String& table_name() const { return m_table_name; }
|
|
|
|
bool select_from_expression() const { return !m_expression.is_null(); }
|
|
const RefPtr<Expression>& expression() const { return m_expression; }
|
|
const String& column_alias() const { return m_column_alias; }
|
|
|
|
private:
|
|
ResultType m_type { ResultType::All };
|
|
|
|
String m_table_name {};
|
|
|
|
RefPtr<Expression> m_expression {};
|
|
String m_column_alias {};
|
|
};
|
|
|
|
class GroupByClause : public ASTNode {
|
|
public:
|
|
GroupByClause(NonnullRefPtrVector<Expression> group_by_list, RefPtr<Expression> having_clause)
|
|
: m_group_by_list(move(group_by_list))
|
|
, m_having_clause(move(having_clause))
|
|
{
|
|
VERIFY(!m_group_by_list.is_empty());
|
|
}
|
|
|
|
const NonnullRefPtrVector<Expression>& group_by_list() const { return m_group_by_list; }
|
|
const RefPtr<Expression>& having_clause() const { return m_having_clause; }
|
|
|
|
private:
|
|
NonnullRefPtrVector<Expression> m_group_by_list;
|
|
RefPtr<Expression> m_having_clause;
|
|
};
|
|
|
|
class TableOrSubquery : public ASTNode {
|
|
public:
|
|
TableOrSubquery() = default;
|
|
|
|
TableOrSubquery(String schema_name, String table_name, String table_alias)
|
|
: m_is_table(true)
|
|
, m_schema_name(move(schema_name))
|
|
, m_table_name(move(table_name))
|
|
, m_table_alias(move(table_alias))
|
|
{
|
|
}
|
|
|
|
explicit TableOrSubquery(NonnullRefPtrVector<TableOrSubquery> subqueries)
|
|
: m_is_subquery(!subqueries.is_empty())
|
|
, m_subqueries(move(subqueries))
|
|
{
|
|
}
|
|
|
|
bool is_table() const { return m_is_table; }
|
|
const String& schema_name() const { return m_schema_name; }
|
|
const String& table_name() const { return m_table_name; }
|
|
const String& table_alias() const { return m_table_alias; }
|
|
|
|
bool is_subquery() const { return m_is_subquery; }
|
|
const NonnullRefPtrVector<TableOrSubquery>& subqueries() const { return m_subqueries; }
|
|
|
|
private:
|
|
bool m_is_table { false };
|
|
String m_schema_name {};
|
|
String m_table_name {};
|
|
String m_table_alias {};
|
|
|
|
bool m_is_subquery { false };
|
|
NonnullRefPtrVector<TableOrSubquery> m_subqueries {};
|
|
};
|
|
|
|
class OrderingTerm : public ASTNode {
|
|
public:
|
|
OrderingTerm(NonnullRefPtr<Expression> expression, String collation_name, Order order, Nulls nulls)
|
|
: m_expression(move(expression))
|
|
, m_collation_name(move(collation_name))
|
|
, m_order(order)
|
|
, m_nulls(nulls)
|
|
{
|
|
}
|
|
|
|
const NonnullRefPtr<Expression>& expression() const { return m_expression; }
|
|
const String& collation_name() const { return m_collation_name; }
|
|
Order order() const { return m_order; }
|
|
Nulls nulls() const { return m_nulls; }
|
|
|
|
private:
|
|
NonnullRefPtr<Expression> m_expression;
|
|
String m_collation_name;
|
|
Order m_order;
|
|
Nulls m_nulls;
|
|
};
|
|
|
|
class LimitClause : public ASTNode {
|
|
public:
|
|
LimitClause(NonnullRefPtr<Expression> limit_expression, RefPtr<Expression> offset_expression)
|
|
: m_limit_expression(move(limit_expression))
|
|
, m_offset_expression(move(offset_expression))
|
|
{
|
|
}
|
|
|
|
const NonnullRefPtr<Expression>& limit_expression() const { return m_limit_expression; }
|
|
const RefPtr<Expression>& offset_expression() const { return m_offset_expression; }
|
|
|
|
private:
|
|
NonnullRefPtr<Expression> m_limit_expression;
|
|
RefPtr<Expression> m_offset_expression;
|
|
};
|
|
|
|
//==================================================================================================
|
|
// Expressions
|
|
//==================================================================================================
|
|
|
|
class Expression : public ASTNode {
|
|
};
|
|
|
|
class ErrorExpression final : public Expression {
|
|
};
|
|
|
|
class NumericLiteral : public Expression {
|
|
public:
|
|
explicit NumericLiteral(double value)
|
|
: m_value(value)
|
|
{
|
|
}
|
|
|
|
double value() const { return m_value; }
|
|
|
|
private:
|
|
double m_value;
|
|
};
|
|
|
|
class StringLiteral : public Expression {
|
|
public:
|
|
explicit StringLiteral(String value)
|
|
: m_value(move(value))
|
|
{
|
|
}
|
|
|
|
const String& value() const { return m_value; }
|
|
|
|
private:
|
|
String m_value;
|
|
};
|
|
|
|
class BlobLiteral : public Expression {
|
|
public:
|
|
explicit BlobLiteral(String value)
|
|
: m_value(move(value))
|
|
{
|
|
}
|
|
|
|
const String& value() const { return m_value; }
|
|
|
|
private:
|
|
String m_value;
|
|
};
|
|
|
|
class NullLiteral : public Expression {
|
|
};
|
|
|
|
class NestedExpression : public Expression {
|
|
public:
|
|
const NonnullRefPtr<Expression>& expression() const { return m_expression; }
|
|
|
|
protected:
|
|
explicit NestedExpression(NonnullRefPtr<Expression> expression)
|
|
: m_expression(move(expression))
|
|
{
|
|
}
|
|
|
|
private:
|
|
NonnullRefPtr<Expression> m_expression;
|
|
};
|
|
|
|
class NestedDoubleExpression : public Expression {
|
|
public:
|
|
const NonnullRefPtr<Expression>& lhs() const { return m_lhs; }
|
|
const NonnullRefPtr<Expression>& rhs() const { return m_rhs; }
|
|
|
|
protected:
|
|
NestedDoubleExpression(NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs)
|
|
: m_lhs(move(lhs))
|
|
, m_rhs(move(rhs))
|
|
{
|
|
}
|
|
|
|
private:
|
|
NonnullRefPtr<Expression> m_lhs;
|
|
NonnullRefPtr<Expression> m_rhs;
|
|
};
|
|
|
|
class InvertibleNestedExpression : public NestedExpression {
|
|
public:
|
|
bool invert_expression() const { return m_invert_expression; }
|
|
|
|
protected:
|
|
InvertibleNestedExpression(NonnullRefPtr<Expression> expression, bool invert_expression)
|
|
: NestedExpression(move(expression))
|
|
, m_invert_expression(invert_expression)
|
|
{
|
|
}
|
|
|
|
private:
|
|
bool m_invert_expression;
|
|
};
|
|
|
|
class InvertibleNestedDoubleExpression : public NestedDoubleExpression {
|
|
public:
|
|
bool invert_expression() const { return m_invert_expression; }
|
|
|
|
protected:
|
|
InvertibleNestedDoubleExpression(NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs, bool invert_expression)
|
|
: NestedDoubleExpression(move(lhs), move(rhs))
|
|
, m_invert_expression(invert_expression)
|
|
{
|
|
}
|
|
|
|
private:
|
|
bool m_invert_expression;
|
|
};
|
|
|
|
class ColumnNameExpression : public Expression {
|
|
public:
|
|
ColumnNameExpression(String schema_name, String table_name, String column_name)
|
|
: m_schema_name(move(schema_name))
|
|
, m_table_name(move(table_name))
|
|
, m_column_name(move(column_name))
|
|
{
|
|
}
|
|
|
|
const String& schema_name() const { return m_schema_name; }
|
|
const String& table_name() const { return m_table_name; }
|
|
const String& column_name() const { return m_column_name; }
|
|
|
|
private:
|
|
String m_schema_name;
|
|
String m_table_name;
|
|
String m_column_name;
|
|
};
|
|
|
|
enum class UnaryOperator {
|
|
Minus,
|
|
Plus,
|
|
BitwiseNot,
|
|
Not,
|
|
};
|
|
|
|
class UnaryOperatorExpression : public NestedExpression {
|
|
public:
|
|
UnaryOperatorExpression(UnaryOperator type, NonnullRefPtr<Expression> expression)
|
|
: NestedExpression(move(expression))
|
|
, m_type(type)
|
|
{
|
|
}
|
|
|
|
UnaryOperator type() const { return m_type; }
|
|
|
|
private:
|
|
UnaryOperator m_type;
|
|
};
|
|
|
|
enum class BinaryOperator {
|
|
// Note: These are in order of highest-to-lowest operator precedence.
|
|
Concatenate,
|
|
Multiplication,
|
|
Division,
|
|
Modulo,
|
|
Plus,
|
|
Minus,
|
|
ShiftLeft,
|
|
ShiftRight,
|
|
BitwiseAnd,
|
|
BitwiseOr,
|
|
LessThan,
|
|
LessThanEquals,
|
|
GreaterThan,
|
|
GreaterThanEquals,
|
|
Equals,
|
|
NotEquals,
|
|
And,
|
|
Or,
|
|
};
|
|
|
|
class BinaryOperatorExpression : public NestedDoubleExpression {
|
|
public:
|
|
BinaryOperatorExpression(BinaryOperator type, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs)
|
|
: NestedDoubleExpression(move(lhs), move(rhs))
|
|
, m_type(type)
|
|
{
|
|
}
|
|
|
|
BinaryOperator type() const { return m_type; }
|
|
|
|
private:
|
|
BinaryOperator m_type;
|
|
};
|
|
|
|
class ChainedExpression : public Expression {
|
|
public:
|
|
explicit ChainedExpression(NonnullRefPtrVector<Expression> expressions)
|
|
: m_expressions(move(expressions))
|
|
{
|
|
}
|
|
|
|
const NonnullRefPtrVector<Expression>& expressions() const { return m_expressions; }
|
|
|
|
private:
|
|
NonnullRefPtrVector<Expression> m_expressions;
|
|
};
|
|
|
|
class CastExpression : public NestedExpression {
|
|
public:
|
|
CastExpression(NonnullRefPtr<Expression> expression, NonnullRefPtr<TypeName> type_name)
|
|
: NestedExpression(move(expression))
|
|
, m_type_name(move(type_name))
|
|
{
|
|
}
|
|
|
|
const NonnullRefPtr<TypeName>& type_name() const { return m_type_name; }
|
|
|
|
private:
|
|
NonnullRefPtr<TypeName> m_type_name;
|
|
};
|
|
|
|
class CaseExpression : public Expression {
|
|
public:
|
|
struct WhenThenClause {
|
|
NonnullRefPtr<Expression> when;
|
|
NonnullRefPtr<Expression> then;
|
|
};
|
|
|
|
CaseExpression(RefPtr<Expression> case_expression, Vector<WhenThenClause> when_then_clauses, RefPtr<Expression> else_expression)
|
|
: m_case_expression(case_expression)
|
|
, m_when_then_clauses(when_then_clauses)
|
|
, m_else_expression(else_expression)
|
|
{
|
|
VERIFY(!m_when_then_clauses.is_empty());
|
|
}
|
|
|
|
const RefPtr<Expression>& case_expression() const { return m_case_expression; }
|
|
const Vector<WhenThenClause>& when_then_clauses() const { return m_when_then_clauses; }
|
|
const RefPtr<Expression>& else_expression() const { return m_else_expression; }
|
|
|
|
private:
|
|
RefPtr<Expression> m_case_expression;
|
|
Vector<WhenThenClause> m_when_then_clauses;
|
|
RefPtr<Expression> m_else_expression;
|
|
};
|
|
|
|
class ExistsExpression : public Expression {
|
|
public:
|
|
ExistsExpression(NonnullRefPtr<Select> select_statement, bool invert_expression)
|
|
: m_select_statement(move(select_statement))
|
|
, m_invert_expression(invert_expression)
|
|
{
|
|
}
|
|
|
|
const NonnullRefPtr<Select>& select_statement() const { return m_select_statement; }
|
|
bool invert_expression() const { return m_invert_expression; }
|
|
|
|
private:
|
|
NonnullRefPtr<Select> m_select_statement;
|
|
bool m_invert_expression;
|
|
};
|
|
|
|
class CollateExpression : public NestedExpression {
|
|
public:
|
|
CollateExpression(NonnullRefPtr<Expression> 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<Expression> lhs, NonnullRefPtr<Expression> rhs, RefPtr<Expression> 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<Expression>& escape() const { return m_escape; }
|
|
|
|
private:
|
|
MatchOperator m_type;
|
|
RefPtr<Expression> m_escape;
|
|
};
|
|
|
|
class NullExpression : public InvertibleNestedExpression {
|
|
public:
|
|
NullExpression(NonnullRefPtr<Expression> expression, bool invert_expression)
|
|
: InvertibleNestedExpression(move(expression), invert_expression)
|
|
{
|
|
}
|
|
};
|
|
|
|
class IsExpression : public InvertibleNestedDoubleExpression {
|
|
public:
|
|
IsExpression(NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs, bool invert_expression)
|
|
: InvertibleNestedDoubleExpression(move(lhs), move(rhs), invert_expression)
|
|
{
|
|
}
|
|
};
|
|
|
|
class BetweenExpression : public InvertibleNestedDoubleExpression {
|
|
public:
|
|
BetweenExpression(NonnullRefPtr<Expression> expression, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs, bool invert_expression)
|
|
: InvertibleNestedDoubleExpression(move(lhs), move(rhs), invert_expression)
|
|
, m_expression(move(expression))
|
|
{
|
|
}
|
|
|
|
const NonnullRefPtr<Expression>& expression() const { return m_expression; }
|
|
|
|
private:
|
|
NonnullRefPtr<Expression> m_expression;
|
|
};
|
|
|
|
class InSelectionExpression : public InvertibleNestedExpression {
|
|
public:
|
|
InSelectionExpression(NonnullRefPtr<Expression> expression, NonnullRefPtr<Select> select_statement, bool invert_expression)
|
|
: InvertibleNestedExpression(move(expression), invert_expression)
|
|
, m_select_statement(move(select_statement))
|
|
{
|
|
}
|
|
|
|
const NonnullRefPtr<Select>& select_statement() const { return m_select_statement; }
|
|
|
|
private:
|
|
NonnullRefPtr<Select> m_select_statement;
|
|
};
|
|
|
|
class InChainedExpression : public InvertibleNestedExpression {
|
|
public:
|
|
InChainedExpression(NonnullRefPtr<Expression> expression, NonnullRefPtr<ChainedExpression> expression_chain, bool invert_expression)
|
|
: InvertibleNestedExpression(move(expression), invert_expression)
|
|
, m_expression_chain(move(expression_chain))
|
|
{
|
|
}
|
|
|
|
const NonnullRefPtr<ChainedExpression>& expression_chain() const { return m_expression_chain; }
|
|
|
|
private:
|
|
NonnullRefPtr<ChainedExpression> m_expression_chain;
|
|
};
|
|
|
|
class InTableExpression : public InvertibleNestedExpression {
|
|
public:
|
|
InTableExpression(NonnullRefPtr<Expression> 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 {
|
|
public:
|
|
virtual RefPtr<SQLResult> execute(NonnullRefPtr<Database>) const { return nullptr; }
|
|
};
|
|
|
|
class ErrorStatement final : public Statement {
|
|
};
|
|
|
|
class CreateSchema : public Statement {
|
|
public:
|
|
CreateSchema(String schema_name, bool is_error_if_schema_exists)
|
|
: m_schema_name(move(schema_name))
|
|
, m_is_error_if_schema_exists(is_error_if_schema_exists)
|
|
{
|
|
}
|
|
|
|
const String& schema_name() const { return m_schema_name; }
|
|
bool is_error_if_schema_exists() const { return m_is_error_if_schema_exists; }
|
|
|
|
RefPtr<SQLResult> execute(NonnullRefPtr<Database>) const override;
|
|
|
|
private:
|
|
String m_schema_name;
|
|
bool m_is_error_if_schema_exists;
|
|
};
|
|
|
|
class CreateTable : public Statement {
|
|
public:
|
|
CreateTable(String schema_name, String table_name, RefPtr<Select> 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(String schema_name, String table_name, NonnullRefPtrVector<ColumnDefinition> 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)
|
|
{
|
|
}
|
|
|
|
const String& schema_name() const { return m_schema_name; }
|
|
const String& table_name() const { return m_table_name; }
|
|
|
|
bool has_selection() const { return !m_select_statement.is_null(); }
|
|
const RefPtr<Select>& select_statement() const { return m_select_statement; }
|
|
|
|
bool has_columns() const { return !m_columns.is_empty(); }
|
|
const NonnullRefPtrVector<ColumnDefinition>& 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; }
|
|
|
|
RefPtr<SQLResult> execute(NonnullRefPtr<Database>) const override;
|
|
|
|
private:
|
|
String m_schema_name;
|
|
String m_table_name;
|
|
RefPtr<Select> m_select_statement;
|
|
NonnullRefPtrVector<ColumnDefinition> m_columns;
|
|
bool m_is_temporary;
|
|
bool m_is_error_if_table_exists;
|
|
};
|
|
|
|
class AlterTable : public Statement {
|
|
public:
|
|
const String& schema_name() const { return m_schema_name; }
|
|
const String& table_name() const { return m_table_name; }
|
|
|
|
protected:
|
|
AlterTable(String schema_name, String table_name)
|
|
: m_schema_name(move(schema_name))
|
|
, m_table_name(move(table_name))
|
|
{
|
|
}
|
|
|
|
private:
|
|
String m_schema_name;
|
|
String m_table_name;
|
|
};
|
|
|
|
class RenameTable : public AlterTable {
|
|
public:
|
|
RenameTable(String schema_name, String table_name, String new_table_name)
|
|
: AlterTable(move(schema_name), move(table_name))
|
|
, m_new_table_name(move(new_table_name))
|
|
{
|
|
}
|
|
|
|
const String& new_table_name() const { return m_new_table_name; }
|
|
|
|
private:
|
|
String m_new_table_name;
|
|
};
|
|
|
|
class RenameColumn : public AlterTable {
|
|
public:
|
|
RenameColumn(String schema_name, String table_name, String column_name, String new_column_name)
|
|
: AlterTable(move(schema_name), move(table_name))
|
|
, m_column_name(move(column_name))
|
|
, m_new_column_name(move(new_column_name))
|
|
{
|
|
}
|
|
|
|
const String& column_name() const { return m_column_name; }
|
|
const String& new_column_name() const { return m_new_column_name; }
|
|
|
|
private:
|
|
String m_column_name;
|
|
String m_new_column_name;
|
|
};
|
|
|
|
class AddColumn : public AlterTable {
|
|
public:
|
|
AddColumn(String schema_name, String table_name, NonnullRefPtr<ColumnDefinition> column)
|
|
: AlterTable(move(schema_name), move(table_name))
|
|
, m_column(move(column))
|
|
{
|
|
}
|
|
|
|
const NonnullRefPtr<ColumnDefinition>& column() const { return m_column; }
|
|
|
|
private:
|
|
NonnullRefPtr<ColumnDefinition> m_column;
|
|
};
|
|
|
|
class DropColumn : public AlterTable {
|
|
public:
|
|
DropColumn(String schema_name, String table_name, String column_name)
|
|
: AlterTable(move(schema_name), move(table_name))
|
|
, m_column_name(move(column_name))
|
|
{
|
|
}
|
|
|
|
const String& column_name() const { return m_column_name; }
|
|
|
|
private:
|
|
String m_column_name;
|
|
};
|
|
|
|
class DropTable : public Statement {
|
|
public:
|
|
DropTable(String schema_name, String 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)
|
|
{
|
|
}
|
|
|
|
const String& schema_name() const { return m_schema_name; }
|
|
const String& 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:
|
|
String m_schema_name;
|
|
String 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<CommonTableExpressionList> common_table_expression_list, ConflictResolution conflict_resolution, String schema_name, String table_name, String alias, Vector<String> column_names, NonnullRefPtrVector<ChainedExpression> 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<CommonTableExpressionList> common_table_expression_list, ConflictResolution conflict_resolution, String schema_name, String table_name, String alias, Vector<String> column_names, RefPtr<Select> select_statement)
|
|
: 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_select_statement(move(select_statement))
|
|
{
|
|
}
|
|
|
|
Insert(RefPtr<CommonTableExpressionList> common_table_expression_list, ConflictResolution conflict_resolution, String schema_name, String table_name, String alias, Vector<String> column_names)
|
|
: 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))
|
|
{
|
|
}
|
|
|
|
const RefPtr<CommonTableExpressionList>& common_table_expression_list() const { return m_common_table_expression_list; }
|
|
ConflictResolution conflict_resolution() const { return m_conflict_resolution; }
|
|
const String& schema_name() const { return m_schema_name; }
|
|
const String& table_name() const { return m_table_name; }
|
|
const String& alias() const { return m_alias; }
|
|
const Vector<String>& column_names() const { return m_column_names; }
|
|
|
|
bool default_values() const { return !has_expressions() && !has_selection(); };
|
|
|
|
bool has_expressions() const { return !m_chained_expressions.is_empty(); }
|
|
const NonnullRefPtrVector<ChainedExpression>& chained_expressions() const { return m_chained_expressions; }
|
|
|
|
bool has_selection() const { return !m_select_statement.is_null(); }
|
|
const RefPtr<Select>& select_statement() const { return m_select_statement; }
|
|
|
|
private:
|
|
RefPtr<CommonTableExpressionList> m_common_table_expression_list;
|
|
ConflictResolution m_conflict_resolution;
|
|
String m_schema_name;
|
|
String m_table_name;
|
|
String m_alias;
|
|
Vector<String> m_column_names;
|
|
NonnullRefPtrVector<ChainedExpression> m_chained_expressions;
|
|
RefPtr<Select> m_select_statement;
|
|
};
|
|
|
|
class Update : public Statement {
|
|
public:
|
|
struct UpdateColumns {
|
|
Vector<String> column_names;
|
|
NonnullRefPtr<Expression> expression;
|
|
};
|
|
|
|
Update(RefPtr<CommonTableExpressionList> common_table_expression_list, ConflictResolution conflict_resolution, NonnullRefPtr<QualifiedTableName> qualified_table_name, Vector<UpdateColumns> update_columns, NonnullRefPtrVector<TableOrSubquery> table_or_subquery_list, RefPtr<Expression> where_clause, RefPtr<ReturningClause> returning_clause)
|
|
: m_common_table_expression_list(move(common_table_expression_list))
|
|
, m_conflict_resolution(conflict_resolution)
|
|
, m_qualified_table_name(move(qualified_table_name))
|
|
, m_update_columns(move(update_columns))
|
|
, m_table_or_subquery_list(move(table_or_subquery_list))
|
|
, m_where_clause(move(where_clause))
|
|
, m_returning_clause(move(returning_clause))
|
|
{
|
|
}
|
|
|
|
const RefPtr<CommonTableExpressionList>& common_table_expression_list() const { return m_common_table_expression_list; }
|
|
ConflictResolution conflict_resolution() const { return m_conflict_resolution; }
|
|
const NonnullRefPtr<QualifiedTableName>& qualified_table_name() const { return m_qualified_table_name; }
|
|
const Vector<UpdateColumns>& update_columns() const { return m_update_columns; }
|
|
const NonnullRefPtrVector<TableOrSubquery>& table_or_subquery_list() const { return m_table_or_subquery_list; }
|
|
const RefPtr<Expression>& where_clause() const { return m_where_clause; }
|
|
const RefPtr<ReturningClause>& returning_clause() const { return m_returning_clause; }
|
|
|
|
private:
|
|
RefPtr<CommonTableExpressionList> m_common_table_expression_list;
|
|
ConflictResolution m_conflict_resolution;
|
|
NonnullRefPtr<QualifiedTableName> m_qualified_table_name;
|
|
Vector<UpdateColumns> m_update_columns;
|
|
NonnullRefPtrVector<TableOrSubquery> m_table_or_subquery_list;
|
|
RefPtr<Expression> m_where_clause;
|
|
RefPtr<ReturningClause> m_returning_clause;
|
|
};
|
|
|
|
class Delete : public Statement {
|
|
public:
|
|
Delete(RefPtr<CommonTableExpressionList> common_table_expression_list, NonnullRefPtr<QualifiedTableName> qualified_table_name, RefPtr<Expression> where_clause, RefPtr<ReturningClause> returning_clause)
|
|
: m_common_table_expression_list(move(common_table_expression_list))
|
|
, m_qualified_table_name(move(qualified_table_name))
|
|
, m_where_clause(move(where_clause))
|
|
, m_returning_clause(move(returning_clause))
|
|
{
|
|
}
|
|
|
|
const RefPtr<CommonTableExpressionList>& common_table_expression_list() const { return m_common_table_expression_list; }
|
|
const NonnullRefPtr<QualifiedTableName>& qualified_table_name() const { return m_qualified_table_name; }
|
|
const RefPtr<Expression>& where_clause() const { return m_where_clause; }
|
|
const RefPtr<ReturningClause>& returning_clause() const { return m_returning_clause; }
|
|
|
|
private:
|
|
RefPtr<CommonTableExpressionList> m_common_table_expression_list;
|
|
NonnullRefPtr<QualifiedTableName> m_qualified_table_name;
|
|
RefPtr<Expression> m_where_clause;
|
|
RefPtr<ReturningClause> m_returning_clause;
|
|
};
|
|
|
|
class Select : public Statement {
|
|
public:
|
|
Select(RefPtr<CommonTableExpressionList> common_table_expression_list, bool select_all, NonnullRefPtrVector<ResultColumn> result_column_list, NonnullRefPtrVector<TableOrSubquery> table_or_subquery_list, RefPtr<Expression> where_clause, RefPtr<GroupByClause> group_by_clause, NonnullRefPtrVector<OrderingTerm> ordering_term_list, RefPtr<LimitClause> limit_clause)
|
|
: m_common_table_expression_list(move(common_table_expression_list))
|
|
, m_select_all(move(select_all))
|
|
, m_result_column_list(move(result_column_list))
|
|
, m_table_or_subquery_list(move(table_or_subquery_list))
|
|
, m_where_clause(move(where_clause))
|
|
, m_group_by_clause(move(group_by_clause))
|
|
, m_ordering_term_list(move(ordering_term_list))
|
|
, m_limit_clause(move(limit_clause))
|
|
{
|
|
}
|
|
|
|
const RefPtr<CommonTableExpressionList>& common_table_expression_list() const { return m_common_table_expression_list; }
|
|
bool select_all() const { return m_select_all; }
|
|
const NonnullRefPtrVector<ResultColumn>& result_column_list() const { return m_result_column_list; }
|
|
const NonnullRefPtrVector<TableOrSubquery>& table_or_subquery_list() const { return m_table_or_subquery_list; }
|
|
const RefPtr<Expression>& where_clause() const { return m_where_clause; }
|
|
const RefPtr<GroupByClause>& group_by_clause() const { return m_group_by_clause; }
|
|
const NonnullRefPtrVector<OrderingTerm>& ordering_term_list() const { return m_ordering_term_list; }
|
|
const RefPtr<LimitClause>& limit_clause() const { return m_limit_clause; }
|
|
|
|
private:
|
|
RefPtr<CommonTableExpressionList> m_common_table_expression_list;
|
|
bool m_select_all;
|
|
NonnullRefPtrVector<ResultColumn> m_result_column_list;
|
|
NonnullRefPtrVector<TableOrSubquery> m_table_or_subquery_list;
|
|
RefPtr<Expression> m_where_clause;
|
|
RefPtr<GroupByClause> m_group_by_clause;
|
|
NonnullRefPtrVector<OrderingTerm> m_ordering_term_list;
|
|
RefPtr<LimitClause> m_limit_clause;
|
|
};
|
|
|
|
}
|