diff --git a/.gitignore b/.gitignore index 655dafc..d8ee45f 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,6 @@ lib-test/ *.exe *.out *.app + +*.cpp.orig +*.h.orig \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..d9e0929 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,20 @@ + +language: cpp + +install: + - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test + - sudo apt-get -qq update + - sudo apt-get install -y bison flex + - sudo apt-get install -y g++-4.8 libstdc++-4.8-dev + - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 90 + - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 90 + - which g++ + - g++ -v + +compiler: + - gcc + - clang + +script: + - make + - make test diff --git a/Makefile b/Makefile index 5103d04..0aad8f8 100644 --- a/Makefile +++ b/Makefile @@ -9,25 +9,27 @@ LIBCPP = $(shell find $(SRC) -name '*.cpp' -not -path "$(SRCPARSER)/*") $(S LIBOBJ = $(LIBCPP:%.cpp=%.o) TESTCPP = $(shell find test/lib/ -name '*.cpp') +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') + # compile & link flages -CC = g++ CFLAGS = -std=c++11 -Wall -fPIC LIBFLAGS = -shared TARGET = libsqlparser.so INSTALL = /usr/local -CTESTFLAGS = -Wall -Isrc/ -Itest/ -L./ -std=c++11 +CTESTFLAGS = -Wall -Isrc/ -Itest/ -L./ -std=c++11 -lstdc++ all: library library: $(TARGET) $(TARGET): $(LIBOBJ) - $(CC) $(LIBFLAGS) -o $(TARGET) $(LIBOBJ) + $(CXX) $(LIBFLAGS) -o $(TARGET) $(LIBOBJ) %.o: %.cpp $(PARSERFILES) - $(CC) $(CFLAGS) -c -o $@ $< + $(CXX) $(CFLAGS) -c -o $@ $< $(SRCPARSER)/bison_parser.cpp: parser $(SRCPARSER)/flex_lexer.cpp: parser @@ -48,20 +50,26 @@ cleanall: clean cleanparser install: cp $(TARGET) $(INSTALL)/lib/$(TARGET) +format: + astyle --options=astyle.options $(ALLLIB) + astyle --options=astyle.options $(ALLTEST) + ############ ### Test ### ############ test: $(BIN)/sql_tests $(BIN)/sql_grammar_test - LD_LIBRARY_PATH=./ $(BIN)/sql_grammar_test -f "test/lib/valid_queries.sql" - LD_LIBRARY_PATH=./ $(BIN)/sql_tests + bash test/test.sh + +# test whete +test_install: + make -C example/ + ./example/example "SELECT * FROM students WHERE name = 'Max Mustermann';" $(BIN)/sql_tests: library @mkdir -p $(BIN)/ - $(CC) $(CTESTFLAGS) $(TESTCPP) test/sql_tests.cpp -o $(BIN)/sql_tests -lsqlparser + $(CXX) $(CTESTFLAGS) $(TESTCPP) test/sql_tests.cpp -o $(BIN)/sql_tests -lsqlparser $(BIN)/sql_grammar_test: library @mkdir -p $(BIN)/ - $(CC) $(CTESTFLAGS) test/sql_grammar_test.cpp -o $(BIN)/sql_grammar_test -lsqlparser - - + $(CXX) $(CTESTFLAGS) test/sql_grammar_test.cpp -o $(BIN)/sql_grammar_test -lsqlparser diff --git a/README.md b/README.md index 2a372cd..f990d85 100644 --- a/README.md +++ b/README.md @@ -9,20 +9,25 @@ In March 2015 we've also written a short paper outlining discussing some develop ### Usage -To use the SQL parser in your own projects you simply have to follow these few steps. The only requirement for is GCC 4.8+. Older versions of GCC probably also work, but are untested. +**Requirements:** + * gcc 4.8+ + +To use the SQL parser in your own projects you simply have to follow these few steps. The only requirement for is gcc 4.8+. Older versions of gcc might also work, but are untested. 1. Download the [latest release here](https://github.com/hyrise/sql-parser/releases) 2. Compile the library `make` to create `libsqlparser.so` + 3. *(Optional)* Run `make install` to copy the library to `/usr/local/lib/` 3. Run the tests `make test` to make sure everything worked - 4. Take a look at the [example project here](https://github.com/hyrise/sql-parser/tree/dynamic-library/example) + 4. Take a look at the [example project here](https://github.com/hyrise/sql-parser/tree/master/example) 5. Include the `SQLParser.h` from `src/` and link the library in your project ### Development -**Prerequisites:** -* [bison](https://www.gnu.org/software/bison/) (tested with v3.0.2) -* [flex](http://flex.sourceforge.net/) (tested with v2.5.5) +**Requirements for development:** + * gcc 4.8 (or newer) + * [bison](https://www.gnu.org/software/bison/) (tested with v3.0.2) + * [flex](http://flex.sourceforge.net/) (tested with v2.5.5) First step to extending this parser is cloning the repository `git clone git@github.com:hyrise/sql-parser.git` and making sure everything works by running the following steps: @@ -45,12 +50,10 @@ make test # build parser, library and runs the tests We strongly encourage you to contribute to this project! If you want to contribute to this project there are several options. If you've noticed a bug or would like an improvement let us know by creating a [new issue](https://github.com/hyrise/sql-parser/issues). If you want to develop a new feature yourself or just improve the quality of the system, feel free to fork the reposistory and implement your changes. Open a pull request as soon as your done and we will look over it. If we think it's good then your pull request will be merged into this repository. -### Documenation +### Resources -* [Working Syntax Examples](docs/syntax.md) -* [Known Issues](docs/issues.md) -* [Developer Documentation](docs/documentation.md) -* [Integration in Hyrise](docs/integration.md) + * [Working Syntax Examples](docs/syntax.md) + * [Developer Documentation](docs/dev-docs.md) ### License diff --git a/astyle.options b/astyle.options new file mode 100644 index 0000000..58989d5 --- /dev/null +++ b/astyle.options @@ -0,0 +1,8 @@ + +# indentation +--indent=spaces=4 +--indent-namespaces + +--style=java +--style=attach +-A2 \ No newline at end of file diff --git a/docs/documentation.md b/docs/dev-docs.md similarity index 51% rename from docs/documentation.md rename to docs/dev-docs.md index 7cb9edb..1214879 100644 --- a/docs/documentation.md +++ b/docs/dev-docs.md @@ -1,29 +1,31 @@ Developer Documentation ======================= -This page contains information about how to extend this parser with new functionalities. +## Developing New Functionality + +This section contains information about how to extend this parser with new functionalities. +### Implementing a new Statement -## Implementing Statement Class - -Create a new file and class in src/lib/statements/ or extend any of the existing Statements. Every statement needs to have the base class SQLStatement and needs to call its super constructor with its type. If your defining a new statement type, you need to define a new StatementType in SQLStatement.h. +Create a new file and class in `src/sql/` or extend any of the existing Statements. Every statement needs to have the base class SQLStatement and needs to call its super constructor with its type. If your defining a new statement type, you need to define a new StatementType in `SQLStatement.h`. It is important that you create an appropriate constructor for your statement that zero-initializes all its pointer variables and that your create an appropriate destructor. -Lastly you need to include your new file in src/lib/sqllib.h +Finally you will need to include your new file in `src/sql/statements.h`. - -## Extending the Grammar +### Extending the Grammar Related files: - * src/parser/bison_parser.y - * src/parser/flex_lexer.l - * src/parser/keywordlist_generator.py - * src/parser/sql_keywords.txt +```` +src/parser/bison_parser.y +src/parser/flex_lexer.l +src/parser/keywordlist_generator.py +src/parser/sql_keywords.txt +``` -To extend the grammar the file you will mostly have to deal with is the bison grammar definition in src/parser/bison_parser.y. +To extend the grammar the file you will mostly have to deal with is the bison grammar definition in `src/parser/bison_parser.y`. If your extending an existing statement, skip to the non-terminal definition for that statement. I.e. for an InsertStatement the non-terminal insert_statement. @@ -33,7 +35,6 @@ If your defining a new statement, you will need to define your type in the \%uni ## Implementing Tests -Related files: - * src/sql_tests.cpp +All test related files are in `test/`. Take a look to see how tests are implemented. diff --git a/docs/doxy.conf b/docs/doxy.conf deleted file mode 100644 index 4ea6b16..0000000 --- a/docs/doxy.conf +++ /dev/null @@ -1,20 +0,0 @@ -@PROJECT_NAME = "SQL Parser for Hyrise (C++)" - -@OUTPUT_DIRECTORY = docs/__doxygen__/ -@GENERATE_LATEX = NO -@GENERATE_HTML = YES - -@INCLUDE_FILE_PATTERNS = *.y *.l -@FILE_PATTERNS = *.y *.l *.h *.cpp *.md - - -@INPUT = README.md \ - docs/ \ - src/parser/SQLParser.h \ - src/parser/SQLParser.cpp \ - src/parser/bison_parser.y \ - src/parser/flex_lexer.l \ - src/lib/ \ - - -@RECURSIVE = YES \ No newline at end of file diff --git a/docs/integration.md b/docs/integration.md deleted file mode 100644 index b2173b1..0000000 --- a/docs/integration.md +++ /dev/null @@ -1,8 +0,0 @@ -Integration in Hyrise -===================== - -On this page we describe how to integrate changes to the parser into Hyrise. - -## Update the Parser code in Hyrise - -Run `./deploy_to_hyrise.sh path/to/hyrise` to update the SQL parser code within Hyrise. \ No newline at end of file diff --git a/docs/issues.md b/docs/issues.md deleted file mode 100644 index 90a3c3d..0000000 --- a/docs/issues.md +++ /dev/null @@ -1,10 +0,0 @@ -Known Issues -============ - -Here we will keep track of issues with the parser and the integration in Hyrise. - -## Missing Functionality - - * Union clauses - * Create anything other than tables - * Alter/Rename statements diff --git a/example/Makefile b/example/Makefile index 6957afc..18a3f54 100644 --- a/example/Makefile +++ b/example/Makefile @@ -1,7 +1,6 @@ -CC = g++ -CFLAGS = -std=c++11 -Wall -I../src/ -L../ +CFLAGS = -std=c++11 -lstdc++ -Wall -I../src/ -L../ all: - $(CC) $(CFLAGS) example.cpp -o example -lsqlparser + $(CXX) $(CFLAGS) example.cpp -o example -lsqlparser diff --git a/example/example.cpp b/example/example.cpp index f5c1ab2..008c92e 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -16,20 +16,21 @@ int main(int argc, char *argv[]) { std::string query = argv[1]; // parse a given query - hsql::SQLStatementList* result = hsql::SQLParser::parseSQLString(query); + hsql::SQLParserResult* result = hsql::SQLParser::parseSQLString(query); // check whether the parsing was successful if (result->isValid) { printf("Parsed successfully!\n"); - printf("Number of statements: %lu\n", result->numStatements()); + printf("Number of statements: %lu\n", result->size()); for (hsql::SQLStatement* stmt : result->statements) { // process the statements... hsql::printStatementInfo(stmt); } + + return 0; } else { printf("Invalid SQL!\n"); + return -1; } - - return 0; } \ No newline at end of file diff --git a/benchmark/benchmark.py b/hyrise/benchmark/benchmark.py similarity index 100% rename from benchmark/benchmark.py rename to hyrise/benchmark/benchmark.py diff --git a/src/SQLParser.cpp b/src/SQLParser.cpp index e3039e1..fa90168 100644 --- a/src/SQLParser.cpp +++ b/src/SQLParser.cpp @@ -8,38 +8,39 @@ namespace hsql { -SQLParser::SQLParser() { - fprintf(stderr, "SQLParser only has static methods atm! Do not initialize!\n"); -} - - -SQLStatementList* SQLParser::parseSQLString(const char *text) { - SQLStatementList* result; - yyscan_t scanner; - YY_BUFFER_STATE state; - - if (hsql_lex_init(&scanner)) { - // couldn't initialize - fprintf(stderr, "[Error] SQLParser: Error when initializing lexer!\n"); - return NULL; + SQLParser::SQLParser() { + fprintf(stderr, "SQLParser only has static methods atm! Do not initialize!\n"); } - state = hsql__scan_string(text, scanner); - if (hsql_parse(&result, scanner)) { - // Returns an error stmt object + SQLParserResult* SQLParser::parseSQLString(const char *text) { + SQLParserResult* result = NULL; + yyscan_t scanner; + YY_BUFFER_STATE state; + + if (hsql_lex_init(&scanner)) { + // couldn't initialize + fprintf(stderr, "[Error] SQLParser: Error when initializing lexer!\n"); + return NULL; + } + + state = hsql__scan_string(text, scanner); + + if (hsql_parse(&result, scanner)) { + // Returns an error stmt object + return result; + } + + hsql__delete_buffer(state, scanner); + + hsql_lex_destroy(scanner); return result; } - hsql__delete_buffer(state, scanner); - hsql_lex_destroy(scanner); - return result; -} + SQLParserResult* SQLParser::parseSQLString(const std::string& text) { + return parseSQLString(text.c_str()); + } -SQLStatementList* SQLParser::parseSQLString(const std::string& text) { - return parseSQLString(text.c_str()); -} - } // namespace hsql \ No newline at end of file diff --git a/src/SQLParser.h b/src/SQLParser.h index 3d82b8a..0fa414d 100644 --- a/src/SQLParser.h +++ b/src/SQLParser.h @@ -1,27 +1,23 @@ #ifndef __SQLPARSER_H_ #define __SQLPARSER_H_ -#include "sqltypes.h" +#include "SQLParserResult.h" +#include "sql/statements.h" namespace hsql { + /** + * Main class for parsing SQL strings + */ + class SQLParser { + public: + static SQLParserResult* parseSQLString(const char* sql); + static SQLParserResult* parseSQLString(const std::string& sql); -/*! - * \mainpage SQLParser (C++) - */ + private: + SQLParser(); + }; -/*! - * @brief Main class for parsing SQL strings - */ -class SQLParser { -public: - static SQLStatementList* parseSQLString(const char* sql); - static SQLStatementList* parseSQLString(const std::string& sql); -private: - SQLParser(); -}; - - } // namespace hsql diff --git a/src/SQLParserResult.cpp b/src/SQLParserResult.cpp new file mode 100644 index 0000000..5ca2180 --- /dev/null +++ b/src/SQLParserResult.cpp @@ -0,0 +1,41 @@ + +#include "SQLParserResult.h" + +namespace hsql { + + SQLParserResult::SQLParserResult() : + isValid(true), + errorMsg(NULL) {}; + + + SQLParserResult::SQLParserResult(SQLStatement* stmt) : + isValid(true), + errorMsg(NULL) { + addStatement(stmt); + }; + + + SQLParserResult::~SQLParserResult() { + for (std::vector::iterator it = statements.begin(); it != statements.end(); ++it) { + delete *it; + } + + delete errorMsg; + } + + + void SQLParserResult::addStatement(SQLStatement* stmt) { + statements.push_back(stmt); + } + + + SQLStatement* SQLParserResult::getStatement(int id) { + return statements[id]; + } + + + size_t SQLParserResult::size() { + return statements.size(); + } + +} // namespace hsql \ No newline at end of file diff --git a/src/SQLParserResult.h b/src/SQLParserResult.h new file mode 100644 index 0000000..285befc --- /dev/null +++ b/src/SQLParserResult.h @@ -0,0 +1,35 @@ +#ifndef __SQLPARSERRESULT__ +#define __SQLPARSERRESULT__ + +#include "sql/SQLStatement.h" + +namespace hsql { + /** + * Represents the result of the SQLParser. + * If parsing was successful it contains a list of SQLStatement. + */ + class SQLParserResult { + public: + + SQLParserResult(); + SQLParserResult(SQLStatement* stmt); + virtual ~SQLParserResult(); + + void addStatement(SQLStatement* stmt); + + SQLStatement* getStatement(int id); + + size_t size(); + + // public properties + std::vector statements; + bool isValid; + + const char* errorMsg; + int errorLine; + int errorColumn; + }; + +} // namespace hsql + +#endif // __SQLPARSERRESULT__ \ No newline at end of file diff --git a/src/parser/bison_parser.cpp b/src/parser/bison_parser.cpp index 2fa2e11..6bcf236 100644 --- a/src/parser/bison_parser.cpp +++ b/src/parser/bison_parser.cpp @@ -84,7 +84,6 @@ ** Section 1: C Declarations *********************************/ -#include "../sqltypes.h" #include "bison_parser.h" #include "flex_lexer.h" @@ -92,13 +91,13 @@ using namespace hsql; -int yyerror(YYLTYPE* llocp, SQLStatementList** result, yyscan_t scanner, const char *msg) { +int yyerror(YYLTYPE* llocp, SQLParserResult** result, yyscan_t scanner, const char *msg) { - SQLStatementList* list = new SQLStatementList(); + SQLParserResult* list = new SQLParserResult(); list->isValid = false; - list->parser_msg = strdup(msg); - list->error_line = llocp->first_line; - list->error_col = llocp->first_column; + list->errorMsg = strdup(msg); + list->errorLine = llocp->first_line; + list->errorColumn = llocp->first_column; *result = list; return 0; @@ -107,7 +106,7 @@ int yyerror(YYLTYPE* llocp, SQLStatementList** result, yyscan_t scanner, const c -#line 111 "bison_parser.cpp" /* yacc.c:339 */ +#line 110 "bison_parser.cpp" /* yacc.c:339 */ # ifndef YY_NULLPTR # if defined __cplusplus && 201103L <= __cplusplus @@ -145,9 +144,12 @@ int yyerror(YYLTYPE* llocp, SQLStatementList** result, yyscan_t scanner, const c extern int hsql_debug; #endif /* "%code requires" blocks. */ -#line 43 "bison_parser.y" /* yacc.c:355 */ +#line 42 "bison_parser.y" /* yacc.c:355 */ // %code requires block + +#include "../sql/statements.h" +#include "../SQLParserResult.h" #include "parser_typedef.h" // Auto update column and line number @@ -165,7 +167,7 @@ extern int hsql_debug; } \ } -#line 169 "bison_parser.cpp" /* yacc.c:355 */ +#line 171 "bison_parser.cpp" /* yacc.c:355 */ /* Token type. */ #ifndef HSQL_TOKENTYPE @@ -303,7 +305,7 @@ extern int hsql_debug; typedef union HSQL_STYPE HSQL_STYPE; union HSQL_STYPE { -#line 99 "bison_parser.y" /* yacc.c:355 */ +#line 101 "bison_parser.y" /* yacc.c:355 */ double fval; int64_t ival; @@ -331,7 +333,7 @@ union HSQL_STYPE hsql::GroupByDescription* group_t; hsql::UpdateClause* update_t; - hsql::SQLStatementList* stmt_list; + hsql::SQLParserResult* stmt_list; std::vector* str_vec; std::vector* table_vec; @@ -339,7 +341,7 @@ union HSQL_STYPE std::vector* update_vec; std::vector* expr_vec; -#line 343 "bison_parser.cpp" /* yacc.c:355 */ +#line 345 "bison_parser.cpp" /* yacc.c:355 */ }; # define HSQL_STYPE_IS_TRIVIAL 1 # define HSQL_STYPE_IS_DECLARED 1 @@ -361,13 +363,13 @@ struct HSQL_LTYPE -int hsql_parse (hsql::SQLStatementList** result, yyscan_t scanner); +int hsql_parse (hsql::SQLParserResult** result, yyscan_t scanner); #endif /* !YY_HSQL_BISON_PARSER_H_INCLUDED */ /* Copy the second part of user declarations. */ -#line 371 "bison_parser.cpp" /* yacc.c:358 */ +#line 373 "bison_parser.cpp" /* yacc.c:358 */ #ifdef short # undef short @@ -679,21 +681,21 @@ static const yytype_uint8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 227, 227, 234, 235, 239, 244, 249, 250, 251, - 252, 253, 254, 255, 256, 257, 265, 270, 278, 282, - 294, 302, 306, 316, 322, 331, 332, 336, 337, 341, - 348, 349, 350, 351, 361, 365, 377, 385, 397, 403, - 413, 414, 424, 433, 434, 438, 450, 451, 455, 456, - 460, 465, 477, 478, 479, 483, 494, 495, 499, 504, - 509, 510, 514, 519, 523, 524, 527, 528, 532, 533, - 534, 539, 540, 541, 548, 549, 553, 554, 558, 565, - 566, 567, 568, 569, 573, 574, 575, 579, 580, 584, - 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, - 599, 600, 601, 602, 603, 604, 608, 612, 613, 617, - 618, 619, 623, 628, 629, 633, 637, 642, 653, 654, - 664, 665, 671, 676, 677, 682, 692, 700, 701, 706, - 707, 711, 712, 720, 732, 733, 734, 735, 736, 742, - 748, 752, 761, 762, 767, 768 + 0, 229, 229, 236, 237, 241, 246, 251, 252, 253, + 254, 255, 256, 257, 258, 259, 267, 272, 280, 284, + 296, 304, 308, 318, 324, 333, 334, 338, 339, 343, + 350, 351, 352, 353, 363, 367, 379, 387, 399, 405, + 415, 416, 426, 435, 436, 440, 452, 453, 457, 458, + 462, 467, 479, 480, 481, 485, 496, 497, 501, 506, + 511, 512, 516, 521, 525, 526, 529, 530, 534, 535, + 536, 541, 542, 543, 550, 551, 555, 556, 560, 567, + 568, 569, 570, 571, 575, 576, 577, 581, 582, 586, + 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, + 601, 602, 603, 604, 605, 606, 610, 614, 615, 619, + 620, 621, 625, 630, 631, 635, 639, 644, 655, 656, + 666, 667, 673, 678, 679, 684, 694, 702, 703, 708, + 709, 713, 714, 722, 734, 735, 736, 737, 738, 744, + 750, 754, 763, 764, 769, 770 }; #endif @@ -1174,7 +1176,7 @@ do { \ `----------------------------------------*/ static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, hsql::SQLStatementList** result, yyscan_t scanner) +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, hsql::SQLParserResult** result, yyscan_t scanner) { FILE *yyo = yyoutput; YYUSE (yyo); @@ -1196,7 +1198,7 @@ yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvalue `--------------------------------*/ static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, hsql::SQLStatementList** result, yyscan_t scanner) +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, hsql::SQLParserResult** result, yyscan_t scanner) { YYFPRINTF (yyoutput, "%s %s (", yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); @@ -1236,7 +1238,7 @@ do { \ `------------------------------------------------*/ static void -yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, hsql::SQLStatementList** result, yyscan_t scanner) +yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, hsql::SQLParserResult** result, yyscan_t scanner) { unsigned long int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; @@ -1516,7 +1518,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, `-----------------------------------------------*/ static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, hsql::SQLStatementList** result, yyscan_t scanner) +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, hsql::SQLParserResult** result, yyscan_t scanner) { YYUSE (yyvaluep); YYUSE (yylocationp); @@ -1539,7 +1541,7 @@ yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocatio `----------*/ int -yyparse (hsql::SQLStatementList** result, yyscan_t scanner) +yyparse (hsql::SQLParserResult** result, yyscan_t scanner) { /* The lookahead symbol. */ int yychar; @@ -1629,7 +1631,7 @@ YYLTYPE yylloc = yyloc_default; yychar = YYEMPTY; /* Cause a token to be read. */ /* User initialization code. */ -#line 77 "bison_parser.y" /* yacc.c:1429 */ +#line 79 "bison_parser.y" /* yacc.c:1429 */ { // Initialize yylloc.first_column = 0; @@ -1640,7 +1642,7 @@ YYLTYPE yylloc = yyloc_default; yylloc.placeholder_id = 0; } -#line 1644 "bison_parser.cpp" /* yacc.c:1429 */ +#line 1646 "bison_parser.cpp" /* yacc.c:1429 */ yylsp[0] = yylloc; goto yysetstate; @@ -1827,753 +1829,753 @@ yyreduce: switch (yyn) { case 2: -#line 227 "bison_parser.y" /* yacc.c:1646 */ +#line 229 "bison_parser.y" /* yacc.c:1646 */ { *result = (yyvsp[-1].stmt_list); } -#line 1835 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1837 "bison_parser.cpp" /* yacc.c:1646 */ break; case 3: -#line 234 "bison_parser.y" /* yacc.c:1646 */ - { (yyval.stmt_list) = new SQLStatementList((yyvsp[0].statement)); } -#line 1841 "bison_parser.cpp" /* yacc.c:1646 */ +#line 236 "bison_parser.y" /* yacc.c:1646 */ + { (yyval.stmt_list) = new SQLParserResult((yyvsp[0].statement)); } +#line 1843 "bison_parser.cpp" /* yacc.c:1646 */ break; case 4: -#line 235 "bison_parser.y" /* yacc.c:1646 */ +#line 237 "bison_parser.y" /* yacc.c:1646 */ { (yyvsp[-2].stmt_list)->addStatement((yyvsp[0].statement)); (yyval.stmt_list) = (yyvsp[-2].stmt_list); } -#line 1847 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1849 "bison_parser.cpp" /* yacc.c:1646 */ break; case 5: -#line 239 "bison_parser.y" /* yacc.c:1646 */ +#line 241 "bison_parser.y" /* yacc.c:1646 */ { (yyvsp[0].prep_stmt)->setPlaceholders(yyloc.placeholder_list); yyloc.placeholder_list.clear(); (yyval.statement) = (yyvsp[0].prep_stmt); } -#line 1857 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1859 "bison_parser.cpp" /* yacc.c:1646 */ break; case 7: -#line 249 "bison_parser.y" /* yacc.c:1646 */ +#line 251 "bison_parser.y" /* yacc.c:1646 */ { (yyval.statement) = (yyvsp[0].select_stmt); } -#line 1863 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1865 "bison_parser.cpp" /* yacc.c:1646 */ break; case 8: -#line 250 "bison_parser.y" /* yacc.c:1646 */ +#line 252 "bison_parser.y" /* yacc.c:1646 */ { (yyval.statement) = (yyvsp[0].import_stmt); } -#line 1869 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1871 "bison_parser.cpp" /* yacc.c:1646 */ break; case 9: -#line 251 "bison_parser.y" /* yacc.c:1646 */ +#line 253 "bison_parser.y" /* yacc.c:1646 */ { (yyval.statement) = (yyvsp[0].create_stmt); } -#line 1875 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1877 "bison_parser.cpp" /* yacc.c:1646 */ break; case 10: -#line 252 "bison_parser.y" /* yacc.c:1646 */ +#line 254 "bison_parser.y" /* yacc.c:1646 */ { (yyval.statement) = (yyvsp[0].insert_stmt); } -#line 1881 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1883 "bison_parser.cpp" /* yacc.c:1646 */ break; case 11: -#line 253 "bison_parser.y" /* yacc.c:1646 */ +#line 255 "bison_parser.y" /* yacc.c:1646 */ { (yyval.statement) = (yyvsp[0].delete_stmt); } -#line 1887 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1889 "bison_parser.cpp" /* yacc.c:1646 */ break; case 12: -#line 254 "bison_parser.y" /* yacc.c:1646 */ +#line 256 "bison_parser.y" /* yacc.c:1646 */ { (yyval.statement) = (yyvsp[0].delete_stmt); } -#line 1893 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1895 "bison_parser.cpp" /* yacc.c:1646 */ break; case 13: -#line 255 "bison_parser.y" /* yacc.c:1646 */ +#line 257 "bison_parser.y" /* yacc.c:1646 */ { (yyval.statement) = (yyvsp[0].update_stmt); } -#line 1899 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1901 "bison_parser.cpp" /* yacc.c:1646 */ break; case 14: -#line 256 "bison_parser.y" /* yacc.c:1646 */ +#line 258 "bison_parser.y" /* yacc.c:1646 */ { (yyval.statement) = (yyvsp[0].drop_stmt); } -#line 1905 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1907 "bison_parser.cpp" /* yacc.c:1646 */ break; case 15: -#line 257 "bison_parser.y" /* yacc.c:1646 */ +#line 259 "bison_parser.y" /* yacc.c:1646 */ { (yyval.statement) = (yyvsp[0].exec_stmt); } -#line 1911 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1913 "bison_parser.cpp" /* yacc.c:1646 */ break; case 16: -#line 265 "bison_parser.y" /* yacc.c:1646 */ +#line 267 "bison_parser.y" /* yacc.c:1646 */ { (yyval.prep_stmt) = new PrepareStatement(); (yyval.prep_stmt)->name = (yyvsp[-2].sval); - (yyval.prep_stmt)->query = new SQLStatementList((yyvsp[0].statement)); + (yyval.prep_stmt)->query = new SQLParserResult((yyvsp[0].statement)); } -#line 1921 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1923 "bison_parser.cpp" /* yacc.c:1646 */ break; case 17: -#line 270 "bison_parser.y" /* yacc.c:1646 */ +#line 272 "bison_parser.y" /* yacc.c:1646 */ { (yyval.prep_stmt) = new PrepareStatement(); (yyval.prep_stmt)->name = (yyvsp[-4].sval); (yyval.prep_stmt)->query = (yyvsp[-2].stmt_list); } -#line 1931 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1933 "bison_parser.cpp" /* yacc.c:1646 */ break; case 18: -#line 278 "bison_parser.y" /* yacc.c:1646 */ +#line 280 "bison_parser.y" /* yacc.c:1646 */ { (yyval.exec_stmt) = new ExecuteStatement(); (yyval.exec_stmt)->name = (yyvsp[0].sval); } -#line 1940 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1942 "bison_parser.cpp" /* yacc.c:1646 */ break; case 19: -#line 282 "bison_parser.y" /* yacc.c:1646 */ +#line 284 "bison_parser.y" /* yacc.c:1646 */ { (yyval.exec_stmt) = new ExecuteStatement(); (yyval.exec_stmt)->name = (yyvsp[-3].sval); (yyval.exec_stmt)->parameters = (yyvsp[-1].expr_vec); } -#line 1950 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1952 "bison_parser.cpp" /* yacc.c:1646 */ break; case 20: -#line 294 "bison_parser.y" /* yacc.c:1646 */ +#line 296 "bison_parser.y" /* yacc.c:1646 */ { (yyval.import_stmt) = new ImportStatement((ImportStatement::ImportType) (yyvsp[-4].uval)); - (yyval.import_stmt)->file_path = (yyvsp[-2].sval); - (yyval.import_stmt)->table_name = (yyvsp[0].sval); + (yyval.import_stmt)->filePath = (yyvsp[-2].sval); + (yyval.import_stmt)->tableName = (yyvsp[0].sval); } -#line 1960 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1962 "bison_parser.cpp" /* yacc.c:1646 */ break; case 21: -#line 302 "bison_parser.y" /* yacc.c:1646 */ +#line 304 "bison_parser.y" /* yacc.c:1646 */ { (yyval.uval) = ImportStatement::kImportCSV; } -#line 1966 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1968 "bison_parser.cpp" /* yacc.c:1646 */ break; case 22: -#line 306 "bison_parser.y" /* yacc.c:1646 */ +#line 308 "bison_parser.y" /* yacc.c:1646 */ { (yyval.sval) = (yyvsp[0].expr)->name; } -#line 1972 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1974 "bison_parser.cpp" /* yacc.c:1646 */ break; case 23: -#line 316 "bison_parser.y" /* yacc.c:1646 */ +#line 318 "bison_parser.y" /* yacc.c:1646 */ { (yyval.create_stmt) = new CreateStatement(CreateStatement::kTableFromTbl); - (yyval.create_stmt)->if_not_exists = (yyvsp[-5].bval); - (yyval.create_stmt)->table_name = (yyvsp[-4].sval); - (yyval.create_stmt)->file_path = (yyvsp[0].sval); + (yyval.create_stmt)->ifNotExists = (yyvsp[-5].bval); + (yyval.create_stmt)->tableName = (yyvsp[-4].sval); + (yyval.create_stmt)->filePath = (yyvsp[0].sval); } -#line 1983 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1985 "bison_parser.cpp" /* yacc.c:1646 */ break; case 24: -#line 322 "bison_parser.y" /* yacc.c:1646 */ +#line 324 "bison_parser.y" /* yacc.c:1646 */ { (yyval.create_stmt) = new CreateStatement(CreateStatement::kTable); - (yyval.create_stmt)->if_not_exists = (yyvsp[-4].bval); - (yyval.create_stmt)->table_name = (yyvsp[-3].sval); + (yyval.create_stmt)->ifNotExists = (yyvsp[-4].bval); + (yyval.create_stmt)->tableName = (yyvsp[-3].sval); (yyval.create_stmt)->columns = (yyvsp[-1].column_vec); } -#line 1994 "bison_parser.cpp" /* yacc.c:1646 */ +#line 1996 "bison_parser.cpp" /* yacc.c:1646 */ break; case 25: -#line 331 "bison_parser.y" /* yacc.c:1646 */ +#line 333 "bison_parser.y" /* yacc.c:1646 */ { (yyval.bval) = true; } -#line 2000 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2002 "bison_parser.cpp" /* yacc.c:1646 */ break; case 26: -#line 332 "bison_parser.y" /* yacc.c:1646 */ +#line 334 "bison_parser.y" /* yacc.c:1646 */ { (yyval.bval) = false; } -#line 2006 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2008 "bison_parser.cpp" /* yacc.c:1646 */ break; case 27: -#line 336 "bison_parser.y" /* yacc.c:1646 */ +#line 338 "bison_parser.y" /* yacc.c:1646 */ { (yyval.column_vec) = new std::vector(); (yyval.column_vec)->push_back((yyvsp[0].column_t)); } -#line 2012 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2014 "bison_parser.cpp" /* yacc.c:1646 */ break; case 28: -#line 337 "bison_parser.y" /* yacc.c:1646 */ +#line 339 "bison_parser.y" /* yacc.c:1646 */ { (yyvsp[-2].column_vec)->push_back((yyvsp[0].column_t)); (yyval.column_vec) = (yyvsp[-2].column_vec); } -#line 2018 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2020 "bison_parser.cpp" /* yacc.c:1646 */ break; case 29: -#line 341 "bison_parser.y" /* yacc.c:1646 */ +#line 343 "bison_parser.y" /* yacc.c:1646 */ { (yyval.column_t) = new ColumnDefinition((yyvsp[-1].sval), (ColumnDefinition::DataType) (yyvsp[0].uval)); } -#line 2026 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2028 "bison_parser.cpp" /* yacc.c:1646 */ break; case 30: -#line 348 "bison_parser.y" /* yacc.c:1646 */ +#line 350 "bison_parser.y" /* yacc.c:1646 */ { (yyval.uval) = ColumnDefinition::INT; } -#line 2032 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2034 "bison_parser.cpp" /* yacc.c:1646 */ break; case 31: -#line 349 "bison_parser.y" /* yacc.c:1646 */ +#line 351 "bison_parser.y" /* yacc.c:1646 */ { (yyval.uval) = ColumnDefinition::INT; } -#line 2038 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2040 "bison_parser.cpp" /* yacc.c:1646 */ break; case 32: -#line 350 "bison_parser.y" /* yacc.c:1646 */ +#line 352 "bison_parser.y" /* yacc.c:1646 */ { (yyval.uval) = ColumnDefinition::DOUBLE; } -#line 2044 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2046 "bison_parser.cpp" /* yacc.c:1646 */ break; case 33: -#line 351 "bison_parser.y" /* yacc.c:1646 */ +#line 353 "bison_parser.y" /* yacc.c:1646 */ { (yyval.uval) = ColumnDefinition::TEXT; } -#line 2050 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2052 "bison_parser.cpp" /* yacc.c:1646 */ break; case 34: -#line 361 "bison_parser.y" /* yacc.c:1646 */ +#line 363 "bison_parser.y" /* yacc.c:1646 */ { (yyval.drop_stmt) = new DropStatement(DropStatement::kTable); (yyval.drop_stmt)->name = (yyvsp[0].sval); } -#line 2059 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2061 "bison_parser.cpp" /* yacc.c:1646 */ break; case 35: -#line 365 "bison_parser.y" /* yacc.c:1646 */ +#line 367 "bison_parser.y" /* yacc.c:1646 */ { (yyval.drop_stmt) = new DropStatement(DropStatement::kPreparedStatement); (yyval.drop_stmt)->name = (yyvsp[0].sval); } -#line 2068 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2070 "bison_parser.cpp" /* yacc.c:1646 */ break; case 36: -#line 377 "bison_parser.y" /* yacc.c:1646 */ +#line 379 "bison_parser.y" /* yacc.c:1646 */ { (yyval.delete_stmt) = new DeleteStatement(); - (yyval.delete_stmt)->table_name = (yyvsp[-1].sval); + (yyval.delete_stmt)->tableName = (yyvsp[-1].sval); (yyval.delete_stmt)->expr = (yyvsp[0].expr); } -#line 2078 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2080 "bison_parser.cpp" /* yacc.c:1646 */ break; case 37: -#line 385 "bison_parser.y" /* yacc.c:1646 */ +#line 387 "bison_parser.y" /* yacc.c:1646 */ { (yyval.delete_stmt) = new DeleteStatement(); - (yyval.delete_stmt)->table_name = (yyvsp[0].sval); + (yyval.delete_stmt)->tableName = (yyvsp[0].sval); } -#line 2087 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2089 "bison_parser.cpp" /* yacc.c:1646 */ break; case 38: -#line 397 "bison_parser.y" /* yacc.c:1646 */ +#line 399 "bison_parser.y" /* yacc.c:1646 */ { (yyval.insert_stmt) = new InsertStatement(InsertStatement::kInsertValues); - (yyval.insert_stmt)->table_name = (yyvsp[-5].sval); + (yyval.insert_stmt)->tableName = (yyvsp[-5].sval); (yyval.insert_stmt)->columns = (yyvsp[-4].str_vec); (yyval.insert_stmt)->values = (yyvsp[-1].expr_vec); } -#line 2098 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2100 "bison_parser.cpp" /* yacc.c:1646 */ break; case 39: -#line 403 "bison_parser.y" /* yacc.c:1646 */ +#line 405 "bison_parser.y" /* yacc.c:1646 */ { (yyval.insert_stmt) = new InsertStatement(InsertStatement::kInsertSelect); - (yyval.insert_stmt)->table_name = (yyvsp[-2].sval); + (yyval.insert_stmt)->tableName = (yyvsp[-2].sval); (yyval.insert_stmt)->columns = (yyvsp[-1].str_vec); (yyval.insert_stmt)->select = (yyvsp[0].select_stmt); } -#line 2109 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2111 "bison_parser.cpp" /* yacc.c:1646 */ break; case 40: -#line 413 "bison_parser.y" /* yacc.c:1646 */ +#line 415 "bison_parser.y" /* yacc.c:1646 */ { (yyval.str_vec) = (yyvsp[-1].str_vec); } -#line 2115 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2117 "bison_parser.cpp" /* yacc.c:1646 */ break; case 41: -#line 414 "bison_parser.y" /* yacc.c:1646 */ +#line 416 "bison_parser.y" /* yacc.c:1646 */ { (yyval.str_vec) = NULL; } -#line 2121 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2123 "bison_parser.cpp" /* yacc.c:1646 */ break; case 42: -#line 424 "bison_parser.y" /* yacc.c:1646 */ +#line 426 "bison_parser.y" /* yacc.c:1646 */ { (yyval.update_stmt) = new UpdateStatement(); (yyval.update_stmt)->table = (yyvsp[-3].table); (yyval.update_stmt)->updates = (yyvsp[-1].update_vec); (yyval.update_stmt)->where = (yyvsp[0].expr); } -#line 2132 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2134 "bison_parser.cpp" /* yacc.c:1646 */ break; case 43: -#line 433 "bison_parser.y" /* yacc.c:1646 */ +#line 435 "bison_parser.y" /* yacc.c:1646 */ { (yyval.update_vec) = new std::vector(); (yyval.update_vec)->push_back((yyvsp[0].update_t)); } -#line 2138 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2140 "bison_parser.cpp" /* yacc.c:1646 */ break; case 44: -#line 434 "bison_parser.y" /* yacc.c:1646 */ +#line 436 "bison_parser.y" /* yacc.c:1646 */ { (yyvsp[-2].update_vec)->push_back((yyvsp[0].update_t)); (yyval.update_vec) = (yyvsp[-2].update_vec); } -#line 2144 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2146 "bison_parser.cpp" /* yacc.c:1646 */ break; case 45: -#line 438 "bison_parser.y" /* yacc.c:1646 */ +#line 440 "bison_parser.y" /* yacc.c:1646 */ { (yyval.update_t) = new UpdateClause(); (yyval.update_t)->column = (yyvsp[-2].sval); (yyval.update_t)->value = (yyvsp[0].expr); } -#line 2154 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2156 "bison_parser.cpp" /* yacc.c:1646 */ break; case 48: -#line 455 "bison_parser.y" /* yacc.c:1646 */ +#line 457 "bison_parser.y" /* yacc.c:1646 */ { (yyval.select_stmt) = (yyvsp[-1].select_stmt); } -#line 2160 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2162 "bison_parser.cpp" /* yacc.c:1646 */ break; case 49: -#line 456 "bison_parser.y" /* yacc.c:1646 */ +#line 458 "bison_parser.y" /* yacc.c:1646 */ { (yyval.select_stmt) = (yyvsp[-1].select_stmt); } -#line 2166 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2168 "bison_parser.cpp" /* yacc.c:1646 */ break; case 50: -#line 460 "bison_parser.y" /* yacc.c:1646 */ +#line 462 "bison_parser.y" /* yacc.c:1646 */ { (yyval.select_stmt) = (yyvsp[-2].select_stmt); (yyval.select_stmt)->order = (yyvsp[-1].order); (yyval.select_stmt)->limit = (yyvsp[0].limit); } -#line 2176 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2178 "bison_parser.cpp" /* yacc.c:1646 */ break; case 51: -#line 465 "bison_parser.y" /* yacc.c:1646 */ +#line 467 "bison_parser.y" /* yacc.c:1646 */ { // TODO: allow multiple unions (through linked list) // TODO: capture type of set_operator // TODO: might overwrite order and limit of first select here (yyval.select_stmt) = (yyvsp[-4].select_stmt); - (yyval.select_stmt)->union_select = (yyvsp[-2].select_stmt); + (yyval.select_stmt)->unionSelect = (yyvsp[-2].select_stmt); (yyval.select_stmt)->order = (yyvsp[-1].order); (yyval.select_stmt)->limit = (yyvsp[0].limit); } -#line 2190 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2192 "bison_parser.cpp" /* yacc.c:1646 */ break; case 55: -#line 483 "bison_parser.y" /* yacc.c:1646 */ +#line 485 "bison_parser.y" /* yacc.c:1646 */ { (yyval.select_stmt) = new SelectStatement(); - (yyval.select_stmt)->select_distinct = (yyvsp[-4].bval); - (yyval.select_stmt)->select_list = (yyvsp[-3].expr_vec); - (yyval.select_stmt)->from_table = (yyvsp[-2].table); - (yyval.select_stmt)->where_clause = (yyvsp[-1].expr); - (yyval.select_stmt)->group_by = (yyvsp[0].group_t); + (yyval.select_stmt)->selectDistinct = (yyvsp[-4].bval); + (yyval.select_stmt)->selectList = (yyvsp[-3].expr_vec); + (yyval.select_stmt)->fromTable = (yyvsp[-2].table); + (yyval.select_stmt)->whereClause = (yyvsp[-1].expr); + (yyval.select_stmt)->groupBy = (yyvsp[0].group_t); } -#line 2203 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2205 "bison_parser.cpp" /* yacc.c:1646 */ break; case 56: -#line 494 "bison_parser.y" /* yacc.c:1646 */ +#line 496 "bison_parser.y" /* yacc.c:1646 */ { (yyval.bval) = true; } -#line 2209 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2211 "bison_parser.cpp" /* yacc.c:1646 */ break; case 57: -#line 495 "bison_parser.y" /* yacc.c:1646 */ +#line 497 "bison_parser.y" /* yacc.c:1646 */ { (yyval.bval) = false; } -#line 2215 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2217 "bison_parser.cpp" /* yacc.c:1646 */ break; case 59: -#line 504 "bison_parser.y" /* yacc.c:1646 */ +#line 506 "bison_parser.y" /* yacc.c:1646 */ { (yyval.table) = (yyvsp[0].table); } -#line 2221 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2223 "bison_parser.cpp" /* yacc.c:1646 */ break; case 60: -#line 509 "bison_parser.y" /* yacc.c:1646 */ +#line 511 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = (yyvsp[0].expr); } -#line 2227 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2229 "bison_parser.cpp" /* yacc.c:1646 */ break; case 61: -#line 510 "bison_parser.y" /* yacc.c:1646 */ +#line 512 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = NULL; } -#line 2233 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2235 "bison_parser.cpp" /* yacc.c:1646 */ break; case 62: -#line 514 "bison_parser.y" /* yacc.c:1646 */ +#line 516 "bison_parser.y" /* yacc.c:1646 */ { (yyval.group_t) = new GroupByDescription(); (yyval.group_t)->columns = (yyvsp[-1].expr_vec); (yyval.group_t)->having = (yyvsp[0].expr); } -#line 2243 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2245 "bison_parser.cpp" /* yacc.c:1646 */ break; case 63: -#line 519 "bison_parser.y" /* yacc.c:1646 */ +#line 521 "bison_parser.y" /* yacc.c:1646 */ { (yyval.group_t) = NULL; } -#line 2249 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2251 "bison_parser.cpp" /* yacc.c:1646 */ break; case 64: -#line 523 "bison_parser.y" /* yacc.c:1646 */ +#line 525 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = (yyvsp[0].expr); } -#line 2255 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2257 "bison_parser.cpp" /* yacc.c:1646 */ break; case 65: -#line 524 "bison_parser.y" /* yacc.c:1646 */ +#line 526 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = NULL; } -#line 2261 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2263 "bison_parser.cpp" /* yacc.c:1646 */ break; case 66: -#line 527 "bison_parser.y" /* yacc.c:1646 */ +#line 529 "bison_parser.y" /* yacc.c:1646 */ { (yyval.order) = new OrderDescription((yyvsp[0].order_type), (yyvsp[-1].expr)); } -#line 2267 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2269 "bison_parser.cpp" /* yacc.c:1646 */ break; case 67: -#line 528 "bison_parser.y" /* yacc.c:1646 */ +#line 530 "bison_parser.y" /* yacc.c:1646 */ { (yyval.order) = NULL; } -#line 2273 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2275 "bison_parser.cpp" /* yacc.c:1646 */ break; case 68: -#line 532 "bison_parser.y" /* yacc.c:1646 */ +#line 534 "bison_parser.y" /* yacc.c:1646 */ { (yyval.order_type) = kOrderAsc; } -#line 2279 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2281 "bison_parser.cpp" /* yacc.c:1646 */ break; case 69: -#line 533 "bison_parser.y" /* yacc.c:1646 */ +#line 535 "bison_parser.y" /* yacc.c:1646 */ { (yyval.order_type) = kOrderDesc; } -#line 2285 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2287 "bison_parser.cpp" /* yacc.c:1646 */ break; case 70: -#line 534 "bison_parser.y" /* yacc.c:1646 */ +#line 536 "bison_parser.y" /* yacc.c:1646 */ { (yyval.order_type) = kOrderAsc; } -#line 2291 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2293 "bison_parser.cpp" /* yacc.c:1646 */ break; case 71: -#line 539 "bison_parser.y" /* yacc.c:1646 */ +#line 541 "bison_parser.y" /* yacc.c:1646 */ { (yyval.limit) = new LimitDescription((yyvsp[0].expr)->ival, kNoOffset); delete (yyvsp[0].expr); } -#line 2297 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2299 "bison_parser.cpp" /* yacc.c:1646 */ break; case 72: -#line 540 "bison_parser.y" /* yacc.c:1646 */ +#line 542 "bison_parser.y" /* yacc.c:1646 */ { (yyval.limit) = new LimitDescription((yyvsp[-2].expr)->ival, (yyvsp[0].expr)->ival); delete (yyvsp[-2].expr); delete (yyvsp[0].expr); } -#line 2303 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2305 "bison_parser.cpp" /* yacc.c:1646 */ break; case 73: -#line 541 "bison_parser.y" /* yacc.c:1646 */ +#line 543 "bison_parser.y" /* yacc.c:1646 */ { (yyval.limit) = NULL; } -#line 2309 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2311 "bison_parser.cpp" /* yacc.c:1646 */ break; case 74: -#line 548 "bison_parser.y" /* yacc.c:1646 */ +#line 550 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr_vec) = new std::vector(); (yyval.expr_vec)->push_back((yyvsp[0].expr)); } -#line 2315 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2317 "bison_parser.cpp" /* yacc.c:1646 */ break; case 75: -#line 549 "bison_parser.y" /* yacc.c:1646 */ +#line 551 "bison_parser.y" /* yacc.c:1646 */ { (yyvsp[-2].expr_vec)->push_back((yyvsp[0].expr)); (yyval.expr_vec) = (yyvsp[-2].expr_vec); } -#line 2321 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2323 "bison_parser.cpp" /* yacc.c:1646 */ break; case 76: -#line 553 "bison_parser.y" /* yacc.c:1646 */ +#line 555 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr_vec) = new std::vector(); (yyval.expr_vec)->push_back((yyvsp[0].expr)); } -#line 2327 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2329 "bison_parser.cpp" /* yacc.c:1646 */ break; case 77: -#line 554 "bison_parser.y" /* yacc.c:1646 */ +#line 556 "bison_parser.y" /* yacc.c:1646 */ { (yyvsp[-2].expr_vec)->push_back((yyvsp[0].expr)); (yyval.expr_vec) = (yyvsp[-2].expr_vec); } -#line 2333 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2335 "bison_parser.cpp" /* yacc.c:1646 */ break; case 78: -#line 558 "bison_parser.y" /* yacc.c:1646 */ +#line 560 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = (yyvsp[-1].expr); (yyval.expr)->alias = (yyvsp[0].sval); } -#line 2342 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2344 "bison_parser.cpp" /* yacc.c:1646 */ break; case 79: -#line 565 "bison_parser.y" /* yacc.c:1646 */ +#line 567 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = (yyvsp[-1].expr); } -#line 2348 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2350 "bison_parser.cpp" /* yacc.c:1646 */ break; case 87: -#line 579 "bison_parser.y" /* yacc.c:1646 */ +#line 581 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeOpUnary(Expr::UMINUS, (yyvsp[0].expr)); } -#line 2354 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2356 "bison_parser.cpp" /* yacc.c:1646 */ break; case 88: -#line 580 "bison_parser.y" /* yacc.c:1646 */ +#line 582 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeOpUnary(Expr::NOT, (yyvsp[0].expr)); } -#line 2360 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2362 "bison_parser.cpp" /* yacc.c:1646 */ break; case 90: -#line 585 "bison_parser.y" /* yacc.c:1646 */ +#line 587 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeOpBinary((yyvsp[-2].expr), '-', (yyvsp[0].expr)); } -#line 2366 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2368 "bison_parser.cpp" /* yacc.c:1646 */ break; case 91: -#line 586 "bison_parser.y" /* yacc.c:1646 */ +#line 588 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeOpBinary((yyvsp[-2].expr), '+', (yyvsp[0].expr)); } -#line 2372 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2374 "bison_parser.cpp" /* yacc.c:1646 */ break; case 92: -#line 587 "bison_parser.y" /* yacc.c:1646 */ +#line 589 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeOpBinary((yyvsp[-2].expr), '/', (yyvsp[0].expr)); } -#line 2378 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2380 "bison_parser.cpp" /* yacc.c:1646 */ break; case 93: -#line 588 "bison_parser.y" /* yacc.c:1646 */ +#line 590 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeOpBinary((yyvsp[-2].expr), '*', (yyvsp[0].expr)); } -#line 2384 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2386 "bison_parser.cpp" /* yacc.c:1646 */ break; case 94: -#line 589 "bison_parser.y" /* yacc.c:1646 */ +#line 591 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeOpBinary((yyvsp[-2].expr), '%', (yyvsp[0].expr)); } -#line 2390 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2392 "bison_parser.cpp" /* yacc.c:1646 */ break; case 95: -#line 590 "bison_parser.y" /* yacc.c:1646 */ +#line 592 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeOpBinary((yyvsp[-2].expr), '^', (yyvsp[0].expr)); } -#line 2396 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2398 "bison_parser.cpp" /* yacc.c:1646 */ break; case 96: -#line 591 "bison_parser.y" /* yacc.c:1646 */ +#line 593 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeOpBinary((yyvsp[-2].expr), Expr::AND, (yyvsp[0].expr)); } -#line 2402 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2404 "bison_parser.cpp" /* yacc.c:1646 */ break; case 97: -#line 592 "bison_parser.y" /* yacc.c:1646 */ +#line 594 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeOpBinary((yyvsp[-2].expr), Expr::OR, (yyvsp[0].expr)); } -#line 2408 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2410 "bison_parser.cpp" /* yacc.c:1646 */ break; case 98: -#line 593 "bison_parser.y" /* yacc.c:1646 */ +#line 595 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeOpBinary((yyvsp[-2].expr), Expr::LIKE, (yyvsp[0].expr)); } -#line 2414 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2416 "bison_parser.cpp" /* yacc.c:1646 */ break; case 99: -#line 594 "bison_parser.y" /* yacc.c:1646 */ +#line 596 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeOpBinary((yyvsp[-3].expr), Expr::NOT_LIKE, (yyvsp[0].expr)); } -#line 2420 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2422 "bison_parser.cpp" /* yacc.c:1646 */ break; case 100: -#line 599 "bison_parser.y" /* yacc.c:1646 */ +#line 601 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeOpBinary((yyvsp[-2].expr), '=', (yyvsp[0].expr)); } -#line 2426 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2428 "bison_parser.cpp" /* yacc.c:1646 */ break; case 101: -#line 600 "bison_parser.y" /* yacc.c:1646 */ +#line 602 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeOpBinary((yyvsp[-2].expr), Expr::NOT_EQUALS, (yyvsp[0].expr)); } -#line 2432 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2434 "bison_parser.cpp" /* yacc.c:1646 */ break; case 102: -#line 601 "bison_parser.y" /* yacc.c:1646 */ +#line 603 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeOpBinary((yyvsp[-2].expr), '<', (yyvsp[0].expr)); } -#line 2438 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2440 "bison_parser.cpp" /* yacc.c:1646 */ break; case 103: -#line 602 "bison_parser.y" /* yacc.c:1646 */ +#line 604 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeOpBinary((yyvsp[-2].expr), '>', (yyvsp[0].expr)); } -#line 2444 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2446 "bison_parser.cpp" /* yacc.c:1646 */ break; case 104: -#line 603 "bison_parser.y" /* yacc.c:1646 */ +#line 605 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeOpBinary((yyvsp[-2].expr), Expr::LESS_EQ, (yyvsp[0].expr)); } -#line 2450 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2452 "bison_parser.cpp" /* yacc.c:1646 */ break; case 105: -#line 604 "bison_parser.y" /* yacc.c:1646 */ +#line 606 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeOpBinary((yyvsp[-2].expr), Expr::GREATER_EQ, (yyvsp[0].expr)); } -#line 2456 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2458 "bison_parser.cpp" /* yacc.c:1646 */ break; case 106: -#line 608 "bison_parser.y" /* yacc.c:1646 */ +#line 610 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeFunctionRef((yyvsp[-4].sval), (yyvsp[-1].expr), (yyvsp[-2].bval)); } -#line 2462 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2464 "bison_parser.cpp" /* yacc.c:1646 */ break; case 107: -#line 612 "bison_parser.y" /* yacc.c:1646 */ +#line 614 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeColumnRef((yyvsp[0].sval)); } -#line 2468 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2470 "bison_parser.cpp" /* yacc.c:1646 */ break; case 108: -#line 613 "bison_parser.y" /* yacc.c:1646 */ +#line 615 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeColumnRef((yyvsp[-2].sval), (yyvsp[0].sval)); } -#line 2474 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2476 "bison_parser.cpp" /* yacc.c:1646 */ break; case 112: -#line 623 "bison_parser.y" /* yacc.c:1646 */ +#line 625 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeLiteral((yyvsp[0].sval)); } -#line 2480 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2482 "bison_parser.cpp" /* yacc.c:1646 */ break; case 113: -#line 628 "bison_parser.y" /* yacc.c:1646 */ +#line 630 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeLiteral((yyvsp[0].fval)); } -#line 2486 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2488 "bison_parser.cpp" /* yacc.c:1646 */ break; case 115: -#line 633 "bison_parser.y" /* yacc.c:1646 */ +#line 635 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makeLiteral((yyvsp[0].ival)); } -#line 2492 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2494 "bison_parser.cpp" /* yacc.c:1646 */ break; case 116: -#line 637 "bison_parser.y" /* yacc.c:1646 */ +#line 639 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = new Expr(kExprStar); } -#line 2498 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2500 "bison_parser.cpp" /* yacc.c:1646 */ break; case 117: -#line 642 "bison_parser.y" /* yacc.c:1646 */ +#line 644 "bison_parser.y" /* yacc.c:1646 */ { (yyval.expr) = Expr::makePlaceholder(yylloc.total_column); yyloc.placeholder_list.push_back((yyval.expr)); } -#line 2507 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2509 "bison_parser.cpp" /* yacc.c:1646 */ break; case 119: -#line 654 "bison_parser.y" /* yacc.c:1646 */ +#line 656 "bison_parser.y" /* yacc.c:1646 */ { (yyvsp[0].table_vec)->push_back((yyvsp[-2].table)); auto tbl = new TableRef(kTableCrossProduct); tbl->list = (yyvsp[0].table_vec); (yyval.table) = tbl; } -#line 2518 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2520 "bison_parser.cpp" /* yacc.c:1646 */ break; case 121: -#line 665 "bison_parser.y" /* yacc.c:1646 */ +#line 667 "bison_parser.y" /* yacc.c:1646 */ { auto tbl = new TableRef(kTableSelect); tbl->select = (yyvsp[-2].select_stmt); tbl->alias = (yyvsp[0].sval); (yyval.table) = tbl; } -#line 2529 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2531 "bison_parser.cpp" /* yacc.c:1646 */ break; case 123: -#line 676 "bison_parser.y" /* yacc.c:1646 */ +#line 678 "bison_parser.y" /* yacc.c:1646 */ { (yyval.table_vec) = new std::vector(); (yyval.table_vec)->push_back((yyvsp[0].table)); } -#line 2535 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2537 "bison_parser.cpp" /* yacc.c:1646 */ break; case 124: -#line 677 "bison_parser.y" /* yacc.c:1646 */ +#line 679 "bison_parser.y" /* yacc.c:1646 */ { (yyvsp[-2].table_vec)->push_back((yyvsp[0].table)); (yyval.table_vec) = (yyvsp[-2].table_vec); } -#line 2541 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2543 "bison_parser.cpp" /* yacc.c:1646 */ break; case 125: -#line 682 "bison_parser.y" /* yacc.c:1646 */ +#line 684 "bison_parser.y" /* yacc.c:1646 */ { auto tbl = new TableRef(kTableName); tbl->name = (yyvsp[-1].sval); tbl->alias = (yyvsp[0].sval); (yyval.table) = tbl; } -#line 2552 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2554 "bison_parser.cpp" /* yacc.c:1646 */ break; case 126: -#line 692 "bison_parser.y" /* yacc.c:1646 */ +#line 694 "bison_parser.y" /* yacc.c:1646 */ { (yyval.table) = new TableRef(kTableName); (yyval.table)->name = (yyvsp[0].sval); } -#line 2561 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2563 "bison_parser.cpp" /* yacc.c:1646 */ break; case 129: -#line 706 "bison_parser.y" /* yacc.c:1646 */ +#line 708 "bison_parser.y" /* yacc.c:1646 */ { (yyval.sval) = (yyvsp[0].sval); } -#line 2567 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2569 "bison_parser.cpp" /* yacc.c:1646 */ break; case 132: -#line 712 "bison_parser.y" /* yacc.c:1646 */ +#line 714 "bison_parser.y" /* yacc.c:1646 */ { (yyval.sval) = NULL; } -#line 2573 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2575 "bison_parser.cpp" /* yacc.c:1646 */ break; case 133: -#line 721 "bison_parser.y" /* yacc.c:1646 */ +#line 723 "bison_parser.y" /* yacc.c:1646 */ { (yyval.table) = new TableRef(kTableJoin); (yyval.table)->join = new JoinDefinition(); @@ -2582,64 +2584,64 @@ yyreduce: (yyval.table)->join->right = (yyvsp[-2].table); (yyval.table)->join->condition = (yyvsp[0].expr); } -#line 2586 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2588 "bison_parser.cpp" /* yacc.c:1646 */ break; case 134: -#line 732 "bison_parser.y" /* yacc.c:1646 */ +#line 734 "bison_parser.y" /* yacc.c:1646 */ { (yyval.uval) = kJoinInner; } -#line 2592 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2594 "bison_parser.cpp" /* yacc.c:1646 */ break; case 135: -#line 733 "bison_parser.y" /* yacc.c:1646 */ +#line 735 "bison_parser.y" /* yacc.c:1646 */ { (yyval.uval) = kJoinOuter; } -#line 2598 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2600 "bison_parser.cpp" /* yacc.c:1646 */ break; case 136: -#line 734 "bison_parser.y" /* yacc.c:1646 */ +#line 736 "bison_parser.y" /* yacc.c:1646 */ { (yyval.uval) = kJoinLeft; } -#line 2604 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2606 "bison_parser.cpp" /* yacc.c:1646 */ break; case 137: -#line 735 "bison_parser.y" /* yacc.c:1646 */ +#line 737 "bison_parser.y" /* yacc.c:1646 */ { (yyval.uval) = kJoinRight; } -#line 2610 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2612 "bison_parser.cpp" /* yacc.c:1646 */ break; case 138: -#line 736 "bison_parser.y" /* yacc.c:1646 */ +#line 738 "bison_parser.y" /* yacc.c:1646 */ { (yyval.uval) = kJoinInner; } -#line 2616 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2618 "bison_parser.cpp" /* yacc.c:1646 */ break; case 139: -#line 742 "bison_parser.y" /* yacc.c:1646 */ +#line 744 "bison_parser.y" /* yacc.c:1646 */ { auto tbl = new TableRef(kTableSelect); tbl->select = (yyvsp[-2].select_stmt); tbl->alias = (yyvsp[0].sval); (yyval.table) = tbl; } -#line 2627 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2629 "bison_parser.cpp" /* yacc.c:1646 */ break; case 144: -#line 767 "bison_parser.y" /* yacc.c:1646 */ +#line 769 "bison_parser.y" /* yacc.c:1646 */ { (yyval.str_vec) = new std::vector(); (yyval.str_vec)->push_back((yyvsp[0].sval)); } -#line 2633 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2635 "bison_parser.cpp" /* yacc.c:1646 */ break; case 145: -#line 768 "bison_parser.y" /* yacc.c:1646 */ +#line 770 "bison_parser.y" /* yacc.c:1646 */ { (yyvsp[-2].str_vec)->push_back((yyvsp[0].sval)); (yyval.str_vec) = (yyvsp[-2].str_vec); } -#line 2639 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2641 "bison_parser.cpp" /* yacc.c:1646 */ break; -#line 2643 "bison_parser.cpp" /* yacc.c:1646 */ +#line 2645 "bison_parser.cpp" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -2874,7 +2876,7 @@ yyreturn: #endif return yyresult; } -#line 771 "bison_parser.y" /* yacc.c:1906 */ +#line 773 "bison_parser.y" /* yacc.c:1906 */ /********************************* ** Section 4: Additional C code diff --git a/src/parser/bison_parser.h b/src/parser/bison_parser.h index 21a9415..67cfa52 100644 --- a/src/parser/bison_parser.h +++ b/src/parser/bison_parser.h @@ -48,9 +48,12 @@ extern int hsql_debug; #endif /* "%code requires" blocks. */ -#line 43 "bison_parser.y" /* yacc.c:1909 */ +#line 42 "bison_parser.y" /* yacc.c:1909 */ // %code requires block + +#include "../sql/statements.h" +#include "../SQLParserResult.h" #include "parser_typedef.h" // Auto update column and line number @@ -68,7 +71,7 @@ extern int hsql_debug; } \ } -#line 72 "bison_parser.h" /* yacc.c:1909 */ +#line 75 "bison_parser.h" /* yacc.c:1909 */ /* Token type. */ #ifndef HSQL_TOKENTYPE @@ -206,7 +209,7 @@ extern int hsql_debug; typedef union HSQL_STYPE HSQL_STYPE; union HSQL_STYPE { -#line 99 "bison_parser.y" /* yacc.c:1909 */ +#line 101 "bison_parser.y" /* yacc.c:1909 */ double fval; int64_t ival; @@ -234,7 +237,7 @@ union HSQL_STYPE hsql::GroupByDescription* group_t; hsql::UpdateClause* update_t; - hsql::SQLStatementList* stmt_list; + hsql::SQLParserResult* stmt_list; std::vector* str_vec; std::vector* table_vec; @@ -242,7 +245,7 @@ union HSQL_STYPE std::vector* update_vec; std::vector* expr_vec; -#line 246 "bison_parser.h" /* yacc.c:1909 */ +#line 249 "bison_parser.h" /* yacc.c:1909 */ }; # define HSQL_STYPE_IS_TRIVIAL 1 # define HSQL_STYPE_IS_DECLARED 1 @@ -264,6 +267,6 @@ struct HSQL_LTYPE -int hsql_parse (hsql::SQLStatementList** result, yyscan_t scanner); +int hsql_parse (hsql::SQLParserResult** result, yyscan_t scanner); #endif /* !YY_HSQL_BISON_PARSER_H_INCLUDED */ diff --git a/src/parser/bison_parser.y b/src/parser/bison_parser.y index 54616bd..62e3009 100644 --- a/src/parser/bison_parser.y +++ b/src/parser/bison_parser.y @@ -11,7 +11,6 @@ ** Section 1: C Declarations *********************************/ -#include "../sqltypes.h" #include "bison_parser.h" #include "flex_lexer.h" @@ -19,13 +18,13 @@ using namespace hsql; -int yyerror(YYLTYPE* llocp, SQLStatementList** result, yyscan_t scanner, const char *msg) { +int yyerror(YYLTYPE* llocp, SQLParserResult** result, yyscan_t scanner, const char *msg) { - SQLStatementList* list = new SQLStatementList(); + SQLParserResult* list = new SQLParserResult(); list->isValid = false; - list->parser_msg = strdup(msg); - list->error_line = llocp->first_line; - list->error_col = llocp->first_column; + list->errorMsg = strdup(msg); + list->errorLine = llocp->first_line; + list->errorColumn = llocp->first_column; *result = list; return 0; @@ -42,6 +41,9 @@ int yyerror(YYLTYPE* llocp, SQLStatementList** result, yyscan_t scanner, const c // Specify code that is included in the generated .h and .c files %code requires { // %code requires block + +#include "../sql/statements.h" +#include "../SQLParserResult.h" #include "parser_typedef.h" // Auto update column and line number @@ -89,7 +91,7 @@ int yyerror(YYLTYPE* llocp, SQLStatementList** result, yyscan_t scanner, const c %lex-param { yyscan_t scanner } // Define additional parameters for yyparse -%parse-param { hsql::SQLStatementList** result } +%parse-param { hsql::SQLParserResult** result } %parse-param { yyscan_t scanner } @@ -123,7 +125,7 @@ int yyerror(YYLTYPE* llocp, SQLStatementList** result, yyscan_t scanner, const c hsql::GroupByDescription* group_t; hsql::UpdateClause* update_t; - hsql::SQLStatementList* stmt_list; + hsql::SQLParserResult* stmt_list; std::vector* str_vec; std::vector* table_vec; @@ -231,7 +233,7 @@ input: statement_list: - statement { $$ = new SQLStatementList($1); } + statement { $$ = new SQLParserResult($1); } | statement_list ';' statement { $1->addStatement($3); $$ = $1; } ; @@ -265,7 +267,7 @@ prepare_statement: PREPARE IDENTIFIER ':' preparable_statement { $$ = new PrepareStatement(); $$->name = $2; - $$->query = new SQLStatementList($4); + $$->query = new SQLParserResult($4); } | PREPARE IDENTIFIER '{' statement_list opt_semicolon '}' { $$ = new PrepareStatement(); @@ -293,8 +295,8 @@ execute_statement: import_statement: IMPORT FROM import_file_type FILE file_path INTO table_name { $$ = new ImportStatement((ImportStatement::ImportType) $3); - $$->file_path = $5; - $$->table_name = $7; + $$->filePath = $5; + $$->tableName = $7; } ; @@ -315,14 +317,14 @@ file_path: create_statement: CREATE TABLE opt_not_exists table_name FROM TBL FILE file_path { $$ = new CreateStatement(CreateStatement::kTableFromTbl); - $$->if_not_exists = $3; - $$->table_name = $4; - $$->file_path = $8; + $$->ifNotExists = $3; + $$->tableName = $4; + $$->filePath = $8; } | CREATE TABLE opt_not_exists table_name '(' column_def_commalist ')' { $$ = new CreateStatement(CreateStatement::kTable); - $$->if_not_exists = $3; - $$->table_name = $4; + $$->ifNotExists = $3; + $$->tableName = $4; $$->columns = $6; } ; @@ -376,7 +378,7 @@ drop_statement: delete_statement: DELETE FROM table_name opt_where { $$ = new DeleteStatement(); - $$->table_name = $3; + $$->tableName = $3; $$->expr = $4; } ; @@ -384,7 +386,7 @@ delete_statement: truncate_statement: TRUNCATE table_name { $$ = new DeleteStatement(); - $$->table_name = $2; + $$->tableName = $2; } ; @@ -396,13 +398,13 @@ truncate_statement: insert_statement: INSERT INTO table_name opt_column_list VALUES '(' literal_list ')' { $$ = new InsertStatement(InsertStatement::kInsertValues); - $$->table_name = $3; + $$->tableName = $3; $$->columns = $4; $$->values = $7; } | INSERT INTO table_name opt_column_list select_no_paren { $$ = new InsertStatement(InsertStatement::kInsertSelect); - $$->table_name = $3; + $$->tableName = $3; $$->columns = $4; $$->select = $5; } @@ -467,7 +469,7 @@ select_no_paren: // TODO: capture type of set_operator // TODO: might overwrite order and limit of first select here $$ = $1; - $$->union_select = $3; + $$->unionSelect = $3; $$->order = $4; $$->limit = $5; } @@ -482,11 +484,11 @@ set_operator: select_clause: SELECT opt_distinct select_list from_clause opt_where opt_group { $$ = new SelectStatement(); - $$->select_distinct = $2; - $$->select_list = $3; - $$->from_table = $4; - $$->where_clause = $5; - $$->group_by = $6; + $$->selectDistinct = $2; + $$->selectList = $3; + $$->fromTable = $4; + $$->whereClause = $5; + $$->groupBy = $6; } ; diff --git a/src/parser/flex_lexer.cpp b/src/parser/flex_lexer.cpp index ae00970..728a210 100644 --- a/src/parser/flex_lexer.cpp +++ b/src/parser/flex_lexer.cpp @@ -1545,7 +1545,7 @@ static yyconst flex_int16_t yy_chk[3639] = ***************************/ #line 12 "flex_lexer.l" -#include "../sqltypes.h" +#include "../sql/Expr.h" #include "bison_parser.h" #include diff --git a/src/parser/flex_lexer.l b/src/parser/flex_lexer.l index 44d955b..13e1054 100644 --- a/src/parser/flex_lexer.l +++ b/src/parser/flex_lexer.l @@ -10,7 +10,7 @@ ***************************/ %{ -#include "../sqltypes.h" +#include "../sql/Expr.h" #include "bison_parser.h" #include diff --git a/src/sql/CreateStatement.h b/src/sql/CreateStatement.h index 348cb12..6c9dbf7 100644 --- a/src/sql/CreateStatement.h +++ b/src/sql/CreateStatement.h @@ -4,65 +4,59 @@ #include "SQLStatement.h" namespace hsql { + /** + * Represents definition of a table column + */ + struct ColumnDefinition { + enum DataType { + TEXT, + INT, + DOUBLE + }; -/** - * @struct ColumnDefinition - * @brief Represents definition of a table column - */ -struct ColumnDefinition { - enum DataType { - TEXT, - INT, - DOUBLE - }; + ColumnDefinition(char* name, DataType type) : + name(name), + type(type) {} - ColumnDefinition(char* name, DataType type) : - name(name), - type(type) {} + virtual ~ColumnDefinition() { + delete name; + } - virtual ~ColumnDefinition() { - delete name; - } + char* name; + DataType type; + }; - char* name; - DataType type; -}; + /** + * Represents SQL Create statements. + * Example: "CREATE TABLE students (name TEXT, student_number INTEGER, city TEXT, grade DOUBLE)" + */ + struct CreateStatement : SQLStatement { + enum CreateType { + kTable, + kTableFromTbl // Hyrise file format + }; + CreateStatement(CreateType type) : + SQLStatement(kStmtCreate), + type(type), + ifNotExists(false), + filePath(NULL), + tableName(NULL), + columns(NULL) {}; -/** - * @struct CreateStatement - * @brief Represents "CREATE TABLE students (name TEXT, student_number INTEGER, city TEXT, grade DOUBLE)" - */ -struct CreateStatement : SQLStatement { - enum CreateType { - kTable, - kTableFromTbl, // Hyrise file format - }; - - CreateStatement(CreateType type) : - SQLStatement(kStmtCreate), - type(type), - if_not_exists(false), - columns(NULL), - file_path(NULL), - table_name(NULL) {}; - - virtual ~CreateStatement() { - delete columns; - delete file_path; - delete table_name; - } - - CreateType type; - bool if_not_exists; - - std::vector* columns; - - const char* file_path; - const char* table_name; -}; + virtual ~CreateStatement() { + delete columns; + delete filePath; + delete tableName; + } + CreateType type; + bool ifNotExists; + const char* filePath; + const char* tableName; + std::vector* columns; + }; } // namespace hsql #endif \ No newline at end of file diff --git a/src/sql/DeleteStatement.h b/src/sql/DeleteStatement.h index 516702c..202672c 100644 --- a/src/sql/DeleteStatement.h +++ b/src/sql/DeleteStatement.h @@ -4,31 +4,26 @@ #include "SQLStatement.h" namespace hsql { + /** + * Represents SQL Delete statements. + * Example: "DELETE FROM students WHERE grade > 3.0" + * + * Note: if (expr == NULL) => delete all rows (truncate) + */ + struct DeleteStatement : SQLStatement { + DeleteStatement() : + SQLStatement(kStmtDelete), + tableName(NULL), + expr(NULL) {}; + virtual ~DeleteStatement() { + delete tableName; + delete expr; + } -/** - * @struct DeleteStatement - * @brief Represents "DELETE FROM students WHERE grade > 3.0" - * - * If expr == NULL => delete all rows (truncate) - */ -struct DeleteStatement : SQLStatement { - DeleteStatement() : - SQLStatement(kStmtDelete), - table_name(NULL), - expr(NULL) {}; - - virtual ~DeleteStatement() { - delete table_name; - delete expr; - } - - - char* table_name; - Expr* expr; -}; - - + char* tableName; + Expr* expr; + }; } // namespace hsql #endif \ No newline at end of file diff --git a/src/sql/DropStatement.h b/src/sql/DropStatement.h index 32a7b1c..6c2aa10 100644 --- a/src/sql/DropStatement.h +++ b/src/sql/DropStatement.h @@ -4,39 +4,31 @@ #include "SQLStatement.h" namespace hsql { + /** + * Represents SQL Delete statements. + * Example "DROP TABLE students;" + */ + struct DropStatement : SQLStatement { + enum EntityType { + kTable, + kSchema, + kIndex, + kView, + kPreparedStatement + }; + DropStatement(EntityType type) : + SQLStatement(kStmtDrop), + type(type), + name(NULL) {} -/** - * @struct DropStatement - * @brief Represents "DROP TABLE" - */ -struct DropStatement : SQLStatement { - enum EntityType { - kTable, - kSchema, - kIndex, - kView, - kPreparedStatement - }; - - - DropStatement(EntityType type) : - SQLStatement(kStmtDrop), - type(type), - name(NULL) {} - - virtual ~DropStatement() { - delete name; - } - - - EntityType type; - const char* name; -}; - - - + virtual ~DropStatement() { + delete name; + } + EntityType type; + const char* name; + }; } // namespace hsql #endif \ No newline at end of file diff --git a/src/sql/ExecuteStatement.h b/src/sql/ExecuteStatement.h index bc314ea..1896bbb 100644 --- a/src/sql/ExecuteStatement.h +++ b/src/sql/ExecuteStatement.h @@ -4,29 +4,24 @@ #include "SQLStatement.h" namespace hsql { + /** + * Represents SQL Execute statements. + * Example: "EXECUTE ins_prep(100, "test", 2.3);" + */ + struct ExecuteStatement : SQLStatement { + ExecuteStatement() : + SQLStatement(kStmtExecute), + name(NULL), + parameters(NULL) {} + virtual ~ExecuteStatement() { + delete name; + delete parameters; + } -/** - * @struct ExecuteStatement - * @brief Represents "EXECUTE ins_prep(100, "test", 2.3);" - */ -struct ExecuteStatement : SQLStatement { - ExecuteStatement() : - SQLStatement(kStmtExecute), - name(NULL), - parameters(NULL) {} - - virtual ~ExecuteStatement() { - delete name; - delete parameters; - } - - const char* name; - std::vector* parameters; -}; - - - + const char* name; + std::vector* parameters; + }; } // namsepace hsql #endif \ No newline at end of file diff --git a/src/sql/Expr.cpp b/src/sql/Expr.cpp index f8ec75d..04b1c79 100644 --- a/src/sql/Expr.cpp +++ b/src/sql/Expr.cpp @@ -5,98 +5,98 @@ namespace hsql { -char* substr(const char* source, int from, int to) { - int len = to-from; - char* copy = new char[len+1]; - strncpy(copy, source+from, len); - copy[len] = '\0'; - return copy; -} + char* substr(const char* source, int from, int to) { + int len = to-from; + char* copy = new char[len+1]; + strncpy(copy, source+from, len); + copy[len] = '\0'; + return copy; + } -Expr* Expr::makeOpUnary(OperatorType op, Expr* expr) { - Expr* e = new Expr(kExprOperator); - e->op_type = op; - e->expr = expr; - e->expr2 = NULL; - return e; -} + Expr* Expr::makeOpUnary(OperatorType op, Expr* expr) { + Expr* e = new Expr(kExprOperator); + e->op_type = op; + e->expr = expr; + e->expr2 = NULL; + return e; + } -Expr* Expr::makeOpBinary(Expr* expr1, OperatorType op, Expr* expr2) { - Expr* e = new Expr(kExprOperator); - e->op_type = op; - e->op_char = 0; - e->expr = expr1; - e->expr2 = expr2; - return e; -} + Expr* Expr::makeOpBinary(Expr* expr1, OperatorType op, Expr* expr2) { + Expr* e = new Expr(kExprOperator); + e->op_type = op; + e->op_char = 0; + e->expr = expr1; + e->expr2 = expr2; + return e; + } -Expr* Expr::makeOpBinary(Expr* expr1, char op, Expr* expr2) { - Expr* e = new Expr(kExprOperator); - e->op_type = SIMPLE_OP; - e->op_char = op; - e->expr = expr1; - e->expr2 = expr2; - return e; -} + Expr* Expr::makeOpBinary(Expr* expr1, char op, Expr* expr2) { + Expr* e = new Expr(kExprOperator); + e->op_type = SIMPLE_OP; + e->op_char = op; + e->expr = expr1; + e->expr2 = expr2; + return e; + } -Expr* Expr::makeLiteral(int64_t val) { - Expr* e = new Expr(kExprLiteralInt); - e->ival = val; - return e; -} + Expr* Expr::makeLiteral(int64_t val) { + Expr* e = new Expr(kExprLiteralInt); + e->ival = val; + return e; + } -Expr* Expr::makeLiteral(double value) { - Expr* e = new Expr(kExprLiteralFloat); - e->fval = value; - return e; -} + Expr* Expr::makeLiteral(double value) { + Expr* e = new Expr(kExprLiteralFloat); + e->fval = value; + return e; + } -Expr* Expr::makeLiteral(char* string) { - Expr* e = new Expr(kExprLiteralString); - e->name = string; - return e; -} + Expr* Expr::makeLiteral(char* string) { + Expr* e = new Expr(kExprLiteralString); + e->name = string; + return e; + } -Expr* Expr::makeColumnRef(char* name) { - Expr* e = new Expr(kExprColumnRef); - e->name = name; - return e; -} + Expr* Expr::makeColumnRef(char* name) { + Expr* e = new Expr(kExprColumnRef); + e->name = name; + return e; + } -Expr* Expr::makeColumnRef(char* table, char* name) { - Expr* e = new Expr(kExprColumnRef); - e->name = name; - e->table = table; - return e; -} + Expr* Expr::makeColumnRef(char* table, char* name) { + Expr* e = new Expr(kExprColumnRef); + e->name = name; + e->table = table; + return e; + } -Expr* Expr::makeFunctionRef(char* func_name, Expr* expr, bool distinct) { - Expr* e = new Expr(kExprFunctionRef); - e->name = func_name; - e->expr = expr; - e->distinct = distinct; - return e; -} + Expr* Expr::makeFunctionRef(char* func_name, Expr* expr, bool distinct) { + Expr* e = new Expr(kExprFunctionRef); + e->name = func_name; + e->expr = expr; + e->distinct = distinct; + return e; + } -Expr* Expr::makePlaceholder(int id) { - Expr* e = new Expr(kExprPlaceholder); - e->ival = id; - return e; -} + Expr* Expr::makePlaceholder(int id) { + Expr* e = new Expr(kExprPlaceholder); + e->ival = id; + return e; + } -Expr::~Expr() { - delete expr; - delete expr2; - delete name; - delete table; -} + Expr::~Expr() { + delete expr; + delete expr2; + delete name; + delete table; + } } // namespace hsql \ No newline at end of file diff --git a/src/sql/Expr.h b/src/sql/Expr.h index 97be9be..9301ea6 100644 --- a/src/sql/Expr.h +++ b/src/sql/Expr.h @@ -7,116 +7,127 @@ namespace hsql { // Helper function -char* substr(const char* source, int from, int to); + char* substr(const char* source, int from, int to); -typedef enum { - kExprLiteralFloat, - kExprLiteralString, - kExprLiteralInt, - kExprStar, - kExprPlaceholder, - kExprColumnRef, - kExprFunctionRef, - kExprOperator -} ExprType; + typedef enum { + kExprLiteralFloat, + kExprLiteralString, + kExprLiteralInt, + kExprStar, + kExprPlaceholder, + kExprColumnRef, + kExprFunctionRef, + kExprOperator + } ExprType; -typedef struct Expr Expr; + typedef struct Expr Expr; -/** - * @class Expr - * @brief Represents SQL expressions (i.e. literals, operators, column_refs) - * - * TODO: When destructing a placeholder expression, we might need to alter the placeholder_list - */ -struct Expr { - /** - * Operator types. These are important for expressions of type kExprOperator - * Trivial types are those that can be described by a single character e.g: - * + - * / < > = % - * Non-trivial are: - * <> <= >= LIKE ISNULL NOT - */ - typedef enum { - SIMPLE_OP, - // Binary - NOT_EQUALS, - LESS_EQ, - GREATER_EQ, - LIKE, - NOT_LIKE, - AND, - OR, - // Unary - NOT, - UMINUS, - ISNULL - } OperatorType; + /** + * Represents SQL expressions (i.e. literals, operators, column_refs) + * + * TODO: When destructing a placeholder expression, we might need to alter the placeholder_list + */ + struct Expr { + /** + * Operator types. These are important for expressions of type kExprOperator + * Trivial types are those that can be described by a single character e.g: + * + - * / < > = % + * Non-trivial are: + * <> <= >= LIKE ISNULL NOT + */ + typedef enum { + SIMPLE_OP, + // Binary + NOT_EQUALS, + LESS_EQ, + GREATER_EQ, + LIKE, + NOT_LIKE, + AND, + OR, + // Unary + NOT, + UMINUS, + ISNULL + } OperatorType; - Expr(ExprType type) : - type(type), - expr(NULL), - expr2(NULL), - name(NULL), - table(NULL), - alias(NULL) {}; + Expr(ExprType type) : + type(type), + expr(NULL), + expr2(NULL), + name(NULL), + table(NULL), + alias(NULL) {}; - // Interesting side-effect: - // Making the destructor virtual used to cause segmentation faults - ~Expr(); - - ExprType type; + // Interesting side-effect: + // Making the destructor virtual used to cause segmentation faults + ~Expr(); - Expr* expr; - Expr* expr2; - char* name; - char* table; - char* alias; - float fval; - int64_t ival; - int64_t ival2; + ExprType type; - OperatorType op_type; - char op_char; - bool distinct; + Expr* expr; + Expr* expr2; + char* name; + char* table; + char* alias; + float fval; + int64_t ival; + int64_t ival2; + + OperatorType op_type; + char op_char; + bool distinct; - /** - * Convenience accessor methods - */ - inline bool isType(ExprType e_type) { return e_type == type; } - inline bool isLiteral() { return isType(kExprLiteralInt) || isType(kExprLiteralFloat) || isType(kExprLiteralString) || isType(kExprPlaceholder); } - inline bool hasAlias() { return alias != NULL; } - inline bool hasTable() { return table != NULL; } - inline char* getName() { - if (alias != NULL) return alias; - else return name; - } - inline bool isSimpleOp() { return op_type == SIMPLE_OP; } - inline bool isSimpleOp(char op) { return isSimpleOp() && op_char == op; } + /** + * Convenience accessor methods + */ + inline bool isType(ExprType e_type) { + return e_type == type; + } + inline bool isLiteral() { + return isType(kExprLiteralInt) || isType(kExprLiteralFloat) || isType(kExprLiteralString) || isType(kExprPlaceholder); + } + inline bool hasAlias() { + return alias != NULL; + } + inline bool hasTable() { + return table != NULL; + } + inline char* getName() { + if (alias != NULL) return alias; + else return name; + } + inline bool isSimpleOp() { + return op_type == SIMPLE_OP; + } + inline bool isSimpleOp(char op) { + return isSimpleOp() && op_char == op; + } - /** - * Static expression constructors - */ - static Expr* makeOpUnary(OperatorType op, Expr* expr); - static Expr* makeOpBinary(Expr* expr1, char op, Expr* expr2); - static Expr* makeOpBinary(Expr* expr1, OperatorType op, Expr* expr2); + /** + * Static expression constructors + */ + static Expr* makeOpUnary(OperatorType op, Expr* expr); + static Expr* makeOpBinary(Expr* expr1, char op, Expr* expr2); + static Expr* makeOpBinary(Expr* expr1, OperatorType op, Expr* expr2); - static Expr* makeLiteral(int64_t val); - static Expr* makeLiteral(double val); - static Expr* makeLiteral(char* val); + static Expr* makeLiteral(int64_t val); + static Expr* makeLiteral(double val); + static Expr* makeLiteral(char* val); - static Expr* makeColumnRef(char* name); - static Expr* makeColumnRef(char* table, char* name); - static Expr* makeFunctionRef(char* func_name, Expr* expr, bool distinct); + static Expr* makeColumnRef(char* name); + static Expr* makeColumnRef(char* table, char* name); + static Expr* makeFunctionRef(char* func_name, Expr* expr, bool distinct); - static Expr* makePlaceholder(int id); -}; + static Expr* makePlaceholder(int id); + }; // Zero initializes an Expr object and assigns it to a space in the heap // For Hyrise we still had to put in the explicit NULL constructor diff --git a/src/sql/ImportStatement.h b/src/sql/ImportStatement.h index c974053..7087f57 100644 --- a/src/sql/ImportStatement.h +++ b/src/sql/ImportStatement.h @@ -4,39 +4,30 @@ #include "SQLStatement.h" namespace hsql { + /** + * Represents SQL Import statements. + */ + struct ImportStatement : SQLStatement { + enum ImportType { + kImportCSV, + kImportTbl, // Hyrise file format + }; + ImportStatement(ImportType type) : + SQLStatement(kStmtImport), + type(type), + filePath(NULL), + tableName(NULL) {}; + virtual ~ImportStatement() { + delete filePath; + delete tableName; + } - -/** - * @struct ImportStatement - * @brief Represents "IMPORT" - */ -struct ImportStatement : SQLStatement { - enum ImportType { - kImportCSV, - kImportTbl, // Hyrise file format - }; - - - ImportStatement(ImportType type) : - SQLStatement(kStmtImport), - type(type), - file_path(NULL), - table_name(NULL) {}; - - virtual ~ImportStatement() { - delete file_path; - delete table_name; - } - - - ImportType type; - const char* file_path; - const char* table_name; -}; - - + ImportType type; + const char* filePath; + const char* tableName; + }; } // namespace hsql diff --git a/src/sql/InsertStatement.h b/src/sql/InsertStatement.h index 01aa576..9d23995 100644 --- a/src/sql/InsertStatement.h +++ b/src/sql/InsertStatement.h @@ -5,42 +5,37 @@ #include "SelectStatement.h" namespace hsql { + /** + * Represents SQL Insert statements. + * Example: "INSERT INTO students VALUES ('Max', 1112233, 'Musterhausen', 2.3)" + */ + struct InsertStatement : SQLStatement { + enum InsertType { + kInsertValues, + kInsertSelect + }; + InsertStatement(InsertType type) : + SQLStatement(kStmtInsert), + type(type), + tableName(NULL), + columns(NULL), + values(NULL), + select(NULL) {} -/** - * @struct InsertStatement - * @brief Represents "INSERT INTO students VALUES ('Max', 1112233, 'Musterhausen', 2.3)" - */ -struct InsertStatement : SQLStatement { - enum InsertType { - kInsertValues, - kInsertSelect - }; - - InsertStatement(InsertType type) : - SQLStatement(kStmtInsert), - type(type), - table_name(NULL), - columns(NULL), - values(NULL), - select(NULL) {} - - virtual ~InsertStatement() { - delete table_name; - delete columns; - delete values; - delete select; - } - - InsertType type; - const char* table_name; - std::vector* columns; - std::vector* values; - SelectStatement* select; -}; - - + virtual ~InsertStatement() { + delete tableName; + delete columns; + delete values; + delete select; + } + InsertType type; + const char* tableName; + std::vector* columns; + std::vector* values; + SelectStatement* select; + }; } // namsepace hsql #endif \ No newline at end of file diff --git a/src/sql/PrepareStatement.h b/src/sql/PrepareStatement.h index cf050fb..271293a 100644 --- a/src/sql/PrepareStatement.h +++ b/src/sql/PrepareStatement.h @@ -1,53 +1,49 @@ #ifndef __PREPARE_STATEMENT_H__ #define __PREPARE_STATEMENT_H__ +#include "../SQLParserResult.h" #include "SQLStatement.h" #include "SelectStatement.h" #include namespace hsql { + /** + * Represents SQL Prepare statements. + * Example: "PREPARE ins_prep: SELECT * FROM t1 WHERE c1 = ? AND c2 = ?" + */ + struct PrepareStatement : SQLStatement { + PrepareStatement() : + SQLStatement(kStmtPrepare), + name(NULL), + query(NULL) {} + virtual ~PrepareStatement() { + delete query; + delete name; + } -/** - * @struct PrepareStatement - * @brief Represents "PREPARE ins_prep: SELECT * FROM t1 WHERE c1 = ? AND c2 = ?" - */ -struct PrepareStatement : SQLStatement { - PrepareStatement() : - SQLStatement(kStmtPrepare), - name(NULL), - query(NULL) {} - - virtual ~PrepareStatement() { - delete query; - delete name; - } - - /** - * @param vector of placeholders that the parser found - * - * When setting the placeholders we need to make sure that they are in the correct order. - * To ensure that, during parsing we store the character position use that to sort the list here. - */ - void setPlaceholders(std::vector ph) { - for (void* e : ph) { - if (e != NULL) - placeholders.push_back((Expr*) e); - } - // Sort by col-id - 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 - for (uint i = 0; i < placeholders.size(); ++i) placeholders[i]->ival = i; - } - - const char* name; - SQLStatementList* query; - std::vector placeholders; -}; - + /** + * When setting the placeholders we need to make sure that they are in the correct order. + * To ensure that, during parsing we store the character position use that to sort the list here. + * + * @param vector of placeholders that the parser found + */ + void setPlaceholders(std::vector ph) { + for (void* e : ph) { + if (e != NULL) + placeholders.push_back((Expr*) e); + } + // Sort by col-id + 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 + for (uint i = 0; i < placeholders.size(); ++i) placeholders[i]->ival = i; + } + const char* name; + SQLParserResult* query; + std::vector placeholders; + }; } // namsepace hsql #endif \ No newline at end of file diff --git a/src/sql/SQLStatement.h b/src/sql/SQLStatement.h index e3d39a2..634e606 100644 --- a/src/sql/SQLStatement.h +++ b/src/sql/SQLStatement.h @@ -1,86 +1,42 @@ -/* - * SQLStatement.h - * Definition of the structure used to build the syntax tree. - */ -#ifndef __STATEMENT_H__ -#define __STATEMENT_H__ +#ifndef __SQLSTATEMENT_H__ +#define __SQLSTATEMENT_H__ #include "Expr.h" #include namespace hsql { + typedef enum { + kStmtError, // unused + kStmtSelect, + kStmtImport, + kStmtInsert, + kStmtUpdate, + kStmtDelete, + kStmtCreate, + kStmtDrop, + kStmtPrepare, + kStmtExecute, + kStmtExport, + kStmtRename, + kStmtAlter + } StatementType; + /** + * Base struct for every SQL statement + */ + struct SQLStatement { + SQLStatement(StatementType type) : + _type(type) {}; -typedef enum { - kStmtError, // Unused - kStmtSelect, - kStmtImport, - kStmtInsert, - kStmtUpdate, - kStmtDelete, - kStmtCreate, - kStmtDrop, - kStmtPrepare, - kStmtExecute, - kStmtExport, - kStmtRename, - kStmtAlter -} StatementType; - - -/** - * @struct SQLStatement - * @brief Base class for every SQLStatement - */ -struct SQLStatement { - SQLStatement(StatementType type) : - _type(type) {}; - - virtual ~SQLStatement() {} - - virtual StatementType type() { return _type; } - -private: - StatementType _type; -}; - - -/** - * @struct SQLStatementList - * @brief Represents the result of the SQLParser. If parsing was successful it is a list of SQLStatement. - */ -struct SQLStatementList { -public: - SQLStatementList() : - isValid(true), - parser_msg(NULL) {}; - - SQLStatementList(SQLStatement* stmt) : - isValid(true), - parser_msg(NULL) { - addStatement(stmt); - }; - - virtual ~SQLStatementList() { - for (std::vector::iterator it = statements.begin(); it != statements.end(); ++it) { - delete *it; - } - delete parser_msg; - } - - void addStatement(SQLStatement* stmt) { statements.push_back(stmt); } - SQLStatement* getStatement(int id) { return statements[id]; } - size_t numStatements() { return statements.size(); } - - std::vector statements; - bool isValid; - const char* parser_msg; - int error_line; - int error_col; -}; + virtual ~SQLStatement() {} + virtual StatementType type() { + return _type; + } + private: + StatementType _type; + }; } // namespace hsql - -#endif // __STATEMENT_H__ +#endif // __SQLSTATEMENT_H__ diff --git a/src/sql/SelectStatement.h b/src/sql/SelectStatement.h index 51ddf6e..d4ca6f5 100644 --- a/src/sql/SelectStatement.h +++ b/src/sql/SelectStatement.h @@ -6,103 +6,95 @@ #include "Table.h" namespace hsql { + typedef enum { + kOrderAsc, + kOrderDesc + } OrderType; + /** + * Description of the order by clause within a select statement + * TODO: hold multiple expressions to be sorted by + */ + struct OrderDescription { + OrderDescription(OrderType type, Expr* expr) : + type(type), + expr(expr) {} + virtual ~OrderDescription() { + delete expr; + } -/** - * @struct OrderDescription - * @brief Description of the order by clause within a select statement - * - * TODO: hold multiple expressions to be sorted by - */ -typedef enum { - kOrderAsc, - kOrderDesc -} OrderType; + OrderType type; + Expr* expr; + }; -struct OrderDescription { - OrderDescription(OrderType type, Expr* expr) : - type(type), - expr(expr) {} - - virtual ~OrderDescription() { - delete expr; - } + const int64_t kNoLimit = -1; + const int64_t kNoOffset = -1; - OrderType type; - Expr* expr; -}; + /** + * Description of the limit clause within a select statement + */ + struct LimitDescription { + LimitDescription(int64_t limit, int64_t offset) : + limit(limit), + offset(offset) {} -/** - * @struct LimitDescription - * @brief Description of the limit clause within a select statement - */ -const int64_t kNoLimit = -1; -const int64_t kNoOffset = -1; -struct LimitDescription { - LimitDescription(int64_t limit, int64_t offset) : - limit(limit), - offset(offset) {} + int64_t limit; + int64_t offset; + }; - int64_t limit; - int64_t offset; -}; + /** + * Description of the group-by clause within a select statement + */ + struct GroupByDescription { + GroupByDescription() : + columns(NULL), + having(NULL) {} -/** - * @struct GroupByDescription - */ -struct GroupByDescription { - GroupByDescription() : - columns(NULL), - having(NULL) {} + ~GroupByDescription() { + delete columns; + delete having; + } - ~GroupByDescription() { - delete columns; - delete having; - } + std::vector* columns; + Expr* having; + }; - std::vector* columns; - Expr* having; -}; + /** + * Representation of a full SQL select statement. + * TODO: add union_order and union_limit + */ + struct SelectStatement : SQLStatement { + SelectStatement() : + SQLStatement(kStmtSelect), + fromTable(NULL), + selectDistinct(false), + selectList(NULL), + whereClause(NULL), + groupBy(NULL), + unionSelect(NULL), + order(NULL), + limit(NULL) {}; -/** - * @struct SelectStatement - * @brief Representation of a full select statement. - * - * TODO: add union_order and union_limit - */ -struct SelectStatement : SQLStatement { - SelectStatement() : - SQLStatement(kStmtSelect), - from_table(NULL), - select_list(NULL), - where_clause(NULL), - group_by(NULL), - union_select(NULL), - order(NULL), - limit(NULL) {}; + virtual ~SelectStatement() { + delete fromTable; + delete selectList; + delete whereClause; + delete groupBy; + delete order; + delete limit; + } - virtual ~SelectStatement() { - delete from_table; - delete select_list; - delete where_clause; - delete group_by; - delete order; - delete limit; - } - - TableRef* from_table; - bool select_distinct; - std::vector* select_list; - Expr* where_clause; - GroupByDescription* group_by; - - SelectStatement* union_select; - OrderDescription* order; - LimitDescription* limit; -}; + TableRef* fromTable; + bool selectDistinct; + std::vector* selectList; + Expr* whereClause; + GroupByDescription* groupBy; + SelectStatement* unionSelect; + OrderDescription* order; + LimitDescription* limit; + }; } // namespace hsql - #endif \ No newline at end of file diff --git a/src/sql/Table.h b/src/sql/Table.h index b27c924..ec778a8 100644 --- a/src/sql/Table.h +++ b/src/sql/Table.h @@ -7,97 +7,99 @@ namespace hsql { -struct SelectStatement; -struct JoinDefinition; -struct TableRef; + struct SelectStatement; + struct JoinDefinition; + struct TableRef; -/** - * @enum TableRefType - * Types table references - */ -typedef enum { - kTableName, - kTableSelect, - kTableJoin, - kTableCrossProduct -} TableRefType; + /** + * @enum TableRefType + * Types table references + */ + typedef enum { + kTableName, + kTableSelect, + kTableJoin, + kTableCrossProduct + } TableRefType; -/** - * @struct TableRef - * @brief Holds reference to tables. Can be either table names or a select statement. - */ -struct TableRef { - TableRef(TableRefType type) : - type(type), - schema(NULL), - name(NULL), - alias(NULL), - select(NULL), - list(NULL), - join(NULL) {} - - virtual ~TableRef(); + /** + * @struct TableRef + * @brief Holds reference to tables. Can be either table names or a select statement. + */ + struct TableRef { + TableRef(TableRefType type) : + type(type), + schema(NULL), + name(NULL), + alias(NULL), + select(NULL), + list(NULL), + join(NULL) {} - TableRefType type; + virtual ~TableRef(); - char* schema; - char* name; - char* alias; + TableRefType type; - SelectStatement* select; - std::vector* list; - JoinDefinition* join; + char* schema; + char* name; + char* alias; + + SelectStatement* select; + std::vector* list; + JoinDefinition* join; - /** - * Convenience accessor methods - */ - inline bool hasSchema() { return schema != NULL; } + /** + * Convenience accessor methods + */ + inline bool hasSchema() { + return schema != NULL; + } - inline char* getName() { - if (alias != NULL) return alias; - else return name; - } -}; + inline char* getName() { + if (alias != NULL) return alias; + else return name; + } + }; -/** - * @enum JoinType - * Types of joins - */ -typedef enum { - kJoinInner, - kJoinOuter, - kJoinLeft, - kJoinRight, -} JoinType; + /** + * @enum JoinType + * Types of joins + */ + typedef enum { + kJoinInner, + kJoinOuter, + kJoinLeft, + kJoinRight, + } JoinType; -/** - * @struct JoinDefinition - * @brief Definition of a join table - */ -struct JoinDefinition { - JoinDefinition() : - left(NULL), - right(NULL), - condition(NULL), - type(kJoinInner) {} + /** + * @struct JoinDefinition + * @brief Definition of a join table + */ + struct JoinDefinition { + JoinDefinition() : + left(NULL), + right(NULL), + condition(NULL), + type(kJoinInner) {} - virtual ~JoinDefinition() { - delete left; - delete right; - delete condition; - } + virtual ~JoinDefinition() { + delete left; + delete right; + delete condition; + } - TableRef* left; - TableRef* right; - Expr* condition; + TableRef* left; + TableRef* right; + Expr* condition; - JoinType type; -}; + JoinType type; + }; diff --git a/src/sql/UpdateStatement.h b/src/sql/UpdateStatement.h index 9c88cdd..ad9fe5a 100644 --- a/src/sql/UpdateStatement.h +++ b/src/sql/UpdateStatement.h @@ -4,42 +4,35 @@ #include "SQLStatement.h" namespace hsql { + /** + * Represents "column = value" expressions + */ + struct UpdateClause { + char* column; + Expr* value; + }; + /** + * Represents SQL Update statements. + */ + struct UpdateStatement : SQLStatement { + UpdateStatement() : + SQLStatement(kStmtUpdate), + table(NULL), + updates(NULL), + where(NULL) {} -/** - * @struct UpdateClause - * @brief Represents "column = value" expressions - */ -struct UpdateClause { - char* column; - Expr* value; -}; - - -/** - * @struct UpdateStatement - * @brief Represents "UPDATE" - */ -struct UpdateStatement : SQLStatement { - UpdateStatement() : - SQLStatement(kStmtUpdate), - table(NULL), - updates(NULL), - where(NULL) {} - - virtual ~UpdateStatement() { - delete table; - delete updates; - delete where; - } - - // TODO: switch to char* instead of TableRef - TableRef* table; - std::vector* updates; - Expr* where; -}; - + virtual ~UpdateStatement() { + delete table; + delete updates; + delete where; + } + // TODO: switch to char* instead of TableRef + TableRef* table; + std::vector* updates; + Expr* where; + }; } // namsepace hsql #endif \ No newline at end of file diff --git a/src/sql/destruct.cpp b/src/sql/destruct.cpp index 73d1a7e..5e04742 100644 --- a/src/sql/destruct.cpp +++ b/src/sql/destruct.cpp @@ -5,12 +5,12 @@ namespace hsql { -TableRef::~TableRef() { - delete name; - delete alias; - delete select; - delete list; -} + TableRef::~TableRef() { + delete name; + delete alias; + delete select; + delete list; + } } // namespace hsql \ No newline at end of file diff --git a/src/sql/statements.h b/src/sql/statements.h new file mode 100644 index 0000000..13c4a30 --- /dev/null +++ b/src/sql/statements.h @@ -0,0 +1,14 @@ +#ifndef __STATEMENTS_H__ +#define __STATEMENTS_H__ + +#include "SelectStatement.h" +#include "ImportStatement.h" +#include "CreateStatement.h" +#include "InsertStatement.h" +#include "UpdateStatement.h" +#include "DeleteStatement.h" +#include "DropStatement.h" +#include "PrepareStatement.h" +#include "ExecuteStatement.h" + +#endif // __STATEMENTS_H__ \ No newline at end of file diff --git a/src/sqlhelper.cpp b/src/sqlhelper.cpp index 5ae1bd3..bf8dc1f 100644 --- a/src/sqlhelper.cpp +++ b/src/sqlhelper.cpp @@ -5,159 +5,204 @@ namespace hsql { -void printOperatorExpression(Expr* expr, uint num_indent); + void printOperatorExpression(Expr* expr, uint numIndent); -std::string indent(uint num_indent) { return std::string(num_indent, '\t'); } -void inprint(int64_t val, uint num_indent) { printf("%s%lld \n", indent(num_indent).c_str(), val); } -void inprint(float val, uint num_indent) { printf("%s%f\n", indent(num_indent).c_str(), val); } -void inprint(const char* val, uint num_indent) { printf("%s%s\n", indent(num_indent).c_str(), val); } -void inprint(const char* val, const char* val2, uint num_indent) { printf("%s%s->%s\n", indent(num_indent).c_str(), val, val2); } -void inprintC(char val, uint num_indent) { printf("%s%c\n", indent(num_indent).c_str(), val); } -void inprintU(uint64_t val, uint num_indent) { printf("%s%llu\n", indent(num_indent).c_str(), val); } - -void printTableRefInfo(TableRef* table, uint num_indent) { - switch (table->type) { - case kTableName: - inprint(table->name, num_indent); - break; - case kTableSelect: - printSelectStatementInfo(table->select, num_indent); - break; - case kTableJoin: - inprint("Join Table", num_indent); - inprint("Left", num_indent+1); - printTableRefInfo(table->join->left, num_indent+2); - inprint("Right", num_indent+1); - printTableRefInfo(table->join->right, num_indent+2); - inprint("Join Condition", num_indent+1); - printExpression(table->join->condition, num_indent+2); - break; - case kTableCrossProduct: - for (TableRef* tbl : *table->list) printTableRefInfo(tbl, num_indent); - break; - } - if (table->alias != NULL) { - inprint("Alias", num_indent+1); - inprint(table->alias, num_indent+2); - } -} - -void printOperatorExpression(Expr* expr, uint num_indent) { - if (expr == NULL) { inprint("null", num_indent); return; } - - switch (expr->op_type) { - case Expr::SIMPLE_OP: inprintC(expr->op_char, num_indent); break; - case Expr::AND: inprint("AND", num_indent); break; - case Expr::OR: inprint("OR", num_indent); break; - case Expr::NOT: inprint("NOT", num_indent); break; - default: inprintU(expr->op_type, num_indent); break; - } - printExpression(expr->expr, num_indent+1); - if (expr->expr2 != NULL) printExpression(expr->expr2, num_indent+1); -} - -void printExpression(Expr* expr, uint num_indent) { - switch (expr->type) { - case kExprStar: inprint("*", num_indent); break; - case kExprColumnRef: inprint(expr->name, num_indent); break; - // case kExprTableColumnRef: inprint(expr->table, expr->name, num_indent); break; - case kExprLiteralFloat: inprint(expr->fval, num_indent); break; - case kExprLiteralInt: inprint(expr->ival, num_indent); break; - case kExprLiteralString: inprint(expr->name, num_indent); break; - case kExprFunctionRef: inprint(expr->name, num_indent); inprint(expr->expr->name, num_indent+1); break; - case kExprOperator: printOperatorExpression(expr, num_indent); break; - default: fprintf(stderr, "Unrecognized expression type %d\n", expr->type); return; - } - if (expr->alias != NULL) { - inprint("Alias", num_indent+1); inprint(expr->alias, num_indent+2); - } -} - -void printSelectStatementInfo(SelectStatement* stmt, uint num_indent) { - inprint("SelectStatement", num_indent); - inprint("Fields:", num_indent+1); - for (Expr* expr : *stmt->select_list) printExpression(expr, num_indent+2); - - inprint("Sources:", num_indent+1); - printTableRefInfo(stmt->from_table, num_indent+2); - - if (stmt->where_clause != NULL) { - inprint("Search Conditions:", num_indent+1); - printExpression(stmt->where_clause, num_indent+2); - } - - - if (stmt->union_select != NULL) { - inprint("Union:", num_indent+1); - printSelectStatementInfo(stmt->union_select, num_indent+2); - } - - if (stmt->order != NULL) { - inprint("OrderBy:", num_indent+1); - printExpression(stmt->order->expr, num_indent+2); - if (stmt->order->type == kOrderAsc) inprint("ascending", num_indent+2); - else inprint("descending", num_indent+2); - } - - if (stmt->limit != NULL) { - inprint("Limit:", num_indent+1); - inprint(stmt->limit->limit, num_indent+2); - } -} - - - -void printImportStatementInfo(ImportStatement* stmt, uint num_indent) { - inprint("ImportStatment", num_indent); - inprint(stmt->file_path, num_indent+1); - inprint(stmt->table_name, num_indent+1); -} - -void printCreateStatementInfo(CreateStatement* stmt, uint num_indent) { - inprint("CreateStatment", num_indent); - inprint(stmt->table_name, num_indent+1); - inprint(stmt->file_path, num_indent+1); -} - -void printInsertStatementInfo(InsertStatement* stmt, uint num_indent) { - inprint("InsertStatment", num_indent); - inprint(stmt->table_name, num_indent+1); - if (stmt->columns != NULL) { - inprint("Columns", num_indent+1); - for (char* col_name : *stmt->columns) { - inprint(col_name, num_indent+2); + std::string indent(uint numIndent) { + return std::string(numIndent, '\t'); + } + void inprint(int64_t val, uint numIndent) { + printf("%s%ld \n", indent(numIndent).c_str(), val); + } + void inprint(float val, uint numIndent) { + printf("%s%f\n", indent(numIndent).c_str(), val); + } + void inprint(const char* val, uint numIndent) { + printf("%s%s\n", indent(numIndent).c_str(), val); + } + void inprint(const char* val, const char* val2, uint numIndent) { + printf("%s%s->%s\n", indent(numIndent).c_str(), val, val2); + } + void inprintC(char val, uint numIndent) { + printf("%s%c\n", indent(numIndent).c_str(), val); + } + void inprintU(uint64_t val, uint numIndent) { + printf("%s%lu\n", indent(numIndent).c_str(), val); } - } - switch (stmt->type) { - case InsertStatement::kInsertValues: - inprint("Values", num_indent+1); - for (Expr* expr : *stmt->values) { - printExpression(expr, num_indent+2); - } - break; - case InsertStatement::kInsertSelect: - printSelectStatementInfo(stmt->select, num_indent+1); - break; - } -} -void printStatementInfo(SQLStatement* stmt) { - switch (stmt->type()) { - case kStmtSelect: - printSelectStatementInfo((SelectStatement*) stmt, 0); - break; - case kStmtInsert: - printInsertStatementInfo((InsertStatement*) stmt, 0); - break; - case kStmtCreate: - printCreateStatementInfo((CreateStatement*) stmt, 0); - break; - case kStmtImport: - printImportStatementInfo((ImportStatement*) stmt, 0); - break; - default: - break; - } -} + void printTableRefInfo(TableRef* table, uint numIndent) { + switch (table->type) { + case kTableName: + inprint(table->name, numIndent); + break; + case kTableSelect: + printSelectStatementInfo(table->select, numIndent); + break; + case kTableJoin: + inprint("Join Table", numIndent); + inprint("Left", numIndent+1); + printTableRefInfo(table->join->left, numIndent+2); + inprint("Right", numIndent+1); + printTableRefInfo(table->join->right, numIndent+2); + inprint("Join Condition", numIndent+1); + printExpression(table->join->condition, numIndent+2); + break; + case kTableCrossProduct: + for (TableRef* tbl : *table->list) printTableRefInfo(tbl, numIndent); + break; + } + if (table->alias != NULL) { + inprint("Alias", numIndent+1); + inprint(table->alias, numIndent+2); + } + } + + void printOperatorExpression(Expr* expr, uint numIndent) { + if (expr == NULL) { + inprint("null", numIndent); + return; + } + + switch (expr->op_type) { + case Expr::SIMPLE_OP: + inprintC(expr->op_char, numIndent); + break; + case Expr::AND: + inprint("AND", numIndent); + break; + case Expr::OR: + inprint("OR", numIndent); + break; + case Expr::NOT: + inprint("NOT", numIndent); + break; + default: + inprintU(expr->op_type, numIndent); + break; + } + printExpression(expr->expr, numIndent+1); + if (expr->expr2 != NULL) printExpression(expr->expr2, numIndent+1); + } + + void printExpression(Expr* expr, uint numIndent) { + switch (expr->type) { + case kExprStar: + inprint("*", numIndent); + break; + case kExprColumnRef: + inprint(expr->name, numIndent); + break; + // case kExprTableColumnRef: inprint(expr->table, expr->name, numIndent); break; + case kExprLiteralFloat: + inprint(expr->fval, numIndent); + break; + case kExprLiteralInt: + inprint(expr->ival, numIndent); + break; + case kExprLiteralString: + inprint(expr->name, numIndent); + break; + case kExprFunctionRef: + inprint(expr->name, numIndent); + inprint(expr->expr->name, numIndent+1); + break; + case kExprOperator: + printOperatorExpression(expr, numIndent); + break; + default: + fprintf(stderr, "Unrecognized expression type %d\n", expr->type); + return; + } + if (expr->alias != NULL) { + inprint("Alias", numIndent+1); + inprint(expr->alias, numIndent+2); + } + } + + void printSelectStatementInfo(SelectStatement* stmt, uint numIndent) { + inprint("SelectStatement", numIndent); + inprint("Fields:", numIndent+1); + for (Expr* expr : *stmt->selectList) printExpression(expr, numIndent+2); + + inprint("Sources:", numIndent+1); + printTableRefInfo(stmt->fromTable, numIndent+2); + + if (stmt->whereClause != NULL) { + inprint("Search Conditions:", numIndent+1); + printExpression(stmt->whereClause, numIndent+2); + } + + + if (stmt->unionSelect != NULL) { + inprint("Union:", numIndent+1); + printSelectStatementInfo(stmt->unionSelect, numIndent+2); + } + + if (stmt->order != NULL) { + inprint("OrderBy:", numIndent+1); + printExpression(stmt->order->expr, numIndent+2); + if (stmt->order->type == kOrderAsc) inprint("ascending", numIndent+2); + else inprint("descending", numIndent+2); + } + + if (stmt->limit != NULL) { + inprint("Limit:", numIndent+1); + inprint(stmt->limit->limit, numIndent+2); + } + } + + + + void printImportStatementInfo(ImportStatement* stmt, uint numIndent) { + inprint("ImportStatment", numIndent); + inprint(stmt->filePath, numIndent+1); + inprint(stmt->tableName, numIndent+1); + } + + void printCreateStatementInfo(CreateStatement* stmt, uint numIndent) { + inprint("CreateStatment", numIndent); + inprint(stmt->tableName, numIndent+1); + inprint(stmt->filePath, numIndent+1); + } + + void printInsertStatementInfo(InsertStatement* stmt, uint numIndent) { + inprint("InsertStatment", numIndent); + inprint(stmt->tableName, numIndent+1); + if (stmt->columns != NULL) { + inprint("Columns", numIndent+1); + for (char* col_name : *stmt->columns) { + inprint(col_name, numIndent+2); + } + } + switch (stmt->type) { + case InsertStatement::kInsertValues: + inprint("Values", numIndent+1); + for (Expr* expr : *stmt->values) { + printExpression(expr, numIndent+2); + } + break; + case InsertStatement::kInsertSelect: + printSelectStatementInfo(stmt->select, numIndent+1); + break; + } + } + + void printStatementInfo(SQLStatement* stmt) { + switch (stmt->type()) { + case kStmtSelect: + printSelectStatementInfo((SelectStatement*) stmt, 0); + break; + case kStmtInsert: + printInsertStatementInfo((InsertStatement*) stmt, 0); + break; + case kStmtCreate: + printCreateStatementInfo((CreateStatement*) stmt, 0); + break; + case kStmtImport: + printImportStatementInfo((ImportStatement*) stmt, 0); + break; + default: + break; + } + } } // namespace hsql \ No newline at end of file diff --git a/src/sqlhelper.h b/src/sqlhelper.h index 17690d0..81ee53e 100644 --- a/src/sqlhelper.h +++ b/src/sqlhelper.h @@ -1,18 +1,16 @@ - #ifndef __SQLHELPER_H__ #define __SQLHELPER_H__ - -#include "sqltypes.h" +#include "sql/statements.h" namespace hsql { -void printStatementInfo(SQLStatement* stmt); -void printSelectStatementInfo(SelectStatement* stmt, uint num_indent); -void printImportStatementInfo(ImportStatement* stmt, uint num_indent); -void printInsertStatementInfo(InsertStatement* stmt, uint num_indent); -void printCreateStatementInfo(CreateStatement* stmt, uint num_indent); -void printExpression(Expr* expr, uint num_indent); + void printStatementInfo(SQLStatement* stmt); + void printSelectStatementInfo(SelectStatement* stmt, uint num_indent); + void printImportStatementInfo(ImportStatement* stmt, uint num_indent); + void printInsertStatementInfo(InsertStatement* stmt, uint num_indent); + void printCreateStatementInfo(CreateStatement* stmt, uint num_indent); + void printExpression(Expr* expr, uint num_indent); } // namespace hsql diff --git a/src/sqltypes.h b/src/sqltypes.h deleted file mode 100644 index e81e6f8..0000000 --- a/src/sqltypes.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __SQLLIB_H__ -#define __SQLLIB_H__ - -typedef unsigned int uint; - -#include "sql/SelectStatement.h" -#include "sql/ImportStatement.h" -#include "sql/CreateStatement.h" -#include "sql/InsertStatement.h" -#include "sql/UpdateStatement.h" -#include "sql/DeleteStatement.h" -#include "sql/DropStatement.h" -#include "sql/PrepareStatement.h" -#include "sql/ExecuteStatement.h" - -#endif \ No newline at end of file diff --git a/test/lib/helper.h b/test/lib/helper.h index b6bfc80..5e74da9 100644 --- a/test/lib/helper.h +++ b/test/lib/helper.h @@ -2,21 +2,21 @@ #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_SQL_QUERY(query, outputVar, numStatements) \ + SQLParserResult* outputVar = SQLParser::parseSQLString(query); \ + ASSERT(outputVar->isValid); \ + ASSERT_EQ(outputVar->size(), numStatements); -#define TEST_PARSE_SINGLE_SQL(query, stmt_type, stmt_class, output_var) \ +#define TEST_PARSE_SINGLE_SQL(query, stmtType, stmtClass, outputVar) \ 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); + ASSERT_EQ(stmt_list->getStatement(0)->type(), stmtType); \ + stmtClass* outputVar = (stmtClass*) stmt_list->getStatement(0); -#define TEST_CAST_STMT(stmt_list, stmt_index, stmt_type, stmt_class, output_var) \ - ASSERT_EQ(stmt_list->getStatement(stmt_index)->type(), stmt_type); \ - stmt_class* output_var = (stmt_class*) stmt_list->getStatement(stmt_index); +#define TEST_CAST_STMT(stmt_list, stmt_index, stmtType, stmtClass, outputVar) \ + ASSERT_EQ(stmt_list->getStatement(stmt_index)->type(), stmtType); \ + stmtClass* outputVar = (stmtClass*) stmt_list->getStatement(stmt_index); #endif \ No newline at end of file diff --git a/test/lib/select.cpp b/test/lib/select.cpp index e30f5c8..04af2a6 100644 --- a/test/lib/select.cpp +++ b/test/lib/select.cpp @@ -7,40 +7,40 @@ using namespace hsql; TEST(SelectTest) { - TEST_PARSE_SINGLE_SQL("SELECT * FROM students;", kStmtSelect, SelectStatement, stmt); + TEST_PARSE_SINGLE_SQL("SELECT * FROM students;", kStmtSelect, SelectStatement, stmt); - ASSERT_NULL(stmt->where_clause); - ASSERT_NULL(stmt->group_by); + ASSERT_NULL(stmt->whereClause); + ASSERT_NULL(stmt->groupBy); } TEST(SelectHavingTest) { - TEST_PARSE_SINGLE_SQL("SELECT city, AVG(grade) AS avg_grade FROM students GROUP BY city HAVING AVG(grade) < 2.0", kStmtSelect, SelectStatement, stmt); - ASSERT_FALSE(stmt->select_distinct); + TEST_PARSE_SINGLE_SQL("SELECT city, AVG(grade) AS avg_grade FROM students GROUP BY city HAVING AVG(grade) < 2.0", kStmtSelect, SelectStatement, stmt); + ASSERT_FALSE(stmt->selectDistinct); - GroupByDescription* group = stmt->group_by; - ASSERT_NOTNULL(group); - ASSERT_EQ(group->columns->size(), 1); - ASSERT(group->having->isSimpleOp('<')); - ASSERT(group->having->expr->isType(kExprFunctionRef)); - ASSERT(group->having->expr2->isType(kExprLiteralFloat)); + GroupByDescription* group = stmt->groupBy; + ASSERT_NOTNULL(group); + ASSERT_EQ(group->columns->size(), 1); + ASSERT(group->having->isSimpleOp('<')); + ASSERT(group->having->expr->isType(kExprFunctionRef)); + ASSERT(group->having->expr2->isType(kExprLiteralFloat)); } TEST(SelectDistinctTest) { - TEST_PARSE_SINGLE_SQL("SELECT DISTINCT grade, city FROM students;", kStmtSelect, SelectStatement, stmt); + TEST_PARSE_SINGLE_SQL("SELECT DISTINCT grade, city FROM students;", kStmtSelect, SelectStatement, stmt); - ASSERT(stmt->select_distinct); - ASSERT_NULL(stmt->where_clause); + ASSERT(stmt->selectDistinct); + ASSERT_NULL(stmt->whereClause); } TEST(SelectGroupDistinctTest) { - TEST_PARSE_SINGLE_SQL("SELECT city, COUNT(name), COUNT(DISTINCT grade) FROM students GROUP BY city;", kStmtSelect, SelectStatement, stmt); + TEST_PARSE_SINGLE_SQL("SELECT city, COUNT(name), COUNT(DISTINCT grade) FROM students GROUP BY city;", kStmtSelect, SelectStatement, stmt); - ASSERT_FALSE(stmt->select_distinct); - ASSERT_EQ(stmt->select_list->size(), 3); - ASSERT(!stmt->select_list->at(1)->distinct); - ASSERT(stmt->select_list->at(2)->distinct); + ASSERT_FALSE(stmt->selectDistinct); + ASSERT_EQ(stmt->selectList->size(), 3); + ASSERT(!stmt->selectList->at(1)->distinct); + ASSERT(stmt->selectList->at(2)->distinct); } diff --git a/test/lib/test.cpp b/test/lib/test.cpp index 949bf04..c2be54e 100644 --- a/test/lib/test.cpp +++ b/test/lib/test.cpp @@ -3,53 +3,57 @@ class TestsManager { - // Note: static initialization fiasco - // http://www.parashift.com/c++-faq-lite/static-init-order.html - // http://www.parashift.com/c++-faq-lite/static-init-order-on-first-use.html + // Note: static initialization fiasco + // http://www.parashift.com/c++-faq-lite/static-init-order.html + // http://www.parashift.com/c++-faq-lite/static-init-order-on-first-use.html public: - static std::vector& test_names() { - static std::vector* test_names = new std::vector; - return *test_names; - } + static std::vector& testNames() { + static std::vector* _testNames = new std::vector; + return *_testNames; + } - static std::vector& tests() { - static std::vector* tests = new std::vector; - return *tests; - } + static std::vector& tests() { + static std::vector* tests = new std::vector; + return *tests; + } }; int AddTest(void (*foo)(void), std::string name) { - TestsManager::tests().push_back(foo); - TestsManager::test_names().push_back(name); - return 0; + TestsManager::tests().push_back(foo); + TestsManager::testNames().push_back(name); + return 0; } -void RunTests() { - size_t num_failed = 0; - for (size_t i = 0; i < TestsManager::tests().size(); ++i) { - printf("\033[0;32m{ running}\033[0m %s\n", TestsManager::test_names()[i].c_str()); +size_t RunTests() { + size_t numFailed = 0; + for (size_t i = 0; i < TestsManager::tests().size(); ++i) { + printf("\033[0;32m{ running}\033[0m %s\n", TestsManager::testNames()[i].c_str()); - try { - // Run test - (*TestsManager::tests()[i])(); - printf("\033[0;32m{ ok}\033[0m %s\n", TestsManager::test_names()[i].c_str()); + try { + // Run test + (*TestsManager::tests()[i])(); + printf("\033[0;32m{ ok}\033[0m %s\n", TestsManager::testNames()[i].c_str()); - } catch (AssertionFailedException& e) { - printf("\033[1;31m{ failed} %s\n", TestsManager::test_names()[i].c_str()); - printf("\tAssertion failed: %s\n\033[0m", e.what()); - num_failed++; - } - - } + } catch (AssertionFailedException& e) { + printf("\033[1;31m{ failed} %s\n", TestsManager::testNames()[i].c_str()); + printf("\tAssertion failed: %s\n\033[0m", e.what()); + numFailed++; + } + } + return numFailed; } int main() { - RunTests(); - return 0; + size_t numFailed = RunTests(); + if (numFailed == 0) { + return 0; + } else { + return -1; + } } \ No newline at end of file diff --git a/test/lib/test.h b/test/lib/test.h index 274e96c..19efae6 100644 --- a/test/lib/test.h +++ b/test/lib/test.h @@ -13,7 +13,7 @@ #define ASSERT(cond) if (!(cond)) throw AssertionFailedException(#cond); - + #define ASSERT_TRUE(cond) ASSERT(cond); #define ASSERT_FALSE(cond) if (cond) throw AssertionFailedException(#cond); @@ -27,28 +27,23 @@ std::cout << "Actual values: " << a << " != " << b << std::endl; \ } \ ASSERT(a == b); - + class AssertionFailedException: public std::exception { public: - AssertionFailedException(std::string msg) : - std::exception(), - _msg(msg) {}; + AssertionFailedException(std::string msg) : + std::exception(), + _msg(msg) {}; - virtual const char* what() const throw() { - return _msg.c_str(); - } + virtual const char* what() const throw() { + return _msg.c_str(); + } protected: - std::string _msg; + std::string _msg; }; - - - int AddTest(void (*foo)(void), std::string name); - - #endif \ No newline at end of file diff --git a/test/sql_grammar_test.cpp b/test/sql_grammar_test.cpp index 63acdd8..e4ca602 100644 --- a/test/sql_grammar_test.cpp +++ b/test/sql_grammar_test.cpp @@ -33,17 +33,17 @@ int main(int argc, char *argv[]) { return -1; } - bool expect_false = false; - bool use_file = false; - std::string file_path = ""; + bool expectFalse = false; + bool useFile = false; + std::string filePath = ""; // Parse command line arguments int i = 1; for (; i < argc; ++i) { - if (STREQ(argv[i], "--false")) expect_false = true; + if (STREQ(argv[i], "--false")) expectFalse = true; else if (STREQ(argv[i], "-f")) { - use_file = true; - file_path = argv[++i]; + useFile = true; + filePath = argv[++i]; } else { break; } @@ -52,44 +52,43 @@ int main(int argc, char *argv[]) { // Read list of queries for this rest std::vector queries; - if (use_file) { - queries = readlines(file_path); + if (useFile) { + queries = readlines(filePath); } else { for (; i < argc; ++i) queries.push_back(argv[i]); } // Execute queries - int num_failed = 0; + int numFailed = 0; for (std::string sql : queries) { // Measuring the parsing time std::chrono::time_point start, end; start = std::chrono::system_clock::now(); // Parsing - SQLStatementList* stmt_list = SQLParser::parseSQLString(sql.c_str()); + SQLParserResult* stmt_list = SQLParser::parseSQLString(sql.c_str()); end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end-start; double us = elapsed_seconds.count() * 1000 * 1000; - if (expect_false == stmt_list->isValid) { + if (expectFalse == stmt_list->isValid) { printf("\033[0;31m{ failed}\033[0m\n"); - printf("\t\033[0;31m%s (L%d:%d)\n\033[0m", stmt_list->parser_msg, stmt_list->error_line, stmt_list->error_col); + printf("\t\033[0;31m%s (L%d:%d)\n\033[0m", stmt_list->errorMsg, stmt_list->errorLine, stmt_list->errorColumn); printf("\t%s\n", sql.c_str()); - num_failed++; + numFailed++; } else { - // TODO: indicate whether expect_false was set + // TODO: indicate whether expectFalse was set printf("\033[0;32m{ ok} (%.1fus)\033[0m %s\n", us, sql.c_str()); } } - if (num_failed == 0) { + if (numFailed == 0) { printf("\033[0;32m{ ok} \033[0mAll %lu grammar tests completed successfully!\n", queries.size()); + return 0; } else { - fprintf(stderr, "\033[0;31m{ failed} \033[0mSome grammar tests failed! %d out of %lu tests failed!\n", num_failed, queries.size()); + fprintf(stderr, "\033[0;31m{ failed} \033[0mSome grammar tests failed! %d out of %lu tests failed!\n", numFailed, queries.size()); + return -1; } - - - return 0; } \ No newline at end of file diff --git a/test/sql_tests.cpp b/test/sql_tests.cpp index dabfd2f..8550e00 100644 --- a/test/sql_tests.cpp +++ b/test/sql_tests.cpp @@ -11,13 +11,13 @@ using namespace hsql; TEST(DeleteStatementTest) { - SQLStatementList* stmt_list = SQLParser::parseSQLString("DELETE FROM students WHERE grade > 2.0;"); - ASSERT(stmt_list->isValid); - ASSERT_EQ(stmt_list->numStatements(), 1); - ASSERT(stmt_list->getStatement(0)->type() == kStmtDelete); + SQLParserResult* result = SQLParser::parseSQLString("DELETE FROM students WHERE grade > 2.0;"); + ASSERT(result->isValid); + ASSERT_EQ(result->size(), 1); + ASSERT(result->getStatement(0)->type() == kStmtDelete); - DeleteStatement* stmt = (DeleteStatement*) stmt_list->getStatement(0); - ASSERT_STREQ(stmt->table_name, "students"); + DeleteStatement* stmt = (DeleteStatement*) result->getStatement(0); + ASSERT_STREQ(stmt->tableName, "students"); ASSERT_NOTNULL(stmt->expr); ASSERT(stmt->expr->isType(kExprOperator)); ASSERT_STREQ(stmt->expr->expr->name, "grade"); @@ -25,14 +25,14 @@ TEST(DeleteStatementTest) { } TEST(CreateStatementTest) { - SQLStatementList* stmt_list = SQLParser::parseSQLString("CREATE TABLE students (name TEXT, student_number INT, city INTEGER, grade DOUBLE)"); - ASSERT(stmt_list->isValid); - ASSERT_EQ(stmt_list->numStatements(), 1); - ASSERT_EQ(stmt_list->getStatement(0)->type(), kStmtCreate); + SQLParserResult* result = SQLParser::parseSQLString("CREATE TABLE students (name TEXT, student_number INT, city INTEGER, grade DOUBLE)"); + ASSERT(result->isValid); + ASSERT_EQ(result->size(), 1); + ASSERT_EQ(result->getStatement(0)->type(), kStmtCreate); - CreateStatement* stmt = (CreateStatement*) stmt_list->getStatement(0); + CreateStatement* stmt = (CreateStatement*) result->getStatement(0); ASSERT_EQ(stmt->type, CreateStatement::kTable); - ASSERT_STREQ(stmt->table_name, "students"); + ASSERT_STREQ(stmt->tableName, "students"); ASSERT_NOTNULL(stmt->columns); ASSERT_EQ(stmt->columns->size(), 4); ASSERT_STREQ(stmt->columns->at(0)->name, "name"); @@ -47,12 +47,12 @@ TEST(CreateStatementTest) { TEST(UpdateStatementTest) { - SQLStatementList* stmt_list = SQLParser::parseSQLString("UPDATE students SET grade = 5.0, name = 'test' WHERE name = 'Max Mustermann';"); - ASSERT(stmt_list->isValid); - ASSERT_EQ(stmt_list->numStatements(), 1); - ASSERT_EQ(stmt_list->getStatement(0)->type(), kStmtUpdate); + SQLParserResult* result = SQLParser::parseSQLString("UPDATE students SET grade = 5.0, name = 'test' WHERE name = 'Max Mustermann';"); + ASSERT(result->isValid); + ASSERT_EQ(result->size(), 1); + ASSERT_EQ(result->getStatement(0)->type(), kStmtUpdate); - UpdateStatement* stmt = (UpdateStatement*) stmt_list->getStatement(0); + UpdateStatement* stmt = (UpdateStatement*) result->getStatement(0); ASSERT_NOTNULL(stmt->table); ASSERT_STREQ(stmt->table->name, "students"); @@ -99,33 +99,33 @@ TEST(PrepareStatementTest) { "PREPARE stmt: SELECT * FROM data WHERE c1 = ?;" "DEALLOCATE PREPARE stmt;"; - TEST_PARSE_SQL_QUERY(query, stmt_list, 3); + TEST_PARSE_SQL_QUERY(query, result, 3); - TEST_CAST_STMT(stmt_list, 0, kStmtPrepare, PrepareStatement, prep1); - TEST_CAST_STMT(stmt_list, 1, kStmtPrepare, PrepareStatement, prep2); - TEST_CAST_STMT(stmt_list, 2, kStmtDrop, DropStatement, drop); + 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->numStatements(), 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)); - ASSERT(select->select_list->at(0)->isType(kExprPlaceholder)); - ASSERT(select->where_clause->expr2->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->select_list->at(0)->ival, 1); - ASSERT_EQ(select->select_list->at(0), prep1->placeholders[1]); + ASSERT_EQ(select->selectList->at(0)->ival, 1); + ASSERT_EQ(select->selectList->at(0), prep1->placeholders[1]); - ASSERT_EQ(select->where_clause->expr2->ival, 2); - ASSERT_EQ(select->where_clause->expr2, prep1->placeholders[2]); + ASSERT_EQ(select->whereClause->expr2->ival, 2); + ASSERT_EQ(select->whereClause->expr2, prep1->placeholders[2]); // Prepare Statement #2 ASSERT_STREQ(prep2->name, "stmt"); diff --git a/test/test.sh b/test/test.sh new file mode 100755 index 0000000..3df2e42 --- /dev/null +++ b/test/test.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# has to be executed from the root of the repository +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./ + +bin/sql_grammar_test -f "test/lib/valid_queries.sql" +RET1=$? + +bin/sql_tests +RET2=$? + +if [[ $RET1 != 0 ]]; then exit $RET1; fi +if [[ $RET2 != 0 ]]; then exit $RET2; fi + +exit 0