#pragma once #include "lexer.h" #include "exception.h" #include "ml_date.h" #include "settings.h" #include #include #include static const int FUNCTION_CALL = -1; 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, create_index, set, show, database_value, offset_limit, column_order, function, column_def, error }; struct Node { NodeType node_type; explicit Node(const NodeType type) : node_type(type) {} virtual ~Node() = default; virtual void dump() const { std::cout << "type: Node" << std::endl; } }; struct ColOrderNode : Node { std::string col_name; int col_index; bool ascending; ColOrderNode(std::string name, bool asc) : Node(NodeType::column_order), col_name(std::move(name)), col_index(-1), ascending(asc) {} ColOrderNode(int index, bool asc) : Node(NodeType::database_value), col_index(index), ascending(asc) {} void dump() const override { std::cout << "type: ColOrderNode, col_name: " << col_name << ", col_index: " << col_index << ", asc: " << ascending << std::endl; } }; struct OffsetLimitNode : Node { int offset; int limit; OffsetLimitNode(int off, int lim) : Node(NodeType::offset_limit), offset(off), limit(lim) {} void dump() const override { std::cout << "type: OffsetLimitNode, offset: " << offset << ", limit: " << limit << std::endl; } }; struct SelectColNode : Node { std::unique_ptr value; std::string name; SelectColNode(std::unique_ptr column, std::string alias) : Node(NodeType::database_value), value(std::move(column)), name(std::move(alias)) {} void dump() const override { std::cout << "type: SelectColNode, name:" << name << "value:" << std::endl; value->dump(); } }; struct ColDefNode : Node { std::string name; ColumnType type; int order; int length; bool null; ColDefNode(std::string col_name, ColumnType col_type, int col_order, int col_len, bool nullable) : Node(NodeType::column_def), name(std::move(col_name)), type(col_type), order(col_order), length(col_len), null(nullable) {} void dump() const override { std::cout << "type: ColDefNode, name: " << name << ", type: " << (int)type << " TODO add more" << std::endl; } }; struct FunctionNode : Node { std::string function; // TODO use enum std::vector> params; FunctionNode(std::string func_name, std::vector> pars) : Node(NodeType::function), function(std::move(func_name)), params(std::move(pars)) {} void dump() const override { std::cout << "type: FunctionNode, function: " << function << " TODO add more" << std::endl; } }; struct TrueNode : Node { TrueNode() : Node(NodeType::true_node) {} void dump() const override { std::cout << "type: TrueNode," << std::endl; } }; struct ValueNode : Node { explicit ValueNode(NodeType type) : Node(type) {} virtual bool isNull() const { return false; } virtual long getIntegerValue() const = 0; virtual double getDoubleValue() const = 0; virtual std::string getStringValue() const = 0; virtual long getDateValue() const = 0; virtual bool getBooleanValue() const = 0; ~ValueNode() override = default; }; struct NullValueNode : ValueNode { NullValueNode() : ValueNode(NodeType::null_value) {} bool isNull() const override { return true; } long getIntegerValue() const override { throw Exception("getIntegerValue not supported on NullValueNode"); }; double getDoubleValue() const override { throw Exception("getDoubleValue not supported on NullValueNode"); }; std::string getStringValue() const override { throw Exception("getStringValue not supported on NullValueNode"); }; long getDateValue() const override { throw Exception("getDateValue not supported on NullValueNode"); }; bool getBooleanValue() const override { throw Exception("getBooleanValue not supported on NullValueNode"); }; void dump() const override { std::cout << "type: NullValueNode," << std::endl; } }; struct IntValueNode : ValueNode { long value; explicit IntValueNode(long value) : ValueNode(NodeType::int_value), value(value) {} long getIntegerValue() const override { return value; }; double getDoubleValue() const override { return (double) value; }; std::string getStringValue() const override { return Settings::long_to_string(value); } long getDateValue() const override { return value; }; bool getBooleanValue() const override { return value != 0; }; void dump() const override { std::cout << "type: IntValueNode, value: " << value << std::endl; } }; struct DoubleValueNode : ValueNode { double value; explicit DoubleValueNode(double value) : ValueNode(NodeType::float_value), value(value) {} long getIntegerValue() const override { return (long) value; }; double getDoubleValue() const override { return value; }; std::string getStringValue() const override { return Settings::double_to_string(value); } long getDateValue() const override { return (long) value; }; bool getBooleanValue() const override { return value != 0.0; }; void dump() const override { std::cout << "type: DoubleValueNode, value: " << value << std::endl; } }; struct StringValueNode : ValueNode { std::string value; explicit StringValueNode(std::string value) : ValueNode(NodeType::string_value), value(std::move(value)) {} long getIntegerValue() const override { return Settings::string_to_long(value); }; double getDoubleValue() const override { return Settings::string_to_double(value); }; std::string getStringValue() const override { return value; }; long getDateValue() const override { return Settings::string_to_date(value); }; bool getBooleanValue() const override { return Settings::string_to_bool(value); }; void dump() const override { std::cout << "type: StringValueNode, value: " << value << std::endl; } }; struct BooleanValueNode : ValueNode { bool value; explicit BooleanValueNode(bool value) : ValueNode(NodeType::bool_value), value(value) {} long getIntegerValue() const override { return (long) value; }; double getDoubleValue() const override { return (double) value; }; std::string getStringValue() const override { return Settings::bool_to_string(value); } long getDateValue() const override { return (long) value; }; bool getBooleanValue() const override { return value; }; void dump() const override { std::cout << "type: BooleanValueNode, value: " << value << std::endl; } }; struct DatabaseValueNode : Node { std::string col_name; explicit DatabaseValueNode(std::string name) : Node(NodeType::database_value), col_name(std::move(name)) {} void dump() const override { std::cout << "type: DatabaseValueNode, col_name: " << col_name << std::endl; } }; 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)) {}; void dump() const override { std::cout << "type: LogicalOperatorNode, op: " << (int)op << std::endl; left->dump(); right->dump(); } }; enum class RelationalOperatorType { equal, greater, greater_equal, lesser, lesser_equal, not_equal, is, is_not // 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)) {}; void dump() const override { std::cout << "type: RelationalOperatorNode, op: " << (int)op << std::endl; left->dump(); right->dump(); } }; 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)) {}; void dump() const override { std::cout << "type: ArithmeticalOperatorNode, op: " << (int)op << std::endl; left->dump(); right->dump(); } }; struct CreateTableNode : Node { std::string table_name; std::vector cols_defs; CreateTableNode(std::string name, std::vector defs) : Node(NodeType::create_table), table_name(std::move(name)), cols_defs(std::move(defs)) {} void dump() const override { std::cout << "type: CreateTableNode, table_name: " << table_name << "TODO complete me" << std::endl; } }; struct InsertIntoTableNode : Node { std::string table_name; std::vector cols_names; std::vector> cols_values; InsertIntoTableNode(std::string name, std::vector names, std::vector> values) : Node(NodeType::insert_into), table_name(std::move(name)), cols_names(std::move(names)), cols_values(std::move(values)) {} void dump() const override { std::cout << "type: InsertIntoTableNode, table_name: " << table_name << "TODO complete me" << std::endl; } }; 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(std::move(offlim)), distinct(distinct_) {} void dump() const override { std::cout << "type: SelectFromTableNode, table_name: " << table_name << "TODO complete me" << std::endl; where->dump(); } }; struct CreateTableAsSelectNode : Node { std::string table_name; std::unique_ptr select_table; CreateTableAsSelectNode(std::string name, std::unique_ptr table) : Node(NodeType::create_table_as_select), table_name(std::move(name)), select_table(std::move(table)) {} void dump() const override { std::cout << "type: CreateTableAsSelectNode, table_name: " << table_name << std::endl; select_table->dump(); } }; struct UpdateTableNode : Node { std::string table_name; std::vector cols_names; std::vector> values; std::unique_ptr where; UpdateTableNode(std::string name, std::vector names, std::vector> vals, std::unique_ptr where_clause) : Node(NodeType::update_table), table_name(std::move(name)), cols_names(std::move(names)), values(std::move(vals)), where(std::move(where_clause)) {} void dump() const override { std::cout << "type: UpdateTableNode, table_name: " << table_name << "TODO complete me" << std::endl; where->dump(); } }; struct LoadIntoTableNode : Node { std::string table_name; std::string filename; LoadIntoTableNode(std::string name, std::string file) : Node(NodeType::load_table), table_name(std::move(name)), filename(std::move(file)) {} void dump() const override { std::cout << "type: LoadIntoTableNode, table_name: " << table_name << ", filename" << filename << std::endl; } }; struct SaveTableNode : Node { std::string table_name; std::string filename; SaveTableNode(std::string name, std::string file) : Node(NodeType::save_table), table_name(std::move(name)), filename(std::move(file)) {} void dump() const override { std::cout << "type: SaveTableNode, table_name: " << table_name << ", filename" << filename << std::endl; } }; struct DropTableNode : Node { std::string table_name; explicit DropTableNode(std::string name) : Node(NodeType::drop_table), table_name(std::move(name)) {} void dump() const override { std::cout << "type: SelectFromTableNode, table_name: " << table_name << std::endl; } }; struct DeleteFromTableNode : Node { std::string table_name; std::unique_ptr where; DeleteFromTableNode(std::string name, std::unique_ptr where_clause) : Node(NodeType::delete_from), table_name(std::move(name)), where(std::move(where_clause)) {} void dump() const override { std::cout << "type: DeleteFromTableNode, table_name: " << table_name << std::endl; where->dump(); } }; struct SetNode : Node { std::string name; std::string value; SetNode(std::string node_name, std::string node_value) : Node(NodeType::set), name(std::move(node_name)), value(std::move(node_value)) {} void dump() const override { std::cout << "type: SetNode, name: " << name << ", value: " << value << std::endl; } }; struct ShowNode : Node { std::string name; explicit ShowNode(std::string node_name) : Node(NodeType::show), name(std::move(node_name)) {} void dump() const override { std::cout << "type: ShowNode, name: " << name << std::endl; } }; struct CreateIndexNode : Node { std::string index_name; std::string table_name; std::string column_name; CreateIndexNode(std::string idx_name, std::string tbl_name, std::string col_name) : Node(NodeType::create_index), index_name(std::move(idx_name)), table_name(std::move(tbl_name)), column_name(std::move(col_name)) {} void dump() const override { std::cout << "type: CreateIndexNode, table_name: " << table_name << ", index_name: " << index_name << ", column_name: " << column_name << std::endl; } }; 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::unique_ptr parse_create_index(); 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