modification to prepare syntax
This commit is contained in:
parent
c3ded749e6
commit
ab9a85704f
|
@ -34,5 +34,10 @@ SQLStatementList* SQLParser::parseSQLString(const char *text) {
|
||||||
hsql_lex_destroy(scanner);
|
hsql_lex_destroy(scanner);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SQLStatementList* SQLParser::parseSQLString(const std::string& text) {
|
||||||
|
return parseSQLString(text.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace hsql
|
} // namespace hsql
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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]* |
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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;
|
Loading…
Reference in New Issue