#pragma once #include "lexer.h" #include "exception.h" #include "ml_date.h" #include "settings.h" #include #include namespace usql { enum class ColumnType { integer_type, float_type, varchar_type, date_type, bool_type }; enum class NodeType { true_node, null_value, int_value, float_value, string_value, bool_value, logical_operator, relational_operator, arithmetical_operator, create_table, create_table_as_select, insert_into, select_from, delete_from, update_table, load_table, save_table, drop_table, set, show, database_value, offset_limit, column_order, column_value, function, column_def, error }; struct Node { NodeType node_type; explicit Node(const NodeType type) : node_type(type) {} }; struct ColOrderNode : Node { std::string col_name; int col_index; bool ascending; ColOrderNode(const std::string& name, bool asc) : Node(NodeType::column_order), col_name(name), col_index(-1), ascending(asc) {} ColOrderNode(int index, bool asc) : Node(NodeType::database_value), col_name(""), col_index(index), ascending(asc) {} }; struct OffsetLimitNode : Node { int offset; int limit; OffsetLimitNode(int off, int lim) : Node(NodeType::offset_limit), offset(off), limit(lim) {} }; struct SelectColNode : Node { std::unique_ptr value; std::string name; SelectColNode(std::unique_ptr column, const std::string &alias) : Node(NodeType::database_value), value(std::move(column)), name(alias) {} }; struct ColDefNode : Node { std::string name; ColumnType type; int order; int length; bool null; ColDefNode(const std::string& col_name, ColumnType col_type, int col_order, int col_len, bool nullable) : Node(NodeType::column_def), name(col_name), type(col_type), order(col_order), length(col_len), null(nullable) {} }; struct FunctionNode : Node { std::string function; // TODO use enum std::vector> params; FunctionNode(const std::string& func_name, std::vector> pars) : Node(NodeType::function), function(func_name), params(std::move(pars)) {} }; struct TrueNode : Node { TrueNode() : Node(NodeType::true_node) {} }; struct ValueNode : Node { explicit ValueNode(NodeType type) : Node(type) {} virtual bool isNull() { return false; } virtual long getIntegerValue() = 0; virtual double getDoubleValue() = 0; virtual std::string getStringValue() = 0; virtual long getDateValue() = 0; virtual bool getBooleanValue() = 0; virtual ~ValueNode() = default; }; struct NullValueNode : ValueNode { NullValueNode() : ValueNode(NodeType::null_value) {} bool isNull() override { return true; } long getIntegerValue() override { throw Exception("getIntegerValue not supported on NullValueNode"); }; double getDoubleValue() override { throw Exception("getDoubleValue not supported on NullValueNode"); }; std::string getStringValue() override { throw Exception("getStringValue not supported on NullValueNode"); }; long getDateValue() override { throw Exception("getDateValue not supported on NullValueNode"); }; bool getBooleanValue() override { throw Exception("getBooleanValue not supported on NullValueNode"); }; }; struct IntValueNode : ValueNode { long value; explicit IntValueNode(long value) : ValueNode(NodeType::int_value), value(value) {} long getIntegerValue() override { return value; }; double getDoubleValue() override { return (double) value; }; std::string getStringValue() override { return std::to_string(value); } long getDateValue() override { return value; }; bool getBooleanValue() override { return value != 0; }; }; struct DoubleValueNode : ValueNode { double value; explicit DoubleValueNode(double value) : ValueNode(NodeType::float_value), value(value) {} long getIntegerValue() override { return (long) value; }; double getDoubleValue() override { return value; }; std::string getStringValue() override { return std::to_string(value); } long getDateValue() override { return (long) value; }; bool getBooleanValue() override { return value != 0.0; }; }; struct StringValueNode : ValueNode { std::string value; explicit StringValueNode(const std::string &value) : ValueNode(NodeType::string_value), value(value) {} long getIntegerValue() override { return std::stoi(value); }; double getDoubleValue() override { return std::stod(value); }; std::string getStringValue() override { return value; }; long getDateValue() override { return Settings::string_to_date(value); }; bool getBooleanValue() override { return value == "true"; }; }; struct BooleanValueNode : ValueNode { bool value; explicit BooleanValueNode(bool value) : ValueNode(NodeType::bool_value), value(value) {} long getIntegerValue() override { return (long) value; }; double getDoubleValue() override { return (double) value; }; std::string getStringValue() override { return value ? "true" : "false"; } long getDateValue() override { return (long) value; }; bool getBooleanValue() override { return value; }; }; struct DatabaseValueNode : Node { std::string col_name; explicit DatabaseValueNode(const std::string &name) : Node(NodeType::database_value), col_name(name) {} }; enum class LogicalOperatorType { and_operator, or_operator, not_operator }; struct LogicalOperatorNode : Node { LogicalOperatorType op; std::unique_ptr left; std::unique_ptr right; LogicalOperatorNode(LogicalOperatorType op, std::unique_ptr left, std::unique_ptr right) : Node(NodeType::logical_operator), op(op), left(std::move(left)), right(std::move(right)) {}; }; enum class RelationalOperatorType { equal, greater, greater_equal, lesser, lesser_equal, not_equal // like }; struct RelationalOperatorNode : Node { RelationalOperatorType op; std::unique_ptr left; std::unique_ptr right; RelationalOperatorNode(RelationalOperatorType op, std::unique_ptr left, std::unique_ptr right) : Node(NodeType::relational_operator), op(op), left(std::move(left)), right(std::move(right)) {}; }; enum class ArithmeticalOperatorType { copy_value, // just copy lef value and do nothing with it plus_operator, minus_operator, multiply_operator, divide_operator }; struct ArithmeticalOperatorNode : Node { ArithmeticalOperatorType op; std::unique_ptr left; std::unique_ptr right; ArithmeticalOperatorNode(ArithmeticalOperatorType op, std::unique_ptr left, std::unique_ptr right) : Node(NodeType::arithmetical_operator), op(op), left(std::move(left)), right(std::move(right)) {}; }; struct CreateTableNode : Node { std::string table_name; std::vector cols_defs; CreateTableNode(const std::string& name, std::vector defs) : Node(NodeType::create_table), table_name(name), cols_defs(std::move(defs)) {} }; struct InsertIntoTableNode : Node { std::string table_name; std::vector cols_names; std::vector> cols_values; InsertIntoTableNode(const std::string& name, std::vector names, std::vector> values) : Node(NodeType::insert_into), table_name(name), cols_names(std::move(names)), cols_values(std::move(values)) {} }; struct SelectFromTableNode : Node { std::string table_name; std::unique_ptr> cols_names; std::unique_ptr where; std::vector order_by; OffsetLimitNode offset_limit; bool distinct; SelectFromTableNode(std::string name, std::unique_ptr> names, std::unique_ptr where_clause, std::vector orderby, OffsetLimitNode offlim, bool distinct_): Node(NodeType::select_from), table_name(std::move(name)), cols_names(std::move(names)), where(std::move(where_clause)), order_by(std::move(orderby)), offset_limit(offlim), distinct(distinct_) {} }; struct CreateTableAsSelectNode : Node { std::string table_name; std::unique_ptr select_table; CreateTableAsSelectNode(const std::string& name, std::unique_ptr table) : Node(NodeType::create_table_as_select), table_name(name), select_table(std::move(table)) {} }; struct UpdateTableNode : Node { std::string table_name; std::vector cols_names; std::vector> values; std::unique_ptr where; UpdateTableNode(const std::string &name, std::vector names, std::vector> vals, std::unique_ptr where_clause) : Node(NodeType::update_table), table_name(name), cols_names(names), values(std::move(vals)), where(std::move(where_clause)) {} }; struct LoadIntoTableNode : Node { std::string table_name; std::string filename; LoadIntoTableNode(const std::string& name, const std::string &file) : Node(NodeType::load_table), table_name(name), filename(file) {} }; struct SaveTableNode : Node { std::string table_name; std::string filename; SaveTableNode(const std::string& name, const std::string &file) : Node(NodeType::save_table), table_name(name), filename(file) {} }; struct DropTableNode : Node { std::string table_name; explicit DropTableNode(const std::string& name) : Node(NodeType::drop_table), table_name(name) {} }; struct DeleteFromTableNode : Node { std::string table_name; std::unique_ptr where; DeleteFromTableNode(const std::string& name, std::unique_ptr where_clause) : Node(NodeType::delete_from), table_name(name), where(std::move(where_clause)) {} }; struct SetNode : Node { std::string name; std::string value; SetNode(const std::string& name_, const std::string& value_) : Node(NodeType::set), name(name_), value(value_) {} }; struct ShowNode : Node { std::string name; explicit ShowNode(const std::string& name_) : Node(NodeType::show), name(name_) {} }; class Parser { private: public: Parser(); std::unique_ptr parse(const std::string &code); private: std::unique_ptr parse_create_table(); std::unique_ptr parse_drop_table(); std::unique_ptr parse_load_table(); std::unique_ptr parse_save_table(); std::unique_ptr parse_set(); std::unique_ptr parse_show(); std::unique_ptr parse_insert_into_table(); std::unique_ptr parse_select_from_table(); std::unique_ptr parse_delete_from_table(); std::unique_ptr parse_update_table(); std::vector parse_order_by_clause(); OffsetLimitNode parse_offset_limit_clause(); std::unique_ptr parse_where_clause(); std::unique_ptr parse_expression(); std::unique_ptr parse_expression(std::unique_ptr left); std::unique_ptr parse_value(); RelationalOperatorType parse_relational_operator(); LogicalOperatorType parse_logical_operator(); ArithmeticalOperatorType parse_arithmetical_operator(); private: Lexer m_lexer; }; } // namespace