add 10 tpch style queries and test for them

This commit is contained in:
Pedro 2017-03-07 02:01:00 +01:00
parent 42049b4d56
commit 36adab70c5
17 changed files with 875 additions and 729 deletions

View File

@ -10,7 +10,7 @@ LIBOBJ = $(LIBCPP:%.cpp=%.o)
TESTCPP = $(shell find test/ -name '*.cpp') TESTCPP = $(shell find test/ -name '*.cpp')
ALLLIB = $(shell find $(SRC) -name '*.cpp' -not -path "$(SRCPARSER)/*") $(shell find $(SRC) -name '*.h' -not -path "$(SRCPARSER)/*") ALLLIB = $(shell find $(SRC) -name '*.cpp' -not -path "$(SRCPARSER)/*") $(shell find $(SRC) -name '*.h' -not -path "$(SRCPARSER)/*")
ALLTEST = $(shell find test/lib/ -name '*.cpp') $(shell find test/lib/ -name '*.h') ALLTEST = $(shell find test/ -name '*.cpp') $(shell find test/ -name '*.h')
# compile & link flages # compile & link flages
CFLAGS = -std=c++11 -Wall -fPIC -g CFLAGS = -std=c++11 -Wall -fPIC -g

File diff suppressed because it is too large Load Diff

View File

@ -138,7 +138,7 @@ namespace hsql {
placeholders.push_back((Expr*) e); placeholders.push_back((Expr*) e);
} }
// Sort by col-id // Sort by col-id
std::sort(placeholders.begin(), placeholders.end(), [](Expr* i, Expr* j) -> bool { return (i->ival < j->ival); }); std::sort(placeholders.begin(), placeholders.end(), [](Expr * i, Expr * j) -> bool { return (i->ival < j->ival); });
// Set the placeholder id on the Expr. This replaces the previously stored column id // Set the placeholder id on the Expr. This replaces the previously stored column id
for (uintmax_t i = 0; i < placeholders.size(); ++i) placeholders[i]->ival = i; for (uintmax_t i = 0; i < placeholders.size(); ++i) placeholders[i]->ival = i;

View File

@ -0,0 +1,9 @@
-- http://www.sqlserver-dba.com/2011/09/this-is-a-followup-on-my-earlier-post-of-sql-server-test-data-generation-testing-tools-i-had-some-requests-for-my-set-up-pr.html
SELECT L_RETURNFLAG, L_LINESTATUS, SUM(L_QUANTITY) AS SUM_QTY,
SUM(L_EXTENDEDPRICE) AS SUM_BASE_PRICE, SUM(L_EXTENDEDPRICE*(1-L_DISCOUNT)) AS SUM_DISC_PRICE,
SUM(L_EXTENDEDPRICE*(1-L_DISCOUNT)*(1+L_TAX)) AS SUM_CHARGE, AVG(L_QUANTITY) AS AVG_QTY,
AVG(L_EXTENDEDPRICE) AS AVG_PRICE, AVG(L_DISCOUNT) AS AVG_DISC, COUNT(*) AS COUNT_ORDER
FROM LINEITEM
WHERE L_SHIPDATE <= dateadd(dd, -90, cast('1998-12-01' as datetime))
GROUP BY L_RETURNFLAG, L_LINESTATUS
ORDER BY L_RETURNFLAG,L_LINESTATUS

10
test/queries/tpc-h-02.sql Normal file
View File

@ -0,0 +1,10 @@
-- http://www.sqlserver-dba.com/2011/09/this-is-a-followup-on-my-earlier-post-of-sql-server-test-data-generation-testing-tools-i-had-some-requests-for-my-set-up-pr.html
SELECT TOP 100 S_ACCTBAL, S_NAME, N_NAME, P_PARTKEY, P_MFGR, S_ADDRESS, S_PHONE, S_COMMENT
FROM PART, SUPPLIER, PARTSUPP, NATION, REGION
WHERE P_PARTKEY = PS_PARTKEY AND S_SUPPKEY = PS_SUPPKEY AND P_SIZE = 15 AND
P_TYPE LIKE '%%BRASS' AND S_NATIONKEY = N_NATIONKEY AND N_REGIONKEY = R_REGIONKEY AND
R_NAME = 'EUROPE' AND
PS_SUPPLYCOST = (SELECT MIN(PS_SUPPLYCOST) FROM PARTSUPP, SUPPLIER, NATION, REGION
WHERE P_PARTKEY = PS_PARTKEY AND S_SUPPKEY = PS_SUPPKEY
AND S_NATIONKEY = N_NATIONKEY AND N_REGIONKEY = R_REGIONKEY AND R_NAME = 'EUROPE')
ORDER BY S_ACCTBAL DESC, N_NAME, S_NAME, P_PARTKEY

View File

@ -0,0 +1,7 @@
-- http://www.sqlserver-dba.com/2011/09/this-is-a-followup-on-my-earlier-post-of-sql-server-test-data-generation-testing-tools-i-had-some-requests-for-my-set-up-pr.html
SELECT TOP 10 L_ORDERKEY, SUM(L_EXTENDEDPRICE*(1-L_DISCOUNT)) AS REVENUE, O_ORDERDATE, O_SHIPPRIORITY
FROM CUSTOMER, ORDERS, LINEITEM
WHERE C_MKTSEGMENT = 'BUILDING' AND C_CUSTKEY = O_CUSTKEY AND L_ORDERKEY = O_ORDERKEY AND
O_ORDERDATE < '1995-03-15' AND L_SHIPDATE > '1995-03-15'
GROUP BY L_ORDERKEY, O_ORDERDATE, O_SHIPPRIORITY
ORDER BY REVENUE DESC, O_ORDERDATE;

View File

@ -0,0 +1,6 @@
-- http://www.sqlserver-dba.com/2011/09/this-is-a-followup-on-my-earlier-post-of-sql-server-test-data-generation-testing-tools-i-had-some-requests-for-my-set-up-pr.html
SELECT O_ORDERPRIORITY, COUNT(*) AS ORDER_COUNT FROM ORDERS
WHERE O_ORDERDATE >= '1993-07-01' AND O_ORDERDATE < dateadd(mm,3, cast('1993-07-01' as datetime))
AND EXISTS (SELECT * FROM LINEITEM WHERE L_ORDERKEY = O_ORDERKEY AND L_COMMITDATE < L_RECEIPTDATE)
GROUP BY O_ORDERPRIORITY
ORDER BY O_ORDERPRIORITY

View File

@ -0,0 +1,9 @@
-- http://www.sqlserver-dba.com/2011/09/this-is-a-followup-on-my-earlier-post-of-sql-server-test-data-generation-testing-tools-i-had-some-requests-for-my-set-up-pr.html
SELECT N_NAME, SUM(L_EXTENDEDPRICE*(1-L_DISCOUNT)) AS REVENUE
FROM CUSTOMER, ORDERS, LINEITEM, SUPPLIER, NATION, REGION
WHERE C_CUSTKEY = O_CUSTKEY AND L_ORDERKEY = O_ORDERKEY AND L_SUPPKEY = S_SUPPKEY
AND C_NATIONKEY = S_NATIONKEY AND S_NATIONKEY = N_NATIONKEY AND N_REGIONKEY = R_REGIONKEY
AND R_NAME = 'ASIA' AND O_ORDERDATE >= '1994-01-01'
AND O_ORDERDATE < DATEADD(YY, 1, cast('1994-01-01' as datetime))
GROUP BY N_NAME
ORDER BY REVENUE DESC

View File

@ -0,0 +1,5 @@
-- http://www.sqlserver-dba.com/2011/09/this-is-a-followup-on-my-earlier-post-of-sql-server-test-data-generation-testing-tools-i-had-some-requests-for-my-set-up-pr.html
SELECT SUM(L_EXTENDEDPRICE*L_DISCOUNT) AS REVENUE
FROM LINEITEM
WHERE L_SHIPDATE >= '1994-01-01' AND L_SHIPDATE < dateadd(yy, 1, cast('1994-01-01' as datetime))
AND L_DISCOUNT BETWEEN .06 - 0.01 AND .06 + 0.01 AND L_QUANTITY < 24

11
test/queries/tpc-h-07.sql Normal file
View File

@ -0,0 +1,11 @@
-- http://www.sqlserver-dba.com/2011/09/this-is-a-followup-on-my-earlier-post-of-sql-server-test-data-generation-testing-tools-i-had-some-requests-for-my-set-up-pr.html
SELECT SUPP_NATION, CUST_NATION, L_YEAR, SUM(VOLUME) AS REVENUE
FROM ( SELECT N1.N_NAME AS SUPP_NATION, N2.N_NAME AS CUST_NATION, datepart(yy, L_SHIPDATE) AS L_YEAR,
L_EXTENDEDPRICE*(1-L_DISCOUNT) AS VOLUME
FROM SUPPLIER, LINEITEM, ORDERS, CUSTOMER, NATION N1, NATION N2
WHERE S_SUPPKEY = L_SUPPKEY AND O_ORDERKEY = L_ORDERKEY AND C_CUSTKEY = O_CUSTKEY
AND S_NATIONKEY = N1.N_NATIONKEY AND C_NATIONKEY = N2.N_NATIONKEY AND ((N1.N_NAME = 'FRANCE' AND N2.N_NAME = 'GERMANY') OR
(N1.N_NAME = 'GERMANY' AND N2.N_NAME = 'FRANCE')) AND
L_SHIPDATE BETWEEN '1995-01-01' AND '1996-12-31' ) AS SHIPPING
GROUP BY SUPP_NATION, CUST_NATION, L_YEAR
ORDER BY SUPP_NATION, CUST_NATION, L_YEAR

10
test/queries/tpc-h-08.sql Normal file
View File

@ -0,0 +1,10 @@
-- http://www.sqlserver-dba.com/2011/09/this-is-a-followup-on-my-earlier-post-of-sql-server-test-data-generation-testing-tools-i-had-some-requests-for-my-set-up-pr.html
SELECT O_YEAR, SUM(CASE WHEN NATION = 'BRAZIL' THEN VOLUME ELSE 0 END)/SUM(VOLUME) AS MKT_SHARE
FROM (SELECT datepart(yy,O_ORDERDATE) AS O_YEAR, L_EXTENDEDPRICE*(1-L_DISCOUNT) AS VOLUME, N2.N_NAME AS NATION
FROM PART, SUPPLIER, LINEITEM, ORDERS, CUSTOMER, NATION N1, NATION N2, REGION
WHERE P_PARTKEY = L_PARTKEY AND S_SUPPKEY = L_SUPPKEY AND L_ORDERKEY = O_ORDERKEY
AND O_CUSTKEY = C_CUSTKEY AND C_NATIONKEY = N1.N_NATIONKEY AND
N1.N_REGIONKEY = R_REGIONKEY AND R_NAME = 'AMERICA' AND S_NATIONKEY = N2.N_NATIONKEY
AND O_ORDERDATE BETWEEN '1995-01-01' AND '1996-12-31' AND P_TYPE= 'ECONOMY ANODIZED STEEL') AS ALL_NATIONS
GROUP BY O_YEAR
ORDER BY O_YEAR

10
test/queries/tpc-h-09.sql Normal file
View File

@ -0,0 +1,10 @@
-- http://www.sqlserver-dba.com/2011/09/this-is-a-followup-on-my-earlier-post-of-sql-server-test-data-generation-testing-tools-i-had-some-requests-for-my-set-up-pr.html
SELECT NATION, O_YEAR, SUM(AMOUNT) AS SUM_PROFIT
FROM (SELECT N_NAME AS NATION, datepart(yy, O_ORDERDATE) AS O_YEAR,
L_EXTENDEDPRICE*(1-L_DISCOUNT)-PS_SUPPLYCOST*L_QUANTITY AS AMOUNT
FROM PART, SUPPLIER, LINEITEM, PARTSUPP, ORDERS, NATION
WHERE S_SUPPKEY = L_SUPPKEY AND PS_SUPPKEY= L_SUPPKEY AND PS_PARTKEY = L_PARTKEY AND
P_PARTKEY= L_PARTKEY AND O_ORDERKEY = L_ORDERKEY AND S_NATIONKEY = N_NATIONKEY AND
P_NAME LIKE '%%green%%') AS PROFIT
GROUP BY NATION, O_YEAR
ORDER BY NATION, O_YEAR DESC

View File

@ -0,0 +1,9 @@
-- http://www.sqlserver-dba.com/2011/09/this-is-a-followup-on-my-earlier-post-of-sql-server-test-data-generation-testing-tools-i-had-some-requests-for-my-set-up-pr.html
SELECT TOP 20 C_CUSTKEY, C_NAME, SUM(L_EXTENDEDPRICE*(1-L_DISCOUNT)) AS REVENUE, C_ACCTBAL,
N_NAME, C_ADDRESS, C_PHONE, C_COMMENT
FROM CUSTOMER, ORDERS, LINEITEM, NATION
WHERE C_CUSTKEY = O_CUSTKEY AND L_ORDERKEY = O_ORDERKEY AND O_ORDERDATE>= '1993-10-01' AND
O_ORDERDATE < dateadd(mm, 3, cast('1993-10-01' as datetime)) AND
L_RETURNFLAG = 'R' AND C_NATIONKEY = N_NATIONKEY
GROUP BY C_CUSTKEY, C_NAME, C_ACCTBAL, C_PHONE, N_NAME, C_ADDRESS, C_COMMENT
ORDER BY REVENUE DESC

View File

@ -46,7 +46,7 @@ TEST(SelectDistinctTest) {
TEST_PARSE_SINGLE_SQL( TEST_PARSE_SINGLE_SQL(
"SELECT DISTINCT grade, city FROM students;", "SELECT DISTINCT grade, city FROM students;",
kStmtSelect, kStmtSelect,
SelectStatement, SelectStatement,
result, result,
stmt); stmt);

View File

@ -13,96 +13,96 @@ using namespace hsql;
std::vector<std::string> readlines(std::string path) { std::vector<std::string> readlines(std::string path) {
std::ifstream infile(path); std::ifstream infile(path);
std::vector<std::string> lines; std::vector<std::string> lines;
std::string line; std::string line;
while (std::getline(infile, line)) { while (std::getline(infile, line)) {
std::istringstream iss(line); std::istringstream iss(line);
// Skip comments // Skip comments
if (line[0] == '#' || if (line[0] == '#' ||
(line[0] == '-' && line[1] == '-')) { (line[0] == '-' && line[1] == '-')) {
continue; continue;
}
lines.push_back(line);
} }
return lines;
lines.push_back(line);
}
return lines;
} }
#define STREQ(a, b) (std::string(a).compare(std::string(b)) == 0) #define STREQ(a, b) (std::string(a).compare(std::string(b)) == 0)
TEST(AutoGrammarTest) { TEST(AutoGrammarTest) {
const std::vector<std::string>& args = mt::Runtime::args(); const std::vector<std::string>& args = mt::Runtime::args();
if (args.size() <= 1) { if (args.size() <= 1) {
fprintf(stderr, "Usage: grammar_test [--false] [-f path] query, ...\n"); fprintf(stderr, "Usage: grammar_test [--false] [-f path] query, ...\n");
return; return;
} }
bool globalExpectFalse = false; bool globalExpectFalse = false;
bool useFile = false; bool useFile = false;
std::string filePath = ""; std::string filePath = "";
// Parse command line arguments
uint i = 1;
for (; i < args.size(); ++i) {
if (STREQ(args[i], "--false")) globalExpectFalse = true;
else if (STREQ(args[i], "-f")) {
useFile = true;
filePath = args[++i];
} else {
break;
}
}
// Parse command line arguments
// Read list of queries for this rest uint i = 1;
std::vector<std::string> queries; for (; i < args.size(); ++i) {
if (useFile) { if (STREQ(args[i], "--false")) globalExpectFalse = true;
queries = readlines(filePath); else if (STREQ(args[i], "-f")) {
useFile = true;
filePath = args[++i];
} else { } else {
for (; i < args.size(); ++i) queries.push_back(args[i]); break;
}
}
// Read list of queries for this rest
std::vector<std::string> queries;
if (useFile) {
queries = readlines(filePath);
} else {
for (; i < args.size(); ++i) queries.push_back(args[i]);
}
// Execute queries
int numFailed = 0;
for (std::string sql : queries) {
bool expectFalse = globalExpectFalse;
if (sql.at(0) == '!') {
expectFalse = !expectFalse;
sql = sql.substr(1);
} }
// Measuring the parsing time
std::chrono::time_point<std::chrono::system_clock> start, end;
start = std::chrono::system_clock::now();
// Execute queries // Parsing
int numFailed = 0; SQLParserResult* result = SQLParser::parseSQLString(sql.c_str());
for (std::string sql : queries) {
bool expectFalse = globalExpectFalse;
if (sql.at(0) == '!') {
expectFalse = !expectFalse;
sql = sql.substr(1);
}
// Measuring the parsing time end = std::chrono::system_clock::now();
std::chrono::time_point<std::chrono::system_clock> start, end; std::chrono::duration<double> elapsed_seconds = end - start;
start = std::chrono::system_clock::now(); double us = elapsed_seconds.count() * 1000 * 1000;
// Parsing if (expectFalse == result->isValid()) {
SQLParserResult* result = SQLParser::parseSQLString(sql.c_str()); printf("\033[0;31m{ failed}\033[0m\n");
printf("\t\033[0;31m%s (L%d:%d)\n\033[0m", result->errorMsg(), result->errorLine(), result->errorColumn());
end = std::chrono::system_clock::now(); printf("\t%s\n", sql.c_str());
std::chrono::duration<double> elapsed_seconds = end-start; numFailed++;
double us = elapsed_seconds.count() * 1000 * 1000;
if (expectFalse == result->isValid()) {
printf("\033[0;31m{ failed}\033[0m\n");
printf("\t\033[0;31m%s (L%d:%d)\n\033[0m", result->errorMsg(), result->errorLine(), result->errorColumn());
printf("\t%s\n", sql.c_str());
numFailed++;
} else {
// TODO: indicate whether expectFalse was set
printf("\033[0;32m{ ok} (%.1fus)\033[0m %s\n", us, sql.c_str());
}
delete result;
}
if (numFailed == 0) {
printf("\033[0;32m{ ok} \033[0mAll %lu grammar tests completed successfully!\n", queries.size());
} else { } else {
fprintf(stderr, "\033[0;31m{ failed} \033[0mSome grammar tests failed! %d out of %lu tests failed!\n", numFailed, queries.size()); // TODO: indicate whether expectFalse was set
printf("\033[0;32m{ ok} (%.1fus)\033[0m %s\n", us, sql.c_str());
} }
ASSERT_EQ(numFailed, 0);
delete result;
}
if (numFailed == 0) {
printf("\033[0;32m{ ok} \033[0mAll %lu grammar tests completed successfully!\n", queries.size());
} else {
fprintf(stderr, "\033[0;31m{ failed} \033[0mSome grammar tests failed! %d out of %lu tests failed!\n", numFailed, queries.size());
}
ASSERT_EQ(numFailed, 0);
} }

View File

@ -11,160 +11,161 @@ using namespace hsql;
TEST(DeleteStatementTest) { TEST(DeleteStatementTest) {
const SQLParserResult* result = SQLParser::parseSQLString("DELETE FROM students WHERE grade > 2.0;"); const SQLParserResult* result = SQLParser::parseSQLString("DELETE FROM students WHERE grade > 2.0;");
ASSERT(result->isValid()); ASSERT(result->isValid());
ASSERT_EQ(result->size(), 1); ASSERT_EQ(result->size(), 1);
ASSERT(result->getStatement(0)->type() == kStmtDelete); ASSERT(result->getStatement(0)->type() == kStmtDelete);
const DeleteStatement* stmt = (const DeleteStatement*) result->getStatement(0); const DeleteStatement* stmt = (const DeleteStatement*) result->getStatement(0);
ASSERT_STREQ(stmt->tableName, "students"); ASSERT_STREQ(stmt->tableName, "students");
ASSERT_NOTNULL(stmt->expr); ASSERT_NOTNULL(stmt->expr);
ASSERT(stmt->expr->isType(kExprOperator)); ASSERT(stmt->expr->isType(kExprOperator));
ASSERT_STREQ(stmt->expr->expr->name, "grade"); ASSERT_STREQ(stmt->expr->expr->name, "grade");
ASSERT_EQ(stmt->expr->expr2->fval, 2.0); ASSERT_EQ(stmt->expr->expr2->fval, 2.0);
delete result; delete result;
} }
TEST(CreateStatementTest) { TEST(CreateStatementTest) {
const SQLParserResult* result = SQLParser::parseSQLString("CREATE TABLE students (name TEXT, student_number INT, city INTEGER, grade DOUBLE)"); const SQLParserResult* result = SQLParser::parseSQLString("CREATE TABLE students (name TEXT, student_number INT, city INTEGER, grade DOUBLE)");
ASSERT(result->isValid()); ASSERT(result->isValid());
ASSERT_EQ(result->size(), 1); ASSERT_EQ(result->size(), 1);
ASSERT_EQ(result->getStatement(0)->type(), kStmtCreate); ASSERT_EQ(result->getStatement(0)->type(), kStmtCreate);
const CreateStatement* stmt = (const CreateStatement*) result->getStatement(0); const CreateStatement* stmt = (const CreateStatement*) result->getStatement(0);
ASSERT_EQ(stmt->type, CreateStatement::kTable); ASSERT_EQ(stmt->type, CreateStatement::kTable);
ASSERT_STREQ(stmt->tableName, "students"); ASSERT_STREQ(stmt->tableName, "students");
ASSERT_NOTNULL(stmt->columns); ASSERT_NOTNULL(stmt->columns);
ASSERT_EQ(stmt->columns->size(), 4); ASSERT_EQ(stmt->columns->size(), 4);
ASSERT_STREQ(stmt->columns->at(0)->name, "name"); ASSERT_STREQ(stmt->columns->at(0)->name, "name");
ASSERT_STREQ(stmt->columns->at(1)->name, "student_number"); ASSERT_STREQ(stmt->columns->at(1)->name, "student_number");
ASSERT_STREQ(stmt->columns->at(2)->name, "city"); ASSERT_STREQ(stmt->columns->at(2)->name, "city");
ASSERT_STREQ(stmt->columns->at(3)->name, "grade"); ASSERT_STREQ(stmt->columns->at(3)->name, "grade");
ASSERT_EQ(stmt->columns->at(0)->type, ColumnDefinition::TEXT); ASSERT_EQ(stmt->columns->at(0)->type, ColumnDefinition::TEXT);
ASSERT_EQ(stmt->columns->at(1)->type, ColumnDefinition::INT); ASSERT_EQ(stmt->columns->at(1)->type, ColumnDefinition::INT);
ASSERT_EQ(stmt->columns->at(2)->type, ColumnDefinition::INT); ASSERT_EQ(stmt->columns->at(2)->type, ColumnDefinition::INT);
ASSERT_EQ(stmt->columns->at(3)->type, ColumnDefinition::DOUBLE); ASSERT_EQ(stmt->columns->at(3)->type, ColumnDefinition::DOUBLE);
delete result; delete result;
} }
TEST(UpdateStatementTest) { TEST(UpdateStatementTest) {
const SQLParserResult* result = SQLParser::parseSQLString("UPDATE students SET grade = 5.0, name = 'test' WHERE name = 'Max Mustermann';"); const SQLParserResult* result = SQLParser::parseSQLString("UPDATE students SET grade = 5.0, name = 'test' WHERE name = 'Max Mustermann';");
ASSERT(result->isValid()); ASSERT(result->isValid());
ASSERT_EQ(result->size(), 1); ASSERT_EQ(result->size(), 1);
ASSERT_EQ(result->getStatement(0)->type(), kStmtUpdate); ASSERT_EQ(result->getStatement(0)->type(), kStmtUpdate);
const UpdateStatement* stmt = (const UpdateStatement*) result->getStatement(0); const UpdateStatement* stmt = (const UpdateStatement*) result->getStatement(0);
ASSERT_NOTNULL(stmt->table); ASSERT_NOTNULL(stmt->table);
ASSERT_STREQ(stmt->table->name, "students"); ASSERT_STREQ(stmt->table->name, "students");
ASSERT_NOTNULL(stmt->updates);
ASSERT_EQ(stmt->updates->size(), 2);
ASSERT_STREQ(stmt->updates->at(0)->column, "grade");
ASSERT_STREQ(stmt->updates->at(1)->column, "name");
ASSERT(stmt->updates->at(0)->value->isType(kExprLiteralFloat));
ASSERT(stmt->updates->at(1)->value->isType(kExprLiteralString));
ASSERT_EQ(stmt->updates->at(0)->value->fval, 5.0);
ASSERT_STREQ(stmt->updates->at(1)->value->name, "test");
ASSERT_NOTNULL(stmt->where); ASSERT_NOTNULL(stmt->updates);
ASSERT(stmt->where->isType(kExprOperator)); ASSERT_EQ(stmt->updates->size(), 2);
ASSERT(stmt->where->isSimpleOp('=')); ASSERT_STREQ(stmt->updates->at(0)->column, "grade");
ASSERT_STREQ(stmt->where->expr->name, "name"); ASSERT_STREQ(stmt->updates->at(1)->column, "name");
ASSERT_STREQ(stmt->where->expr2->name, "Max Mustermann");\ ASSERT(stmt->updates->at(0)->value->isType(kExprLiteralFloat));
ASSERT(stmt->updates->at(1)->value->isType(kExprLiteralString));
ASSERT_EQ(stmt->updates->at(0)->value->fval, 5.0);
ASSERT_STREQ(stmt->updates->at(1)->value->name, "test");
delete result; ASSERT_NOTNULL(stmt->where);
ASSERT(stmt->where->isType(kExprOperator));
ASSERT(stmt->where->isSimpleOp('='));
ASSERT_STREQ(stmt->where->expr->name, "name");
ASSERT_STREQ(stmt->where->expr2->name, "Max Mustermann");
\
delete result;
} }
TEST(InsertStatementTest) { TEST(InsertStatementTest) {
TEST_PARSE_SINGLE_SQL( TEST_PARSE_SINGLE_SQL(
"INSERT INTO students VALUES ('Max Mustermann', 12345, 'Musterhausen', 2.0)", "INSERT INTO students VALUES ('Max Mustermann', 12345, 'Musterhausen', 2.0)",
kStmtInsert, kStmtInsert,
InsertStatement, InsertStatement,
result, result,
stmt); stmt);
ASSERT_EQ(stmt->values->size(), 4); ASSERT_EQ(stmt->values->size(), 4);
// TODO // TODO
delete result; delete result;
} }
TEST(DropTableStatementTest) { TEST(DropTableStatementTest) {
TEST_PARSE_SINGLE_SQL( TEST_PARSE_SINGLE_SQL(
"DROP TABLE students", "DROP TABLE students",
kStmtDrop, kStmtDrop,
DropStatement, DropStatement,
result, result,
stmt); stmt);
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");
delete result; delete result;
} }
TEST(PrepareStatementTest) { TEST(PrepareStatementTest) {
std::string query = "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 = ?;"
"};" "};"
"PREPARE stmt: SELECT * FROM data WHERE c1 = ?;" "PREPARE stmt: SELECT * FROM data WHERE c1 = ?;"
"DEALLOCATE PREPARE stmt;"; "DEALLOCATE PREPARE stmt;";
TEST_PARSE_SQL_QUERY(query, result, 3); TEST_PARSE_SQL_QUERY(query, result, 3);
TEST_CAST_STMT(result, 0, kStmtPrepare, PrepareStatement, prep1); TEST_CAST_STMT(result, 0, kStmtPrepare, PrepareStatement, prep1);
TEST_CAST_STMT(result, 1, kStmtPrepare, PrepareStatement, prep2); TEST_CAST_STMT(result, 1, kStmtPrepare, PrepareStatement, prep2);
TEST_CAST_STMT(result, 2, kStmtDrop, DropStatement, drop); TEST_CAST_STMT(result, 2, kStmtDrop, DropStatement, drop);
// Prepare Statement #1 // Prepare Statement #1
ASSERT_STREQ(prep1->name, "test"); ASSERT_STREQ(prep1->name, "test");
ASSERT_EQ(prep1->placeholders.size(), 3); ASSERT_EQ(prep1->placeholders.size(), 3);
ASSERT_EQ(prep1->query->size(), 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);
ASSERT(insert->values->at(0)->isType(kExprPlaceholder)); TEST_CAST_STMT(prep1->query, 0, kStmtInsert, InsertStatement, insert);
ASSERT(select->selectList->at(0)->isType(kExprPlaceholder)); TEST_CAST_STMT(prep1->query, 1, kStmtSelect, SelectStatement, select);
ASSERT(select->whereClause->expr2->isType(kExprPlaceholder));
// Check IDs of placeholders ASSERT(insert->values->at(0)->isType(kExprPlaceholder));
ASSERT_EQ(insert->values->at(0)->ival, 0); ASSERT(select->selectList->at(0)->isType(kExprPlaceholder));
ASSERT_EQ(insert->values->at(0), prep1->placeholders[0]); ASSERT(select->whereClause->expr2->isType(kExprPlaceholder));
ASSERT_EQ(select->selectList->at(0)->ival, 1); // Check IDs of placeholders
ASSERT_EQ(select->selectList->at(0), prep1->placeholders[1]); ASSERT_EQ(insert->values->at(0)->ival, 0);
ASSERT_EQ(insert->values->at(0), prep1->placeholders[0]);
ASSERT_EQ(select->whereClause->expr2->ival, 2); ASSERT_EQ(select->selectList->at(0)->ival, 1);
ASSERT_EQ(select->whereClause->expr2, prep1->placeholders[2]); ASSERT_EQ(select->selectList->at(0), prep1->placeholders[1]);
// Prepare Statement #2 ASSERT_EQ(select->whereClause->expr2->ival, 2);
ASSERT_STREQ(prep2->name, "stmt"); ASSERT_EQ(select->whereClause->expr2, prep1->placeholders[2]);
ASSERT_EQ(prep2->placeholders.size(), 1);
// Deallocate Statement // Prepare Statement #2
ASSERT_EQ(drop->type, DropStatement::kPreparedStatement); ASSERT_STREQ(prep2->name, "stmt");
ASSERT_STREQ(drop->name, "stmt"); ASSERT_EQ(prep2->placeholders.size(), 1);
delete result; // Deallocate Statement
ASSERT_EQ(drop->type, DropStatement::kPreparedStatement);
ASSERT_STREQ(drop->name, "stmt");
delete result;
} }
TEST(ExecuteStatementTest) { TEST(ExecuteStatementTest) {
TEST_PARSE_SINGLE_SQL("EXECUTE test(1, 2);", kStmtExecute, ExecuteStatement, result, stmt); TEST_PARSE_SINGLE_SQL("EXECUTE test(1, 2);", kStmtExecute, ExecuteStatement, result, stmt);
ASSERT_STREQ(stmt->name, "test"); ASSERT_STREQ(stmt->name, "test");
ASSERT_EQ(stmt->parameters->size(), 2); ASSERT_EQ(stmt->parameters->size(), 2);
delete result; delete result;
} }
TEST_MAIN(); TEST_MAIN();

43
test/tpc_h_tests.cpp Normal file
View File

@ -0,0 +1,43 @@
#include "thirdparty/microtest/microtest.h"
#include "sql_asserts.h"
#include "SQLParser.h"
#include "sqlhelper.h"
#include <string>
#include <fstream>
#include <streambuf>
#include <iostream>
using namespace hsql;
TEST(TPCHQueryTests) {
std::vector<std::string> files = {
"test/queries/tpc-h-01.sql",
"test/queries/tpc-h-02.sql",
"test/queries/tpc-h-03.sql",
"test/queries/tpc-h-04.sql",
"test/queries/tpc-h-05.sql",
"test/queries/tpc-h-06.sql",
"test/queries/tpc-h-07.sql",
"test/queries/tpc-h-08.sql",
"test/queries/tpc-h-09.sql",
"test/queries/tpc-h-10.sql"
};
int testsFailed = 0;
for (const std::string& file_path : files) {
std::ifstream t(file_path.c_str());
std::string query((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());
SQLParserResult* result = SQLParser::parseSQLString(query.c_str());
if (!result->isValid()) {
mt::printFailed(file_path.c_str());
printf("%s %s (L%d:%d)%s\n", mt::red(), result->errorMsg(), result->errorLine(), result->errorColumn(), mt::def());
++testsFailed;
} else {
mt::printOk(file_path.c_str());
}
}
ASSERT_EQ(testsFailed, 0);
}