diff --git a/src/SQLParser.cpp b/src/SQLParser.cpp index e8e474c..91d6366 100644 --- a/src/SQLParser.cpp +++ b/src/SQLParser.cpp @@ -37,6 +37,7 @@ namespace hsql { return result; } + SQLParserResult* SQLParser::parseSQLString(const std::string& text) { return parseSQLString(text.c_str()); } diff --git a/src/SQLParser.h b/src/SQLParser.h index a88e357..d41532b 100644 --- a/src/SQLParser.h +++ b/src/SQLParser.h @@ -1,7 +1,6 @@ #ifndef __SQLPARSER_H_ #define __SQLPARSER_H_ -#include "sqltypes.h" #include "SQLParserResult.h" #include "sql/statements.h" diff --git a/src/SQLParserResult.cpp b/src/SQLParserResult.cpp index 1484c51..a0e10f9 100644 --- a/src/SQLParserResult.cpp +++ b/src/SQLParserResult.cpp @@ -1,2 +1,41 @@ -#include "SQLParserResult.h" \ No newline at end of file +#include "SQLParserResult.h" + +namespace hsql { + + SQLParserResult::SQLParserResult() : + isValid(true), + errorMsg(NULL) {}; + + + SQLParserResult::SQLParserResult(SQLStatement* stmt) : + isValid(true), + errorMsg(NULL) { + addStatement(stmt); + }; + + + SQLParserResult::~SQLParserResult() { + for (std::vector::iterator it = statements.begin(); it != statements.end(); ++it) { + delete *it; + } + + delete errorMsg; + } + + + void SQLParserResult::addStatement(SQLStatement* stmt) { + statements.push_back(stmt); + } + + + SQLStatement* SQLParserResult::getStatement(int id) { + return statements[id]; + } + + + size_t SQLParserResult::size() { + return statements.size(); + } + +} // namespace hsql \ No newline at end of file diff --git a/src/SQLParserResult.h b/src/SQLParserResult.h index 5ed85db..f32b827 100644 --- a/src/SQLParserResult.h +++ b/src/SQLParserResult.h @@ -8,36 +8,28 @@ namespace hsql { * Represents the result of the SQLParser. * If parsing was successful it contains a list of SQLStatement. */ - struct SQLParserResult { + class SQLParserResult { public: - SQLParserResult() : - isValid(true), - parser_msg(NULL) {}; - SQLParserResult(SQLStatement* stmt) : - isValid(true), - parser_msg(NULL) { - addStatement(stmt); - }; - - virtual ~SQLParserResult() { - for (std::vector::iterator it = statements.begin(); it != statements.end(); ++it) { - delete *it; - } - delete parser_msg; - } + SQLParserResult(); + SQLParserResult(SQLStatement* stmt); + virtual ~SQLParserResult(); - void addStatement(SQLStatement* stmt) { statements.push_back(stmt); } - SQLStatement* getStatement(int id) { return statements[id]; } - size_t numStatements() { return statements.size(); } + void addStatement(SQLStatement* stmt); + + SQLStatement* getStatement(int id); + + size_t size(); + // public properties std::vector statements; bool isValid; - const char* parser_msg; - int error_line; - int error_col; + + const char* errorMsg; + int errorLine; + int errorColumn; }; -} +} // namespace hsql #endif // __SQLPARSERRESULT__ \ No newline at end of file diff --git a/src/parser/bison_parser.cpp b/src/parser/bison_parser.cpp index 6913391..54228d8 100644 --- a/src/parser/bison_parser.cpp +++ b/src/parser/bison_parser.cpp @@ -95,9 +95,9 @@ int yyerror(YYLTYPE* llocp, SQLParserResult** result, yyscan_t scanner, const ch SQLParserResult* list = new SQLParserResult(); list->isValid = false; - list->parser_msg = strdup(msg); - list->error_line = llocp->first_line; - list->error_col = llocp->first_column; + list->errorMsg = strdup(msg); + list->errorLine = llocp->first_line; + list->errorColumn = llocp->first_column; *result = list; return 0; diff --git a/src/parser/bison_parser.y b/src/parser/bison_parser.y index e211ca1..292be16 100644 --- a/src/parser/bison_parser.y +++ b/src/parser/bison_parser.y @@ -22,9 +22,9 @@ int yyerror(YYLTYPE* llocp, SQLParserResult** result, yyscan_t scanner, const ch SQLParserResult* list = new SQLParserResult(); list->isValid = false; - list->parser_msg = strdup(msg); - list->error_line = llocp->first_line; - list->error_col = llocp->first_column; + list->errorMsg = strdup(msg); + list->errorLine = llocp->first_line; + list->errorColumn = llocp->first_column; *result = list; return 0; diff --git a/src/sql/Expr.h b/src/sql/Expr.h index 97be9be..ac04173 100644 --- a/src/sql/Expr.h +++ b/src/sql/Expr.h @@ -26,8 +26,7 @@ typedef enum { typedef struct Expr Expr; /** - * @class Expr - * @brief Represents SQL expressions (i.e. literals, operators, column_refs) + * Represents SQL expressions (i.e. literals, operators, column_refs) * * TODO: When destructing a placeholder expression, we might need to alter the placeholder_list */ diff --git a/src/sqlhelper.cpp b/src/sqlhelper.cpp index 5ae1bd3..32f0784 100644 --- a/src/sqlhelper.cpp +++ b/src/sqlhelper.cpp @@ -8,156 +8,156 @@ namespace hsql { void printOperatorExpression(Expr* expr, uint num_indent); std::string indent(uint num_indent) { return std::string(num_indent, '\t'); } -void inprint(int64_t val, uint num_indent) { printf("%s%lld \n", indent(num_indent).c_str(), val); } +void inprint(int64_t val, uint num_indent) { printf("%s%ld \n", indent(num_indent).c_str(), val); } void inprint(float val, uint num_indent) { printf("%s%f\n", indent(num_indent).c_str(), val); } void inprint(const char* val, uint num_indent) { printf("%s%s\n", indent(num_indent).c_str(), val); } void inprint(const char* val, const char* val2, uint num_indent) { printf("%s%s->%s\n", indent(num_indent).c_str(), val, val2); } void inprintC(char val, uint num_indent) { printf("%s%c\n", indent(num_indent).c_str(), val); } -void inprintU(uint64_t val, uint num_indent) { printf("%s%llu\n", indent(num_indent).c_str(), val); } +void inprintU(uint64_t val, uint num_indent) { printf("%s%lu\n", indent(num_indent).c_str(), val); } void printTableRefInfo(TableRef* table, uint num_indent) { - switch (table->type) { - case kTableName: - inprint(table->name, num_indent); - break; - case kTableSelect: - printSelectStatementInfo(table->select, num_indent); - break; - case kTableJoin: - inprint("Join Table", num_indent); - inprint("Left", num_indent+1); - printTableRefInfo(table->join->left, num_indent+2); - inprint("Right", num_indent+1); - printTableRefInfo(table->join->right, num_indent+2); - inprint("Join Condition", num_indent+1); - printExpression(table->join->condition, num_indent+2); - break; - case kTableCrossProduct: - for (TableRef* tbl : *table->list) printTableRefInfo(tbl, num_indent); - break; - } - if (table->alias != NULL) { - inprint("Alias", num_indent+1); - inprint(table->alias, num_indent+2); - } + switch (table->type) { + case kTableName: + inprint(table->name, num_indent); + break; + case kTableSelect: + printSelectStatementInfo(table->select, num_indent); + break; + case kTableJoin: + inprint("Join Table", num_indent); + inprint("Left", num_indent+1); + printTableRefInfo(table->join->left, num_indent+2); + inprint("Right", num_indent+1); + printTableRefInfo(table->join->right, num_indent+2); + inprint("Join Condition", num_indent+1); + printExpression(table->join->condition, num_indent+2); + break; + case kTableCrossProduct: + for (TableRef* tbl : *table->list) printTableRefInfo(tbl, num_indent); + break; + } + if (table->alias != NULL) { + inprint("Alias", num_indent+1); + inprint(table->alias, num_indent+2); + } } void printOperatorExpression(Expr* expr, uint num_indent) { - if (expr == NULL) { inprint("null", num_indent); return; } + if (expr == NULL) { inprint("null", num_indent); return; } - switch (expr->op_type) { - case Expr::SIMPLE_OP: inprintC(expr->op_char, num_indent); break; - case Expr::AND: inprint("AND", num_indent); break; - case Expr::OR: inprint("OR", num_indent); break; - case Expr::NOT: inprint("NOT", num_indent); break; - default: inprintU(expr->op_type, num_indent); break; - } - printExpression(expr->expr, num_indent+1); - if (expr->expr2 != NULL) printExpression(expr->expr2, num_indent+1); + switch (expr->op_type) { + case Expr::SIMPLE_OP: inprintC(expr->op_char, num_indent); break; + case Expr::AND: inprint("AND", num_indent); break; + case Expr::OR: inprint("OR", num_indent); break; + case Expr::NOT: inprint("NOT", num_indent); break; + default: inprintU(expr->op_type, num_indent); break; + } + printExpression(expr->expr, num_indent+1); + if (expr->expr2 != NULL) printExpression(expr->expr2, num_indent+1); } void printExpression(Expr* expr, uint num_indent) { - switch (expr->type) { - case kExprStar: inprint("*", num_indent); break; - case kExprColumnRef: inprint(expr->name, num_indent); break; - // case kExprTableColumnRef: inprint(expr->table, expr->name, num_indent); break; - case kExprLiteralFloat: inprint(expr->fval, num_indent); break; - case kExprLiteralInt: inprint(expr->ival, num_indent); break; - case kExprLiteralString: inprint(expr->name, num_indent); break; - case kExprFunctionRef: inprint(expr->name, num_indent); inprint(expr->expr->name, num_indent+1); break; - case kExprOperator: printOperatorExpression(expr, num_indent); break; - default: fprintf(stderr, "Unrecognized expression type %d\n", expr->type); return; - } - if (expr->alias != NULL) { - inprint("Alias", num_indent+1); inprint(expr->alias, num_indent+2); - } + switch (expr->type) { + case kExprStar: inprint("*", num_indent); break; + case kExprColumnRef: inprint(expr->name, num_indent); break; + // case kExprTableColumnRef: inprint(expr->table, expr->name, num_indent); break; + case kExprLiteralFloat: inprint(expr->fval, num_indent); break; + case kExprLiteralInt: inprint(expr->ival, num_indent); break; + case kExprLiteralString: inprint(expr->name, num_indent); break; + case kExprFunctionRef: inprint(expr->name, num_indent); inprint(expr->expr->name, num_indent+1); break; + case kExprOperator: printOperatorExpression(expr, num_indent); break; + default: fprintf(stderr, "Unrecognized expression type %d\n", expr->type); return; + } + if (expr->alias != NULL) { + inprint("Alias", num_indent+1); inprint(expr->alias, num_indent+2); + } } void printSelectStatementInfo(SelectStatement* stmt, uint num_indent) { - inprint("SelectStatement", num_indent); - inprint("Fields:", num_indent+1); - for (Expr* expr : *stmt->select_list) printExpression(expr, num_indent+2); + inprint("SelectStatement", num_indent); + inprint("Fields:", num_indent+1); + for (Expr* expr : *stmt->select_list) printExpression(expr, num_indent+2); - inprint("Sources:", num_indent+1); - printTableRefInfo(stmt->from_table, num_indent+2); + inprint("Sources:", num_indent+1); + printTableRefInfo(stmt->from_table, num_indent+2); - if (stmt->where_clause != NULL) { - inprint("Search Conditions:", num_indent+1); - printExpression(stmt->where_clause, num_indent+2); - } + if (stmt->where_clause != NULL) { + inprint("Search Conditions:", num_indent+1); + printExpression(stmt->where_clause, num_indent+2); + } - if (stmt->union_select != NULL) { - inprint("Union:", num_indent+1); - printSelectStatementInfo(stmt->union_select, num_indent+2); - } + if (stmt->union_select != NULL) { + inprint("Union:", num_indent+1); + printSelectStatementInfo(stmt->union_select, num_indent+2); + } - if (stmt->order != NULL) { - inprint("OrderBy:", num_indent+1); - printExpression(stmt->order->expr, num_indent+2); - if (stmt->order->type == kOrderAsc) inprint("ascending", num_indent+2); - else inprint("descending", num_indent+2); - } + if (stmt->order != NULL) { + inprint("OrderBy:", num_indent+1); + printExpression(stmt->order->expr, num_indent+2); + if (stmt->order->type == kOrderAsc) inprint("ascending", num_indent+2); + else inprint("descending", num_indent+2); + } - if (stmt->limit != NULL) { - inprint("Limit:", num_indent+1); - inprint(stmt->limit->limit, num_indent+2); - } + if (stmt->limit != NULL) { + inprint("Limit:", num_indent+1); + inprint(stmt->limit->limit, num_indent+2); + } } void printImportStatementInfo(ImportStatement* stmt, uint num_indent) { - inprint("ImportStatment", num_indent); - inprint(stmt->file_path, num_indent+1); - inprint(stmt->table_name, num_indent+1); + inprint("ImportStatment", num_indent); + inprint(stmt->file_path, num_indent+1); + inprint(stmt->table_name, num_indent+1); } void printCreateStatementInfo(CreateStatement* stmt, uint num_indent) { - inprint("CreateStatment", num_indent); - inprint(stmt->table_name, num_indent+1); - inprint(stmt->file_path, num_indent+1); + inprint("CreateStatment", num_indent); + inprint(stmt->table_name, num_indent+1); + inprint(stmt->file_path, num_indent+1); } void printInsertStatementInfo(InsertStatement* stmt, uint num_indent) { - inprint("InsertStatment", num_indent); - inprint(stmt->table_name, num_indent+1); - if (stmt->columns != NULL) { - inprint("Columns", num_indent+1); - for (char* col_name : *stmt->columns) { - inprint(col_name, num_indent+2); - } - } - switch (stmt->type) { - case InsertStatement::kInsertValues: - inprint("Values", num_indent+1); - for (Expr* expr : *stmt->values) { - printExpression(expr, num_indent+2); - } - break; - case InsertStatement::kInsertSelect: - printSelectStatementInfo(stmt->select, num_indent+1); - break; - } + inprint("InsertStatment", num_indent); + inprint(stmt->table_name, num_indent+1); + if (stmt->columns != NULL) { + inprint("Columns", num_indent+1); + for (char* col_name : *stmt->columns) { + inprint(col_name, num_indent+2); + } + } + switch (stmt->type) { + case InsertStatement::kInsertValues: + inprint("Values", num_indent+1); + for (Expr* expr : *stmt->values) { + printExpression(expr, num_indent+2); + } + break; + case InsertStatement::kInsertSelect: + printSelectStatementInfo(stmt->select, num_indent+1); + break; + } } void printStatementInfo(SQLStatement* stmt) { - switch (stmt->type()) { - case kStmtSelect: - printSelectStatementInfo((SelectStatement*) stmt, 0); - break; - case kStmtInsert: - printInsertStatementInfo((InsertStatement*) stmt, 0); - break; - case kStmtCreate: - printCreateStatementInfo((CreateStatement*) stmt, 0); - break; - case kStmtImport: - printImportStatementInfo((ImportStatement*) stmt, 0); - break; - default: - break; - } + switch (stmt->type()) { + case kStmtSelect: + printSelectStatementInfo((SelectStatement*) stmt, 0); + break; + case kStmtInsert: + printInsertStatementInfo((InsertStatement*) stmt, 0); + break; + case kStmtCreate: + printCreateStatementInfo((CreateStatement*) stmt, 0); + break; + case kStmtImport: + printImportStatementInfo((ImportStatement*) stmt, 0); + break; + default: + break; + } } } // namespace hsql \ No newline at end of file diff --git a/src/sqlhelper.h b/src/sqlhelper.h index ea6aa10..536a43b 100644 --- a/src/sqlhelper.h +++ b/src/sqlhelper.h @@ -1,19 +1,16 @@ - #ifndef __SQLHELPER_H__ #define __SQLHELPER_H__ - -#include "sqltypes.h" #include "sql/statements.h" namespace hsql { -void printStatementInfo(SQLStatement* stmt); -void printSelectStatementInfo(SelectStatement* stmt, uint num_indent); -void printImportStatementInfo(ImportStatement* stmt, uint num_indent); -void printInsertStatementInfo(InsertStatement* stmt, uint num_indent); -void printCreateStatementInfo(CreateStatement* stmt, uint num_indent); -void printExpression(Expr* expr, uint num_indent); + void printStatementInfo(SQLStatement* stmt); + void printSelectStatementInfo(SelectStatement* stmt, uint num_indent); + void printImportStatementInfo(ImportStatement* stmt, uint num_indent); + void printInsertStatementInfo(InsertStatement* stmt, uint num_indent); + void printCreateStatementInfo(CreateStatement* stmt, uint num_indent); + void printExpression(Expr* expr, uint num_indent); } // namespace hsql diff --git a/src/sqltypes.h b/src/sqltypes.h deleted file mode 100644 index 9975a14..0000000 --- a/src/sqltypes.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __SQLLIB_H__ -#define __SQLLIB_H__ - -typedef unsigned int uint; - -#endif \ No newline at end of file diff --git a/test/lib/helper.h b/test/lib/helper.h index 2b8f788..bcc0eaf 100644 --- a/test/lib/helper.h +++ b/test/lib/helper.h @@ -5,7 +5,7 @@ #define TEST_PARSE_SQL_QUERY(query, output_var, num_statements) \ SQLParserResult* output_var = SQLParser::parseSQLString(query); \ ASSERT(output_var->isValid); \ - ASSERT_EQ(output_var->numStatements(), num_statements); + ASSERT_EQ(output_var->size(), num_statements); #define TEST_PARSE_SINGLE_SQL(query, stmt_type, stmt_class, output_var) \ diff --git a/test/sql_grammar_test.cpp b/test/sql_grammar_test.cpp index b12212d..8c6520b 100644 --- a/test/sql_grammar_test.cpp +++ b/test/sql_grammar_test.cpp @@ -75,7 +75,7 @@ int main(int argc, char *argv[]) { if (expect_false == stmt_list->isValid) { printf("\033[0;31m{ failed}\033[0m\n"); - printf("\t\033[0;31m%s (L%d:%d)\n\033[0m", stmt_list->parser_msg, stmt_list->error_line, stmt_list->error_col); + printf("\t\033[0;31m%s (L%d:%d)\n\033[0m", stmt_list->errorMsg, stmt_list->errorLine, stmt_list->errorColumn); printf("\t%s\n", sql.c_str()); num_failed++; } else { diff --git a/test/sql_tests.cpp b/test/sql_tests.cpp index abb107f..1bc89c6 100644 --- a/test/sql_tests.cpp +++ b/test/sql_tests.cpp @@ -11,12 +11,12 @@ using namespace hsql; TEST(DeleteStatementTest) { - SQLParserResult* stmt_list = SQLParser::parseSQLString("DELETE FROM students WHERE grade > 2.0;"); - ASSERT(stmt_list->isValid); - ASSERT_EQ(stmt_list->numStatements(), 1); - ASSERT(stmt_list->getStatement(0)->type() == kStmtDelete); + SQLParserResult* result = SQLParser::parseSQLString("DELETE FROM students WHERE grade > 2.0;"); + ASSERT(result->isValid); + ASSERT_EQ(result->size(), 1); + ASSERT(result->getStatement(0)->type() == kStmtDelete); - DeleteStatement* stmt = (DeleteStatement*) stmt_list->getStatement(0); + DeleteStatement* stmt = (DeleteStatement*) result->getStatement(0); ASSERT_STREQ(stmt->table_name, "students"); ASSERT_NOTNULL(stmt->expr); ASSERT(stmt->expr->isType(kExprOperator)); @@ -25,12 +25,12 @@ TEST(DeleteStatementTest) { } TEST(CreateStatementTest) { - SQLParserResult* stmt_list = SQLParser::parseSQLString("CREATE TABLE students (name TEXT, student_number INT, city INTEGER, grade DOUBLE)"); - ASSERT(stmt_list->isValid); - ASSERT_EQ(stmt_list->numStatements(), 1); - ASSERT_EQ(stmt_list->getStatement(0)->type(), kStmtCreate); + SQLParserResult* result = SQLParser::parseSQLString("CREATE TABLE students (name TEXT, student_number INT, city INTEGER, grade DOUBLE)"); + ASSERT(result->isValid); + ASSERT_EQ(result->size(), 1); + ASSERT_EQ(result->getStatement(0)->type(), kStmtCreate); - CreateStatement* stmt = (CreateStatement*) stmt_list->getStatement(0); + CreateStatement* stmt = (CreateStatement*) result->getStatement(0); ASSERT_EQ(stmt->type, CreateStatement::kTable); ASSERT_STREQ(stmt->table_name, "students"); ASSERT_NOTNULL(stmt->columns); @@ -47,12 +47,12 @@ TEST(CreateStatementTest) { TEST(UpdateStatementTest) { - SQLParserResult* stmt_list = SQLParser::parseSQLString("UPDATE students SET grade = 5.0, name = 'test' WHERE name = 'Max Mustermann';"); - ASSERT(stmt_list->isValid); - ASSERT_EQ(stmt_list->numStatements(), 1); - ASSERT_EQ(stmt_list->getStatement(0)->type(), kStmtUpdate); + SQLParserResult* result = SQLParser::parseSQLString("UPDATE students SET grade = 5.0, name = 'test' WHERE name = 'Max Mustermann';"); + ASSERT(result->isValid); + ASSERT_EQ(result->size(), 1); + ASSERT_EQ(result->getStatement(0)->type(), kStmtUpdate); - UpdateStatement* stmt = (UpdateStatement*) stmt_list->getStatement(0); + UpdateStatement* stmt = (UpdateStatement*) result->getStatement(0); ASSERT_NOTNULL(stmt->table); ASSERT_STREQ(stmt->table->name, "students"); @@ -99,16 +99,16 @@ TEST(PrepareStatementTest) { "PREPARE stmt: SELECT * FROM data WHERE c1 = ?;" "DEALLOCATE PREPARE stmt;"; - TEST_PARSE_SQL_QUERY(query, stmt_list, 3); + TEST_PARSE_SQL_QUERY(query, result, 3); - TEST_CAST_STMT(stmt_list, 0, kStmtPrepare, PrepareStatement, prep1); - TEST_CAST_STMT(stmt_list, 1, kStmtPrepare, PrepareStatement, prep2); - TEST_CAST_STMT(stmt_list, 2, kStmtDrop, DropStatement, drop); + TEST_CAST_STMT(result, 0, kStmtPrepare, PrepareStatement, prep1); + TEST_CAST_STMT(result, 1, kStmtPrepare, PrepareStatement, prep2); + TEST_CAST_STMT(result, 2, kStmtDrop, DropStatement, drop); // Prepare Statement #1 ASSERT_STREQ(prep1->name, "test"); ASSERT_EQ(prep1->placeholders.size(), 3); - ASSERT_EQ(prep1->query->numStatements(), 2); + ASSERT_EQ(prep1->query->size(), 2); TEST_CAST_STMT(prep1->query, 0, kStmtInsert, InsertStatement, insert); TEST_CAST_STMT(prep1->query, 1, kStmtSelect, SelectStatement, select);