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

@ -34,5 +34,10 @@ SQLStatementList* SQLParser::parseSQLString(const char *text) {
hsql_lex_destroy(scanner);
return result;
}
SQLStatementList* SQLParser::parseSQLString(const std::string& text) {
return parseSQLString(text.c_str());
}
} // namespace hsql

View File

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

View File

@ -224,11 +224,7 @@ int yyerror(YYLTYPE* llocp, SQLStatementList** result, yyscan_t scanner, const c
// Defines our general input.
input:
prepare_statement {
$1->setPlaceholders(yyloc.placeholder_list);
*result = new SQLStatementList($1);
}
| statement_list opt_semicolon {
statement_list opt_semicolon {
*result = $1;
}
;
@ -240,7 +236,12 @@ statement_list:
;
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
******************************/
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();
$$->name = $2;
$$->query = $4;

View File

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

View File

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

View File

@ -33,5 +33,6 @@ UPDATE students SET grade = 1.0;
DROP TABLE students;
# PREPARE
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;