├── sql-parser ├── lib │ └── libsqlparser.so └── include │ ├── sql │ ├── ExecuteStatement.h │ ├── PrepareStatement.h │ ├── statements.h │ ├── ExportStatement.h │ ├── TransactionStatement.h │ ├── ImportStatement.h │ ├── ShowStatement.h │ ├── UpdateStatement.h │ ├── DeleteStatement.h │ ├── DropStatement.h │ ├── InsertStatement.h │ ├── AlterStatement.h │ ├── ColumnType.h │ ├── SQLStatement.h │ ├── Table.h │ ├── CreateStatement.h │ ├── SelectStatement.h │ └── Expr.h │ ├── SQLParser.h │ ├── util │ └── sqlhelper.h │ └── SQLParserResult.h ├── README.md ├── format.sh ├── src ├── sql-parser-test │ ├── CMakeLists.txt │ └── test.cpp └── main │ ├── CMakeLists.txt │ ├── trx.h │ ├── util.h │ ├── parser.h │ ├── main.cpp │ ├── trx.cpp │ ├── metadata.h │ ├── storage.h │ ├── optimizer.h │ ├── executor.h │ ├── metadata.cpp │ ├── storage.cpp │ ├── util.cpp │ ├── optimizer.cpp │ ├── executor.cpp │ └── parser.cpp ├── CMakeLists.txt ├── LICENSE ├── .clang-format └── .vscode └── settings.json /sql-parser/lib/libsqlparser.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thuyy/ByteYoungDB/HEAD/sql-parser/lib/libsqlparser.so -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ByteYoungDB 2 | How to compile: 3 | ``` 4 | mkdir build 5 | cd build 6 | cmake ../ 7 | make 8 | ``` 9 | -------------------------------------------------------------------------------- /format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | format_cmd="clang-format -style=file -i '{}'" 4 | source_regex="^(src).*\.(cc|cpp|h|y)" 5 | 6 | find src | grep -E "$source_regex" | xargs -I{} sh -c "${format_cmd}" 7 | -------------------------------------------------------------------------------- /src/sql-parser-test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SQL_PARSER_TEST_SRC 2 | test.cpp 3 | ) 4 | 5 | add_executable(sql-parser-test 6 | ${SQL_PARSER_TEST_SRC}) 7 | 8 | target_link_libraries(sql-parser-test 9 | ${CMAKE_SOURCE_DIR}/sql-parser/lib/libsqlparser.so) -------------------------------------------------------------------------------- /src/main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(BYTE_YOUNG_SRC 2 | main.cpp 3 | executor.cpp 4 | metadata.cpp 5 | optimizer.cpp 6 | parser.cpp 7 | storage.cpp 8 | trx.cpp 9 | util.cpp 10 | ) 11 | 12 | add_executable(bydb 13 | ${BYTE_YOUNG_SRC}) 14 | 15 | target_link_libraries(bydb 16 | ${CMAKE_SOURCE_DIR}/sql-parser/lib/libsqlparser.so) -------------------------------------------------------------------------------- /sql-parser/include/sql/ExecuteStatement.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_EXECUTE_STATEMENT_H 2 | #define SQLPARSER_EXECUTE_STATEMENT_H 3 | 4 | #include "SQLStatement.h" 5 | 6 | namespace hsql { 7 | 8 | // Represents SQL Execute statements. 9 | // Example: "EXECUTE ins_prep(100, "test", 2.3);" 10 | struct ExecuteStatement : SQLStatement { 11 | ExecuteStatement(); 12 | ~ExecuteStatement() override; 13 | 14 | char* name; 15 | std::vector* parameters; 16 | }; 17 | 18 | } // namespace hsql 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /sql-parser/include/sql/PrepareStatement.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_PREPARE_STATEMENT_H 2 | #define SQLPARSER_PREPARE_STATEMENT_H 3 | 4 | #include "SQLStatement.h" 5 | 6 | namespace hsql { 7 | 8 | // Represents SQL Prepare statements. 9 | // Example: PREPARE test FROM 'SELECT * FROM test WHERE a = ?;' 10 | struct PrepareStatement : SQLStatement { 11 | PrepareStatement(); 12 | ~PrepareStatement() override; 13 | 14 | char* name; 15 | 16 | // The query that is supposed to be prepared. 17 | char* query; 18 | }; 19 | 20 | } // namespace hsql 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /sql-parser/include/sql/statements.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_STATEMENTS_H 2 | #define SQLPARSER_STATEMENTS_H 3 | 4 | #include "AlterStatement.h" 5 | #include "CreateStatement.h" 6 | #include "DeleteStatement.h" 7 | #include "DropStatement.h" 8 | #include "ExecuteStatement.h" 9 | #include "ExportStatement.h" 10 | #include "ImportStatement.h" 11 | #include "InsertStatement.h" 12 | #include "PrepareStatement.h" 13 | #include "SelectStatement.h" 14 | #include "ShowStatement.h" 15 | #include "TransactionStatement.h" 16 | #include "UpdateStatement.h" 17 | 18 | #endif // SQLPARSER_STATEMENTS_H 19 | -------------------------------------------------------------------------------- /sql-parser/include/sql/ExportStatement.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_EXPORT_STATEMENT_H 2 | #define SQLPARSER_EXPORT_STATEMENT_H 3 | 4 | #include "ImportStatement.h" 5 | #include "SQLStatement.h" 6 | 7 | namespace hsql { 8 | // Represents SQL Export statements. 9 | struct ExportStatement : SQLStatement { 10 | ExportStatement(ImportType type); 11 | ~ExportStatement() override; 12 | 13 | // ImportType is used for compatibility reasons 14 | ImportType type; 15 | char* filePath; 16 | char* schema; 17 | char* tableName; 18 | }; 19 | 20 | } // namespace hsql 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /sql-parser/include/sql/TransactionStatement.h: -------------------------------------------------------------------------------- 1 | #ifndef HYRISE_TRANSACTIONSTATEMENT_H 2 | #define HYRISE_TRANSACTIONSTATEMENT_H 3 | 4 | #include "SQLStatement.h" 5 | 6 | namespace hsql { 7 | 8 | // Represents SQL Transaction statements. 9 | // Example: BEGIN TRANSACTION; 10 | enum TransactionCommand { kBeginTransaction, kCommitTransaction, kRollbackTransaction }; 11 | 12 | struct TransactionStatement : SQLStatement { 13 | TransactionStatement(TransactionCommand command); 14 | ~TransactionStatement() override; 15 | 16 | TransactionCommand command; 17 | }; 18 | 19 | } // namespace hsql 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ByteYoungDB) 3 | set(CMAKE_CXX_STANDARD 11) 4 | set(CMAKE_CXX_COMPILER "g++") 5 | set(CMAKE_CXX_FLAGS "-g -Wall -Werror -std=c++11") 6 | set(CMAKE_CXX_FLAGS_DEBUG "-O0") 7 | set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG ") 8 | 9 | set(CMAKE_INSTALL_PREFIX "install") 10 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY 11 | ${CMAKE_BINARY_DIR}/lib) 12 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY 13 | ${CMAKE_BINARY_DIR}/bin) 14 | 15 | include_directories(${CMAKE_SOURCE_DIR}/sql-parser/include) 16 | 17 | add_subdirectory(src/main) 18 | add_subdirectory(src/sql-parser-test) 19 | -------------------------------------------------------------------------------- /sql-parser/include/sql/ImportStatement.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_IMPORT_STATEMENT_H 2 | #define SQLPARSER_IMPORT_STATEMENT_H 3 | 4 | #include "SQLStatement.h" 5 | 6 | namespace hsql { 7 | enum ImportType { 8 | kImportCSV, 9 | kImportTbl, // Hyrise file format 10 | kImportBinary, 11 | kImportAuto 12 | }; 13 | 14 | // Represents SQL Import statements. 15 | struct ImportStatement : SQLStatement { 16 | ImportStatement(ImportType type); 17 | ~ImportStatement() override; 18 | 19 | ImportType type; 20 | char* filePath; 21 | char* schema; 22 | char* tableName; 23 | }; 24 | 25 | } // namespace hsql 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /sql-parser/include/sql/ShowStatement.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_SHOW_STATEMENT_H 2 | #define SQLPARSER_SHOW_STATEMENT_H 3 | 4 | #include "SQLStatement.h" 5 | #include "SQLParserResult.h" 6 | 7 | // Note: Implementations of constructors and destructors can be found in statements.cpp. 8 | namespace hsql { 9 | 10 | enum ShowType { kShowColumns, kShowTables }; 11 | 12 | // Represents SQL SHOW statements. 13 | // Example "SHOW TABLES;" 14 | struct ShowStatement : SQLStatement { 15 | ShowStatement(ShowType type); 16 | ~ShowStatement() override; 17 | 18 | ShowType type; 19 | char* schema; 20 | char* name; 21 | }; 22 | 23 | } // namespace hsql 24 | #endif 25 | -------------------------------------------------------------------------------- /sql-parser/include/sql/UpdateStatement.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_UPDATE_STATEMENT_H 2 | #define SQLPARSER_UPDATE_STATEMENT_H 3 | 4 | #include "SQLStatement.h" 5 | 6 | namespace hsql { 7 | 8 | // Represents "column = value" expressions. 9 | struct UpdateClause { 10 | char* column; 11 | Expr* value; 12 | }; 13 | 14 | // Represents SQL Update statements. 15 | struct UpdateStatement : SQLStatement { 16 | UpdateStatement(); 17 | ~UpdateStatement() override; 18 | 19 | // TODO: switch to char* instead of TableRef 20 | TableRef* table; 21 | std::vector* updates; 22 | Expr* where; 23 | }; 24 | 25 | } // namespace hsql 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /sql-parser/include/sql/DeleteStatement.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_DELETE_STATEMENT_H 2 | #define SQLPARSER_DELETE_STATEMENT_H 3 | 4 | #include "SQLStatement.h" 5 | 6 | // Note: Implementations of constructors and destructors can be found in statements.cpp. 7 | namespace hsql { 8 | 9 | // Represents SQL Delete statements. 10 | // Example: "DELETE FROM students WHERE grade > 3.0" 11 | // Note: if (expr == nullptr) => delete all rows (truncate) 12 | struct DeleteStatement : SQLStatement { 13 | DeleteStatement(); 14 | ~DeleteStatement() override; 15 | 16 | char* schema; 17 | char* tableName; 18 | Expr* expr; 19 | }; 20 | 21 | } // namespace hsql 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /sql-parser/include/sql/DropStatement.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_DROP_STATEMENT_H 2 | #define SQLPARSER_DROP_STATEMENT_H 3 | 4 | #include "SQLStatement.h" 5 | 6 | // Note: Implementations of constructors and destructors can be found in statements.cpp. 7 | namespace hsql { 8 | 9 | enum DropType { kDropTable, kDropSchema, kDropIndex, kDropView, kDropPreparedStatement }; 10 | 11 | // Represents SQL Delete statements. 12 | // Example "DROP TABLE students;" 13 | struct DropStatement : SQLStatement { 14 | DropStatement(DropType type); 15 | ~DropStatement() override; 16 | 17 | DropType type; 18 | bool ifExists; 19 | char* schema; 20 | char* name; 21 | char* indexName; 22 | }; 23 | 24 | } // namespace hsql 25 | #endif -------------------------------------------------------------------------------- /sql-parser/include/sql/InsertStatement.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_INSERT_STATEMENT_H 2 | #define SQLPARSER_INSERT_STATEMENT_H 3 | 4 | #include "SQLStatement.h" 5 | #include "SelectStatement.h" 6 | 7 | namespace hsql { 8 | enum InsertType { kInsertValues, kInsertSelect }; 9 | 10 | // Represents SQL Insert statements. 11 | // Example: "INSERT INTO students VALUES ('Max', 1112233, 'Musterhausen', 2.3)" 12 | struct InsertStatement : SQLStatement { 13 | InsertStatement(InsertType type); 14 | ~InsertStatement() override; 15 | 16 | InsertType type; 17 | char* schema; 18 | char* tableName; 19 | std::vector* columns; 20 | std::vector* values; 21 | SelectStatement* select; 22 | }; 23 | 24 | } // namespace hsql 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/sql-parser-test/test.cpp: -------------------------------------------------------------------------------- 1 | #include "SQLParser.h" 2 | #include "SQLParserResult.h" 3 | #include "util/sqlhelper.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | int main(int argc, char* argv[]) { 12 | std::string query = argv[1]; 13 | 14 | // parse a given query 15 | hsql::SQLParserResult result; 16 | hsql::SQLParser::parse(query, &result); 17 | 18 | if (result.isValid()) { 19 | printf("Parsed successfully!\n"); 20 | printf("Number of statements: %lu\n", result.size()); 21 | 22 | for (auto i = 0u; i < result.size(); ++i) { 23 | // Print a statement summary. 24 | hsql::printStatementInfo(result.getStatement(i)); 25 | } 26 | return 0; 27 | } else { 28 | fprintf(stderr, "Given string is not a valid SQL query.\n"); 29 | fprintf(stderr, "%s (L%d:%d)\n", result.errorMsg(), result.errorLine(), 30 | result.errorColumn()); 31 | return -1; 32 | } 33 | 34 | return 0; 35 | } -------------------------------------------------------------------------------- /sql-parser/include/sql/AlterStatement.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_ALTER_STATEMENT_H 2 | #define SQLPARSER_ALTER_STATEMENT_H 3 | 4 | #include "SQLStatement.h" 5 | 6 | // Note: Implementations of constructors and destructors can be found in statements.cpp. 7 | namespace hsql { 8 | 9 | enum ActionType { 10 | DropColumn, 11 | }; 12 | 13 | struct AlterAction { 14 | AlterAction(ActionType type); 15 | ActionType type; 16 | virtual ~AlterAction(); 17 | }; 18 | 19 | struct DropColumnAction : AlterAction { 20 | DropColumnAction(char* column_name); 21 | char* columnName; 22 | bool ifExists; 23 | 24 | ~DropColumnAction() override; 25 | }; 26 | 27 | // Represents SQL Alter Table statements. 28 | // Example "ALTER TABLE students DROP COLUMN name;" 29 | struct AlterStatement : SQLStatement { 30 | AlterStatement(char* name, AlterAction* action); 31 | ~AlterStatement() override; 32 | 33 | char* schema; 34 | bool ifTableExists; 35 | char* name; 36 | AlterAction* action; 37 | }; 38 | } // namespace hsql 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /sql-parser/include/sql/ColumnType.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_COLUMN_TYPE_H 2 | #define SQLPARSER_COLUMN_TYPE_H 3 | 4 | #include 5 | 6 | namespace hsql { 7 | enum class DataType { 8 | UNKNOWN, 9 | CHAR, 10 | DATE, 11 | DATETIME, 12 | DECIMAL, 13 | DOUBLE, 14 | FLOAT, 15 | INT, 16 | LONG, 17 | REAL, 18 | SMALLINT, 19 | TEXT, 20 | TIME, 21 | VARCHAR, 22 | }; 23 | 24 | // Represents the type of a column, e.g., FLOAT or VARCHAR(10) 25 | struct ColumnType { 26 | ColumnType() = default; 27 | ColumnType(DataType data_type, int64_t length = 0, int64_t precision = 0, int64_t scale = 0); 28 | DataType data_type; 29 | int64_t length; // Used for, e.g., VARCHAR(10) 30 | int64_t precision; // Used for, e.g., DECIMAL (6, 4) or TIME (5) 31 | int64_t scale; // Used for DECIMAL (6, 4) 32 | }; 33 | 34 | bool operator==(const ColumnType& lhs, const ColumnType& rhs); 35 | bool operator!=(const ColumnType& lhs, const ColumnType& rhs); 36 | std::ostream& operator<<(std::ostream&, const ColumnType&); 37 | 38 | } // namespace hsql 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/main/trx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "storage.h" 4 | 5 | #include 6 | 7 | namespace bydb { 8 | enum UndoType { kInsertUndo, kDeleteUndo, kUpdateUndo }; 9 | 10 | struct Undo { 11 | Undo(UndoType t) 12 | : type(t), tableStore(nullptr), curTup(nullptr), oldTup(nullptr) {} 13 | ~Undo() { 14 | if (type == kUpdateUndo) { 15 | free(oldTup); 16 | } 17 | } 18 | 19 | UndoType type; 20 | TableStore* tableStore; 21 | Tuple* curTup; 22 | Tuple* oldTup; 23 | }; 24 | 25 | class Transaction { 26 | public: 27 | Transaction() : inTransaction_(false) {} 28 | ~Transaction() {} 29 | 30 | void addInsertUndo(TableStore* table_store, Tuple* tup); 31 | void addDeleteUndo(TableStore* table_store, Tuple* tup); 32 | void addUpdateUndo(TableStore* table_store, Tuple* tup); 33 | 34 | void begin(); 35 | void rollback(); 36 | void commit(); 37 | 38 | bool inTransaction() { return inTransaction_; } 39 | 40 | private: 41 | bool inTransaction_; 42 | std::stack undoStack_; 43 | }; 44 | 45 | extern Transaction g_transaction; 46 | } // namespace bydb -------------------------------------------------------------------------------- /sql-parser/include/sql/SQLStatement.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_SQLSTATEMENT_H 2 | #define SQLPARSER_SQLSTATEMENT_H 3 | 4 | #include 5 | 6 | #include "Expr.h" 7 | 8 | namespace hsql { 9 | enum StatementType { 10 | kStmtError, // unused 11 | kStmtSelect, 12 | kStmtImport, 13 | kStmtInsert, 14 | kStmtUpdate, 15 | kStmtDelete, 16 | kStmtCreate, 17 | kStmtDrop, 18 | kStmtPrepare, 19 | kStmtExecute, 20 | kStmtExport, 21 | kStmtRename, 22 | kStmtAlter, 23 | kStmtShow, 24 | kStmtTransaction 25 | }; 26 | 27 | // Base struct for every SQL statement 28 | struct SQLStatement { 29 | SQLStatement(StatementType type); 30 | 31 | virtual ~SQLStatement(); 32 | 33 | StatementType type() const; 34 | 35 | bool isType(StatementType type) const; 36 | 37 | // Shorthand for isType(type). 38 | bool is(StatementType type) const; 39 | 40 | // Length of the string in the SQL query string 41 | size_t stringLength; 42 | 43 | std::vector* hints; 44 | 45 | private: 46 | StatementType type_; 47 | }; 48 | 49 | } // namespace hsql 50 | 51 | #endif // SQLPARSER_SQLSTATEMENT_H 52 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 yangyang.9868@bytedance.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /sql-parser/include/SQLParser.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_SQLPARSER_H 2 | #define SQLPARSER_SQLPARSER_H 3 | 4 | #include "SQLParserResult.h" 5 | #include "sql/statements.h" 6 | 7 | namespace hsql { 8 | 9 | // Static methods used to parse SQL strings. 10 | class SQLParser { 11 | public: 12 | // Parses a given constant character SQL string into the result object. 13 | // Returns true if the lexer and parser could run without internal errors. 14 | // This does NOT mean that the SQL string was valid SQL. To check that 15 | // you need to check result->isValid(); 16 | static bool parse(const std::string& sql, SQLParserResult* result); 17 | 18 | // Run tokenization on the given string and store the tokens in the output vector. 19 | static bool tokenize(const std::string& sql, std::vector* tokens); 20 | 21 | // Deprecated. 22 | // Old method to parse SQL strings. Replaced by parse(). 23 | static bool parseSQLString(const char* sql, SQLParserResult* result); 24 | 25 | // Deprecated. 26 | // Old method to parse SQL strings. Replaced by parse(). 27 | static bool parseSQLString(const std::string& sql, SQLParserResult* result); 28 | 29 | private: 30 | SQLParser(); 31 | }; 32 | 33 | } // namespace hsql 34 | 35 | #endif -------------------------------------------------------------------------------- /src/main/util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "optimizer.h" 4 | #include "storage.h" 5 | 6 | #include "sql/ColumnType.h" 7 | #include "sql/Table.h" 8 | #include "sql/statements.h" 9 | 10 | #include 11 | 12 | using namespace hsql; 13 | 14 | namespace bydb { 15 | inline bool IsDataTypeSupport(DataType type) { 16 | return (type == DataType::INT || type == DataType::LONG || 17 | type == DataType::CHAR || type == DataType::VARCHAR); 18 | } 19 | 20 | inline std::string TableNameToString(char* schema, char* name) { 21 | std::string str = 22 | (schema == nullptr) ? name : schema + std::string(".") + name; 23 | return str; 24 | } 25 | 26 | inline void SetTableName(TableName& table_name, char* schema, char* name) { 27 | table_name.schema = schema; 28 | table_name.name = name; 29 | } 30 | 31 | const char* StmtTypeToString(StatementType type); 32 | const char* DataTypeToString(DataType type); 33 | const char* DropTypeToString(DropType type); 34 | const char* ExprTypeToString(ExprType type); 35 | const char* PlanTypeToString(PlanType type); 36 | 37 | size_t ColumnTypeSize(ColumnType& type); 38 | 39 | void PrintTuples(std::vector& columns, 40 | std::vector& colIds, 41 | std::vector>& tuples); 42 | 43 | } // namespace bydb -------------------------------------------------------------------------------- /src/main/parser.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "metadata.h" 3 | 4 | #include "SQLParser.h" 5 | #include "SQLParserResult.h" 6 | #include "util/sqlhelper.h" 7 | 8 | using namespace hsql; 9 | 10 | namespace bydb { 11 | class Parser { 12 | public: 13 | Parser(); 14 | ~Parser(); 15 | 16 | bool parseStatement(std::string query); 17 | 18 | SQLParserResult* getResult() { return result_; } 19 | 20 | private: 21 | bool checkStmtsMeta(); 22 | 23 | bool checkMeta(const SQLStatement* stmt); 24 | 25 | bool checkSelectStmt(const SelectStatement* stmt); 26 | 27 | bool checkInsertStmt(const InsertStatement* stmt); 28 | 29 | bool checkUpdateStmt(const UpdateStatement* stmt); 30 | 31 | bool checkDeleteStmt(const DeleteStatement* stmt); 32 | 33 | bool checkCreateStmt(const CreateStatement* stmt); 34 | 35 | bool checkDropStmt(const DropStatement* stmt); 36 | 37 | bool checkCreateIndexStmt(const CreateStatement* stmt); 38 | 39 | bool checkCreateTableStmt(const CreateStatement* stmt); 40 | 41 | Table* getTable(TableRef* table_ref); 42 | 43 | bool checkColumn(Table* table, char* col_name); 44 | 45 | bool checkExpr(Table* table, Expr* expr); 46 | 47 | bool checkValues(std::vector* columns, 48 | std::vector* values); 49 | 50 | SQLParserResult* result_; 51 | }; 52 | 53 | } // namespace bydb -------------------------------------------------------------------------------- /sql-parser/include/sql/Table.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_TABLEREF_H 2 | #define SQLPARSER_TABLEREF_H 3 | 4 | #include 5 | #include 6 | #include "Expr.h" 7 | 8 | namespace hsql { 9 | 10 | struct SelectStatement; 11 | struct JoinDefinition; 12 | struct TableRef; 13 | 14 | // Possible table reference types. 15 | enum TableRefType { kTableName, kTableSelect, kTableJoin, kTableCrossProduct }; 16 | 17 | struct TableName { 18 | char* schema; 19 | char* name; 20 | }; 21 | 22 | struct Alias { 23 | Alias(char* name, std::vector* columns = nullptr); 24 | ~Alias(); 25 | 26 | char* name; 27 | std::vector* columns; 28 | }; 29 | 30 | // Holds reference to tables. Can be either table names or a select statement. 31 | struct TableRef { 32 | TableRef(TableRefType type); 33 | virtual ~TableRef(); 34 | 35 | TableRefType type; 36 | 37 | char* schema; 38 | char* name; 39 | Alias* alias; 40 | 41 | SelectStatement* select; 42 | std::vector* list; 43 | JoinDefinition* join; 44 | 45 | // Returns true if a schema is set. 46 | bool hasSchema() const; 47 | 48 | // Returns the alias, if it is set. Otherwise the name. 49 | const char* getName() const; 50 | }; 51 | 52 | // Possible types of joins. 53 | enum JoinType { kJoinInner, kJoinFull, kJoinLeft, kJoinRight, kJoinCross, kJoinNatural }; 54 | 55 | // Definition of a join construct. 56 | struct JoinDefinition { 57 | JoinDefinition(); 58 | virtual ~JoinDefinition(); 59 | 60 | TableRef* left; 61 | TableRef* right; 62 | Expr* condition; 63 | 64 | JoinType type; 65 | }; 66 | 67 | } // namespace hsql 68 | #endif 69 | -------------------------------------------------------------------------------- /sql-parser/include/util/sqlhelper.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_SQLHELPER_H 2 | #define SQLPARSER_SQLHELPER_H 3 | 4 | #include "../sql/statements.h" 5 | 6 | namespace hsql { 7 | 8 | // Prints a summary of the given SQLStatement. 9 | void printStatementInfo(const SQLStatement* stmt); 10 | 11 | // Prints a summary of the given SelectStatement with the given indentation. 12 | void printSelectStatementInfo(const SelectStatement* stmt, uintmax_t num_indent); 13 | 14 | // Prints a summary of the given ImportStatement with the given indentation. 15 | void printImportStatementInfo(const ImportStatement* stmt, uintmax_t num_indent); 16 | 17 | // Prints a summary of the given CopyStatement with the given indentation. 18 | void printExportStatementInfo(const ExportStatement* stmt, uintmax_t num_indent); 19 | 20 | // Prints a summary of the given InsertStatement with the given indentation. 21 | void printInsertStatementInfo(const InsertStatement* stmt, uintmax_t num_indent); 22 | 23 | // Prints a summary of the given CreateStatement with the given indentation. 24 | void printCreateStatementInfo(const CreateStatement* stmt, uintmax_t num_indent); 25 | 26 | // Prints a summary of the given TransactionStatement with the given indentation. 27 | void printTransactionStatementInfo(const TransactionStatement* stmt, uintmax_t num_indent); 28 | 29 | // Prints a summary of the given Expression with the given indentation. 30 | void printExpression(Expr* expr, uintmax_t num_indent); 31 | 32 | // Prints an ORDER BY clause 33 | void printOrderBy(const std::vector* expr, uintmax_t num_indent); 34 | 35 | } // namespace hsql 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/main/main.cpp: -------------------------------------------------------------------------------- 1 | #include "executor.h" 2 | #include "optimizer.h" 3 | #include "parser.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace bydb; 10 | using namespace hsql; 11 | 12 | static bool ExecStmt(std::string stmt) { 13 | Parser parser; 14 | if (parser.parseStatement(stmt)) { 15 | return true; 16 | } 17 | 18 | SQLParserResult* result = parser.getResult(); 19 | Optimizer optimizer; 20 | 21 | for (size_t i = 0; i < result->size(); ++i) { 22 | const SQLStatement* stmt = result->getStatement(i); 23 | Plan* plan = optimizer.createPlanTree(stmt); 24 | if (plan == nullptr) { 25 | return true; 26 | } 27 | 28 | Executor executor(plan); 29 | executor.init(); 30 | if (executor.exec()) { 31 | return true; 32 | } 33 | } 34 | 35 | return false; 36 | } 37 | 38 | int main(int argc, char* argv[]) { 39 | std::cout << "# Welcome to ByteYoung DB!!!" << std::endl; 40 | std::cout << "# Input your query in one line." << std::endl; 41 | std::cout << "# Enter 'exit' or 'q' to quit this program." << std::endl; 42 | 43 | std::string cmd; 44 | while (true) { 45 | std::cout << ">> "; 46 | std::getline(std::cin, cmd); 47 | if (cmd.length() == 0) { 48 | continue; 49 | } 50 | 51 | if (cmd == "exit" || cmd == "q") { 52 | break; 53 | } 54 | 55 | if (ExecStmt(cmd)) { 56 | std::cout << "[BYDB-Error] Failed to execute '" << cmd << "'" 57 | << std::endl; 58 | } 59 | std::cout << std::endl; 60 | } 61 | 62 | std::cout << "# Farewell~~~ " << std::endl; 63 | return 0; 64 | } -------------------------------------------------------------------------------- /src/main/trx.cpp: -------------------------------------------------------------------------------- 1 | #include "trx.h" 2 | 3 | namespace bydb { 4 | Transaction g_transaction; 5 | 6 | void Transaction::addInsertUndo(TableStore* table_store, Tuple* tup) { 7 | Undo* undo = new Undo(kInsertUndo); 8 | undo->tableStore = table_store; 9 | undo->curTup = tup; 10 | undoStack_.push(undo); 11 | } 12 | 13 | void Transaction::addDeleteUndo(TableStore* table_store, Tuple* tup) { 14 | Undo* undo = new Undo(kDeleteUndo); 15 | undo->tableStore = table_store; 16 | undo->oldTup = tup; 17 | undoStack_.push(undo); 18 | } 19 | 20 | void Transaction::addUpdateUndo(TableStore* table_store, Tuple* tup) { 21 | Undo* undo = new Undo(kUpdateUndo); 22 | undo->tableStore = table_store; 23 | undo->oldTup = static_cast(malloc(table_store->tupleSize())); 24 | memcpy(undo->oldTup->data, tup->data, 25 | table_store->tupleSize() - TUPLE_HEADER_SIZE); 26 | undo->curTup = tup; 27 | undoStack_.push(undo); 28 | } 29 | 30 | void Transaction::begin() { inTransaction_ = true; } 31 | 32 | void Transaction::rollback() { 33 | while (!undoStack_.empty()) { 34 | auto undo = undoStack_.top(); 35 | TableStore* table_store = undo->tableStore; 36 | undoStack_.pop(); 37 | switch (undo->type) { 38 | case kInsertUndo: 39 | table_store->removeTuple(undo->curTup); 40 | break; 41 | case kDeleteUndo: 42 | table_store->recoverTuple(undo->oldTup); 43 | break; 44 | case kUpdateUndo: 45 | memcpy(undo->curTup->data, undo->oldTup->data, 46 | table_store->tupleSize() - TUPLE_HEADER_SIZE); 47 | break; 48 | default: 49 | break; 50 | } 51 | delete undo; 52 | } 53 | inTransaction_ = false; 54 | } 55 | 56 | void Transaction::commit() { 57 | while (undoStack_.empty()) { 58 | auto undo = undoStack_.top(); 59 | TableStore* table_store = undo->tableStore; 60 | undoStack_.pop(); 61 | if (undo->type == kDeleteUndo) { 62 | table_store->freeTuple(undo->oldTup); 63 | } 64 | delete undo; 65 | } 66 | inTransaction_ = false; 67 | } 68 | 69 | } // namespace bydb -------------------------------------------------------------------------------- /src/main/metadata.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "sql/CreateStatement.h" 4 | #include "sql/Table.h" 5 | #include "storage.h" 6 | 7 | #include 8 | #include 9 | 10 | using namespace hsql; 11 | 12 | inline uint64_t BKDRHash(const char* str, int len) { 13 | uint64_t seed = 131313; 14 | uint64_t hash = 0; 15 | while (0 != len--) { 16 | hash = hash * seed + (*str++); 17 | } 18 | return hash; 19 | } 20 | 21 | namespace std { 22 | template <> 23 | struct hash { 24 | public: 25 | size_t operator()(const TableName& T) const { 26 | std::size_t hash_val = BKDRHash(T.schema, strlen(T.schema)); 27 | hash_val ^= BKDRHash(T.name, strlen(T.name)); 28 | return hash_val; 29 | } 30 | }; 31 | 32 | template <> 33 | struct equal_to { 34 | public: 35 | bool operator()(const TableName& T1, const TableName& T2) const { 36 | return (strcmp(T1.schema, T2.schema) == 0 && strcmp(T1.name, T2.name) == 0); 37 | } 38 | }; 39 | } // namespace std 40 | 41 | namespace bydb { 42 | 43 | struct Index { 44 | char* name; 45 | std::vector columns; 46 | }; 47 | 48 | class Table { 49 | public: 50 | Table(char* schema, char* name, std::vector* columns); 51 | ~Table(); 52 | 53 | ColumnDefinition* getColumn(char* name); 54 | Index* getIndex(char* name); 55 | char* schema() { return schema_; }; 56 | char* name() { return name_; }; 57 | std::vector* columns() { return &columns_; }; 58 | std::vector* indexes() { return &indexes_; }; 59 | void addIndex(Index* index) { indexes_.push_back(index); }; 60 | TableStore* getTableStore() { return tableStore_; }; 61 | 62 | private: 63 | char* schema_; 64 | char* name_; 65 | std::vector columns_; 66 | std::vector indexes_; 67 | TableStore* tableStore_; 68 | }; 69 | 70 | class MetaData { 71 | public: 72 | MetaData(){}; 73 | ~MetaData(){}; 74 | 75 | bool insertTable(Table* table); 76 | bool dropIndex(char* schema, char* name, char* indexName); 77 | bool dropTable(char* schema, char* name); 78 | bool dropSchema(char* schema); 79 | void getAllTables(std::vector* tables); 80 | 81 | bool findSchema(char* schema); 82 | Table* getTable(char* schema, char* name); 83 | Index* getIndex(char* schema, char* name, char* index_name); 84 | 85 | private: 86 | std::unordered_map table_map_; 87 | }; 88 | 89 | extern MetaData g_meta_data; 90 | 91 | } // namespace bydb 92 | -------------------------------------------------------------------------------- /src/main/storage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "sql/statements.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace hsql; 12 | 13 | namespace bydb { 14 | 15 | #define TUPLE_GROUP_SIZE 100 16 | #define TUPLE_HEADER_SIZE 16 17 | 18 | typedef unsigned char uchar; 19 | 20 | struct Tuple { 21 | Tuple* prev; 22 | Tuple* next; 23 | uchar data[]; 24 | }; 25 | 26 | class TupleList { 27 | public: 28 | TupleList() { 29 | head_ = static_cast(malloc(sizeof(Tuple))); 30 | tail_ = static_cast(malloc(sizeof(Tuple))); 31 | head_->next = tail_; 32 | tail_->prev = head_; 33 | head_->prev = nullptr; 34 | tail_->next = nullptr; 35 | } 36 | 37 | void addHead(Tuple* tup) { 38 | Tuple* ntup = head_->next; 39 | ntup->prev = tup; 40 | tup->next = ntup; 41 | head_->next = tup; 42 | tup->prev = head_; 43 | } 44 | 45 | void delTuple(Tuple* tup) { 46 | Tuple* ntup = tup->next; 47 | Tuple* ptup = tup->prev; 48 | ptup->next = ntup; 49 | ntup->prev = ptup; 50 | tup->next = nullptr; 51 | tup->prev = nullptr; 52 | } 53 | 54 | Tuple* popHead() { 55 | if (head_->next == tail_) { 56 | return nullptr; 57 | } 58 | 59 | Tuple* tup = head_->next; 60 | delTuple(tup); 61 | return tup; 62 | } 63 | 64 | Tuple* getHead() { 65 | if (head_->next == tail_) { 66 | return nullptr; 67 | } 68 | return head_->next; 69 | } 70 | 71 | Tuple* getNext(Tuple* tup) { 72 | return (tup->next == tail_) ? nullptr : tup->next; 73 | } 74 | 75 | bool isEmpty() { return (head_->next == tail_); } 76 | 77 | private: 78 | Tuple* head_; 79 | Tuple* tail_; 80 | }; 81 | 82 | class TableStore { 83 | public: 84 | TableStore(std::vector* columns); 85 | ~TableStore(); 86 | 87 | bool insertTuple(std::vector* values); 88 | bool deleteTuple(Tuple* tup); 89 | bool updateTuple(Tuple* tup, std::vector& idxs, 90 | std::vector& values); 91 | 92 | void removeTuple(Tuple* tup); 93 | void recoverTuple(Tuple* tup); 94 | void freeTuple(Tuple* tup); 95 | 96 | Tuple* seqScan(Tuple* tup); 97 | void parseTuple(Tuple* tup, std::vector& values); 98 | 99 | int tupleSize() { return tupleSize_; } 100 | 101 | private: 102 | bool newTupleGroup(); 103 | void setColValue(Tuple* tup, int idx, Expr* expr); 104 | 105 | int colNum_; 106 | int tupleSize_; 107 | 108 | std::vector* columns_; 109 | std::vector colOffset_; 110 | std::vector tupleGroups_; 111 | TupleList freeList_; 112 | TupleList dataList_; 113 | }; 114 | 115 | } // namespace bydb -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | AccessModifierOffset: -1 4 | AlignAfterOpenBracket: Align 5 | AlignConsecutiveAssignments: false 6 | AlignConsecutiveDeclarations: false 7 | AlignEscapedNewlinesLeft: true 8 | AlignOperands: true 9 | AlignTrailingComments: true 10 | AllowAllParametersOfDeclarationOnNextLine: true 11 | AllowShortBlocksOnASingleLine: false 12 | AllowShortCaseLabelsOnASingleLine: false 13 | AllowShortFunctionsOnASingleLine: All 14 | AllowShortIfStatementsOnASingleLine: true 15 | AllowShortLoopsOnASingleLine: true 16 | AlwaysBreakAfterDefinitionReturnType: None 17 | AlwaysBreakAfterReturnType: None 18 | AlwaysBreakBeforeMultilineStrings: true 19 | AlwaysBreakTemplateDeclarations: true 20 | BinPackArguments: true 21 | BinPackParameters: true 22 | BraceWrapping: 23 | AfterClass: false 24 | AfterControlStatement: false 25 | AfterEnum: false 26 | AfterFunction: false 27 | AfterNamespace: false 28 | AfterObjCDeclaration: false 29 | AfterStruct: false 30 | AfterUnion: false 31 | BeforeCatch: false 32 | BeforeElse: false 33 | IndentBraces: false 34 | BreakBeforeBinaryOperators: None 35 | BreakBeforeBraces: Attach 36 | BreakBeforeTernaryOperators: true 37 | BreakConstructorInitializersBeforeComma: false 38 | ColumnLimit: 80 39 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 40 | ConstructorInitializerIndentWidth: 4 41 | ContinuationIndentWidth: 4 42 | Cpp11BracedListStyle: true 43 | DerivePointerAlignment: false 44 | DisableFormat: false 45 | ExperimentalAutoDetectBinPacking: false 46 | ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] 47 | IncludeCategories: 48 | - Regex: '^<.*\.h>' 49 | Priority: 1 50 | - Regex: '^<.*' 51 | Priority: 2 52 | - Regex: '.*' 53 | Priority: 3 54 | IndentCaseLabels: true 55 | IndentWidth: 2 56 | IndentWrappedFunctionNames: false 57 | KeepEmptyLinesAtTheStartOfBlocks: false 58 | MacroBlockBegin: '' 59 | MacroBlockEnd: '' 60 | MaxEmptyLinesToKeep: 1 61 | NamespaceIndentation: None 62 | ObjCBlockIndentWidth: 2 63 | ObjCSpaceAfterProperty: false 64 | ObjCSpaceBeforeProtocolList: false 65 | PenaltyBreakBeforeFirstCallParameter: 1 66 | PenaltyBreakComment: 300 67 | PenaltyBreakFirstLessLess: 80 68 | PenaltyBreakString: 1000 69 | PenaltyExcessCharacter: 1000000 70 | PenaltyReturnTypeOnItsOwnLine: 200 71 | PointerAlignment: Left 72 | ReflowComments: false 73 | SortIncludes: true 74 | SpaceAfterCStyleCast: false 75 | SpaceBeforeAssignmentOperators: true 76 | SpaceBeforeParens: ControlStatements 77 | SpaceInEmptyParentheses: false 78 | SpacesBeforeTrailingComments: 2 79 | SpacesInAngles: false 80 | SpacesInContainerLiterals: true 81 | SpacesInCStyleCastParentheses: false 82 | SpacesInParentheses: false 83 | SpacesInSquareBrackets: false 84 | Standard: Auto 85 | TabWidth: 8 86 | UseTab: Never 87 | ... 88 | -------------------------------------------------------------------------------- /sql-parser/include/SQLParserResult.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_SQLPARSER_RESULT_H 2 | #define SQLPARSER_SQLPARSER_RESULT_H 3 | 4 | #include "sql/SQLStatement.h" 5 | 6 | namespace hsql { 7 | // Represents the result of the SQLParser. 8 | // If parsing was successful it contains a list of SQLStatement. 9 | class SQLParserResult { 10 | public: 11 | // Initialize with empty statement list. 12 | SQLParserResult(); 13 | 14 | // Initialize with a single statement. 15 | // Takes ownership of the statement. 16 | SQLParserResult(SQLStatement* stmt); 17 | 18 | // Move constructor. 19 | SQLParserResult(SQLParserResult&& moved); 20 | SQLParserResult& operator=(SQLParserResult&& moved); 21 | 22 | // Deletes all statements in the result. 23 | virtual ~SQLParserResult(); 24 | 25 | // Set whether parsing was successful. 26 | void setIsValid(bool isValid); 27 | 28 | // Returns true if parsing was successful. 29 | bool isValid() const; 30 | 31 | // Returns the number of statements in the result. 32 | size_t size() const; 33 | 34 | // Set the details of the error, if available. 35 | // Takes ownership of errorMsg. 36 | void setErrorDetails(char* errorMsg, int errorLine, int errorColumn); 37 | 38 | // Returns the error message, if an error occurred. 39 | const char* errorMsg() const; 40 | 41 | // Returns the line number of the occurrance of the error in the query. 42 | int errorLine() const; 43 | 44 | // Returns the column number of the occurrance of the error in the query. 45 | int errorColumn() const; 46 | 47 | // Adds a statement to the result list of statements. 48 | // SQLParserResult takes ownership of the statement. 49 | void addStatement(SQLStatement* stmt); 50 | 51 | // Gets the SQL statement with the given index. 52 | const SQLStatement* getStatement(size_t index) const; 53 | 54 | // Gets the non const SQL statement with the given index. 55 | SQLStatement* getMutableStatement(size_t index); 56 | 57 | // Get the list of all statements. 58 | const std::vector& getStatements() const; 59 | 60 | // Returns a copy of the list of all statements in this result. 61 | // Removes them from this result. 62 | std::vector releaseStatements(); 63 | 64 | // Deletes all statements and other data within the result. 65 | void reset(); 66 | 67 | // Does NOT take ownership. 68 | void addParameter(Expr* parameter); 69 | 70 | const std::vector& parameters(); 71 | 72 | private: 73 | // List of statements within the result. 74 | std::vector statements_; 75 | 76 | // Flag indicating the parsing was successful. 77 | bool isValid_; 78 | 79 | // Error message, if an error occurred. 80 | char* errorMsg_; 81 | 82 | // Line number of the occurrance of the error in the query. 83 | int errorLine_; 84 | 85 | // Column number of the occurrance of the error in the query. 86 | int errorColumn_; 87 | 88 | // Does NOT have ownership. 89 | std::vector parameters_; 90 | }; 91 | 92 | } // namespace hsql 93 | 94 | #endif // SQLPARSER_SQLPARSER_RESULT_H -------------------------------------------------------------------------------- /src/main/optimizer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "metadata.h" 4 | 5 | #include "sql/statements.h" 6 | 7 | using namespace hsql; 8 | 9 | namespace bydb { 10 | enum PlanType { 11 | kCreate, 12 | kDrop, 13 | kInsert, 14 | kUpdate, 15 | kDelete, 16 | kSelect, 17 | kScan, 18 | kProjection, 19 | kFilter, 20 | kSort, 21 | kLimit, 22 | kTrx, 23 | kShow 24 | }; 25 | 26 | struct Plan { 27 | Plan(PlanType t) : planType(t), next(nullptr) {} 28 | ~Plan() { 29 | delete next; 30 | next = nullptr; 31 | } 32 | 33 | PlanType planType; 34 | Plan* next; 35 | }; 36 | 37 | struct CreatePlan : public Plan { 38 | CreatePlan(CreateType t) : Plan(kCreate), type(t) {} 39 | CreateType type; 40 | bool ifNotExists; 41 | char* schema; 42 | char* tableName; 43 | char* indexName; 44 | std::vector* indexColumns; 45 | std::vector* columns; 46 | }; 47 | 48 | struct DropPlan : public Plan { 49 | DropPlan() : Plan(kDrop) {} 50 | DropType type; 51 | bool ifExists; 52 | char* schema; 53 | char* name; 54 | char* indexName; 55 | }; 56 | 57 | struct InsertPlan : public Plan { 58 | InsertPlan() : Plan(kInsert) {} 59 | InsertType type; 60 | Table* table; 61 | std::vector* values; 62 | }; 63 | 64 | struct UpdatePlan : public Plan { 65 | UpdatePlan() : Plan(kUpdate) {} 66 | Table* table; 67 | std::vector values; 68 | std::vector idxs; 69 | }; 70 | 71 | struct DeletePlan : public Plan { 72 | DeletePlan() : Plan(kDelete) {} 73 | Table* table; 74 | }; 75 | 76 | struct SelectPlan : public Plan { 77 | SelectPlan() : Plan(kSelect) {} 78 | Table* table; 79 | std::vector outCols; 80 | std::vector colIds; 81 | }; 82 | 83 | enum ScanType { kSeqScan, kIndexScan }; 84 | 85 | struct ScanPlan : public Plan { 86 | ScanPlan() : Plan(kScan) {} 87 | ScanType type; 88 | Table* table; 89 | }; 90 | 91 | struct FilterPlan : public Plan { 92 | FilterPlan() : Plan(kFilter), idx(0), val(nullptr) {} 93 | size_t idx; 94 | Expr* val; 95 | }; 96 | 97 | struct SortPlan : public Plan { 98 | SortPlan() : Plan(kSort) {} 99 | Table* table; 100 | std::vector* order; 101 | }; 102 | 103 | struct LimitPlan : public Plan { 104 | LimitPlan() : Plan(kLimit) {} 105 | uint64_t offset; 106 | uint64_t limit; 107 | }; 108 | 109 | struct TrxPlan : public Plan { 110 | TrxPlan() : Plan(kTrx) {} 111 | TransactionCommand command; 112 | }; 113 | 114 | struct ShowPlan : public Plan { 115 | ShowPlan() : Plan(kShow) {} 116 | ShowType type; 117 | char* schema; 118 | char* name; 119 | }; 120 | 121 | class Optimizer { 122 | public: 123 | Optimizer() {} 124 | 125 | Plan* createPlanTree(const SQLStatement* stmt); 126 | 127 | private: 128 | Plan* createCreatePlanTree(const CreateStatement* stmt); 129 | 130 | Plan* createDropPlanTree(const DropStatement* stmt); 131 | 132 | Plan* createInsertPlanTree(const InsertStatement* stmt); 133 | 134 | Plan* createUpdatePlanTree(const UpdateStatement* stmt); 135 | 136 | Plan* createDeletePlanTree(const DeleteStatement* stmt); 137 | 138 | Plan* createSelectPlanTree(const SelectStatement* stmt); 139 | 140 | Plan* createFilterPlan(std::vector* columns, Expr* where); 141 | 142 | Plan* createTrxPlanTree(const TransactionStatement* stmt); 143 | 144 | Plan* createShowPlanTree(const ShowStatement* stmt); 145 | }; 146 | 147 | } // namespace bydb -------------------------------------------------------------------------------- /sql-parser/include/sql/CreateStatement.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_CREATE_STATEMENT_H 2 | #define SQLPARSER_CREATE_STATEMENT_H 3 | 4 | #include "ColumnType.h" 5 | #include "SQLStatement.h" 6 | 7 | #include 8 | 9 | // Note: Implementations of constructors and destructors can be found in statements.cpp. 10 | namespace hsql { 11 | struct SelectStatement; 12 | 13 | enum struct ConstraintType { None, NotNull, Null, PrimaryKey, Unique }; 14 | 15 | // Superclass for both TableConstraint and Column Definition 16 | struct TableElement { 17 | virtual ~TableElement() {} 18 | }; 19 | 20 | // Represents definition of a table constraint 21 | struct TableConstraint : TableElement { 22 | TableConstraint(ConstraintType keyType, std::vector* columnNames); 23 | 24 | ~TableConstraint() override; 25 | 26 | ConstraintType type; 27 | std::vector* columnNames; 28 | }; 29 | 30 | // Represents definition of a table column 31 | struct ColumnDefinition : TableElement { 32 | ColumnDefinition(char* name, ColumnType type, std::vector* column_constraints); 33 | 34 | ~ColumnDefinition() override; 35 | 36 | void setNullableExplicit() { 37 | nullable = false; 38 | 39 | for (unsigned long constraint_index = 0; constraint_index < column_constraints->size(); constraint_index++) { 40 | if (column_constraints->at(constraint_index) == ConstraintType::Null) { 41 | nullable = true; 42 | column_constraints->erase(column_constraints->cbegin() + constraint_index); 43 | } else if (column_constraints->at(constraint_index) == ConstraintType::NotNull) { 44 | column_constraints->erase(column_constraints->cbegin() + constraint_index); 45 | } 46 | } 47 | } 48 | 49 | std::vector* column_constraints; 50 | char* name; 51 | ColumnType type; 52 | bool nullable; 53 | }; 54 | 55 | enum CreateType { 56 | kCreateTable, 57 | kCreateTableFromTbl, // Hyrise file format 58 | kCreateView, 59 | kCreateIndex 60 | }; 61 | 62 | // Represents SQL Create statements. 63 | // Example: "CREATE TABLE students (name TEXT, student_number INTEGER, city TEXT, grade DOUBLE)" 64 | struct CreateStatement : SQLStatement { 65 | CreateStatement(CreateType type); 66 | ~CreateStatement() override; 67 | 68 | void setColumnDefsAndConstraints(std::vector* tableElements) { 69 | columns = new std::vector(); 70 | tableConstraints = new std::vector(); 71 | 72 | for (auto tableElem : *tableElements) { 73 | if (auto* colDef = dynamic_cast(tableElem)) { 74 | columns->emplace_back(colDef); 75 | } else if (auto* tableConstraint = dynamic_cast(tableElem)) { 76 | tableConstraints->emplace_back(tableConstraint); 77 | } 78 | } 79 | } 80 | 81 | CreateType type; 82 | bool ifNotExists; // default: false 83 | char* filePath; // default: nullptr 84 | char* schema; // default: nullptr 85 | char* tableName; // default: nullptr 86 | char* indexName; // default: nullptr 87 | std::vector* indexColumns; // default: nullptr 88 | std::vector* columns; // default: nullptr 89 | std::vector* tableConstraints; // default: nullptr 90 | std::vector* viewColumns; 91 | SelectStatement* select; 92 | }; 93 | 94 | } // namespace hsql 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /src/main/executor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "optimizer.h" 4 | 5 | namespace bydb { 6 | 7 | struct TupleIter { 8 | TupleIter(Tuple* t) : tup(t) {} 9 | ~TupleIter() { 10 | for (auto expr : values) { 11 | delete expr; 12 | } 13 | } 14 | 15 | Tuple* tup; 16 | std::vector values; 17 | }; 18 | 19 | class BaseOperator { 20 | public: 21 | BaseOperator(Plan* plan, BaseOperator* next) : plan_(plan), next_(next) {} 22 | virtual ~BaseOperator() { delete next_; } 23 | virtual bool exec(TupleIter** iter = nullptr) = 0; 24 | 25 | Plan* plan_; 26 | BaseOperator* next_; 27 | }; 28 | 29 | class CreateOperator : public BaseOperator { 30 | public: 31 | CreateOperator(Plan* plan, BaseOperator* next) : BaseOperator(plan, next) {} 32 | ~CreateOperator() {} 33 | bool exec(TupleIter** iter = nullptr) override; 34 | }; 35 | 36 | class DropOperator : public BaseOperator { 37 | public: 38 | DropOperator(Plan* plan, BaseOperator* next) : BaseOperator(plan, next) {} 39 | ~DropOperator() {} 40 | bool exec(TupleIter** iter = nullptr) override; 41 | }; 42 | 43 | class InsertOperator : public BaseOperator { 44 | public: 45 | InsertOperator(Plan* plan, BaseOperator* next) : BaseOperator(plan, next) {} 46 | ~InsertOperator() {} 47 | bool exec(TupleIter** iter = nullptr) override; 48 | }; 49 | 50 | class UpdateOperator : public BaseOperator { 51 | public: 52 | UpdateOperator(Plan* plan, BaseOperator* next) : BaseOperator(plan, next) {} 53 | ~UpdateOperator() {} 54 | bool exec(TupleIter** iter = nullptr) override; 55 | }; 56 | 57 | class DeleteOperator : public BaseOperator { 58 | public: 59 | DeleteOperator(Plan* plan, BaseOperator* next) : BaseOperator(plan, next) {} 60 | ~DeleteOperator() {} 61 | bool exec(TupleIter** iter = nullptr) override; 62 | }; 63 | 64 | class TrxOperator : public BaseOperator { 65 | public: 66 | TrxOperator(Plan* plan, BaseOperator* next) : BaseOperator(plan, next) {} 67 | ~TrxOperator() {} 68 | bool exec(TupleIter** iter = nullptr) override; 69 | }; 70 | 71 | class ShowOperator : public BaseOperator { 72 | public: 73 | ShowOperator(Plan* plan, BaseOperator* next) : BaseOperator(plan, next) {} 74 | ~ShowOperator() {} 75 | bool exec(TupleIter** iter = nullptr) override; 76 | }; 77 | 78 | class SelectOperator : public BaseOperator { 79 | public: 80 | SelectOperator(Plan* plan, BaseOperator* next) : BaseOperator(plan, next) {} 81 | ~SelectOperator() {} 82 | bool exec(TupleIter** iter = nullptr) override; 83 | }; 84 | 85 | class SeqScanOperator : public BaseOperator { 86 | public: 87 | SeqScanOperator(Plan* plan, BaseOperator* next) 88 | : BaseOperator(plan, next), finish(false), nextTuple_(nullptr) {} 89 | ~SeqScanOperator() { 90 | for (auto iter : tuples_) { 91 | delete iter; 92 | } 93 | } 94 | bool exec(TupleIter** iter = nullptr) override; 95 | 96 | private: 97 | bool finish; 98 | Tuple* nextTuple_; 99 | std::vector tuples_; 100 | }; 101 | 102 | class FilterOperator : public BaseOperator { 103 | public: 104 | FilterOperator(Plan* plan, BaseOperator* next) : BaseOperator(plan, next) {} 105 | ~FilterOperator() {} 106 | bool exec(TupleIter** iter = nullptr) override; 107 | 108 | private: 109 | bool execEqualExpr(TupleIter* iter); 110 | }; 111 | 112 | class Executor { 113 | public: 114 | Executor(Plan* plan) : planTree_(plan) {} 115 | ~Executor() {} 116 | void init(); 117 | bool exec(); 118 | 119 | private: 120 | BaseOperator* generateOperator(Plan* Plan); 121 | 122 | Plan* planTree_; 123 | BaseOperator* opTree_; 124 | }; 125 | 126 | } // namespace bydb -------------------------------------------------------------------------------- /sql-parser/include/sql/SelectStatement.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_SELECT_STATEMENT_H 2 | #define SQLPARSER_SELECT_STATEMENT_H 3 | 4 | #include "Expr.h" 5 | #include "SQLStatement.h" 6 | #include "Table.h" 7 | 8 | namespace hsql { 9 | enum OrderType { kOrderAsc, kOrderDesc }; 10 | 11 | enum SetType { kSetUnion, kSetIntersect, kSetExcept }; 12 | 13 | enum RowLockMode { ForUpdate, ForNoKeyUpdate, ForShare, ForKeyShare }; 14 | enum RowLockWaitPolicy { NoWait, SkipLocked, None }; 15 | 16 | // Description of the order by clause within a select statement. 17 | struct OrderDescription { 18 | OrderDescription(OrderType type, Expr* expr); 19 | virtual ~OrderDescription(); 20 | 21 | OrderType type; 22 | Expr* expr; 23 | }; 24 | 25 | // Description of the limit clause within a select statement. 26 | struct LimitDescription { 27 | LimitDescription(Expr* limit, Expr* offset); 28 | virtual ~LimitDescription(); 29 | 30 | Expr* limit; 31 | Expr* offset; 32 | }; 33 | 34 | // Description of the group-by clause within a select statement. 35 | struct GroupByDescription { 36 | GroupByDescription(); 37 | virtual ~GroupByDescription(); 38 | 39 | std::vector* columns; 40 | Expr* having; 41 | }; 42 | 43 | struct WithDescription { 44 | ~WithDescription(); 45 | 46 | char* alias; 47 | SelectStatement* select; 48 | }; 49 | 50 | struct SetOperation { 51 | SetOperation(); 52 | virtual ~SetOperation(); 53 | 54 | SetType setType; 55 | bool isAll; 56 | 57 | SelectStatement* nestedSelectStatement; 58 | std::vector* resultOrder; 59 | LimitDescription* resultLimit; 60 | }; 61 | 62 | struct LockingClause { 63 | RowLockMode rowLockMode; 64 | RowLockWaitPolicy rowLockWaitPolicy; 65 | std::vector* tables; 66 | }; 67 | 68 | // Representation of a full SQL select statement. 69 | struct SelectStatement : SQLStatement { 70 | SelectStatement(); 71 | ~SelectStatement() override; 72 | 73 | TableRef* fromTable; 74 | bool selectDistinct; 75 | std::vector* selectList; 76 | Expr* whereClause; 77 | GroupByDescription* groupBy; 78 | 79 | // Note that a SetOperation is always connected to a 80 | // different SelectStatement. This statement can itself 81 | // have SetOperation connections to other SelectStatements. 82 | // To evaluate the operations in the correct order: 83 | // Iterate over the setOperations vector: 84 | // 1. Fully evaluate the nestedSelectStatement within the SetOperation 85 | // 2. Connect the original statement with the 86 | // evaluated nestedSelectStatement 87 | // 3. Apply the resultOrder and the resultLimit 88 | // 4. The result now functions as the the original statement 89 | // for the next iteration 90 | // 91 | // Example: 92 | // 93 | // (SELECT * FROM students INTERSECT SELECT * FROM students_2) UNION SELECT * FROM students_3 ORDER BY grade ASC; 94 | // 95 | // 1. We evaluate `Select * FROM students` 96 | // 2. Then we iterate over the setOperations vector 97 | // 3. We evalute the nestedSelectStatement of the first entry, which is: `SELECT * FROM students_2` 98 | // 4. We connect the result of 1. with the results of 3. using the setType, which is INTERSECT 99 | // 5. We continue the iteration of the setOperations vector 100 | // 6. We evaluate the new nestedSelectStatement which is: `SELECT * FROM students_3` 101 | // 7. We apply a Union-Operation to connect the results of 4. and 6. 102 | // 8. Finally, we apply the resultOrder of the last SetOperation (ORDER BY grade ASC) 103 | std::vector* setOperations; 104 | 105 | std::vector* order; 106 | std::vector* withDescriptions; 107 | LimitDescription* limit; 108 | std::vector* lockings; 109 | }; 110 | 111 | } // namespace hsql 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "*.ic": "cpp", 4 | "*.ipp": "cpp", 5 | "array": "cpp", 6 | "hash_map": "cpp", 7 | "hash_set": "cpp", 8 | "bitset": "cpp", 9 | "string_view": "cpp", 10 | "rope": "cpp", 11 | "slist": "cpp", 12 | "initializer_list": "cpp", 13 | "regex": "cpp", 14 | "utility": "cpp", 15 | "valarray": "cpp", 16 | "functional": "cpp", 17 | "shared_mutex": "cpp", 18 | "random": "cpp", 19 | "cctype": "cpp", 20 | "clocale": "cpp", 21 | "cmath": "cpp", 22 | "csetjmp": "cpp", 23 | "csignal": "cpp", 24 | "cstdarg": "cpp", 25 | "cstddef": "cpp", 26 | "cstdio": "cpp", 27 | "cstdlib": "cpp", 28 | "cstring": "cpp", 29 | "ctime": "cpp", 30 | "cwchar": "cpp", 31 | "cwctype": "cpp", 32 | "atomic": "cpp", 33 | "strstream": "cpp", 34 | "*.tcc": "cpp", 35 | "chrono": "cpp", 36 | "cinttypes": "cpp", 37 | "codecvt": "cpp", 38 | "complex": "cpp", 39 | "condition_variable": "cpp", 40 | "cstdint": "cpp", 41 | "deque": "cpp", 42 | "forward_list": "cpp", 43 | "list": "cpp", 44 | "unordered_map": "cpp", 45 | "unordered_set": "cpp", 46 | "vector": "cpp", 47 | "exception": "cpp", 48 | "algorithm": "cpp", 49 | "any": "cpp", 50 | "filesystem": "cpp", 51 | "iterator": "cpp", 52 | "map": "cpp", 53 | "memory": "cpp", 54 | "memory_resource": "cpp", 55 | "numeric": "cpp", 56 | "optional": "cpp", 57 | "ratio": "cpp", 58 | "set": "cpp", 59 | "string": "cpp", 60 | "system_error": "cpp", 61 | "tuple": "cpp", 62 | "type_traits": "cpp", 63 | "fstream": "cpp", 64 | "future": "cpp", 65 | "iomanip": "cpp", 66 | "iosfwd": "cpp", 67 | "iostream": "cpp", 68 | "istream": "cpp", 69 | "limits": "cpp", 70 | "mutex": "cpp", 71 | "new": "cpp", 72 | "ostream": "cpp", 73 | "scoped_allocator": "cpp", 74 | "sstream": "cpp", 75 | "stdexcept": "cpp", 76 | "streambuf": "cpp", 77 | "thread": "cpp", 78 | "cfenv": "cpp", 79 | "typeindex": "cpp", 80 | "typeinfo": "cpp", 81 | "__locale": "cpp", 82 | "__node_handle": "cpp", 83 | "__split_buffer": "cpp", 84 | "queue": "cpp", 85 | "stack": "cpp", 86 | "__hash_table": "cpp", 87 | "__tree": "cpp", 88 | "__functional_base": "cpp", 89 | "locale": "cpp", 90 | "__bit_reference": "cpp", 91 | "__string": "cpp", 92 | "__config": "cpp", 93 | "__debug": "cpp", 94 | "__errc": "cpp", 95 | "__mutex_base": "cpp", 96 | "__nullptr": "cpp", 97 | "__threading_support": "cpp", 98 | "__tuple": "cpp", 99 | "bit": "cpp", 100 | "ios": "cpp", 101 | "*.inc": "cpp", 102 | "__functional_base_03": "cpp", 103 | "__functional_03": "cpp", 104 | "*.idl": "cpp", 105 | "compare": "cpp", 106 | "coroutine": "cpp", 107 | "span": "cpp", 108 | "variant": "cpp", 109 | "*.in": "cpp" 110 | }, 111 | "C_Cpp.dimInactiveRegions": false, 112 | "C_Cpp.errorSquiggles": "Disabled", 113 | "editor.tabSize": 2, 114 | "workbench.editor.showTabs": true, 115 | "workbench.editor.enablePreview": false, 116 | "git.ignoreLimitWarning": true, 117 | "editor.rulers": [80], 118 | "search.exclude": { 119 | "**/*.sql": true, 120 | "**/*.result": true, 121 | "**/*.txt": false, 122 | "**/*.rst": true, 123 | "**/*.cmake": true, 124 | "**/*.test": true, 125 | "**/*.sh": true, 126 | "**/*.sample": true 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/main/metadata.cpp: -------------------------------------------------------------------------------- 1 | #include "metadata.h" 2 | #include "util.h" 3 | 4 | #include 5 | 6 | using namespace hsql; 7 | 8 | namespace bydb { 9 | 10 | MetaData g_meta_data; 11 | 12 | Table::Table(char* schema, char* name, 13 | std::vector* columns) { 14 | schema_ = strdup(schema); 15 | name_ = strdup(name); 16 | for (auto col_old : *columns) { 17 | std::vector* column_constraints = 18 | new std::vector(); 19 | *column_constraints = *col_old->column_constraints; 20 | ColumnDefinition* col = new ColumnDefinition( 21 | strdup(col_old->name), col_old->type, column_constraints); 22 | col->nullable = col_old->nullable; 23 | columns_.push_back(col); 24 | } 25 | 26 | tableStore_ = new TableStore(&columns_); 27 | } 28 | 29 | Table::~Table() { 30 | free(schema_); 31 | free(name_); 32 | delete tableStore_; 33 | for (auto col : columns_) { 34 | delete col; 35 | } 36 | } 37 | 38 | ColumnDefinition* Table::getColumn(char* name) { 39 | if (name == nullptr || strlen(name) == 0) { 40 | return nullptr; 41 | } 42 | 43 | for (auto col : columns_) { 44 | if (strcmp(name, col->name) == 0) { 45 | return col; 46 | } 47 | } 48 | 49 | return nullptr; 50 | } 51 | 52 | Index* Table::getIndex(char* name) { 53 | if (name == nullptr || strlen(name) == 0) { 54 | return nullptr; 55 | } 56 | 57 | for (auto index : indexes_) { 58 | if (strcmp(name, index->name)) { 59 | return index; 60 | } 61 | } 62 | 63 | return nullptr; 64 | } 65 | 66 | bool MetaData::insertTable(Table* table) { 67 | if (getTable(table->schema(), table->name()) != nullptr) { 68 | return true; 69 | } else { 70 | TableName table_name; 71 | SetTableName(table_name, table->schema(), table->name()); 72 | table_map_.emplace(table_name, table); 73 | return false; 74 | } 75 | } 76 | 77 | bool MetaData::dropIndex(char* schema, char* name, char* indexName) { 78 | Table* table = getTable(schema, name); 79 | if (table == nullptr) { 80 | std::cout << "[BYDB-Error] Table " << TableNameToString(schema, name) 81 | << " did not exist!" << std::endl; 82 | return true; 83 | } 84 | 85 | bool ret = true; 86 | std::vector& indexes = *table->indexes(); 87 | for (size_t i = 0; i < indexes.size(); i++) { 88 | Index* index = indexes[i]; 89 | if (strcmp(index->name, indexName) == 0) { 90 | indexes.erase(indexes.begin() + i); 91 | ret = false; 92 | } 93 | } 94 | 95 | return ret; 96 | } 97 | 98 | bool MetaData::dropTable(char* schema, char* name) { 99 | Table* table = getTable(schema, name); 100 | if (table == nullptr) { 101 | return true; 102 | } 103 | 104 | TableName table_name; 105 | SetTableName(table_name, schema, name); 106 | table_map_.erase(table_name); 107 | delete table; 108 | return false; 109 | } 110 | 111 | bool MetaData::dropSchema(char* schema) { 112 | auto iter = table_map_.begin(); 113 | bool ret = true; 114 | while (iter != table_map_.end()) { 115 | Table* table = iter->second; 116 | if (strcmp(table->schema(), schema) == 0) { 117 | std::cout << "[BYDB-Info] Drop table " << table->name() << " in schema " 118 | << schema << std::endl; 119 | iter = table_map_.erase(iter); 120 | delete table; 121 | ret = false; 122 | } else { 123 | iter++; 124 | } 125 | } 126 | return ret; 127 | } 128 | 129 | void MetaData::getAllTables(std::vector* tables) { 130 | if (tables == nullptr) { 131 | return; 132 | } 133 | 134 | for (auto iter : table_map_) { 135 | tables->push_back(iter.second); 136 | } 137 | } 138 | 139 | bool MetaData::findSchema(char* schema) { 140 | for (auto iter : table_map_) { 141 | Table* table = iter.second; 142 | if (strcmp(table->schema(), schema) == 0) { 143 | return true; 144 | } 145 | } 146 | 147 | return false; 148 | } 149 | 150 | Table* MetaData::getTable(char* schema, char* name) { 151 | if (schema == nullptr || name == nullptr) { 152 | std::cout << "[BYDB-Error]: Schema and table name should be specified in " 153 | "the query, like 'db.t'." 154 | << std::endl; 155 | return nullptr; 156 | } 157 | 158 | TableName table_name; 159 | SetTableName(table_name, schema, name); 160 | 161 | auto iter = table_map_.find(table_name); 162 | if (iter == table_map_.end()) { 163 | return nullptr; 164 | } else { 165 | return iter->second; 166 | } 167 | } 168 | 169 | Index* MetaData::getIndex(char* schema, char* name, char* index_name) { 170 | Table* table = getTable(schema, name); 171 | if (table == nullptr) { 172 | std::cout << "[BYDB-Error] Table " << TableNameToString(schema, name) 173 | << " did not exist!" << std::endl; 174 | return nullptr; 175 | } 176 | 177 | for (auto index : *table->indexes()) { 178 | if (strcmp(index->name, index_name) == 0) { 179 | return index; 180 | } 181 | } 182 | 183 | return nullptr; 184 | } 185 | 186 | } // namespace bydb -------------------------------------------------------------------------------- /sql-parser/include/sql/Expr.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLPARSER_EXPR_H 2 | #define SQLPARSER_EXPR_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "ColumnType.h" 8 | 9 | namespace hsql { 10 | struct SelectStatement; 11 | 12 | // Helper function used by the lexer. 13 | // TODO: move to more appropriate place. 14 | char* substr(const char* source, int from, int to); 15 | 16 | enum ExprType { 17 | kExprLiteralFloat, 18 | kExprLiteralString, 19 | kExprLiteralInt, 20 | kExprLiteralNull, 21 | kExprLiteralDate, 22 | kExprLiteralInterval, 23 | kExprStar, 24 | kExprParameter, 25 | kExprColumnRef, 26 | kExprFunctionRef, 27 | kExprOperator, 28 | kExprSelect, 29 | kExprHint, 30 | kExprArray, 31 | kExprArrayIndex, 32 | kExprExtract, 33 | kExprCast 34 | }; 35 | 36 | // Operator types. These are important for expressions of type kExprOperator. 37 | enum OperatorType { 38 | kOpNone, 39 | 40 | // Ternary operator 41 | kOpBetween, 42 | 43 | // n-nary special case 44 | kOpCase, 45 | kOpCaseListElement, // `WHEN expr THEN expr` 46 | 47 | // Binary operators. 48 | kOpPlus, 49 | kOpMinus, 50 | kOpAsterisk, 51 | kOpSlash, 52 | kOpPercentage, 53 | kOpCaret, 54 | 55 | kOpEquals, 56 | kOpNotEquals, 57 | kOpLess, 58 | kOpLessEq, 59 | kOpGreater, 60 | kOpGreaterEq, 61 | kOpLike, 62 | kOpNotLike, 63 | kOpILike, 64 | kOpAnd, 65 | kOpOr, 66 | kOpIn, 67 | kOpConcat, 68 | 69 | // Unary operators. 70 | kOpNot, 71 | kOpUnaryMinus, 72 | kOpIsNull, 73 | kOpExists 74 | }; 75 | 76 | enum DatetimeField { 77 | kDatetimeNone, 78 | kDatetimeSecond, 79 | kDatetimeMinute, 80 | kDatetimeHour, 81 | kDatetimeDay, 82 | kDatetimeMonth, 83 | kDatetimeYear, 84 | }; 85 | 86 | typedef struct Expr Expr; 87 | 88 | // Represents SQL expressions (i.e. literals, operators, column_refs). 89 | // TODO: When destructing a placeholder expression, we might need to alter the 90 | // placeholder_list. 91 | struct Expr { 92 | Expr(ExprType type); 93 | virtual ~Expr(); 94 | 95 | ExprType type; 96 | 97 | // TODO: Replace expressions by list. 98 | Expr* expr; 99 | Expr* expr2; 100 | std::vector* exprList; 101 | SelectStatement* select; 102 | char* name; 103 | char* table; 104 | char* alias; 105 | double fval; 106 | int64_t ival; 107 | int64_t ival2; 108 | DatetimeField datetimeField; 109 | ColumnType columnType; 110 | bool isBoolLiteral; 111 | 112 | OperatorType opType; 113 | bool distinct; 114 | 115 | // Convenience accessor methods. 116 | 117 | bool isType(ExprType exprType) const; 118 | 119 | bool isLiteral() const; 120 | 121 | bool hasAlias() const; 122 | 123 | bool hasTable() const; 124 | 125 | const char* getName() const; 126 | 127 | // Static constructors. 128 | 129 | static Expr* make(ExprType type); 130 | 131 | static Expr* makeOpUnary(OperatorType op, Expr* expr); 132 | 133 | static Expr* makeOpBinary(Expr* expr1, OperatorType op, Expr* expr2); 134 | 135 | static Expr* makeBetween(Expr* expr, Expr* left, Expr* right); 136 | 137 | static Expr* makeCaseList(Expr* caseListElement); 138 | 139 | static Expr* makeCaseListElement(Expr* when, Expr* then); 140 | 141 | static Expr* caseListAppend(Expr* caseList, Expr* caseListElement); 142 | 143 | static Expr* makeCase(Expr* expr, Expr* when, Expr* elseExpr); 144 | 145 | static Expr* makeLiteral(int64_t val); 146 | 147 | static Expr* makeLiteral(double val); 148 | 149 | static Expr* makeLiteral(char* val); 150 | 151 | static Expr* makeLiteral(bool val); 152 | 153 | static Expr* makeNullLiteral(); 154 | 155 | static Expr* makeDateLiteral(char* val); 156 | 157 | static Expr* makeIntervalLiteral(int64_t duration, DatetimeField unit); 158 | 159 | static Expr* makeColumnRef(char* name); 160 | 161 | static Expr* makeColumnRef(char* table, char* name); 162 | 163 | static Expr* makeStar(void); 164 | 165 | static Expr* makeStar(char* table); 166 | 167 | static Expr* makeFunctionRef(char* func_name, std::vector* exprList, bool distinct); 168 | 169 | static Expr* makeArray(std::vector* exprList); 170 | 171 | static Expr* makeArrayIndex(Expr* expr, int64_t index); 172 | 173 | static Expr* makeParameter(int id); 174 | 175 | static Expr* makeSelect(SelectStatement* select); 176 | 177 | static Expr* makeExists(SelectStatement* select); 178 | 179 | static Expr* makeInOperator(Expr* expr, std::vector* exprList); 180 | 181 | static Expr* makeInOperator(Expr* expr, SelectStatement* select); 182 | 183 | static Expr* makeExtract(DatetimeField datetimeField1, Expr* expr); 184 | 185 | static Expr* makeCast(Expr* expr, ColumnType columnType); 186 | }; 187 | 188 | // Zero initializes an Expr object and assigns it to a space in the heap 189 | // For Hyrise we still had to put in the explicit NULL constructor 190 | // http://www.ex-parrot.com/~chris/random/initialise.html 191 | // Unused 192 | #define ALLOC_EXPR(var, type) \ 193 | Expr* var; \ 194 | do { \ 195 | Expr zero = {type}; \ 196 | var = (Expr*)malloc(sizeof *var); \ 197 | *var = zero; \ 198 | } while (0); 199 | #undef ALLOC_EXPR 200 | 201 | } // namespace hsql 202 | 203 | #endif 204 | -------------------------------------------------------------------------------- /src/main/storage.cpp: -------------------------------------------------------------------------------- 1 | #include "storage.h" 2 | #include "trx.h" 3 | #include "util.h" 4 | 5 | #include "sql/ColumnType.h" 6 | #include "sql/Expr.h" 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace hsql; 13 | 14 | namespace bydb { 15 | 16 | TableStore::TableStore(std::vector* columns) 17 | : colNum_(columns->size()), tupleSize_(0), columns_(columns) { 18 | colOffset_.push_back(0); 19 | 20 | // Add space for each columns 21 | for (auto col : *columns) { 22 | tupleSize_ += ColumnTypeSize(col->type); 23 | colOffset_.push_back(tupleSize_); 24 | } 25 | 26 | // Add space for null map 27 | tupleSize_ += colNum_; 28 | 29 | // Add space for header 30 | tupleSize_ += TUPLE_HEADER_SIZE; 31 | } 32 | 33 | TableStore::~TableStore() { 34 | for (auto tuple_group : tupleGroups_) { 35 | free(tuple_group); 36 | } 37 | } 38 | 39 | bool TableStore::insertTuple(std::vector* values) { 40 | if (freeList_.isEmpty()) { 41 | if (newTupleGroup()) { 42 | return true; 43 | } 44 | } 45 | 46 | Tuple* tup = freeList_.popHead(); 47 | dataList_.addHead(tup); 48 | 49 | int idx = 0; 50 | for (auto expr : *values) { 51 | setColValue(tup, idx, expr); 52 | idx++; 53 | } 54 | 55 | if (g_transaction.inTransaction()) { 56 | g_transaction.addInsertUndo(this, tup); 57 | } 58 | 59 | return false; 60 | } 61 | 62 | bool TableStore::deleteTuple(Tuple* tup) { 63 | dataList_.delTuple(tup); 64 | freeList_.addHead(tup); 65 | if (g_transaction.inTransaction()) { 66 | g_transaction.addDeleteUndo(this, tup); 67 | } 68 | 69 | return true; 70 | } 71 | 72 | void TableStore::removeTuple(Tuple* tup) { 73 | dataList_.delTuple(tup); 74 | freeList_.addHead(tup); 75 | } 76 | 77 | void TableStore::recoverTuple(Tuple* tup) { dataList_.addHead(tup); } 78 | 79 | void TableStore::freeTuple(Tuple* tup) { freeList_.addHead(tup); } 80 | 81 | bool TableStore::updateTuple(Tuple* tup, std::vector& idxs, 82 | std::vector& values) { 83 | if (g_transaction.inTransaction()) { 84 | g_transaction.addUpdateUndo(this, tup); 85 | } 86 | 87 | for (size_t i = 0; i < idxs.size(); i++) { 88 | size_t idx = idxs[i]; 89 | Expr* expr = values[i]; 90 | setColValue(tup, idx, expr); 91 | } 92 | 93 | return false; 94 | } 95 | 96 | Tuple* TableStore::seqScan(Tuple* tup) { 97 | if (tup == nullptr) { 98 | return dataList_.getHead(); 99 | } else { 100 | return dataList_.getNext(tup); 101 | } 102 | } 103 | 104 | void TableStore::parseTuple(Tuple* tup, std::vector& values) { 105 | bool* is_null = reinterpret_cast(&tup->data[0]); 106 | uchar* data = tup->data + columns_->size(); 107 | 108 | for (size_t i = 0; i < columns_->size(); i++) { 109 | Expr* e = nullptr; 110 | if (is_null[i]) { 111 | e = Expr::makeNullLiteral(); 112 | values.push_back(e); 113 | continue; 114 | } 115 | 116 | ColumnDefinition* col = (*columns_)[i]; 117 | int offset = colOffset_[i]; 118 | int size = colOffset_[i + 1] - colOffset_[i]; 119 | switch (col->type.data_type) { 120 | case DataType::INT: { 121 | int64_t val = *reinterpret_cast(data + offset); 122 | e = Expr::makeLiteral(val); 123 | break; 124 | } 125 | case DataType::LONG: { 126 | int64_t val = *reinterpret_cast(data + offset); 127 | e = Expr::makeLiteral(val); 128 | break; 129 | } 130 | case DataType::CHAR: 131 | case DataType::VARCHAR: { 132 | char* val = static_cast(malloc(size)); 133 | memcpy(val, (data + offset), size); 134 | e = Expr::makeLiteral(val); 135 | break; 136 | } 137 | default: 138 | break; 139 | } 140 | values.push_back(e); 141 | } 142 | } 143 | 144 | bool TableStore::newTupleGroup() { 145 | Tuple* tuple_group = 146 | static_cast(malloc(tupleSize_ * TUPLE_GROUP_SIZE)); 147 | memset(tuple_group, 0, (tupleSize_ * TUPLE_GROUP_SIZE)); 148 | if (tuple_group == nullptr) { 149 | std::cout << "[BYDB-Error] Failed to malloc " 150 | << tupleSize_ * TUPLE_GROUP_SIZE << " bytes"; 151 | return true; 152 | } 153 | 154 | tupleGroups_.push_back(tuple_group); 155 | uchar* ptr = reinterpret_cast(tuple_group); 156 | for (int i = 0; i < TUPLE_GROUP_SIZE; i++) { 157 | Tuple* tup = reinterpret_cast(ptr); 158 | freeList_.addHead(tup); 159 | ptr += tupleSize_; 160 | } 161 | 162 | return false; 163 | } 164 | 165 | void TableStore::setColValue(Tuple* tup, int idx, Expr* expr) { 166 | bool* is_null = reinterpret_cast(&tup->data[0]); 167 | uchar* data = tup->data + colNum_; 168 | int offset = colOffset_[idx]; 169 | int size = colOffset_[idx + 1] - colOffset_[idx]; 170 | uchar* ptr = &data[offset]; 171 | is_null[idx] = false; 172 | 173 | switch (expr->type) { 174 | case kExprLiteralInt: { 175 | if (size == 4) { 176 | *reinterpret_cast(ptr) = static_cast(expr->ival); 177 | } else { 178 | *reinterpret_cast(ptr) = expr->ival; 179 | } 180 | break; 181 | } 182 | case kExprLiteralFloat: { 183 | if (size == 4) { 184 | *reinterpret_cast(ptr) = static_cast(expr->fval); 185 | } else { 186 | *reinterpret_cast(ptr) = expr->fval; 187 | } 188 | break; 189 | } 190 | case kExprLiteralString: { 191 | int len = strlen(expr->name); 192 | memcpy(ptr, expr->name, len); 193 | ptr[len] = '\0'; 194 | break; 195 | } 196 | case kExprLiteralNull: 197 | is_null[idx] = true; 198 | break; 199 | default: 200 | break; 201 | } 202 | } 203 | 204 | } // namespace bydb -------------------------------------------------------------------------------- /src/main/util.cpp: -------------------------------------------------------------------------------- 1 | #include "util.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace bydb { 8 | const char* StmtTypeToString(StatementType type) { 9 | switch (type) { 10 | case kStmtError: 11 | return "ERROR"; 12 | case kStmtSelect: 13 | return "SELECT"; 14 | case kStmtImport: 15 | return "IMPORT"; 16 | case kStmtInsert: 17 | return "INSERT"; 18 | case kStmtUpdate: 19 | return "UPDATE"; 20 | case kStmtDelete: 21 | return "DELETE"; 22 | case kStmtCreate: 23 | return "CREATE"; 24 | case kStmtDrop: 25 | return "DROP"; 26 | case kStmtPrepare: 27 | return "PREPARE"; 28 | case kStmtExecute: 29 | return "EXECUTE"; 30 | case kStmtExport: 31 | return "EXPORT"; 32 | case kStmtRename: 33 | return "RENAME"; 34 | case kStmtAlter: 35 | return "ALTER"; 36 | case kStmtShow: 37 | return "SHOW"; 38 | case kStmtTransaction: 39 | return "TRANSACTION"; 40 | default: 41 | return "UNKOUWN"; 42 | } 43 | } 44 | 45 | const char* DataTypeToString(DataType type) { 46 | switch (type) { 47 | case DataType::CHAR: 48 | return "CHAR"; 49 | case DataType::DATE: 50 | return "DATE"; 51 | case DataType::DATETIME: 52 | return "DATETIME"; 53 | case DataType::DECIMAL: 54 | return "DECIMAL"; 55 | case DataType::DOUBLE: 56 | return "DOUBLE"; 57 | case DataType::FLOAT: 58 | return "FLOAT"; 59 | case DataType::INT: 60 | return "INT"; 61 | case DataType::LONG: 62 | return "LONG"; 63 | case DataType::REAL: 64 | return "REAL"; 65 | case DataType::SMALLINT: 66 | return "SMALLINT"; 67 | case DataType::TEXT: 68 | return "TEXT"; 69 | case DataType::TIME: 70 | return "TIME"; 71 | case DataType::VARCHAR: 72 | return "VARCHAR"; 73 | default: 74 | return "UNKNOWN"; 75 | } 76 | } 77 | 78 | const char* DropTypeToString(DropType type) { 79 | switch (type) { 80 | case kDropTable: 81 | return "DropTable"; 82 | case kDropSchema: 83 | return "DropSchema"; 84 | case kDropIndex: 85 | return "DropIndex"; 86 | case kDropView: 87 | return "DropView"; 88 | case kDropPreparedStatement: 89 | return "DropPreparedStatement"; 90 | default: 91 | return "UNKNOWN"; 92 | } 93 | } 94 | 95 | const char* ExprTypeToString(ExprType type) { 96 | switch (type) { 97 | case kExprLiteralFloat: 98 | return "ExprLiteralFloat"; 99 | case kExprLiteralString: 100 | return "ExprLiteralString"; 101 | case kExprLiteralInt: 102 | return "ExprLiteralInt"; 103 | case kExprLiteralNull: 104 | return "ExprLiteralNull"; 105 | case kExprLiteralDate: 106 | return "ExprLiteralDate"; 107 | case kExprLiteralInterval: 108 | return "ExprLiteralInterval"; 109 | case kExprStar: 110 | return "ExprStar"; 111 | case kExprParameter: 112 | return "ExprParameter"; 113 | case kExprColumnRef: 114 | return "ExprColumnRef"; 115 | case kExprFunctionRef: 116 | return "ExprFunctionRef"; 117 | case kExprOperator: 118 | return "ExprOperator"; 119 | case kExprSelect: 120 | return "ExprSelect"; 121 | case kExprHint: 122 | return "ExprHint"; 123 | case kExprArray: 124 | return "ExprArray"; 125 | case kExprArrayIndex: 126 | return "ExprArrayIndex"; 127 | case kExprExtract: 128 | return "ExprExtract"; 129 | case kExprCast: 130 | return "ExprCast"; 131 | default: 132 | return "UNKNOWN"; 133 | } 134 | } 135 | 136 | const char* PlanTypeToString(PlanType type) { 137 | switch (type) { 138 | case kCreate: 139 | return "Create"; 140 | case kDrop: 141 | return "Drop"; 142 | case kInsert: 143 | return "Insert"; 144 | case kUpdate: 145 | return "Update"; 146 | case kDelete: 147 | return "Delete"; 148 | case kSelect: 149 | return "Select"; 150 | case kScan: 151 | return "Scan"; 152 | case kProjection: 153 | return "Projection"; 154 | case kFilter: 155 | return "Filter"; 156 | case kSort: 157 | return "Sort"; 158 | case kLimit: 159 | return "Limit"; 160 | case kTrx: 161 | return "Trx"; 162 | case kShow: 163 | return "Show"; 164 | default: 165 | return "UNKNOWN"; 166 | } 167 | } 168 | 169 | size_t ColumnTypeSize(ColumnType& type) { 170 | switch (type.data_type) { 171 | case DataType::INT: 172 | return sizeof(int32_t); 173 | case DataType::LONG: 174 | return sizeof(int64_t); 175 | case DataType::CHAR: 176 | return type.length + 1; 177 | case DataType::VARCHAR: 178 | return type.length + 1; 179 | default: 180 | return -1; 181 | } 182 | } 183 | 184 | /* 185 | INT32_MAX: 2,147,483,647 186 | INT64_MAX: 9,223,372,036,854,775,807 187 | add one more byte for the symbol 188 | */ 189 | #define MAX_INT32_LEN 11 190 | #define MAX_INT64_LEN 20 191 | 192 | void PrintTuples(std::vector& columns, 193 | std::vector& colIds, 194 | std::vector>& tuples) { 195 | if (tuples.size() == 0) { 196 | std::cout << "Empty set" << std::endl; 197 | return; 198 | } 199 | 200 | /* Calculate offset and length for each column */ 201 | size_t total_len = 0; 202 | std::vector col_lens; 203 | for (auto col : columns) { 204 | size_t len = col->type.length; 205 | len = (strlen(col->name) > len) ? strlen(col->name) : len; 206 | if (col->type.data_type == DataType::INT) { 207 | len = (MAX_INT32_LEN > len) ? MAX_INT32_LEN : len; 208 | } else if (col->type.data_type == DataType::LONG) { 209 | len = (MAX_INT64_LEN > len) ? MAX_INT64_LEN : len; 210 | } 211 | len += 2; // reserve some space 212 | col_lens.push_back(len); 213 | total_len += len; 214 | } 215 | 216 | /* Print column names */ 217 | for (size_t i = 0; i < columns.size(); i++) { 218 | std::cout.width(col_lens[i]); 219 | std::cout << columns[i]->name; 220 | } 221 | std::cout << std::endl; 222 | 223 | /* Print separators */ 224 | std::cout << std::string(total_len, '-') << std::endl; 225 | 226 | /* Print each tuple */ 227 | for (auto tup : tuples) { 228 | for (size_t i = 0; i < columns.size(); i++) { 229 | Expr* expr = tup[colIds[i]]; 230 | std::cout.width(col_lens[i]); 231 | switch (expr->type) { 232 | case kExprLiteralString: 233 | std::cout << expr->name; 234 | break; 235 | case kExprLiteralInt: 236 | std::cout << expr->ival; 237 | break; 238 | case kExprLiteralNull: 239 | std::cout << "NULL"; 240 | break; 241 | default: 242 | break; 243 | } 244 | } 245 | std::cout << std::endl; 246 | } 247 | 248 | /* Print separators */ 249 | std::cout << std::string(total_len, '-') << std::endl; 250 | std::cout << tuples.size() << " row" << std::endl; 251 | } 252 | 253 | } // namespace bydb -------------------------------------------------------------------------------- /src/main/optimizer.cpp: -------------------------------------------------------------------------------- 1 | #include "optimizer.h" 2 | #include "util.h" 3 | 4 | #include 5 | 6 | using namespace hsql; 7 | 8 | namespace bydb { 9 | 10 | Plan* Optimizer::createPlanTree(const SQLStatement* stmt) { 11 | switch (stmt->type()) { 12 | case kStmtSelect: 13 | return createSelectPlanTree(static_cast(stmt)); 14 | case kStmtInsert: 15 | return createInsertPlanTree(static_cast(stmt)); 16 | case kStmtUpdate: 17 | return createUpdatePlanTree(static_cast(stmt)); 18 | case kStmtDelete: 19 | return createDeletePlanTree(static_cast(stmt)); 20 | case kStmtCreate: 21 | return createCreatePlanTree(static_cast(stmt)); 22 | case kStmtDrop: 23 | return createDropPlanTree(static_cast(stmt)); 24 | case kStmtTransaction: 25 | return createTrxPlanTree(static_cast(stmt)); 26 | case kStmtShow: 27 | return createShowPlanTree(static_cast(stmt)); 28 | default: 29 | std::cout << "[BYDB-Error] Statement type " 30 | << StmtTypeToString(stmt->type()) << " is not supported now." 31 | << std::endl; 32 | } 33 | return nullptr; 34 | } 35 | 36 | Plan* Optimizer::createCreatePlanTree(const CreateStatement* stmt) { 37 | CreatePlan* plan = new CreatePlan(stmt->type); 38 | plan->ifNotExists = stmt->ifNotExists; 39 | plan->type = stmt->type; 40 | plan->schema = stmt->schema; 41 | plan->tableName = stmt->tableName; 42 | plan->indexName = stmt->indexName; 43 | plan->columns = stmt->columns; 44 | plan->next = nullptr; 45 | 46 | if (plan->type == kCreateIndex) { 47 | Table* table = g_meta_data.getTable(plan->schema, plan->tableName); 48 | if (table == nullptr) { 49 | delete plan; 50 | return nullptr; 51 | } 52 | 53 | if (stmt->indexColumns != nullptr) { 54 | plan->indexColumns = new std::vector; 55 | } 56 | 57 | for (auto col_name : *stmt->indexColumns) { 58 | ColumnDefinition* col_def = table->getColumn(col_name); 59 | if (col_def == nullptr) { 60 | delete plan->indexColumns; 61 | delete plan; 62 | return nullptr; 63 | } 64 | plan->indexColumns->push_back(col_def); 65 | } 66 | } 67 | 68 | return plan; 69 | } 70 | 71 | Plan* Optimizer::createDropPlanTree(const DropStatement* stmt) { 72 | DropPlan* plan = new DropPlan(); 73 | plan->type = stmt->type; 74 | plan->ifExists = stmt->ifExists; 75 | plan->schema = stmt->schema; 76 | plan->name = stmt->name; 77 | plan->indexName = stmt->indexName; 78 | plan->next = nullptr; 79 | return plan; 80 | } 81 | 82 | Plan* Optimizer::createInsertPlanTree(const InsertStatement* stmt) { 83 | InsertPlan* plan = new InsertPlan(); 84 | plan->type = stmt->type; 85 | plan->table = g_meta_data.getTable(stmt->schema, stmt->tableName); 86 | plan->values = stmt->values; 87 | 88 | return plan; 89 | } 90 | 91 | Plan* Optimizer::createUpdatePlanTree(const UpdateStatement* stmt) { 92 | Table* table = g_meta_data.getTable(stmt->table->schema, stmt->table->name); 93 | Plan* plan; 94 | 95 | ScanPlan* scan = new ScanPlan(); 96 | scan->type = kSeqScan; 97 | scan->table = table; 98 | plan = scan; 99 | 100 | if (stmt->where != nullptr) { 101 | Plan* filter = createFilterPlan(table->columns(), stmt->where); 102 | filter->next = plan; 103 | plan = filter; 104 | } 105 | 106 | UpdatePlan* update = new UpdatePlan(); 107 | update->table = table; 108 | update->next = plan; 109 | 110 | for (auto upd : *stmt->updates) { 111 | size_t idx = 0; 112 | update->values.push_back(upd->value); 113 | for (auto col : *table->columns()) { 114 | if (strcmp(upd->column, col->name) == 0) { 115 | update->idxs.push_back(idx); 116 | break; 117 | } 118 | idx++; 119 | } 120 | } 121 | 122 | return update; 123 | } 124 | 125 | Plan* Optimizer::createDeletePlanTree(const DeleteStatement* stmt) { 126 | Table* table = g_meta_data.getTable(stmt->schema, stmt->tableName); 127 | Plan* plan; 128 | 129 | ScanPlan* scan = new ScanPlan(); 130 | scan->type = kSeqScan; 131 | scan->table = table; 132 | plan = scan; 133 | 134 | if (stmt->expr != nullptr) { 135 | Plan* filter = createFilterPlan(table->columns(), stmt->expr); 136 | filter->next = plan; 137 | plan = filter; 138 | } 139 | 140 | DeletePlan* del = new DeletePlan(); 141 | del->table = table; 142 | del->next = plan; 143 | return del; 144 | } 145 | 146 | Plan* Optimizer::createSelectPlanTree(const SelectStatement* stmt) { 147 | Table* table = 148 | g_meta_data.getTable(stmt->fromTable->schema, stmt->fromTable->name); 149 | std::vector* columns = table->columns(); 150 | Plan* plan; 151 | 152 | ScanPlan* scan = new ScanPlan(); 153 | scan->type = kSeqScan; 154 | scan->table = table; 155 | plan = scan; 156 | 157 | if (stmt->whereClause != nullptr) { 158 | Plan* filter = createFilterPlan(columns, stmt->whereClause); 159 | filter->next = plan; 160 | plan = filter; 161 | } 162 | 163 | SelectPlan* select = new SelectPlan(); 164 | select->table = table; 165 | select->next = plan; 166 | 167 | for (auto expr : *stmt->selectList) { 168 | if (expr->type == kExprStar) { 169 | for (size_t i = 0; i < columns->size(); i++) { 170 | ColumnDefinition* col = (*columns)[i]; 171 | select->outCols.push_back(col); 172 | select->colIds.push_back(i); 173 | } 174 | } else { 175 | for (size_t i = 0; i < columns->size(); i++) { 176 | ColumnDefinition* col = (*columns)[i]; 177 | if (strcmp(expr->name, col->name) == 0) { 178 | select->outCols.push_back(col); 179 | select->colIds.push_back(i); 180 | } 181 | } 182 | } 183 | } 184 | 185 | return select; 186 | } 187 | 188 | Plan* Optimizer::createFilterPlan(std::vector* columns, 189 | Expr* where) { 190 | FilterPlan* filter = new FilterPlan(); 191 | Expr* col = nullptr; 192 | Expr* val = nullptr; 193 | if (where->expr->type == kExprColumnRef) { 194 | col = where->expr; 195 | val = where->expr2; 196 | } else { 197 | col = where->expr2; 198 | val = where->expr; 199 | } 200 | 201 | for (size_t i = 0; i < columns->size(); i++) { 202 | ColumnDefinition* col_def = (*columns)[i]; 203 | if (strcmp(col->name, col_def->name) == 0) { 204 | filter->idx = i; 205 | } 206 | } 207 | filter->val = val; 208 | 209 | return filter; 210 | } 211 | 212 | Plan* Optimizer::createTrxPlanTree(const TransactionStatement* stmt) { 213 | TrxPlan* plan = new TrxPlan(); 214 | plan->command = stmt->command; 215 | return plan; 216 | } 217 | 218 | Plan* Optimizer::createShowPlanTree(const ShowStatement* stmt) { 219 | ShowPlan* plan = new ShowPlan(); 220 | plan->type = stmt->type; 221 | plan->schema = stmt->schema; 222 | plan->name = stmt->name; 223 | plan->next = nullptr; 224 | return plan; 225 | } 226 | } // namespace bydb -------------------------------------------------------------------------------- /src/main/executor.cpp: -------------------------------------------------------------------------------- 1 | #include "executor.h" 2 | #include "metadata.h" 3 | #include "optimizer.h" 4 | #include "trx.h" 5 | #include "util.h" 6 | 7 | #include 8 | 9 | using namespace hsql; 10 | 11 | namespace bydb { 12 | 13 | void Executor::init() { opTree_ = generateOperator(planTree_); } 14 | 15 | bool Executor::exec() { return opTree_->exec(); } 16 | 17 | BaseOperator* Executor::generateOperator(Plan* plan) { 18 | BaseOperator* op = nullptr; 19 | BaseOperator* next = nullptr; 20 | 21 | /* Build Operator tree from the leaf. */ 22 | if (plan->next != nullptr) { 23 | next = generateOperator(plan->next); 24 | } 25 | 26 | switch (plan->planType) { 27 | case kCreate: 28 | op = new CreateOperator(plan, next); 29 | break; 30 | case kDrop: 31 | op = new DropOperator(plan, next); 32 | break; 33 | case kInsert: 34 | op = new InsertOperator(plan, next); 35 | break; 36 | case kUpdate: 37 | op = new UpdateOperator(plan, next); 38 | break; 39 | case kDelete: 40 | op = new DeleteOperator(plan, next); 41 | break; 42 | case kSelect: 43 | op = new SelectOperator(plan, next); 44 | break; 45 | case kScan: { 46 | ScanPlan* scan_plan = static_cast(plan); 47 | if (scan_plan->type == kSeqScan) { 48 | op = new SeqScanOperator(plan, next); 49 | } 50 | break; 51 | } 52 | case kFilter: 53 | op = new FilterOperator(plan, next); 54 | break; 55 | case kTrx: 56 | op = new TrxOperator(plan, next); 57 | break; 58 | case kShow: 59 | op = new ShowOperator(plan, next); 60 | break; 61 | default: 62 | std::cout << "[BYDB-Error] Not support plan node " 63 | << PlanTypeToString(plan->planType); 64 | break; 65 | } 66 | 67 | return op; 68 | } 69 | 70 | bool CreateOperator::exec(TupleIter** iter) { 71 | CreatePlan* plan = static_cast(plan_); 72 | 73 | if (plan->type == kCreateTable) { 74 | Table* table = new Table(plan->schema, plan->tableName, plan->columns); 75 | if (g_meta_data.insertTable(table)) { 76 | if (plan->ifNotExists) { 77 | std::cout << "[BYDB-Info] Table " 78 | << TableNameToString(plan->schema, plan->tableName) 79 | << " already existed." << std::endl; 80 | return false; 81 | } else { 82 | std::cout << "[BYDB-Error] Table " 83 | << TableNameToString(plan->schema, plan->tableName) 84 | << " already existed." << std::endl; 85 | return true; 86 | } 87 | delete table; 88 | } 89 | 90 | std::cout << "[BYDB-Info] Create table successfully." << std::endl; 91 | return false; 92 | } else if (plan->type == kCreateIndex) { 93 | Table* table = g_meta_data.getTable(plan->schema, plan->tableName); 94 | if (table == nullptr) { 95 | std::cout << "[BYDB-Error] Table " 96 | << TableNameToString(plan->schema, plan->tableName) 97 | << " did not exist." << std::endl; 98 | return true; 99 | } 100 | 101 | Index* index = table->getIndex(plan->indexName); 102 | if (index != nullptr) { 103 | if (plan->ifNotExists) { 104 | return false; 105 | } else { 106 | std::cout << "[BYDB-Error] Index " << plan->indexName 107 | << " already existed." << std::endl; 108 | return true; 109 | } 110 | } 111 | 112 | index = new Index(); 113 | index->name = plan->indexName; 114 | index->columns = *plan->indexColumns; 115 | table->addIndex(index); 116 | std::cout << "[BYDB-Info] Create index successfully." << std::endl; 117 | } else { 118 | std::cout << "[BYDB-Error] Invalid 'Show' statement." << std::endl; 119 | return true; 120 | } 121 | 122 | return false; 123 | } 124 | 125 | bool DropOperator::exec(TupleIter** iter) { 126 | DropPlan* plan = static_cast(plan_); 127 | if (plan->type == kDropSchema) { 128 | if (g_meta_data.dropSchema(plan->schema)) { 129 | if (plan->ifExists) { 130 | std::cout << "[BYDB-Info] Schema " << plan->schema << " did not exist." 131 | << std::endl; 132 | return false; 133 | } else { 134 | std::cout << "[BYDB-Error] Schema " << plan->schema 135 | << " did not exist." << std::endl; 136 | return true; 137 | } 138 | } 139 | 140 | std::cout << "[BYDB-Info] Drop schema successfully." << std::endl; 141 | return false; 142 | } else if (plan->type == kDropTable) { 143 | if (g_meta_data.dropTable(plan->schema, plan->name)) { 144 | if (plan->ifExists) { 145 | std::cout << "[BYDB-Info] Table " 146 | << TableNameToString(plan->schema, plan->name) 147 | << " did not exist." << std::endl; 148 | return false; 149 | } else { 150 | std::cout << "[BYDB-Error] Table " 151 | << TableNameToString(plan->schema, plan->name) 152 | << " did not exist." << std::endl; 153 | return true; 154 | } 155 | } 156 | 157 | std::cout << "[BYDB-Info] Drop schema successfully." << std::endl; 158 | return false; 159 | } else if (plan->type == kDropIndex) { 160 | if (g_meta_data.dropIndex(plan->schema, plan->name, plan->indexName)) { 161 | if (plan->ifExists) { 162 | std::cout << "[BYDB-Info] Index " << plan->indexName 163 | << " did not exist." << std::endl; 164 | return false; 165 | } else { 166 | std::cout << "[BYDB-Error] Index " << plan->indexName 167 | << " did not exist." << std::endl; 168 | return true; 169 | } 170 | } 171 | 172 | std::cout << "[BYDB-Info] Drop index successfully." << std::endl; 173 | return false; 174 | } else { 175 | std::cout << "[BYDB-Error] Invalid 'Drop' statement." << std::endl; 176 | return true; 177 | } 178 | 179 | return false; 180 | } 181 | 182 | bool InsertOperator::exec(TupleIter** iter) { 183 | InsertPlan* plan = static_cast(plan_); 184 | TableStore* table_store = plan->table->getTableStore(); 185 | if (table_store->insertTuple(plan->values)) { 186 | return true; 187 | } 188 | std::cout << "[BYDB-Info] Insert tuple successfully." << std::endl; 189 | return false; 190 | } 191 | 192 | bool UpdateOperator::exec(TupleIter** iter) { 193 | UpdatePlan* update = static_cast(plan_); 194 | Table* table = update->table; 195 | TableStore* table_store = table->getTableStore(); 196 | int upd_cnt = 0; 197 | 198 | while (true) { 199 | TupleIter* tup_iter = nullptr; 200 | if (next_->exec(&tup_iter)) { 201 | return true; 202 | } 203 | 204 | if (tup_iter == nullptr) { 205 | break; 206 | } else { 207 | table_store->updateTuple(tup_iter->tup, update->idxs, update->values); 208 | upd_cnt++; 209 | } 210 | } 211 | 212 | std::cout << "[BYDB-Info] Update " << upd_cnt << " tuple successfully." 213 | << std::endl; 214 | return false; 215 | } 216 | 217 | bool DeleteOperator::exec(TupleIter** iter) { 218 | Table* table = static_cast(plan_)->table; 219 | TableStore* table_store = table->getTableStore(); 220 | int del_cnt = 0; 221 | 222 | while (true) { 223 | TupleIter* tup_iter = nullptr; 224 | if (next_->exec(&tup_iter)) { 225 | return true; 226 | } 227 | 228 | if (tup_iter == nullptr) { 229 | break; 230 | } else { 231 | table_store->deleteTuple(tup_iter->tup); 232 | del_cnt++; 233 | } 234 | } 235 | 236 | std::cout << "[BYDB-Info] Delete " << del_cnt << " tuple successfully." 237 | << std::endl; 238 | return false; 239 | } 240 | 241 | bool TrxOperator::exec(TupleIter** iter) { 242 | TrxPlan* plan = static_cast(plan_); 243 | switch (plan->command) { 244 | case kBeginTransaction: 245 | g_transaction.begin(); 246 | std::cout << "[BYDB-Info] Start transaction" << std::endl; 247 | break; 248 | case kCommitTransaction: 249 | g_transaction.commit(); 250 | std::cout << "[BYDB-Info] Commit transaction" << std::endl; 251 | break; 252 | case kRollbackTransaction: 253 | g_transaction.rollback(); 254 | std::cout << "[BYDB-Info] Rollback transaction" << std::endl; 255 | break; 256 | default: 257 | break; 258 | } 259 | 260 | return false; 261 | } 262 | 263 | bool ShowOperator::exec(TupleIter** iter) { 264 | ShowPlan* show_plan = static_cast(plan_); 265 | if (show_plan->type == kShowTables) { 266 | std::vector tables; 267 | g_meta_data.getAllTables(&tables); 268 | 269 | std::cout << "# Table List:" << std::endl; 270 | for (auto table : tables) { 271 | std::cout << TableNameToString(table->schema(), table->name()) 272 | << std::endl; 273 | } 274 | } else if (show_plan->type == kShowColumns) { 275 | Table* table = g_meta_data.getTable(show_plan->schema, show_plan->name); 276 | if (table == nullptr) { 277 | std::cout << "[BYDB-Error] Failed to find table " 278 | << TableNameToString(show_plan->schema, show_plan->name) 279 | << std::endl; 280 | return true; 281 | } 282 | std::cout << "# Columns in " 283 | << TableNameToString(show_plan->schema, show_plan->name) << ":" 284 | << std::endl; 285 | for (auto col_def : *table->columns()) { 286 | if (col_def->type.data_type == DataType::CHAR || 287 | col_def->type.data_type == DataType::VARCHAR) { 288 | std::cout << col_def->name << "\t" 289 | << DataTypeToString(col_def->type.data_type) << "(" 290 | << col_def->type.length << ")" << std::endl; 291 | } else { 292 | std::cout << col_def->name << "\t" 293 | << DataTypeToString(col_def->type.data_type) << std::endl; 294 | } 295 | } 296 | } else { 297 | std::cout << "[BYDB-Error] Invalid 'Show' statement." << std::endl; 298 | return true; 299 | } 300 | 301 | return false; 302 | } 303 | 304 | bool SelectOperator::exec(TupleIter** iter) { 305 | SelectPlan* plan = static_cast(plan_); 306 | std::vector> tuples; 307 | while (true) { 308 | TupleIter* tup_iter = nullptr; 309 | if (next_->exec(&tup_iter)) { 310 | return true; 311 | } 312 | 313 | if (tup_iter == nullptr) { 314 | break; 315 | } else { 316 | tuples.push_back(tup_iter->values); 317 | } 318 | } 319 | 320 | PrintTuples(plan->outCols, plan->colIds, tuples); 321 | return false; 322 | } 323 | 324 | bool SeqScanOperator::exec(TupleIter** iter) { 325 | ScanPlan* plan = static_cast(plan_); 326 | TableStore* table_store = plan->table->getTableStore(); 327 | Tuple* tup = nullptr; 328 | 329 | if (finish) { 330 | return false; 331 | } 332 | 333 | if (nextTuple_ == nullptr) { 334 | tup = table_store->seqScan(nullptr); 335 | } else { 336 | tup = nextTuple_; 337 | } 338 | 339 | if (tup == nullptr) { 340 | *iter = nullptr; 341 | return false; 342 | } 343 | 344 | TupleIter* tup_iter = new TupleIter(tup); 345 | table_store->parseTuple(tup, tup_iter->values); 346 | tuples_.push_back(tup_iter); 347 | *iter = tup_iter; 348 | 349 | nextTuple_ = table_store->seqScan(tup); 350 | if (nextTuple_ == nullptr) { 351 | finish = true; 352 | } 353 | return false; 354 | } 355 | 356 | bool FilterOperator::exec(TupleIter** iter) { 357 | *iter = nullptr; 358 | while (true) { 359 | TupleIter* tup_iter = nullptr; 360 | if (next_->exec(&tup_iter)) { 361 | return true; 362 | } 363 | 364 | if (tup_iter == nullptr) { 365 | break; 366 | } 367 | 368 | if (execEqualExpr(tup_iter)) { 369 | *iter = tup_iter; 370 | break; 371 | } 372 | } 373 | 374 | return false; 375 | } 376 | 377 | bool FilterOperator::execEqualExpr(TupleIter* iter) { 378 | FilterPlan* filter = static_cast(plan_); 379 | Expr* val = filter->val; 380 | size_t col_id = filter->idx; 381 | 382 | Expr* col_val = iter->values[col_id]; 383 | if (col_val->type != val->type) { 384 | return false; 385 | } 386 | 387 | if (col_val->type == kExprLiteralInt) { 388 | return (col_val->ival == val->ival); 389 | } 390 | 391 | if (col_val->type == kExprLiteralString) { 392 | return (strcmp(col_val->name, val->name) == 0); 393 | } 394 | 395 | return false; 396 | } 397 | 398 | } // namespace bydb -------------------------------------------------------------------------------- /src/main/parser.cpp: -------------------------------------------------------------------------------- 1 | #include "parser.h" 2 | #include "metadata.h" 3 | #include "util.h" 4 | 5 | #include 6 | #include 7 | 8 | using namespace hsql; 9 | 10 | namespace bydb { 11 | 12 | Parser::Parser() { result_ = nullptr; } 13 | 14 | Parser::~Parser() { 15 | delete result_; 16 | result_ = nullptr; 17 | } 18 | 19 | bool Parser::parseStatement(std::string query) { 20 | result_ = new SQLParserResult; 21 | SQLParser::parse(query, result_); 22 | 23 | if (result_->isValid()) { 24 | return checkStmtsMeta(); 25 | } else { 26 | std::cout << "[BYDB-Error] Failed to parse sql statement." << std::endl; 27 | } 28 | 29 | return true; 30 | } 31 | 32 | bool Parser::checkStmtsMeta() { 33 | for (size_t i = 0; i < result_->size(); ++i) { 34 | const SQLStatement* stmt = result_->getStatement(i); 35 | if (checkMeta(stmt)) { 36 | return true; 37 | } 38 | } 39 | 40 | return false; 41 | } 42 | 43 | bool Parser::checkMeta(const SQLStatement* stmt) { 44 | switch (stmt->type()) { 45 | case kStmtSelect: 46 | return checkSelectStmt(static_cast(stmt)); 47 | case kStmtInsert: 48 | return checkInsertStmt(static_cast(stmt)); 49 | case kStmtUpdate: 50 | return checkUpdateStmt(static_cast(stmt)); 51 | case kStmtDelete: 52 | return checkDeleteStmt(static_cast(stmt)); 53 | case kStmtCreate: 54 | return checkCreateStmt(static_cast(stmt)); 55 | case kStmtDrop: 56 | return checkDropStmt(static_cast(stmt)); 57 | case kStmtTransaction: 58 | case kStmtShow: 59 | return false; 60 | default: 61 | std::cout << "[BYDB-Error] Statement type " 62 | << StmtTypeToString(stmt->type()) << " is not supported now." 63 | << std::endl; 64 | } 65 | 66 | return true; 67 | } 68 | 69 | bool Parser::checkSelectStmt(const SelectStatement* stmt) { 70 | TableRef* table_ref = stmt->fromTable; 71 | Table* table = getTable(table_ref); 72 | if (table == nullptr) { 73 | std::cout << "[BYDB-Error] Can not find table " 74 | << TableNameToString(table_ref->schema, table_ref->name) 75 | << std::endl; 76 | return true; 77 | } 78 | 79 | if (stmt->groupBy != nullptr) { 80 | std::cout << "[BYDB-Error] Do not support 'Group By' clause" << std::endl; 81 | return true; 82 | } 83 | 84 | if (stmt->setOperations != nullptr) { 85 | std::cout << "[BYDB-Error] Do not support Set Operation like 'UNION', " 86 | "'Intersect', ect." 87 | << std::endl; 88 | return true; 89 | } 90 | 91 | if (stmt->withDescriptions != nullptr) { 92 | std::cout << "[BYDB-Error] Do not support 'with' clause." << std::endl; 93 | return true; 94 | } 95 | 96 | if (stmt->lockings != nullptr) { 97 | std::cout << "[BYDB-Error] Do not support 'lock' clause." << std::endl; 98 | return true; 99 | } 100 | 101 | if (stmt->selectList != nullptr) { 102 | for (auto expr : *stmt->selectList) { 103 | if (checkExpr(table, expr)) { 104 | return true; 105 | } 106 | } 107 | } 108 | 109 | if (stmt->whereClause != nullptr) { 110 | if (checkExpr(table, stmt->whereClause)) { 111 | return true; 112 | } 113 | } 114 | 115 | if (stmt->order != nullptr) { 116 | for (auto order : *stmt->order) { 117 | if (checkExpr(table, order->expr)) { 118 | return true; 119 | } 120 | } 121 | } 122 | 123 | if (stmt->limit != nullptr) { 124 | if (checkExpr(table, stmt->limit->limit)) { 125 | return true; 126 | } 127 | if (checkExpr(table, stmt->limit->offset)) { 128 | return true; 129 | } 130 | } 131 | 132 | return false; 133 | } 134 | 135 | bool Parser::checkInsertStmt(const InsertStatement* stmt) { 136 | if (stmt->type == kInsertSelect) { 137 | std::cout << "[BYDB-Error] Do not support 'INSERT INTO ... SELECT ...'." 138 | << std::endl; 139 | } 140 | 141 | Table* table = g_meta_data.getTable(stmt->schema, stmt->tableName); 142 | if (table == nullptr) { 143 | std::cout << "[BYDB-Error] Can not find table " 144 | << TableNameToString(stmt->schema, stmt->tableName) << std::endl; 145 | return true; 146 | } 147 | 148 | if (stmt->columns != nullptr) { 149 | for (auto col_name : *stmt->columns) { 150 | if (checkColumn(table, col_name)) { 151 | return true; 152 | } 153 | } 154 | } 155 | 156 | /* Prepare values for each columns in the table. 157 | If value was not provided for some columns, add NULL expr for then. */ 158 | std::vector new_values; 159 | for (size_t i = 0; i < table->columns()->size(); i++) { 160 | auto col_def = (*table->columns())[i]; 161 | if (stmt->columns != nullptr) { 162 | size_t j; 163 | for (j = 0; j < stmt->columns->size(); j++) { 164 | if (strcmp(col_def->name, (*stmt->columns)[j])) { 165 | break; 166 | } 167 | } 168 | if (j < stmt->columns->size()) { 169 | new_values.push_back((*stmt->values)[j]); 170 | } else { 171 | Expr* e = new Expr(kExprLiteralNull); 172 | new_values.push_back(e); 173 | } 174 | } else { 175 | if (i < stmt->values->size()) { 176 | new_values.push_back((*stmt->values)[i]); 177 | } else { 178 | Expr* e = new Expr(kExprLiteralNull); 179 | new_values.push_back(e); 180 | } 181 | } 182 | } 183 | 184 | stmt->values->assign(new_values.begin(), new_values.end()); 185 | 186 | if (checkValues(table->columns(), stmt->values)) { 187 | return true; 188 | } 189 | 190 | return false; 191 | } 192 | 193 | bool Parser::checkUpdateStmt(const UpdateStatement* stmt) { 194 | TableRef* table_ref = stmt->table; 195 | Table* table = getTable(table_ref); 196 | if (table == nullptr) { 197 | std::cout << "[BYDB-Error] Can not find table " 198 | << TableNameToString(table_ref->schema, table_ref->name) 199 | << std::endl; 200 | return true; 201 | } 202 | 203 | if (stmt->updates != nullptr) { 204 | for (auto update : *stmt->updates) { 205 | if (checkColumn(table, update->column)) { 206 | return true; 207 | } 208 | if (checkExpr(table, update->value)) { 209 | return true; 210 | } 211 | } 212 | } 213 | 214 | if (checkExpr(table, stmt->where)) { 215 | return true; 216 | } 217 | 218 | return false; 219 | } 220 | 221 | bool Parser::checkDeleteStmt(const DeleteStatement* stmt) { 222 | Table* table = g_meta_data.getTable(stmt->schema, stmt->tableName); 223 | if (table == nullptr) { 224 | std::cout << "[BYDB-Error] Can not find table " 225 | << TableNameToString(stmt->schema, stmt->tableName) << std::endl; 226 | return true; 227 | } 228 | 229 | if (checkExpr(table, stmt->expr)) { 230 | return true; 231 | } 232 | 233 | return false; 234 | } 235 | 236 | Table* Parser::getTable(TableRef* table_ref) { 237 | if (table_ref->type != kTableName) { 238 | std::cout << "[BYDB-Error] Only support ordinary table." << std::endl; 239 | return nullptr; 240 | } 241 | 242 | Table* table = g_meta_data.getTable(table_ref->schema, table_ref->name); 243 | if (table == nullptr) { 244 | std::cout << "[BYDB-Error] Table " 245 | << TableNameToString(table_ref->schema, table_ref->name) 246 | << " did not exist!" << std::endl; 247 | return nullptr; 248 | } 249 | 250 | return table; 251 | } 252 | 253 | bool Parser::checkColumn(Table* table, char* col_name) { 254 | for (auto col_def : *table->columns()) { 255 | if (strcmp(col_name, col_def->name) == 0) { 256 | return false; 257 | } 258 | } 259 | 260 | std::cout << "[BYDB-Error] Can not find column " << col_name << " in table " 261 | << TableNameToString(table->schema(), table->name()) << std::endl; 262 | return true; 263 | } 264 | 265 | bool Parser::checkExpr(Table* table, Expr* expr) { 266 | switch (expr->type) { 267 | case kExprLiteralFloat: 268 | case kExprLiteralString: 269 | case kExprLiteralInt: 270 | case kExprStar: 271 | return false; 272 | case kExprSelect: 273 | return checkExpr(table, expr->expr); 274 | case kExprOperator: { 275 | if (expr->expr != nullptr && checkExpr(table, expr->expr)) { 276 | return true; 277 | } 278 | if (expr->expr2 != nullptr && checkExpr(table, expr->expr2)) { 279 | return true; 280 | } 281 | break; 282 | } 283 | case kExprColumnRef: { 284 | if (checkColumn(table, expr->name)) { 285 | return true; 286 | } 287 | break; 288 | } 289 | default: 290 | std::cout << "[BYDB-Error] Unsupport opertation " 291 | << ExprTypeToString(expr->type) << std::endl; 292 | return true; 293 | } 294 | 295 | return false; 296 | } 297 | 298 | bool Parser::checkValues(std::vector* columns, 299 | std::vector* values) { 300 | for (size_t i = 0; i < columns->size(); i++) { 301 | auto col_def = (*columns)[i]; 302 | auto expr = (*values)[i]; 303 | 304 | switch (col_def->type.data_type) { 305 | case DataType::INT: 306 | case DataType::LONG: 307 | if (expr->type != kExprLiteralInt) { 308 | std::cout << "[BYDB-Error] Invalid insert value type " 309 | << ExprTypeToString(expr->type) << " for column " 310 | << col_def->name << std::endl; 311 | return true; 312 | } 313 | if (col_def->type.data_type == DataType::INT && 314 | expr->ival > INT32_MAX) { 315 | std::cout << "[BYDB-Error] The value " << expr->ival 316 | << " exceed the limitation of INT32_MAX" << std::endl; 317 | return true; 318 | } 319 | break; 320 | case DataType::CHAR: 321 | case DataType::VARCHAR: 322 | if (expr->type != kExprLiteralString) { 323 | std::cout << "[BYDB-Error] Invalid insert value type " 324 | << ExprTypeToString(expr->type) << " for column " 325 | << col_def->name << std::endl; 326 | return true; 327 | } 328 | if (strlen(expr->name) > static_cast(col_def->type.length)) { 329 | std::cout << "[BYDB-Error] The value '" << expr->name 330 | << "' is too long for column " << col_def->name 331 | << std::endl; 332 | return true; 333 | } 334 | break; 335 | default: 336 | return true; 337 | break; 338 | } 339 | } 340 | 341 | return false; 342 | } 343 | 344 | bool Parser::checkCreateStmt(const CreateStatement* stmt) { 345 | switch (stmt->type) { 346 | case kCreateTable: 347 | if (checkCreateTableStmt(stmt)) { 348 | return true; 349 | } 350 | break; 351 | default: 352 | std::cout << "[BYDB-Error] Only support 'Create Table'." << std::endl; 353 | return true; 354 | } 355 | 356 | return false; 357 | } 358 | 359 | bool Parser::checkCreateTableStmt(const CreateStatement* stmt) { 360 | if (stmt->schema == nullptr || stmt->tableName == nullptr) { 361 | std::cout << "[BYDB-Error]: Schema and table name should be specified in " 362 | "the query, like 'db.t'." 363 | << std::endl; 364 | return true; 365 | } 366 | 367 | // Check if the table already existed. 368 | if (g_meta_data.getTable(stmt->schema, stmt->tableName) != nullptr && 369 | !stmt->ifNotExists) { 370 | std::cout << "[BYDB-Error] Table " 371 | << TableNameToString(stmt->schema, stmt->tableName) 372 | << " already existed!" << std::endl; 373 | return true; 374 | } 375 | 376 | // Check each columns 377 | if (stmt->columns == nullptr || stmt->columns->size() == 0) { 378 | std::cout << "[BYDB-Error] Valid column should be spicified in 'Create " 379 | "Table' statement." 380 | << std::endl; 381 | return true; 382 | } 383 | 384 | for (auto col_def : *stmt->columns) { 385 | if (col_def == nullptr || col_def->name == nullptr) { 386 | std::cout << "[BYDB-Error] Valid column should be spicified in 'Create " 387 | "Table' statement." 388 | << std::endl; 389 | return true; 390 | } 391 | 392 | if (!IsDataTypeSupport(col_def->type.data_type)) { 393 | std::cout << "[BYDB-Error] Unsupport data type " 394 | << DataTypeToString(col_def->type.data_type) << std::endl; 395 | return true; 396 | } 397 | } 398 | 399 | return false; 400 | } 401 | 402 | bool Parser::checkCreateIndexStmt(const CreateStatement* stmt) { 403 | if (g_meta_data.getIndex(stmt->schema, stmt->tableName, stmt->indexName) != 404 | nullptr && 405 | !stmt->ifNotExists) { 406 | std::cout << "[BYDB-Error] Index " << stmt->indexName << "of " 407 | << TableNameToString(stmt->schema, stmt->tableName) 408 | << " already existed!" << std::endl; 409 | return true; 410 | } 411 | 412 | // Check if each column of this index existed. 413 | Table* table = g_meta_data.getTable(stmt->schema, stmt->tableName); 414 | for (auto idx_col : *stmt->indexColumns) { 415 | if (checkColumn(table, idx_col)) { 416 | return true; 417 | } 418 | } 419 | 420 | return false; 421 | } 422 | 423 | bool Parser::checkDropStmt(const DropStatement* stmt) { 424 | switch (stmt->type) { 425 | case kDropTable: { 426 | if (g_meta_data.getTable(stmt->schema, stmt->name) == nullptr && 427 | !stmt->ifExists) { 428 | std::cout << "[BYDB-Error] Table " 429 | << TableNameToString(stmt->schema, stmt->name) 430 | << " did not exist!" << std::endl; 431 | return true; 432 | } 433 | break; 434 | } 435 | case kDropSchema: { 436 | if (!g_meta_data.findSchema(stmt->schema) && !stmt->ifExists) { 437 | std::cout << "[BYDB-Error] Schema " << stmt->schema << " did not exist" 438 | << std::endl; 439 | return true; 440 | } 441 | break; 442 | } 443 | case kDropIndex: { 444 | if (g_meta_data.getIndex(stmt->schema, stmt->name, stmt->indexName) == 445 | nullptr && 446 | !stmt->ifExists) { 447 | std::cout << "[BYDB-Error] Index " << stmt->indexName << " of " 448 | << TableNameToString(stmt->schema, stmt->name) 449 | << " did not exist!" << std::endl; 450 | return true; 451 | } 452 | break; 453 | } 454 | default: 455 | std::cout << "[BYDB-Error] Not support drop statement " 456 | << DropTypeToString(stmt->type) << std::endl; 457 | return true; 458 | } 459 | 460 | return false; 461 | } 462 | 463 | } // namespace bydb 464 | --------------------------------------------------------------------------------