diff --git a/benchmark/Makefile b/benchmark/Makefile index a05a8cb..a33b9d4 100644 --- a/benchmark/Makefile +++ b/benchmark/Makefile @@ -1,4 +1,7 @@ +SRC = ./ +CPP = $(shell find $(SRC) -name '*.cpp') + CFLAGS = -std=c++11 -lstdc++ -Wall -I../src/ -L../ all: parser_benchmark @@ -6,8 +9,8 @@ all: parser_benchmark run: parser_benchmark @export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:../ && ./parser_benchmark -parser_benchmark: parser_benchmark.cpp - $(CXX) $(CFLAGS) parser_benchmark.cpp -o parser_benchmark -lbenchmark -lpthread -lsqlparser +parser_benchmark: $(CPP) + $(CXX) $(CFLAGS) $(CPP) -o parser_benchmark -lbenchmark -lpthread -lsqlparser clean: rm -f parser_benchmark diff --git a/benchmark/parser_benchmark.cpp b/benchmark/parser_benchmark.cpp index 9f0fa07..cea4709 100644 --- a/benchmark/parser_benchmark.cpp +++ b/benchmark/parser_benchmark.cpp @@ -31,6 +31,18 @@ PARSE_QUERY_BENCHMARK(BM_LongSelectElement26, PARSE_QUERY_BENCHMARK(BM_LongSelectElement52, "SELECT aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa FROM test;"); +// Prepare and Execute benchmarks. +PARSE_QUERY_BENCHMARK(BM_ExecuteStatement, + "EXECUTE procedure;"); + +PARSE_QUERY_BENCHMARK(BM_ExecuteWith2ParametersStatement, + "EXECUTE procedure(11, 'test');"); + +PARSE_QUERY_BENCHMARK(BM_ExecuteWith10ParametersStatement, + "EXECUTE procedure(11, 'test', 5.6, 4.2, 'abc', 6, 7, 8, 9, 10000);"); + + + // Benchmark the influence of increasing size of the query, while // the number of tokens remains unchanged. static void BM_CharacterCount(benchmark::State& st) { diff --git a/src/sql/PrepareStatement.h b/src/sql/PrepareStatement.h index c65e7f4..62891eb 100644 --- a/src/sql/PrepareStatement.h +++ b/src/sql/PrepareStatement.h @@ -24,6 +24,8 @@ namespace hsql { void setPlaceholders(std::vector ph); char* name; + + // The result that is stored within this prepared statement. SQLParserResult* query; // The expressions are not owned by this statement. diff --git a/test/prepare_tests.cpp b/test/prepare_tests.cpp new file mode 100644 index 0000000..bd8c51d --- /dev/null +++ b/test/prepare_tests.cpp @@ -0,0 +1,82 @@ + +#include "thirdparty/microtest/microtest.h" +#include "sql_asserts.h" +#include "SQLParser.h" + +using hsql::kExprPlaceholder; + +using hsql::kStmtDrop; +using hsql::kStmtExecute; +using hsql::kStmtInsert; +using hsql::kStmtPrepare; +using hsql::kStmtSelect; + +using hsql::DropStatement; +using hsql::ExecuteStatement; +using hsql::InsertStatement; +using hsql::PrepareStatement; +using hsql::SelectStatement; + + +TEST(PrepareSingleStatementTest) { + const std::string query = "PREPARE test: SELECT * FROM students WHERE grade = ?;"; + TEST_PARSE_SINGLE_SQL(query, kStmtPrepare, PrepareStatement, result, prepare); + + const SelectStatement* select = (const SelectStatement*) prepare->query->getStatement(0); + + ASSERT(select->whereClause->isSimpleOp('=')); + ASSERT_EQ(select->whereClause->expr2, prepare->placeholders[0]) +} + +TEST(PrepareMultiStatementTest) { + const std::string query = "PREPARE test {" + "INSERT INTO test VALUES(?);" + "SELECT ?, test FROM test WHERE c1 = ?;" + "};" + "PREPARE stmt: SELECT * FROM data WHERE c1 = ?;" + "DEALLOCATE PREPARE stmt;"; + + TEST_PARSE_SQL_QUERY(query, result, 3); + + 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->size(), 2); + + TEST_CAST_STMT((*prep1->query), 0, kStmtInsert, InsertStatement, insert); + TEST_CAST_STMT((*prep1->query), 1, kStmtSelect, SelectStatement, select); + + ASSERT(insert->values->at(0)->isType(kExprPlaceholder)); + ASSERT(select->selectList->at(0)->isType(kExprPlaceholder)); + ASSERT(select->whereClause->expr2->isType(kExprPlaceholder)); + + // Check IDs of placeholders + ASSERT_EQ(insert->values->at(0)->ival, 0); + ASSERT_EQ(insert->values->at(0), prep1->placeholders[0]); + + ASSERT_EQ(select->selectList->at(0)->ival, 1); + ASSERT_EQ(select->selectList->at(0), prep1->placeholders[1]); + + ASSERT_EQ(select->whereClause->expr2->ival, 2); + ASSERT_EQ(select->whereClause->expr2, prep1->placeholders[2]); + + // Prepare Statement #2 + ASSERT_STREQ(prep2->name, "stmt"); + ASSERT_EQ(prep2->placeholders.size(), 1); + + // Deallocate Statement + ASSERT_EQ(drop->type, DropStatement::kPreparedStatement); + ASSERT_STREQ(drop->name, "stmt"); +} + + +TEST(ExecuteStatementTest) { + TEST_PARSE_SINGLE_SQL("EXECUTE test(1, 2);", kStmtExecute, ExecuteStatement, result, stmt); + + ASSERT_STREQ(stmt->name, "test"); + ASSERT_EQ(stmt->parameters->size(), 2); +} diff --git a/test/sql_asserts.h b/test/sql_asserts.h index 2c70b3b..13496cd 100644 --- a/test/sql_asserts.h +++ b/test/sql_asserts.h @@ -3,8 +3,8 @@ #define TEST_PARSE_SQL_QUERY(query, result, numStatements) \ - SQLParserResult result; \ - SQLParser::parseSQLString(query, &result); \ + hsql::SQLParserResult result; \ + hsql::SQLParser::parseSQLString(query, &result); \ ASSERT(result.isValid()); \ ASSERT_EQ(result.size(), numStatements); diff --git a/test/sql_tests.cpp b/test/sql_tests.cpp index 3e3d359..fce09d9 100644 --- a/test/sql_tests.cpp +++ b/test/sql_tests.cpp @@ -107,60 +107,6 @@ TEST(DropTableStatementTest) { ASSERT_STREQ(stmt->name, "students"); } - -TEST(PrepareStatementTest) { - std::string query = "PREPARE test {" - "INSERT INTO test VALUES(?);" - "SELECT ?, test FROM test WHERE c1 = ?;" - "};" - "PREPARE stmt: SELECT * FROM data WHERE c1 = ?;" - "DEALLOCATE PREPARE stmt;"; - - TEST_PARSE_SQL_QUERY(query, result, 3); - - 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->size(), 2); - - TEST_CAST_STMT((*prep1->query), 0, kStmtInsert, InsertStatement, insert); - TEST_CAST_STMT((*prep1->query), 1, kStmtSelect, SelectStatement, select); - - ASSERT(insert->values->at(0)->isType(kExprPlaceholder)); - ASSERT(select->selectList->at(0)->isType(kExprPlaceholder)); - ASSERT(select->whereClause->expr2->isType(kExprPlaceholder)); - - // Check IDs of placeholders - ASSERT_EQ(insert->values->at(0)->ival, 0); - ASSERT_EQ(insert->values->at(0), prep1->placeholders[0]); - - ASSERT_EQ(select->selectList->at(0)->ival, 1); - ASSERT_EQ(select->selectList->at(0), prep1->placeholders[1]); - - ASSERT_EQ(select->whereClause->expr2->ival, 2); - ASSERT_EQ(select->whereClause->expr2, prep1->placeholders[2]); - - // Prepare Statement #2 - ASSERT_STREQ(prep2->name, "stmt"); - ASSERT_EQ(prep2->placeholders.size(), 1); - - // Deallocate Statement - ASSERT_EQ(drop->type, DropStatement::kPreparedStatement); - ASSERT_STREQ(drop->name, "stmt"); -} - - -TEST(ExecuteStatementTest) { - TEST_PARSE_SINGLE_SQL("EXECUTE test(1, 2);", kStmtExecute, ExecuteStatement, result, stmt); - - ASSERT_STREQ(stmt->name, "test"); - ASSERT_EQ(stmt->parameters->size(), 2); -} - TEST(ReleaseStatementTest) { TEST_PARSE_SINGLE_SQL( "SELECT * FROM students;",