diff --git a/src/lib/CreateStatement.h b/src/lib/CreateStatement.h index ccc93c3..6f35faa 100644 --- a/src/lib/CreateStatement.h +++ b/src/lib/CreateStatement.h @@ -16,6 +16,12 @@ struct ColumnDefinition { DOUBLE }; + ColumnDefinition(char* name, DataType type) : + name(name), + type(type) {} + + virtual ~ColumnDefinition(); // defined in destructors.cpp + char* name; DataType type; }; @@ -34,13 +40,17 @@ struct CreateStatement : Statement { CreateStatement() : Statement(kStmtCreate), if_not_exists(false), + columns(NULL), file_path(NULL), table_name(NULL) {}; - + virtual ~CreateStatement(); // defined in destructors.cpp CreateType create_type; bool if_not_exists; + + List* columns; + const char* file_path; const char* table_name; }; diff --git a/src/lib/DeleteStatement.h b/src/lib/DeleteStatement.h index db20552..6b4bba8 100644 --- a/src/lib/DeleteStatement.h +++ b/src/lib/DeleteStatement.h @@ -16,6 +16,7 @@ namespace hsql { struct DeleteStatement : Statement { DeleteStatement() : Statement(kStmtDelete), + table_name(NULL), expr(NULL) {}; virtual ~DeleteStatement(); // defined in destructors.cpp diff --git a/src/lib/destructors.cpp b/src/lib/destructors.cpp index 6d2a51f..44d6eae 100644 --- a/src/lib/destructors.cpp +++ b/src/lib/destructors.cpp @@ -4,14 +4,43 @@ namespace hsql { -Statement::~Statement() { - /* empty */ -} - +/** + * Statement.h + */ +Statement::~Statement() { /* empty */ } StatementList::~StatementList() { delete parser_msg; } +/** + * ImportStatement.h + */ +ImportStatement::~ImportStatement() { + delete file_path; + delete table_name; +} + +/** + * InsertStatement.h + */ +InsertStatement::~InsertStatement() { + delete table_name; + delete columns; + delete values; + delete select; +} + +/** + * DeleteStatement.h + */ +DeleteStatement::~DeleteStatement() { + delete table_name; + delete expr; +} + +/** + * SelectStatement.h + */ SelectStatement::~SelectStatement() { delete from_table; delete select_list; @@ -20,43 +49,38 @@ SelectStatement::~SelectStatement() { delete order; delete limit; } - -ImportStatement::~ImportStatement() { - delete file_path; - delete table_name; -} - -CreateStatement::~CreateStatement() { - delete file_path; - delete table_name; -} - -InsertStatement::~InsertStatement() { - delete table_name; - delete select; -} - -DeleteStatement::~DeleteStatement() { - delete expr; -} - - - OrderDescription::~OrderDescription() { delete expr; } +/** + * CreateStatement.h + */ +CreateStatement::~CreateStatement() { + delete columns; + delete file_path; + delete table_name; +} +ColumnDefinition::~ColumnDefinition() { + delete name; +} + +/** + * Table.h + */ TableRef::~TableRef() { delete name; delete alias; delete select; delete list; } - JoinDefinition::~JoinDefinition() { delete left; delete right; delete condition; } + + + } // namespace hsql \ No newline at end of file diff --git a/src/parser/bison_parser.y b/src/parser/bison_parser.y index 4a1c851..e623132 100644 --- a/src/parser/bison_parser.y +++ b/src/parser/bison_parser.y @@ -90,11 +90,13 @@ typedef void* yyscan_t; hsql::OrderDescription* order; hsql::OrderType order_type; hsql::LimitDescription* limit; + hsql::ColumnDefinition* column_t; hsql::StatementList* stmt_list; hsql::List* slist; hsql::List* expr_list; hsql::List* table_list; + hsql::List* column_list_t; } @@ -135,6 +137,7 @@ typedef void* yyscan_t; %type delete_statement truncate_statement %type table_name opt_alias alias file_path %type opt_not_exists +%type import_file_type opt_join_type column_type %type from_clause table_ref table_ref_atomic table_ref_name %type
join_clause join_table %type expr scalar_expr unary_expr binary_expr function_expr star_expr expr_alias @@ -145,8 +148,9 @@ typedef void* yyscan_t; %type opt_order %type opt_limit %type opt_order_type -%type import_file_type opt_join_type %type ident_commalist opt_column_list +%type column_def +%type column_def_commalist /****************************** ** Token Precedence and Associativity @@ -237,7 +241,7 @@ create_statement: $$->create_type = CreateStatement::kTable; $$->if_not_exists = $3; $$->table_name = $4; - // TODO: build into object + $$->columns = $6; } ; @@ -247,18 +251,20 @@ opt_not_exists: ; column_def_commalist: - column_def - | column_def_commalist ',' column_def + column_def { $$ = new List($1); } + | column_def_commalist ',' column_def { $1->push_back($3); $$ = $1; } ; column_def: - IDENTIFIER column_type + IDENTIFIER column_type { + $$ = new ColumnDefinition($1, (ColumnDefinition::DataType) $2); + } ; column_type: - INTEGER - | DOUBLE - | TEXT + INTEGER { $$ = ColumnDefinition::INT; } + | DOUBLE { $$ = ColumnDefinition::DOUBLE; } + | TEXT { $$ = ColumnDefinition::TEXT; } ; diff --git a/src/sql_tests.cpp b/src/sql_tests.cpp index 8d0a9db..5543d5a 100644 --- a/src/sql_tests.cpp +++ b/src/sql_tests.cpp @@ -13,25 +13,41 @@ using namespace hsql; TEST(SelectTest) { StatementList* stmt_list = SQLParser::parseSQLString("SELECT * FROM students;"); ASSERT(stmt_list->isValid); - ASSERT(stmt_list->size() == 1); + ASSERT_EQ(stmt_list->size(), 1); ASSERT(stmt_list->at(0)->type == kStmtSelect); SelectStatement* stmt = (SelectStatement*) stmt_list->at(0); - ASSERT(stmt->where_clause == NULL); + ASSERT_NULL(stmt->where_clause); } TEST(DeleteTest) { StatementList* stmt_list = SQLParser::parseSQLString("DELETE FROM students WHERE grade > 2.0;"); ASSERT(stmt_list->isValid); - ASSERT(stmt_list->size() == 1); + ASSERT_EQ(stmt_list->size(), 1); ASSERT(stmt_list->at(0)->type == kStmtDelete); DeleteStatement* stmt = (DeleteStatement*) stmt_list->at(0); ASSERT_STREQ(stmt->table_name, "students"); - ASSERT(stmt->expr != NULL); + ASSERT_NOTNULL(stmt->expr); ASSERT(stmt->expr->isType(kExprOperator)); ASSERT_STREQ(stmt->expr->expr->name, "grade"); ASSERT_EQ(stmt->expr->expr2->fval, 2.0); } +TEST(CreateTable) { + StatementList* stmt_list = SQLParser::parseSQLString("CREATE TABLE students (name TEXT, student_number INTEGER, city TEXT, grade DOUBLE)"); + ASSERT(stmt_list->isValid); + ASSERT_EQ(stmt_list->size(), 1); + ASSERT_EQ(stmt_list->at(0)->type, kStmtCreate); + + CreateStatement* stmt = (CreateStatement*) stmt_list->at(0); + ASSERT_EQ(stmt->create_type, CreateStatement::kTable); + ASSERT_STREQ(stmt->table_name, "students"); + ASSERT_NOTNULL(stmt->columns); + ASSERT_EQ(stmt->columns->size(), 4); + ASSERT_STREQ(stmt->columns->at(0)->name, "name"); + ASSERT_EQ(stmt->columns->at(0)->type, ColumnDefinition::TEXT); + ASSERT_STREQ(stmt->columns->at(3)->name, "grade"); + ASSERT_EQ(stmt->columns->at(3)->type, ColumnDefinition::DOUBLE); +} \ No newline at end of file diff --git a/src/tests/test.h b/src/tests/test.h index 6af0b60..87c2b69 100644 --- a/src/tests/test.h +++ b/src/tests/test.h @@ -7,13 +7,19 @@ void name() #define ASSERT(cond) if (!(cond)) throw AssertionFailedException(#cond); + #define ASSERT_TRUE(cond) ASSERT(cond); #define ASSERT_FALSE(cond) if (cond) throw AssertionFailedException(#cond); + +#define ASSERT_NULL(value) ASSERT_TRUE(value == NULL); +#define ASSERT_NOTNULL(value) ASSERT_TRUE(value != NULL); + #define ASSERT_STREQ(a, b) \ if (std::string(a).compare(std::string(b)) != 0) throw AssertionFailedException(#a " == " #b) #define ASSERT_EQ(a, b) \ ASSERT(a == b); + class AssertionFailedException: public std::exception { public: AssertionFailedException(std::string msg) :