/* Copyright (C) 2014 InfiniDB, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /*************************************************************************** * dhill@srvengcm1.calpont.com * * Purpose: dll package tester * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include "sqlparser.h" #include "messagequeue.h" using namespace std; using namespace ddlpackage; using namespace messageqcpp; std::string itoa(const int i); bool parse_file(char* fileName) { SqlFileParser parser; parser.Parse(fileName); return parser.Good(); } class ParserTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(ParserTest); CPPUNIT_TEST(atac01); CPPUNIT_TEST(atac05); CPPUNIT_TEST(atac09); CPPUNIT_TEST(atmcdd01); CPPUNIT_TEST(atrt01); CPPUNIT_TEST(ct02); CPPUNIT_TEST(ct06); CPPUNIT_TEST(ct10); CPPUNIT_TEST(dt02); CPPUNIT_TEST(atac02); CPPUNIT_TEST(atac06); CPPUNIT_TEST(atatc01); CPPUNIT_TEST(atmcsd01); CPPUNIT_TEST(ci01); CPPUNIT_TEST(ct03); CPPUNIT_TEST(ct07); CPPUNIT_TEST(ct11); CPPUNIT_TEST(empty_stmt); CPPUNIT_TEST(atac03); CPPUNIT_TEST(atac07); CPPUNIT_TEST(atdc01); CPPUNIT_TEST(atdc02); CPPUNIT_TEST(atdc03); CPPUNIT_TEST(atmct01); CPPUNIT_TEST(atmct02); CPPUNIT_TEST(comment); CPPUNIT_TEST(ct04); CPPUNIT_TEST(ct08); CPPUNIT_TEST(di01); CPPUNIT_TEST(atac04); CPPUNIT_TEST(atac08); CPPUNIT_TEST(atdtc01); CPPUNIT_TEST(atdtc02); CPPUNIT_TEST(atrc01); CPPUNIT_TEST(ct01); CPPUNIT_TEST(ct05); CPPUNIT_TEST(ct09); CPPUNIT_TEST(dt01); CPPUNIT_TEST(foo); CPPUNIT_TEST_SUITE_END(); private: public: void setUp() { } void tearDown() { } void foo() { SqlParser p; p.Parse("drop table foo"); cout << p.GetParseTree(); } void atac01() { CPPUNIT_ASSERT(parse_file("sql/atac01.sql")); } void atac05() { CPPUNIT_ASSERT(parse_file("sql/atac05.sql")); } void atac09() { CPPUNIT_ASSERT(parse_file("sql/atac09.sql")); } void atmcdd01() { CPPUNIT_ASSERT(parse_file("sql/atmcdd01.sql")); } void atrt01() { CPPUNIT_ASSERT(parse_file("sql/atrt01.sql")); } void ct02() { CPPUNIT_ASSERT(parse_file("sql/ct02.sql")); } void ct06() { CPPUNIT_ASSERT(parse_file("sql/ct06.sql")); } void ct10() { CPPUNIT_ASSERT(parse_file("sql/ct10.sql")); } void dt02() { CPPUNIT_ASSERT(parse_file("sql/dt02.sql")); } void atac02() { CPPUNIT_ASSERT(parse_file("sql/atac02.sql")); } void atac06() { CPPUNIT_ASSERT(parse_file("sql/atac06.sql")); } void atatc01() { CPPUNIT_ASSERT(parse_file("sql/atatc01.sql")); } void atmcsd01() { CPPUNIT_ASSERT(parse_file("sql/atmcsd01.sql")); } void ci01() { CPPUNIT_ASSERT(parse_file("sql/ci01.sql")); } void ct03() { CPPUNIT_ASSERT(parse_file("sql/ct03.sql")); } void ct07() { CPPUNIT_ASSERT(parse_file("sql/ct07.sql")); } void ct11() { CPPUNIT_ASSERT(parse_file("sql/ct11.sql")); } void empty_stmt() { CPPUNIT_ASSERT(parse_file("sql/empty-stmt.sql")); } void atac03() { CPPUNIT_ASSERT(parse_file("sql/atac03.sql")); } void atac07() { CPPUNIT_ASSERT(parse_file("sql/atac07.sql")); } void atdc01() { CPPUNIT_ASSERT(parse_file("sql/atdc01.sql")); } void atdc02() { CPPUNIT_ASSERT(parse_file("sql/atdc02.sql")); } void atdc03() { CPPUNIT_ASSERT(parse_file("sql/atdc03.sql")); } void atmct01() { CPPUNIT_ASSERT(parse_file("sql/atmct01.sql")); } void atmct02() { CPPUNIT_ASSERT(parse_file("sql/atmct02.sql")); } void comment() { CPPUNIT_ASSERT(parse_file("sql/comment.sql")); } void ct04() { CPPUNIT_ASSERT(parse_file("sql/ct04.sql")); } void ct08() { CPPUNIT_ASSERT(parse_file("sql/ct08.sql")); } void di01() { CPPUNIT_ASSERT(parse_file("sql/di01.sql")); } void atac04() { CPPUNIT_ASSERT(parse_file("sql/atac04.sql")); } void atac08() { CPPUNIT_ASSERT(parse_file("sql/atac08.sql")); } void atdtc01() { CPPUNIT_ASSERT(parse_file("sql/atdtc01.sql")); } void atdtc02() { CPPUNIT_ASSERT(parse_file("sql/atdtc02.sql")); } void atrc01() { CPPUNIT_ASSERT(parse_file("sql/atrc01.sql")); } void ct01() { CPPUNIT_ASSERT(parse_file("sql/ct01.sql")); } void ct05() { CPPUNIT_ASSERT(parse_file("sql/ct05.sql")); } void ct09() { CPPUNIT_ASSERT(parse_file("sql/ct09.sql")); } void dt01() { CPPUNIT_ASSERT(parse_file("sql/dt01.sql")); } }; template void u_sertest(T* x) { ByteStream bs; stringstream s1, s2; auto_ptr y(new T); x->serialize(bs); y->unserialize(bs); s1 << *x; s2 << *y; cout << "String Compare" << endl; cout << "------------------" << endl; cout << s1.str() << endl << s2.str() << endl; cout << "------------------" << endl; CPPUNIT_ASSERT(s1.str() == s2.str()); } /** @brief Just like u_sertest except that a typecode is pulled off the ByteStream before the unserialize. */ template void t_sertest(T* x) { ByteStream bs; stringstream s1, s2; auto_ptr y(new T); x->serialize(bs); quadbyte type; bs >> type; y->unserialize(bs); s1 << *x; s2 << *y; cout << "String Compare" << endl; cout << "------------------" << endl; cout << s1.str() << endl << s2.str() << endl; cout << "------------------" << endl; CPPUNIT_ASSERT(s1.str() == s2.str()); } class SerializeTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(SerializeTest); CPPUNIT_TEST(qname); CPPUNIT_TEST(columntype); CPPUNIT_TEST(columndefaultvalue); CPPUNIT_TEST(columnconstraintdef); CPPUNIT_TEST(columndef_01); CPPUNIT_TEST(referentialaction); CPPUNIT_TEST(tablecheckconstraint); CPPUNIT_TEST(tableuniqueconstraint); CPPUNIT_TEST(tableprimarykeyconstraint); CPPUNIT_TEST(tablereferencesconstraint); CPPUNIT_TEST(tabledef); CPPUNIT_TEST(createtable); CPPUNIT_TEST(droptable); CPPUNIT_TEST(createindex); CPPUNIT_TEST(dropindex); CPPUNIT_TEST(altertableaddcolumn); CPPUNIT_TEST(altertableaddcolumns); CPPUNIT_TEST(altertabledropcolumns); CPPUNIT_TEST(altertableaddtableconstraint); CPPUNIT_TEST(altertabledropcolumn); CPPUNIT_TEST(altertablesetcolumndefault); CPPUNIT_TEST(altertabledropcolumndefault); CPPUNIT_TEST(altertabledroptableconstraint); CPPUNIT_TEST(altertablerenametable); CPPUNIT_TEST(altertablemodifycolumntype); CPPUNIT_TEST(altertablerenamecolumn); CPPUNIT_TEST_SUITE_END(); private: public: void setUp() { } void tearDown() { } void altertablerenamecolumn() { SqlFileParser p; p.Parse("sql/atrc01.sql"); if (p.Good()) { const ParseTree& stmts = p.GetParseTree(); AlterTableStatement* stmt = dynamic_cast(stmts[0]); CPPUNIT_ASSERT(stmt); t_sertest(stmt); } } void altertablemodifycolumntype() { SqlFileParser p; p.Parse("sql/atmct01.sql"); if (p.Good()) { const ParseTree& stmts = p.GetParseTree(); AlterTableStatement* stmt = dynamic_cast(stmts[0]); CPPUNIT_ASSERT(stmt); t_sertest(stmt); } } void altertablerenametable() { SqlFileParser p; p.Parse("sql/atrt01.sql"); if (p.Good()) { const ParseTree& stmts = p.GetParseTree(); AlterTableStatement* stmt = dynamic_cast(stmts[0]); CPPUNIT_ASSERT(stmt); t_sertest(stmt); } } void altertabledroptableconstraint() { SqlFileParser p; p.Parse("sql/atdtc01.sql"); if (p.Good()) { const ParseTree& stmts = p.GetParseTree(); AlterTableStatement* stmt = dynamic_cast(stmts[0]); CPPUNIT_ASSERT(stmt); t_sertest(stmt); } } void altertabledropcolumndefault() { SqlFileParser p; p.Parse("sql/atmcdd01.sql"); if (p.Good()) { const ParseTree& stmts = p.GetParseTree(); AlterTableStatement* stmt = dynamic_cast(stmts[0]); CPPUNIT_ASSERT(stmt); t_sertest(stmt); } } void altertablesetcolumndefault() { SqlFileParser p; p.Parse("sql/atmcsd01.sql"); if (p.Good()) { const ParseTree& stmts = p.GetParseTree(); AlterTableStatement* stmt = dynamic_cast(stmts[0]); CPPUNIT_ASSERT(stmt); t_sertest(stmt); } } void altertabledropcolumn() { SqlFileParser p; p.Parse("sql/atdc01.sql"); if (p.Good()) { const ParseTree& stmts = p.GetParseTree(); AlterTableStatement* stmt = dynamic_cast(stmts[0]); CPPUNIT_ASSERT(stmt); t_sertest(stmt); } } void altertableaddtableconstraint() { SqlFileParser p; p.Parse("sql/atatc01.sql"); if (p.Good()) { const ParseTree& stmts = p.GetParseTree(); AlterTableStatement* stmt = dynamic_cast(stmts[0]); CPPUNIT_ASSERT(stmt); t_sertest(stmt); } } void altertableaddcolumn() { cout << "Serialize test: AtaAddColumn" << endl; auto_ptr ata(new AtaAddColumn); vector files; files.push_back("sql/ct01.sql"); files.push_back("sql/ct02.sql"); files.push_back("sql/ct03.sql"); files.push_back("sql/ct04.sql"); files.push_back("sql/ct05.sql"); files.push_back("sql/ct06.sql"); files.push_back("sql/ct07.sql"); files.push_back("sql/ct08.sql"); files.push_back("sql/ct09.sql"); files.push_back("sql/ct10.sql"); files.push_back("sql/ct11.sql"); vector::const_iterator itr; for (itr = files.begin(); itr != files.end(); ++itr) { SqlFileParser p; p.Parse(*itr); if (p.Good()) { const ParseTree& stmts = p.GetParseTree(); CreateTableStatement* ct = dynamic_cast(stmts[0]); CPPUNIT_ASSERT(ct); ColumnDefList* columns = &(ct->fTableDef->fColumns); ColumnDefList::const_iterator itr; for (itr = columns->begin(); itr != columns->end(); ++itr) { ata->fColumnDef = *itr; t_sertest(ata.get()); // We borrowed the column def from the parse // tree. Null it to avoid double free. ata->fColumnDef = 0; } } } } void altertableaddcolumns() { cout << "Serialize test: AtaAddColumnS" << endl; auto_ptr ata(new AtaAddColumns); vector files; files.push_back("sql/ct01.sql"); files.push_back("sql/ct02.sql"); files.push_back("sql/ct03.sql"); files.push_back("sql/ct04.sql"); files.push_back("sql/ct05.sql"); files.push_back("sql/ct06.sql"); files.push_back("sql/ct07.sql"); files.push_back("sql/ct08.sql"); files.push_back("sql/ct09.sql"); files.push_back("sql/ct10.sql"); files.push_back("sql/ct11.sql"); vector::const_iterator itr; for (itr = files.begin(); itr != files.end(); ++itr) { SqlFileParser p; p.Parse(*itr); if (p.Good()) { const ParseTree& stmts = p.GetParseTree(); CreateTableStatement* ct = dynamic_cast(stmts[0]); CPPUNIT_ASSERT(ct); ata->fColumns = ct->fTableDef->fColumns; t_sertest(ata.get()); // We borrowed the column defs from the parse // tree. Null it to avoid double free. ata->fColumns.clear(); } } } void altertabledropcolumns() { ColumnNameList* names = new ColumnNameList; names->push_back("c1"); names->push_back("c2"); auto_ptr stmt(new AtaDropColumns(names)); t_sertest(stmt.get()); } void qname() { cout << "Serialize test: QualifiedName" << endl; auto_ptr name(new QualifiedName("one", "two", "three")); u_sertest(name.get()); } void columntype() { cout << "Serialize test: ColumnType" << endl; auto_ptr type(new ColumnType); type->fType = 1; type->fLength = 2; type->fPrecision = 3; type->fScale = 4; type->fWithTimezone = true; u_sertest(type.get()); } void columndefaultvalue() { cout << "Serialize test: ColumnDefaultValue" << endl; auto_ptr dval(new ColumnDefaultValue); dval->fNull = false; dval->fValue = "1.234"; u_sertest(dval.get()); } void columnconstraintdef() { cout << "Serialize test: ColumnConstraintDef" << endl; auto_ptr con(new ColumnConstraintDef); con->fDeferrable = true; con->fCheckTime = DDL_INITIALLY_DEFERRED; con->fConstraintType = DDL_CHECK; con->fCheck = "thecheck"; u_sertest(con.get()); } /** @brief Can we serialize ColumDefs? * * Here we leverage the parser and the ostream operators for * parser objects to test serialization for ColumnDefs. We use * the parser to build parse trees for some create table * statements. Then we push the ColumnDefs through a ByteStream * and compare the results as strings. In other words, if C is a * ColumnDef in the parser constructed tree, we write C to the * ByteStream and then unserialize it back out making a new ColumnDef, * C'. We then format C and C' to respective stringstreams and * then compare the strings. If they are equal, chances are good * the serialization is OK. */ void columndef_01() { cout << "columndef_01" << endl; vector files; files.push_back("sql/ct01.sql"); files.push_back("sql/ct02.sql"); files.push_back("sql/ct03.sql"); files.push_back("sql/ct04.sql"); files.push_back("sql/ct05.sql"); files.push_back("sql/ct06.sql"); files.push_back("sql/ct07.sql"); files.push_back("sql/ct08.sql"); files.push_back("sql/ct09.sql"); files.push_back("sql/ct10.sql"); files.push_back("sql/ct11.sql"); vector::const_iterator itr; for (itr = files.begin(); itr != files.end(); ++itr) { cout << "* * * Checking columndef serialization for " << *itr << endl; SqlFileParser p; p.Parse(*itr); if (p.Good()) { const ParseTree& stmts = p.GetParseTree(); CreateTableStatement* ct = dynamic_cast(stmts[0]); CPPUNIT_ASSERT(ct); cout << "Parsed CreateTable:" << endl; cout << *ct << endl; ColumnDefList* columns = &(ct->fTableDef->fColumns); ColumnDefList::const_iterator itr; for (itr = columns->begin(); itr != columns->end(); ++itr) { u_sertest(*itr); } } } } void referentialaction() { cout << "Serialize test: ReferentialAction" << endl; auto_ptr ref(new ReferentialAction); ref->fOnUpdate = DDL_CASCADE; ref->fOnDelete = DDL_SET_NULL; u_sertest(ref.get()); } void tablecheckconstraint() { cout << "Serialize test: TableCheckConstraintDef" << endl; auto_ptr tc(new TableCheckConstraintDef); tc->fName = "fooby"; tc->fCheck = "check constraint text"; u_sertest(tc.get()); } void tableuniqueconstraint() { cout << "Serialize test: TableUniqueConstraintDef" << endl; auto_ptr tc(new TableUniqueConstraintDef); tc->fName = "fooby"; tc->fColumnNameList.push_back("C1"); tc->fColumnNameList.push_back("C2"); tc->fColumnNameList.push_back("C3"); u_sertest(tc.get()); } void tableprimarykeyconstraint() { cout << "Serialize test: TablePrimaryKeyConstraintDef" << endl; auto_ptr tc(new TablePrimaryKeyConstraintDef); tc->fName = "fooby"; tc->fColumnNameList.push_back("C1"); tc->fColumnNameList.push_back("C2"); tc->fColumnNameList.push_back("C3"); u_sertest(tc.get()); } void tablereferencesconstraint() { cout << "Serialize test: TableReferencesConstraintDef" << endl; auto_ptr tc(new TableReferencesConstraintDef); tc->fName = "fooby"; tc->fColumns.push_back("C1"); tc->fColumns.push_back("C2"); tc->fColumns.push_back("C3"); QualifiedName* qname = new QualifiedName; qname->fCatalog = ""; qname->fSchema = "calpont"; qname->fName = "table_fooby"; tc->fTableName = qname; tc->fForeignColumns.push_back("F1"); tc->fForeignColumns.push_back("F2"); tc->fForeignColumns.push_back("F3"); tc->fMatchType = DDL_FULL; ReferentialAction* ref = new ReferentialAction; ref->fOnUpdate = DDL_CASCADE; ref->fOnDelete = DDL_NO_ACTION; tc->fRefAction = ref; u_sertest(tc.get()); } void tabledef() { cout << "tabledef" << endl; vector files; files.push_back("sql/ct01.sql"); files.push_back("sql/ct02.sql"); files.push_back("sql/ct03.sql"); files.push_back("sql/ct04.sql"); files.push_back("sql/ct05.sql"); files.push_back("sql/ct06.sql"); files.push_back("sql/ct07.sql"); files.push_back("sql/ct08.sql"); files.push_back("sql/ct09.sql"); files.push_back("sql/ct10.sql"); files.push_back("sql/ct11.sql"); vector::const_iterator itr; for (itr = files.begin(); itr != files.end(); ++itr) { cout << "* * * Checking tabledef serialization for " << *itr << endl; SqlFileParser p; p.Parse(*itr); if (p.Good()) { const ParseTree& stmts = p.GetParseTree(); CreateTableStatement* ct = dynamic_cast(stmts[0]); CPPUNIT_ASSERT(ct); cout << "Parsed CreateTable:" << endl; cout << *ct << endl; u_sertest(ct->fTableDef); } } } void createtable() { vector files; files.push_back("sql/ct01.sql"); files.push_back("sql/ct02.sql"); files.push_back("sql/ct03.sql"); files.push_back("sql/ct04.sql"); files.push_back("sql/ct05.sql"); files.push_back("sql/ct06.sql"); files.push_back("sql/ct07.sql"); files.push_back("sql/ct08.sql"); files.push_back("sql/ct09.sql"); files.push_back("sql/ct10.sql"); files.push_back("sql/ct11.sql"); vector::const_iterator itr; for (itr = files.begin(); itr != files.end(); ++itr) { cout << "* * * Checking CreateTableStatement serialization for " << *itr << endl; SqlFileParser p; p.setDefaultSchema("tpch"); p.Parse(*itr); if (p.Good()) { const ParseTree& stmts = p.GetParseTree(); CreateTableStatement* ct = dynamic_cast(stmts[0]); CPPUNIT_ASSERT(ct); cout << "Parsed CreateTable:" << endl; cout << *ct << endl; t_sertest(ct); } } } void droptable() { vector files; files.push_back("sql/dt01.sql"); files.push_back("sql/dt02.sql"); vector::const_iterator itr; for (itr = files.begin(); itr != files.end(); ++itr) { cout << "* * * Checking DropTableStatement serialization for " << *itr << endl; SqlFileParser p; p.Parse(*itr); if (p.Good()) { const ParseTree& stmts = p.GetParseTree(); DropTableStatement* stmt = dynamic_cast(stmts[0]); CPPUNIT_ASSERT(stmt); cout << "Parsed DropTable:" << endl; cout << *stmt << endl; t_sertest(stmt); } } } void createindex() { vector files; files.push_back("sql/ci01.sql"); files.push_back("sql/ci02.sql"); vector::const_iterator itr; for (itr = files.begin(); itr != files.end(); ++itr) { cout << "* * * Checking Create Index serialization for " << *itr << endl; SqlFileParser p; p.Parse(*itr); if (p.Good()) { const ParseTree& stmts = p.GetParseTree(); CreateIndexStatement* stmt = dynamic_cast(stmts[0]); CPPUNIT_ASSERT(stmt); cout << "Parsed:" << endl; cout << *stmt << endl; t_sertest(stmt); } } } void dropindex() { vector files; files.push_back("sql/di01.sql"); vector::const_iterator itr; for (itr = files.begin(); itr != files.end(); ++itr) { cout << "* * * Checking Drop Index serialization for " << *itr << endl; SqlFileParser p; p.Parse(*itr); if (p.Good()) { const ParseTree& stmts = p.GetParseTree(); DropIndexStatement* stmt = dynamic_cast(stmts[0]); CPPUNIT_ASSERT(stmt); cout << "Parsed:" << endl; cout << *stmt << endl; t_sertest(stmt); } } } }; CPPUNIT_TEST_SUITE_REGISTRATION(SerializeTest); CPPUNIT_TEST_SUITE_REGISTRATION(ParserTest); #include #include int main(int argc, char* argv[]) { CppUnit::TextUi::TestRunner runner; CppUnit::TestFactoryRegistry& registry = CppUnit::TestFactoryRegistry::getRegistry(); runner.addTest(registry.makeTest()); bool wasSuccessful = runner.run("", false); return (wasSuccessful ? 0 : 1); } string itoa(const int i) { stringstream ss; ss << i; return ss.str(); }