diff --git a/src/Makefile b/src/Makefile index 6fcf897..834bc3b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -4,20 +4,17 @@ BUILD_DIR = ../build/ BIN_DIR = ../bin CC = g++ -CFLAGS = -O3 -Ilib/ -I./ -Iparser/ -std=c++11 -pthread -Wall -g +CFLAGS = -O3 -I./ -Ilib/ -Ilib/statements/ -Iparser/ -std=c++11 -pthread -Wall -g +LIB_FILES = $(shell find lib/ -name '*.cpp') $(shell find lib/ -name '*.h') parser/bison_parser.cpp parser/flex_lexer.cpp parser/SQLParser.cpp LIB_SOURCES = $(shell find lib/ -name '*.cpp') parser/bison_parser.cpp parser/flex_lexer.cpp parser/SQLParser.cpp TEST_SOURCES = $(shell find tests/ -name '*.cpp') - -# release build is always using bison build: clean make -C parser/ mkdir $(BUILD_DIR) - cp lib/* $(BUILD_DIR) - cp parser/*.h $(BUILD_DIR) - cp parser/*.cpp $(BUILD_DIR) + cp $(LIB_FILES) $(BUILD_DIR) analysis: $(LIB_SOURCES) sql_analysis.cpp diff --git a/src/lib/destructors.cpp b/src/lib/destructors.cpp index be76b0e..1b9dd8e 100644 --- a/src/lib/destructors.cpp +++ b/src/lib/destructors.cpp @@ -5,10 +5,10 @@ namespace hsql { /** - * Statement.h + * SQLStatement.h */ -Statement::~Statement() { /* empty */ } -StatementList::~StatementList() { +SQLStatement::~SQLStatement() { /* empty */ } +SQLStatementList::~SQLStatementList() { delete parser_msg; } diff --git a/src/lib/sqlhelper.cpp b/src/lib/sqlhelper.cpp index dbb05ea..9d65e44 100644 --- a/src/lib/sqlhelper.cpp +++ b/src/lib/sqlhelper.cpp @@ -128,7 +128,7 @@ void printInsertStatementInfo(InsertStatement* stmt, uint num_indent) { inprint(col_name, num_indent+2); } } - switch (stmt->insert_type) { + switch (stmt->type) { case InsertStatement::kInsertValues: inprint("Values", num_indent+1); for (Expr* expr : stmt->values->vector()) { diff --git a/src/lib/CreateStatement.h b/src/lib/statements/CreateStatement.h similarity index 84% rename from src/lib/CreateStatement.h rename to src/lib/statements/CreateStatement.h index 6f35faa..6902436 100644 --- a/src/lib/CreateStatement.h +++ b/src/lib/statements/CreateStatement.h @@ -1,7 +1,7 @@ #ifndef __CREATE_STATEMENT_H__ #define __CREATE_STATEMENT_H__ -#include "Statement.h" +#include "SQLStatement.h" namespace hsql { @@ -31,14 +31,15 @@ struct ColumnDefinition { * CREATE TABLE students (name TEXT, student_number INTEGER, city TEXT, grade DOUBLE) * CREATE TABLE students FROM TBL FILE 'test/students.tbl' */ -struct CreateStatement : Statement { +struct CreateStatement : SQLStatement { enum CreateType { kTable, kTableFromTbl, // Hyrise file format }; - CreateStatement() : - Statement(kStmtCreate), + CreateStatement(CreateType type) : + SQLStatement(kStmtCreate), + type(type), if_not_exists(false), columns(NULL), file_path(NULL), @@ -46,7 +47,7 @@ struct CreateStatement : Statement { virtual ~CreateStatement(); // defined in destructors.cpp - CreateType create_type; + CreateType type; bool if_not_exists; List* columns; diff --git a/src/lib/DeleteStatement.h b/src/lib/statements/DeleteStatement.h similarity index 81% rename from src/lib/DeleteStatement.h rename to src/lib/statements/DeleteStatement.h index 6b4bba8..02274ce 100644 --- a/src/lib/DeleteStatement.h +++ b/src/lib/statements/DeleteStatement.h @@ -1,7 +1,7 @@ #ifndef __DELETE_STATEMENT_H__ #define __DELETE_STATEMENT_H__ -#include "Statement.h" +#include "SQLStatement.h" namespace hsql { @@ -13,9 +13,9 @@ namespace hsql { * * If expr == NULL => delete all rows (truncate) */ -struct DeleteStatement : Statement { +struct DeleteStatement : SQLStatement { DeleteStatement() : - Statement(kStmtDelete), + SQLStatement(kStmtDelete), table_name(NULL), expr(NULL) {}; diff --git a/src/lib/DropStatement.h b/src/lib/statements/DropStatement.h similarity index 56% rename from src/lib/DropStatement.h rename to src/lib/statements/DropStatement.h index 4f4e45d..14128e6 100644 --- a/src/lib/DropStatement.h +++ b/src/lib/statements/DropStatement.h @@ -1,12 +1,12 @@ #ifndef __DROP_STATEMENT_H__ #define __DROP_STATEMENT_H__ -#include "Statement.h" +#include "SQLStatement.h" namespace hsql { -struct DropStatement : Statement { - enum ObjectType { +struct DropStatement : SQLStatement { + enum EntityType { kTable, kSchema, kIndex, @@ -14,17 +14,16 @@ struct DropStatement : Statement { }; - DropStatement(ObjectType type) : - Statement(kStmtDrop), - obj_type(type), + DropStatement(EntityType type) : + SQLStatement(kStmtDrop), + type(type), name(NULL) {} - ObjectType obj_type; + EntityType type; const char* name; - virtual ~DropStatement() { delete name; } diff --git a/src/lib/ImportStatement.h b/src/lib/statements/ImportStatement.h similarity index 55% rename from src/lib/ImportStatement.h rename to src/lib/statements/ImportStatement.h index 9f82769..1bc0906 100644 --- a/src/lib/ImportStatement.h +++ b/src/lib/statements/ImportStatement.h @@ -1,33 +1,34 @@ #ifndef __IMPORT_STATEMENT_H__ #define __IMPORT_STATEMENT_H__ -#include "Statement.h" +#include "SQLStatement.h" namespace hsql { -typedef enum { - kImportCSV, - kImportTbl, // Hyrise file format -} ImportFileType; /** * @struct ImportStatement */ -struct ImportStatement : Statement { - ImportStatement() : - Statement(kStmtImport), +struct ImportStatement : SQLStatement { + enum ImportType { + kImportCSV, + kImportTbl, // Hyrise file format + }; + + + ImportStatement(ImportType type) : + SQLStatement(kStmtImport), + type(type), file_path(NULL), table_name(NULL) {}; virtual ~ImportStatement(); // defined in destructors.cpp - ImportFileType file_type; + ImportType type; const char* file_path; const char* table_name; - - }; diff --git a/src/lib/InsertStatement.h b/src/lib/statements/InsertStatement.h similarity index 74% rename from src/lib/InsertStatement.h rename to src/lib/statements/InsertStatement.h index a2f7329..2967ba1 100644 --- a/src/lib/InsertStatement.h +++ b/src/lib/statements/InsertStatement.h @@ -1,7 +1,7 @@ #ifndef __INSERT_STATEMENT_H__ #define __INSERT_STATEMENT_H__ -#include "Statement.h" +#include "SQLStatement.h" #include "SelectStatement.h" namespace hsql { @@ -12,14 +12,15 @@ namespace hsql { * INSERT INTO students VALUES ('Max', 1112233, 'Musterhausen', 2.3) * INSERT INTO employees SELECT * FROM stundents */ -struct InsertStatement : Statement { - typedef enum { +struct InsertStatement : SQLStatement { + enum InsertType { kInsertValues, kInsertSelect - } Type; + }; - InsertStatement() : - Statement(kStmtInsert), + InsertStatement(InsertType type) : + SQLStatement(kStmtInsert), + type(type), table_name(NULL), columns(NULL), values(NULL), @@ -27,7 +28,7 @@ struct InsertStatement : Statement { virtual ~InsertStatement(); // defined in destructors.cpp - Type insert_type; + InsertType type; const char* table_name; List* columns; List* values; diff --git a/src/lib/Statement.h b/src/lib/statements/SQLStatement.h similarity index 51% rename from src/lib/Statement.h rename to src/lib/statements/SQLStatement.h index 53494ad..5828e55 100644 --- a/src/lib/Statement.h +++ b/src/lib/statements/SQLStatement.h @@ -1,5 +1,5 @@ /* - * Statement.h + * SQLStatement.h * Definition of the structure used to build the syntax tree. */ #ifndef __STATEMENT_H__ @@ -16,44 +16,49 @@ typedef enum { kStmtImport, kStmtInsert, kStmtUpdate, - // Following types are planned but not supported yet kStmtDelete, kStmtCreate, kStmtDrop, + // Following types are not supported yet kStmtExport, kStmtRename, kStmtAlter } StatementType; -struct Statement { - Statement(StatementType type) : - type(type) {}; +struct SQLStatement { + SQLStatement(StatementType type) : + _type(type) {}; - virtual ~Statement(); // defined in destructors.cpp + virtual ~SQLStatement(); // defined in destructors.cpp - StatementType type; + + virtual StatementType type() { return _type; } + + +private: + StatementType _type; }; -class StatementList : public List { +class SQLStatementList : public List { public: - StatementList() : - List(), + SQLStatementList() : + List(), isValid(true), parser_msg(NULL) {}; - StatementList(Statement* stmt) : - List(stmt), + SQLStatementList(SQLStatement* stmt) : + List(stmt), isValid(true), parser_msg(NULL) {}; - virtual ~StatementList(); // defined in destructors.cpp + virtual ~SQLStatementList(); // defined in destructors.cpp bool isValid; const char* parser_msg; }; -// typedef List StatementList; + } // namespace hsql diff --git a/src/lib/SelectStatement.h b/src/lib/statements/SelectStatement.h similarity index 93% rename from src/lib/SelectStatement.h rename to src/lib/statements/SelectStatement.h index b183e36..6fb08f2 100644 --- a/src/lib/SelectStatement.h +++ b/src/lib/statements/SelectStatement.h @@ -1,7 +1,7 @@ #ifndef __SELECT_STATEMENT_H__ #define __SELECT_STATEMENT_H__ -#include "Statement.h" +#include "SQLStatement.h" #include "Expr.h" #include "List.h" #include "Table.h" @@ -50,9 +50,9 @@ struct LimitDescription { * Representation of a full select statement. * TODO: add union_order and union_limit */ -struct SelectStatement : Statement { +struct SelectStatement : SQLStatement { SelectStatement() : - Statement(kStmtSelect), + SQLStatement(kStmtSelect), from_table(NULL), select_list(NULL), where_clause(NULL), diff --git a/src/lib/UpdateStatement.h b/src/lib/statements/UpdateStatement.h similarity index 77% rename from src/lib/UpdateStatement.h rename to src/lib/statements/UpdateStatement.h index e06a3f3..8a003bf 100644 --- a/src/lib/UpdateStatement.h +++ b/src/lib/statements/UpdateStatement.h @@ -1,7 +1,7 @@ #ifndef __UPDATE_STATEMENT_H__ #define __UPDATE_STATEMENT_H__ -#include "Statement.h" +#include "SQLStatement.h" namespace hsql { @@ -10,9 +10,9 @@ struct UpdateClause { Expr* value; }; -struct UpdateStatement : Statement { +struct UpdateStatement : SQLStatement { UpdateStatement() : - Statement(kStmtUpdate), + SQLStatement(kStmtUpdate), table(NULL), updates(NULL), where(NULL) {} diff --git a/src/parser/SQLParser.cpp b/src/parser/SQLParser.cpp index c5638d1..6c11f0e 100644 --- a/src/parser/SQLParser.cpp +++ b/src/parser/SQLParser.cpp @@ -11,8 +11,8 @@ SQLParser::SQLParser() { } -StatementList* SQLParser::parseSQLString(const char *text) { - StatementList* result; +SQLStatementList* SQLParser::parseSQLString(const char *text) { + SQLStatementList* result; yyscan_t scanner; YY_BUFFER_STATE state; diff --git a/src/parser/SQLParser.h b/src/parser/SQLParser.h index 5719aa7..c7ce785 100644 --- a/src/parser/SQLParser.h +++ b/src/parser/SQLParser.h @@ -8,7 +8,7 @@ namespace hsql { class SQLParser { public: - static StatementList* parseSQLString(const char* sql); + static SQLStatementList* parseSQLString(const char* sql); private: SQLParser(); diff --git a/src/parser/bison_parser.y b/src/parser/bison_parser.y index e0b9897..925ac75 100644 --- a/src/parser/bison_parser.y +++ b/src/parser/bison_parser.y @@ -19,9 +19,9 @@ using namespace hsql; -int yyerror(StatementList** result, yyscan_t scanner, const char *msg) { +int yyerror(SQLStatementList** result, yyscan_t scanner, const char *msg) { - StatementList* list = new StatementList(); + SQLStatementList* list = new SQLStatementList(); list->isValid = false; list->parser_msg = strdup(msg); *result = list; @@ -64,7 +64,7 @@ typedef void* yyscan_t; %lex-param { yyscan_t scanner } // Define additional parameters for yyparse -%parse-param { hsql::StatementList** result } +%parse-param { hsql::SQLStatementList** result } %parse-param { yyscan_t scanner } @@ -78,7 +78,7 @@ typedef void* yyscan_t; uint uval; bool bval; - hsql::Statement* statement; + hsql::SQLStatement* statement; hsql::SelectStatement* select_stmt; hsql::ImportStatement* import_stmt; hsql::CreateStatement* create_stmt; @@ -95,7 +95,7 @@ typedef void* yyscan_t; hsql::ColumnDefinition* column_t; hsql::UpdateClause* update_t; - hsql::StatementList* stmt_list; + hsql::SQLStatementList* stmt_list; hsql::List* slist; hsql::List* expr_list; hsql::List* table_list; @@ -195,7 +195,7 @@ input: statement_list: - statement { $$ = new StatementList($1); } + statement { $$ = new SQLStatementList($1); } | statement_list ';' statement { $1->push_back($3); $$ = $1; } ; @@ -217,15 +217,14 @@ statement: ******************************/ import_statement: IMPORT FROM import_file_type FILE file_path INTO table_name { - $$ = new ImportStatement(); - $$->file_type = (ImportFileType) $3; + $$ = new ImportStatement((ImportStatement::ImportType) $3); $$->file_path = $5; $$->table_name = $7; } ; import_file_type: - CSV { $$ = kImportCSV; } + CSV { $$ = ImportStatement::kImportCSV; } ; file_path: @@ -240,15 +239,13 @@ file_path: ******************************/ create_statement: CREATE TABLE opt_not_exists table_name FROM TBL FILE file_path { - $$ = new CreateStatement(); - $$->create_type = CreateStatement::kTableFromTbl; + $$ = new CreateStatement(CreateStatement::kTableFromTbl); $$->if_not_exists = $3; $$->table_name = $4; $$->file_path = $8; } | CREATE TABLE opt_not_exists table_name '(' column_def_commalist ')' { - $$ = new CreateStatement(); - $$->create_type = CreateStatement::kTable; + $$ = new CreateStatement(CreateStatement::kTable); $$->if_not_exists = $3; $$->table_name = $4; $$->columns = $6; @@ -317,15 +314,13 @@ truncate_statement: ******************************/ insert_statement: INSERT INTO table_name opt_column_list VALUES '(' literal_list ')' { - $$ = new InsertStatement(); - $$->insert_type = InsertStatement::kInsertValues; + $$ = new InsertStatement(InsertStatement::kInsertValues); $$->table_name = $3; $$->columns = $4; $$->values = $7; } | INSERT INTO table_name opt_column_list select_no_paren { - $$ = new InsertStatement(); - $$->insert_type = InsertStatement::kInsertSelect; + $$ = new InsertStatement(InsertStatement::kInsertSelect); $$->table_name = $3; $$->columns = $4; $$->select = $5; diff --git a/src/sql_analysis.cpp b/src/sql_analysis.cpp index f7e027e..9f4ffe7 100644 --- a/src/sql_analysis.cpp +++ b/src/sql_analysis.cpp @@ -16,7 +16,7 @@ int main(int argc, char *argv[]) { char* sql = argv[n]; printf("\nEvaluating Query \"%s\"\n", sql); - StatementList* stmt_list = SQLParser::parseSQLString(sql); + SQLStatementList* stmt_list = SQLParser::parseSQLString(sql); if (!stmt_list->isValid) { fprintf(stderr, "Parsing of \"%s\" failed! Reason: %s\n", sql, stmt_list->parser_msg); @@ -24,7 +24,7 @@ int main(int argc, char *argv[]) { } int i = 0; - for (Statement* stmt : stmt_list->vector()) { + for (SQLStatement* stmt : stmt_list->vector()) { printf("Statement %d:\n", i++); switch (stmt->type) { case kStmtSelect: printSelectStatementInfo((SelectStatement*) stmt, 1); break; diff --git a/src/sql_grammar_test.cpp b/src/sql_grammar_test.cpp index 295c9b1..bdb901d 100644 --- a/src/sql_grammar_test.cpp +++ b/src/sql_grammar_test.cpp @@ -68,7 +68,7 @@ int main(int argc, char *argv[]) { start = std::chrono::system_clock::now(); // Parsing - StatementList* stmt_list = SQLParser::parseSQLString(sql.c_str()); + SQLStatementList* stmt_list = SQLParser::parseSQLString(sql.c_str()); end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end-start; diff --git a/src/sql_tests.cpp b/src/sql_tests.cpp index 116e4f1..9118960 100644 --- a/src/sql_tests.cpp +++ b/src/sql_tests.cpp @@ -9,10 +9,10 @@ using namespace hsql; TEST(Delete) { - StatementList* stmt_list = SQLParser::parseSQLString("DELETE FROM students WHERE grade > 2.0;"); + SQLStatementList* stmt_list = SQLParser::parseSQLString("DELETE FROM students WHERE grade > 2.0;"); ASSERT(stmt_list->isValid); ASSERT_EQ(stmt_list->size(), 1); - ASSERT(stmt_list->at(0)->type == kStmtDelete); + ASSERT(stmt_list->at(0)->type() == kStmtDelete); DeleteStatement* stmt = (DeleteStatement*) stmt_list->at(0); ASSERT_STREQ(stmt->table_name, "students"); @@ -23,13 +23,13 @@ TEST(Delete) { } TEST(Create) { - StatementList* stmt_list = SQLParser::parseSQLString("CREATE TABLE students (name TEXT, student_number INT, city INTEGER, grade DOUBLE)"); + SQLStatementList* stmt_list = SQLParser::parseSQLString("CREATE TABLE students (name TEXT, student_number INT, city INTEGER, grade DOUBLE)"); ASSERT(stmt_list->isValid); ASSERT_EQ(stmt_list->size(), 1); - ASSERT_EQ(stmt_list->at(0)->type, kStmtCreate); + ASSERT_EQ(stmt_list->at(0)->type(), kStmtCreate); CreateStatement* stmt = (CreateStatement*) stmt_list->at(0); - ASSERT_EQ(stmt->create_type, CreateStatement::kTable); + ASSERT_EQ(stmt->type, CreateStatement::kTable); ASSERT_STREQ(stmt->table_name, "students"); ASSERT_NOTNULL(stmt->columns); ASSERT_EQ(stmt->columns->size(), 4); @@ -45,10 +45,10 @@ TEST(Create) { TEST(Update) { - StatementList* stmt_list = SQLParser::parseSQLString("UPDATE students SET grade = 5.0, name = 'test' WHERE name = 'Max Mustermann';"); + SQLStatementList* stmt_list = SQLParser::parseSQLString("UPDATE students SET grade = 5.0, name = 'test' WHERE name = 'Max Mustermann';"); ASSERT(stmt_list->isValid); ASSERT_EQ(stmt_list->size(), 1); - ASSERT_EQ(stmt_list->at(0)->type, kStmtUpdate); + ASSERT_EQ(stmt_list->at(0)->type(), kStmtUpdate); UpdateStatement* stmt = (UpdateStatement*) stmt_list->at(0); ASSERT_NOTNULL(stmt->table); @@ -73,22 +73,23 @@ TEST(Update) { TEST(Insert) { - StatementList* stmt_list = SQLParser::parseSQLString("INSERT INTO students VALUES ('Max Mustermann', 12345, 'Musterhausen', 2.0)"); + SQLStatementList* stmt_list = SQLParser::parseSQLString("INSERT INTO students VALUES ('Max Mustermann', 12345, 'Musterhausen', 2.0)"); ASSERT(stmt_list->isValid); ASSERT_EQ(stmt_list->size(), 1); - ASSERT_EQ(stmt_list->at(0)->type, kStmtInsert); + ASSERT_EQ(stmt_list->at(0)->type(), kStmtInsert); // TODO } TEST(DropTable) { - StatementList* stmt_list = SQLParser::parseSQLString("DROP TABLE students"); + SQLStatementList* stmt_list = SQLParser::parseSQLString("DROP TABLE students"); ASSERT(stmt_list->isValid); ASSERT_EQ(stmt_list->size(), 1); - ASSERT_EQ(stmt_list->at(0)->type, kStmtDrop); + ASSERT_EQ(stmt_list->at(0)->type(), kStmtDrop); DropStatement* stmt = (DropStatement*) stmt_list->at(0); + ASSERT_EQ(stmt->type, DropStatement::kTable); ASSERT_NOTNULL(stmt->name); ASSERT_STREQ(stmt->name, "students"); } \ No newline at end of file diff --git a/src/tests/select.cpp b/src/tests/select.cpp index 5073cfc..35b4cd2 100644 --- a/src/tests/select.cpp +++ b/src/tests/select.cpp @@ -5,10 +5,10 @@ using namespace hsql; TEST(Select) { - StatementList* stmt_list = SQLParser::parseSQLString("SELECT * FROM students;"); + SQLStatementList* stmt_list = SQLParser::parseSQLString("SELECT * FROM students;"); ASSERT(stmt_list->isValid); ASSERT_EQ(stmt_list->size(), 1); - ASSERT(stmt_list->at(0)->type == kStmtSelect); + ASSERT_EQ(stmt_list->at(0)->type(), kStmtSelect); SelectStatement* stmt = (SelectStatement*) stmt_list->at(0); ASSERT_NULL(stmt->where_clause);