implemented create with column def
This commit is contained in:
parent
382522db76
commit
2f76183586
|
@ -16,6 +16,12 @@ struct ColumnDefinition {
|
||||||
DOUBLE
|
DOUBLE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ColumnDefinition(char* name, DataType type) :
|
||||||
|
name(name),
|
||||||
|
type(type) {}
|
||||||
|
|
||||||
|
virtual ~ColumnDefinition(); // defined in destructors.cpp
|
||||||
|
|
||||||
char* name;
|
char* name;
|
||||||
DataType type;
|
DataType type;
|
||||||
};
|
};
|
||||||
|
@ -34,6 +40,7 @@ struct CreateStatement : Statement {
|
||||||
CreateStatement() :
|
CreateStatement() :
|
||||||
Statement(kStmtCreate),
|
Statement(kStmtCreate),
|
||||||
if_not_exists(false),
|
if_not_exists(false),
|
||||||
|
columns(NULL),
|
||||||
file_path(NULL),
|
file_path(NULL),
|
||||||
table_name(NULL) {};
|
table_name(NULL) {};
|
||||||
|
|
||||||
|
@ -41,6 +48,9 @@ struct CreateStatement : Statement {
|
||||||
|
|
||||||
CreateType create_type;
|
CreateType create_type;
|
||||||
bool if_not_exists;
|
bool if_not_exists;
|
||||||
|
|
||||||
|
List<ColumnDefinition*>* columns;
|
||||||
|
|
||||||
const char* file_path;
|
const char* file_path;
|
||||||
const char* table_name;
|
const char* table_name;
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,6 +16,7 @@ namespace hsql {
|
||||||
struct DeleteStatement : Statement {
|
struct DeleteStatement : Statement {
|
||||||
DeleteStatement() :
|
DeleteStatement() :
|
||||||
Statement(kStmtDelete),
|
Statement(kStmtDelete),
|
||||||
|
table_name(NULL),
|
||||||
expr(NULL) {};
|
expr(NULL) {};
|
||||||
|
|
||||||
virtual ~DeleteStatement(); // defined in destructors.cpp
|
virtual ~DeleteStatement(); // defined in destructors.cpp
|
||||||
|
|
|
@ -4,14 +4,43 @@
|
||||||
|
|
||||||
namespace hsql {
|
namespace hsql {
|
||||||
|
|
||||||
Statement::~Statement() {
|
/**
|
||||||
/* empty */
|
* Statement.h
|
||||||
}
|
*/
|
||||||
|
Statement::~Statement() { /* empty */ }
|
||||||
StatementList::~StatementList() {
|
StatementList::~StatementList() {
|
||||||
delete parser_msg;
|
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() {
|
SelectStatement::~SelectStatement() {
|
||||||
delete from_table;
|
delete from_table;
|
||||||
delete select_list;
|
delete select_list;
|
||||||
|
@ -20,43 +49,38 @@ SelectStatement::~SelectStatement() {
|
||||||
delete order;
|
delete order;
|
||||||
delete limit;
|
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() {
|
OrderDescription::~OrderDescription() {
|
||||||
delete expr;
|
delete expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CreateStatement.h
|
||||||
|
*/
|
||||||
|
CreateStatement::~CreateStatement() {
|
||||||
|
delete columns;
|
||||||
|
delete file_path;
|
||||||
|
delete table_name;
|
||||||
|
}
|
||||||
|
ColumnDefinition::~ColumnDefinition() {
|
||||||
|
delete name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table.h
|
||||||
|
*/
|
||||||
TableRef::~TableRef() {
|
TableRef::~TableRef() {
|
||||||
delete name;
|
delete name;
|
||||||
delete alias;
|
delete alias;
|
||||||
delete select;
|
delete select;
|
||||||
delete list;
|
delete list;
|
||||||
}
|
}
|
||||||
|
|
||||||
JoinDefinition::~JoinDefinition() {
|
JoinDefinition::~JoinDefinition() {
|
||||||
delete left;
|
delete left;
|
||||||
delete right;
|
delete right;
|
||||||
delete condition;
|
delete condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace hsql
|
} // namespace hsql
|
|
@ -90,11 +90,13 @@ typedef void* yyscan_t;
|
||||||
hsql::OrderDescription* order;
|
hsql::OrderDescription* order;
|
||||||
hsql::OrderType order_type;
|
hsql::OrderType order_type;
|
||||||
hsql::LimitDescription* limit;
|
hsql::LimitDescription* limit;
|
||||||
|
hsql::ColumnDefinition* column_t;
|
||||||
|
|
||||||
hsql::StatementList* stmt_list;
|
hsql::StatementList* stmt_list;
|
||||||
hsql::List<char*>* slist;
|
hsql::List<char*>* slist;
|
||||||
hsql::List<hsql::Expr*>* expr_list;
|
hsql::List<hsql::Expr*>* expr_list;
|
||||||
hsql::List<hsql::TableRef*>* table_list;
|
hsql::List<hsql::TableRef*>* table_list;
|
||||||
|
hsql::List<hsql::ColumnDefinition*>* column_list_t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -135,6 +137,7 @@ typedef void* yyscan_t;
|
||||||
%type <delete_stmt> delete_statement truncate_statement
|
%type <delete_stmt> delete_statement truncate_statement
|
||||||
%type <sval> table_name opt_alias alias file_path
|
%type <sval> table_name opt_alias alias file_path
|
||||||
%type <bval> opt_not_exists
|
%type <bval> opt_not_exists
|
||||||
|
%type <uval> import_file_type opt_join_type column_type
|
||||||
%type <table> from_clause table_ref table_ref_atomic table_ref_name
|
%type <table> from_clause table_ref table_ref_atomic table_ref_name
|
||||||
%type <table> join_clause join_table
|
%type <table> join_clause join_table
|
||||||
%type <expr> expr scalar_expr unary_expr binary_expr function_expr star_expr expr_alias
|
%type <expr> expr scalar_expr unary_expr binary_expr function_expr star_expr expr_alias
|
||||||
|
@ -145,8 +148,9 @@ typedef void* yyscan_t;
|
||||||
%type <order> opt_order
|
%type <order> opt_order
|
||||||
%type <limit> opt_limit
|
%type <limit> opt_limit
|
||||||
%type <order_type> opt_order_type
|
%type <order_type> opt_order_type
|
||||||
%type <uval> import_file_type opt_join_type
|
|
||||||
%type <slist> ident_commalist opt_column_list
|
%type <slist> ident_commalist opt_column_list
|
||||||
|
%type <column_t> column_def
|
||||||
|
%type <column_list_t> column_def_commalist
|
||||||
|
|
||||||
/******************************
|
/******************************
|
||||||
** Token Precedence and Associativity
|
** Token Precedence and Associativity
|
||||||
|
@ -237,7 +241,7 @@ create_statement:
|
||||||
$$->create_type = CreateStatement::kTable;
|
$$->create_type = CreateStatement::kTable;
|
||||||
$$->if_not_exists = $3;
|
$$->if_not_exists = $3;
|
||||||
$$->table_name = $4;
|
$$->table_name = $4;
|
||||||
// TODO: build into object
|
$$->columns = $6;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -247,18 +251,20 @@ opt_not_exists:
|
||||||
;
|
;
|
||||||
|
|
||||||
column_def_commalist:
|
column_def_commalist:
|
||||||
column_def
|
column_def { $$ = new List<ColumnDefinition*>($1); }
|
||||||
| column_def_commalist ',' column_def
|
| column_def_commalist ',' column_def { $1->push_back($3); $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
column_def:
|
column_def:
|
||||||
IDENTIFIER column_type
|
IDENTIFIER column_type {
|
||||||
|
$$ = new ColumnDefinition($1, (ColumnDefinition::DataType) $2);
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
column_type:
|
column_type:
|
||||||
INTEGER
|
INTEGER { $$ = ColumnDefinition::INT; }
|
||||||
| DOUBLE
|
| DOUBLE { $$ = ColumnDefinition::DOUBLE; }
|
||||||
| TEXT
|
| TEXT { $$ = ColumnDefinition::TEXT; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,25 +13,41 @@ using namespace hsql;
|
||||||
TEST(SelectTest) {
|
TEST(SelectTest) {
|
||||||
StatementList* stmt_list = SQLParser::parseSQLString("SELECT * FROM students;");
|
StatementList* stmt_list = SQLParser::parseSQLString("SELECT * FROM students;");
|
||||||
ASSERT(stmt_list->isValid);
|
ASSERT(stmt_list->isValid);
|
||||||
ASSERT(stmt_list->size() == 1);
|
ASSERT_EQ(stmt_list->size(), 1);
|
||||||
ASSERT(stmt_list->at(0)->type == kStmtSelect);
|
ASSERT(stmt_list->at(0)->type == kStmtSelect);
|
||||||
|
|
||||||
SelectStatement* stmt = (SelectStatement*) stmt_list->at(0);
|
SelectStatement* stmt = (SelectStatement*) stmt_list->at(0);
|
||||||
ASSERT(stmt->where_clause == NULL);
|
ASSERT_NULL(stmt->where_clause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST(DeleteTest) {
|
TEST(DeleteTest) {
|
||||||
StatementList* stmt_list = SQLParser::parseSQLString("DELETE FROM students WHERE grade > 2.0;");
|
StatementList* stmt_list = SQLParser::parseSQLString("DELETE FROM students WHERE grade > 2.0;");
|
||||||
ASSERT(stmt_list->isValid);
|
ASSERT(stmt_list->isValid);
|
||||||
ASSERT(stmt_list->size() == 1);
|
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);
|
DeleteStatement* stmt = (DeleteStatement*) stmt_list->at(0);
|
||||||
ASSERT_STREQ(stmt->table_name, "students");
|
ASSERT_STREQ(stmt->table_name, "students");
|
||||||
ASSERT(stmt->expr != NULL);
|
ASSERT_NOTNULL(stmt->expr);
|
||||||
ASSERT(stmt->expr->isType(kExprOperator));
|
ASSERT(stmt->expr->isType(kExprOperator));
|
||||||
ASSERT_STREQ(stmt->expr->expr->name, "grade");
|
ASSERT_STREQ(stmt->expr->expr->name, "grade");
|
||||||
ASSERT_EQ(stmt->expr->expr2->fval, 2.0);
|
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);
|
||||||
|
}
|
|
@ -7,13 +7,19 @@
|
||||||
void name()
|
void name()
|
||||||
|
|
||||||
#define ASSERT(cond) if (!(cond)) throw AssertionFailedException(#cond);
|
#define ASSERT(cond) if (!(cond)) throw AssertionFailedException(#cond);
|
||||||
|
|
||||||
#define ASSERT_TRUE(cond) ASSERT(cond);
|
#define ASSERT_TRUE(cond) ASSERT(cond);
|
||||||
#define ASSERT_FALSE(cond) if (cond) throw AssertionFailedException(#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) \
|
#define ASSERT_STREQ(a, b) \
|
||||||
if (std::string(a).compare(std::string(b)) != 0) throw AssertionFailedException(#a " == " #b)
|
if (std::string(a).compare(std::string(b)) != 0) throw AssertionFailedException(#a " == " #b)
|
||||||
#define ASSERT_EQ(a, b) \
|
#define ASSERT_EQ(a, b) \
|
||||||
ASSERT(a == b);
|
ASSERT(a == b);
|
||||||
|
|
||||||
|
|
||||||
class AssertionFailedException: public std::exception {
|
class AssertionFailedException: public std::exception {
|
||||||
public:
|
public:
|
||||||
AssertionFailedException(std::string msg) :
|
AssertionFailedException(std::string msg) :
|
||||||
|
|
Loading…
Reference in New Issue