modification to prepare syntax

This commit is contained in:
Pedro 2015-01-07 13:24:39 +01:00
parent c3ded749e6
commit ab9a85704f
7 changed files with 54 additions and 33 deletions

View File

@ -35,4 +35,9 @@ SQLStatementList* SQLParser::parseSQLString(const char *text) {
return result; return result;
} }
SQLStatementList* SQLParser::parseSQLString(const std::string& text) {
return parseSQLString(text.c_str());
}
} // namespace hsql } // namespace hsql

View File

@ -16,6 +16,7 @@ namespace hsql {
class SQLParser { class SQLParser {
public: public:
static SQLStatementList* parseSQLString(const char* sql); static SQLStatementList* parseSQLString(const char* sql);
static SQLStatementList* parseSQLString(const std::string& sql);
private: private:
SQLParser(); SQLParser();

View File

@ -224,11 +224,7 @@ int yyerror(YYLTYPE* llocp, SQLStatementList** result, yyscan_t scanner, const c
// Defines our general input. // Defines our general input.
input: input:
prepare_statement { statement_list opt_semicolon {
$1->setPlaceholders(yyloc.placeholder_list);
*result = new SQLStatementList($1);
}
| statement_list opt_semicolon {
*result = $1; *result = $1;
} }
; ;
@ -240,7 +236,12 @@ statement_list:
; ;
statement: statement:
preparable_statement prepare_statement {
$1->setPlaceholders(yyloc.placeholder_list);
yyloc.placeholder_list.clear();
$$ = $1;
}
| preparable_statement
; ;
@ -261,7 +262,12 @@ preparable_statement:
* Prepared Statement * Prepared Statement
******************************/ ******************************/
prepare_statement: prepare_statement:
PREPARE IDENTIFIER ':' statement_list opt_semicolon { PREPARE IDENTIFIER ':' preparable_statement {
$$ = new PrepareStatement();
$$->name = $2;
$$->query = new SQLStatementList($4);
}
| PREPARE IDENTIFIER '{' statement_list opt_semicolon '}' {
$$ = new PrepareStatement(); $$ = new PrepareStatement();
$$->name = $2; $$->name = $2;
$$->query = $4; $$->query = $4;

View File

@ -177,7 +177,7 @@ TO TOKEN(TO)
">=" TOKEN(GREATEREQ) ">=" TOKEN(GREATEREQ)
[-+*/(),.;<>=^%:?] { return yytext[0]; } [-+*/(){},.;<>=^%:?] { return yytext[0]; }
[0-9]+"."[0-9]* | [0-9]+"."[0-9]* |

View File

@ -75,22 +75,16 @@ TEST(UpdateStatementTest) {
TEST(InsertStatementTest) { TEST(InsertStatementTest) {
SQLStatementList* stmt_list = SQLParser::parseSQLString("INSERT INTO students VALUES ('Max Mustermann', 12345, 'Musterhausen', 2.0)"); TEST_PARSE_SINGLE_SQL("INSERT INTO students VALUES ('Max Mustermann', 12345, 'Musterhausen', 2.0)", kStmtInsert, InsertStatement, stmt);
ASSERT(stmt_list->isValid);
ASSERT_EQ(stmt_list->numStatements(), 1);
ASSERT_EQ(stmt_list->getStatement(0)->type(), kStmtInsert);
ASSERT_EQ(stmt->values->size(), 4);
// TODO // TODO
} }
TEST(DropTableStatementTest) { TEST(DropTableStatementTest) {
SQLStatementList* stmt_list = SQLParser::parseSQLString("DROP TABLE students"); TEST_PARSE_SINGLE_SQL("DROP TABLE students", kStmtDrop, DropStatement, stmt);
ASSERT(stmt_list->isValid);
ASSERT_EQ(stmt_list->numStatements(), 1);
ASSERT_EQ(stmt_list->getStatement(0)->type(), kStmtDrop);
DropStatement* stmt = (DropStatement*) stmt_list->getStatement(0);
ASSERT_EQ(stmt->type, DropStatement::kTable); ASSERT_EQ(stmt->type, DropStatement::kTable);
ASSERT_NOTNULL(stmt->name); ASSERT_NOTNULL(stmt->name);
ASSERT_STREQ(stmt->name, "students"); ASSERT_STREQ(stmt->name, "students");
@ -98,22 +92,30 @@ TEST(DropTableStatementTest) {
TEST(PrepareStatementTest) { TEST(PrepareStatementTest) {
TEST_PARSE_SINGLE_SQL("PREPARE test:" std::string query = "PREPARE test {"
"INSERT INTO test VALUES(?);" "INSERT INTO test VALUES(?);"
"SELECT ?, test FROM test WHERE c1 = ?;" "SELECT ?, test FROM test WHERE c1 = ?;"
"", kStmtPrepare, PrepareStatement, prep_stmt); "};"
"PREPARE stmt: SELECT * FROM data WHERE c1 = ?;";
ASSERT_STREQ(prep_stmt->name, "test"); TEST_PARSE_SQL_QUERY(query, stmt_list, 2);
ASSERT_EQ(prep_stmt->placeholders.size(), 3);
ASSERT_EQ(stmt_list->getStatement(0)->type(), kStmtPrepare);
ASSERT_EQ(stmt_list->getStatement(1)->type(), kStmtPrepare);
ASSERT_EQ(prep_stmt->query->numStatements(), 2); PrepareStatement* prep1 = (PrepareStatement*) stmt_list->getStatement(0);
ASSERT_EQ(prep_stmt->query->getStatement(0)->type(), kStmtInsert); PrepareStatement* prep2 = (PrepareStatement*) stmt_list->getStatement(1);
ASSERT_EQ(prep_stmt->query->getStatement(1)->type(), kStmtSelect);
// Prepare Statement #1
ASSERT_STREQ(prep1->name, "test");
ASSERT_EQ(prep1->placeholders.size(), 3);
InsertStatement* insert = (InsertStatement*) prep_stmt->query->getStatement(0); ASSERT_EQ(prep1->query->numStatements(), 2);
SelectStatement* select = (SelectStatement*) prep_stmt->query->getStatement(1); ASSERT_EQ(prep1->query->getStatement(0)->type(), kStmtInsert);
ASSERT_EQ(prep1->query->getStatement(1)->type(), kStmtSelect);
InsertStatement* insert = (InsertStatement*) prep1->query->getStatement(0);
SelectStatement* select = (SelectStatement*) prep1->query->getStatement(1);
ASSERT(insert->values->at(0)->isType(kExprPlaceholder)); ASSERT(insert->values->at(0)->isType(kExprPlaceholder));
ASSERT(select->select_list->at(0)->isType(kExprPlaceholder)); ASSERT(select->select_list->at(0)->isType(kExprPlaceholder));
@ -121,13 +123,17 @@ TEST(PrepareStatementTest) {
// Check IDs of placeholders // Check IDs of placeholders
ASSERT_EQ(insert->values->at(0)->ival, 0); ASSERT_EQ(insert->values->at(0)->ival, 0);
ASSERT_EQ(insert->values->at(0), prep_stmt->placeholders[0]); ASSERT_EQ(insert->values->at(0), prep1->placeholders[0]);
ASSERT_EQ(select->select_list->at(0)->ival, 1); ASSERT_EQ(select->select_list->at(0)->ival, 1);
ASSERT_EQ(select->select_list->at(0), prep_stmt->placeholders[1]); ASSERT_EQ(select->select_list->at(0), prep1->placeholders[1]);
ASSERT_EQ(select->where_clause->expr2->ival, 2); ASSERT_EQ(select->where_clause->expr2->ival, 2);
ASSERT_EQ(select->where_clause->expr2, prep_stmt->placeholders[2]); ASSERT_EQ(select->where_clause->expr2, prep1->placeholders[2]);
// Prepare Statement #2
ASSERT_STREQ(prep2->name, "stmt");
ASSERT_EQ(prep2->placeholders.size(), 1);
} }

View File

@ -2,14 +2,16 @@
#define __HELPER_H__ #define __HELPER_H__
#define TEST_PARSE_SQL_QUERY(query, output_var, num_statements) \
SQLStatementList* output_var = SQLParser::parseSQLString(query); \
ASSERT(output_var->isValid); \
ASSERT_EQ(output_var->numStatements(), num_statements);
#define TEST_PARSE_SINGLE_SQL(query, stmt_type, stmt_class, output_var) \ #define TEST_PARSE_SINGLE_SQL(query, stmt_type, stmt_class, output_var) \
SQLStatementList* stmt_list = SQLParser::parseSQLString(query); \ TEST_PARSE_SQL_QUERY(query, stmt_list, 1); \
ASSERT(stmt_list->isValid); \
ASSERT_EQ(stmt_list->numStatements(), 1); \
ASSERT_EQ(stmt_list->getStatement(0)->type(), stmt_type); \ ASSERT_EQ(stmt_list->getStatement(0)->type(), stmt_type); \
stmt_class* output_var = (stmt_class*) stmt_list->getStatement(0); stmt_class* output_var = (stmt_class*) stmt_list->getStatement(0);
#endif #endif

View File

@ -33,5 +33,6 @@ UPDATE students SET grade = 1.0;
DROP TABLE students; DROP TABLE students;
# PREPARE # PREPARE
PREPARE prep_inst: INSERT INTO test VALUES (?, ?, ?); PREPARE prep_inst: INSERT INTO test VALUES (?, ?, ?);
PREPARE prep2 { INSERT INTO test VALUES (?, 0, 0); INSERT INTO test VALUES (0, ?, 0); INSERT INTO test VALUES (0, 0, ?); };
EXECUTE prep_inst(1, 2, 3); EXECUTE prep_inst(1, 2, 3);
EXECUTE prep; EXECUTE prep;