Documentation & Result Move Constructor (#39)
Updates documentation, adds a move constructor to SQLParserResult, fixes compile-time warnings
This commit is contained in:
parent
9184d5d0c2
commit
0909c6a89a
14
Makefile
14
Makefile
|
@ -4,8 +4,8 @@ SRC = src
|
|||
SRCPARSER = src/parser
|
||||
|
||||
# files
|
||||
PARSERFILES = $(SRCPARSER)/bison_parser.cpp $(SRCPARSER)/flex_lexer.cpp
|
||||
LIBCPP = $(shell find $(SRC) -name '*.cpp' -not -path "$(SRCPARSER)/*") $(SRCPARSER)/bison_parser.cpp $(SRCPARSER)/flex_lexer.cpp
|
||||
PARSERCPP = $(SRCPARSER)/bison_parser.cpp $(SRCPARSER)/flex_lexer.cpp
|
||||
LIBCPP = $(shell find $(SRC) -name '*.cpp' -not -path "$(SRCPARSER)/*") $(PARSERCPP)
|
||||
LIBOBJ = $(LIBCPP:%.cpp=%.o)
|
||||
TESTCPP = $(shell find test/ -name '*.cpp')
|
||||
|
||||
|
@ -27,13 +27,16 @@ library: $(TARGET)
|
|||
$(TARGET): $(LIBOBJ)
|
||||
$(CXX) $(LIBFLAGS) -o $(TARGET) $(LIBOBJ)
|
||||
|
||||
%.o: %.cpp $(PARSERFILES)
|
||||
$(SRCPARSER)/flex_lexer.o: $(SRCPARSER)/flex_lexer.cpp
|
||||
$(CXX) $(CFLAGS) -c -o $@ $< -Wno-sign-compare -Wno-unneeded-internal-declaration -Wno-deprecated-register
|
||||
|
||||
%.o: %.cpp $(PARSERCPP)
|
||||
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
$(SRCPARSER)/bison_parser.cpp:
|
||||
$(SRCPARSER)/bison_parser.cpp: $(SRCPARSER)/bison_parser.y
|
||||
make -C $(SRCPARSER)/ bison_parser.cpp
|
||||
|
||||
$(SRCPARSER)/flex_lexer.cpp:
|
||||
$(SRCPARSER)/flex_lexer.cpp: $(SRCPARSER)/flex_lexer.l
|
||||
make -C $(SRCPARSER)/ flex_lexer.cpp
|
||||
|
||||
parser:
|
||||
|
@ -51,6 +54,7 @@ cleanall: clean cleanparser
|
|||
|
||||
install:
|
||||
cp $(TARGET) $(INSTALL)/lib/$(TARGET)
|
||||
rm -rf $(INSTALL)/include/hsql
|
||||
cp -r src $(INSTALL)/include/hsql
|
||||
find $(INSTALL)/include/hsql -not -name '*.h' -type f | xargs rm
|
||||
|
||||
|
|
63
README.md
63
README.md
|
@ -1,16 +1,16 @@
|
|||
C++ SQL Parser for Hyrise
|
||||
C++ SQL Parser
|
||||
=========================
|
||||
[![GitHub release](https://img.shields.io/github/release/hyrise/sql-parser.svg?maxAge=2592000)]()
|
||||
[![Build Status](https://img.shields.io/travis/hyrise/sql-parser.svg?maxAge=2592000)](https://travis-ci.org/hyrise/sql-parser)
|
||||
|
||||
|
||||
This is a SQL Parser for C++. It parses the given SQL query into C++ objects.
|
||||
It is developed for integration in hyrise (https://github.com/hyrise/hyrise), but can be used in other environments as well.
|
||||
It has been developed for integration in [Hyrise](https://github.com/hyrise/hyrise), but can be used perfectly well in other environments as well.
|
||||
|
||||
In March 2015 we've also written a short paper outlining discussing some development details and the integration into our database Hyrise. You can find the paper [here](http://torpedro.com/paper/HyriseSQL-03-2015.pdf).
|
||||
|
||||
|
||||
### Usage
|
||||
## Usage
|
||||
|
||||
**Note:** You can also find a detailed usage description at this [blog post](http://torpedro.github.io/tech/c++/sql/parser/2016/02/27/c++-sql-parser.html).
|
||||
|
||||
|
@ -21,52 +21,53 @@ To use the SQL parser in your own projects you simply have to follow these few s
|
|||
|
||||
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/master/example)
|
||||
5. Include the `SQLParser.h` from `src/` and link the library in your project
|
||||
3. *(Optional, Recommended)* Run `make install` to copy the library to `/usr/local/lib/`
|
||||
4. Run the tests `make test` to make sure everything worked
|
||||
5. Include the `SQLParser.h` from `src/` (or from `/usr/local/lib/hsql/` if you installed it) and link the library in your project
|
||||
6. Take a look at the [example project here](https://github.com/hyrise/sql-parser/tree/master/example)
|
||||
|
||||
```cpp
|
||||
#include "hsql/SQLParser.h"
|
||||
|
||||
### Extending the parser
|
||||
/* ... */
|
||||
|
||||
**Requirements for development:**
|
||||
* gcc 4.8+ (or clang 3.4+)
|
||||
* [bison](https://www.gnu.org/software/bison/) (v3.0.2+)
|
||||
* [flex](http://flex.sourceforge.net/) (v2.5.5+)
|
||||
{
|
||||
// Basic Usage Example
|
||||
|
||||
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:
|
||||
const std::string query = "...";
|
||||
hsql::SQLParserResult result;
|
||||
hsql::SQLParser::parseSQLString(query, &result);
|
||||
|
||||
```bash
|
||||
make parser # builds the bison parser and flex lexer
|
||||
make library # builds the libsqlparser.so
|
||||
make test # runs the tests with the library
|
||||
if (result.isValid() && result.size() > 0) {
|
||||
const hsql::SQLStatement* statement = result.getStatement(0);
|
||||
|
||||
if (statement.isType(hsql::SelectStatement)) {
|
||||
const hsql::SelectStatement* select = (const hsql::SelectStatement*) statement;
|
||||
/* ... */
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Rerun these steps whenever you change part of the parse. To execute the entire pipeline automatically you can run:
|
||||
Quick Links:
|
||||
|
||||
```bash
|
||||
make cleanall # cleans the parser build and library build
|
||||
make test # build parser, library and runs the tests
|
||||
```
|
||||
* [SQLParser.h](src/SQLParser.h)
|
||||
* [SQLParserResult.h](src/SQLParserResult.h)
|
||||
* [SelectStatement.h](src/sql/SelectStatement.h)
|
||||
|
||||
## How to Contribute
|
||||
|
||||
#### How to contribute
|
||||
**[Developer Documentation](docs/)**
|
||||
|
||||
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.
|
||||
|
||||
|
||||
### Resources
|
||||
|
||||
* [Working Syntax Examples](docs/syntax.md)
|
||||
* [Developer Documentation](docs/dev-docs.md)
|
||||
|
||||
|
||||
### License
|
||||
## License
|
||||
|
||||
HYRISE sql-parser is licensed as open source after the OpenSource "Licence of the Hasso-Plattner Institute" declared in the LICENSE file of this project.
|
||||
|
||||
|
||||
### Contributers
|
||||
## Contributers
|
||||
|
||||
The following people contributed to HYRISE sql-parser in various forms.
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
Documentation
|
||||
=============
|
||||
|
||||
Internal Links:
|
||||
|
||||
* [Developer Documentation](dev-docs.md)
|
||||
* [Working SQL Syntax Examples](syntax-examples.md)
|
||||
|
||||
|
||||
External Resources:
|
||||
|
||||
* [Original Dev-Paper (2015)](http://torpedro.com/paper/HyriseSQL-03-2015.pdf)
|
||||
* [Blog Post about Basic Usage](http://torpedro.github.io/tech/c++/sql/parser/2016/02/27/c++-sql-parser.html)
|
||||
|
||||
|
|
@ -1,6 +1,29 @@
|
|||
Developer Documentation
|
||||
=======================
|
||||
|
||||
## Basic Requirements
|
||||
|
||||
**Requirements for development:**
|
||||
* gcc 4.8+ (or clang 3.4+)
|
||||
* [bison](https://www.gnu.org/software/bison/) (v3.0.2+)
|
||||
* [flex](http://flex.sourceforge.net/) (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:
|
||||
|
||||
```bash
|
||||
make parser # builds the bison parser and flex lexer
|
||||
make library # builds the libsqlparser.so
|
||||
make test # runs the tests with the library
|
||||
```
|
||||
|
||||
Rerun these steps whenever you change part of the parse. To execute the entire pipeline automatically you can run:
|
||||
|
||||
```bash
|
||||
make cleanall # cleans the parser build and library build
|
||||
make test # build parser, library and runs the tests
|
||||
```
|
||||
|
||||
|
||||
## Developing New Functionality
|
||||
|
||||
This section contains information about how to extend this parser with new functionalities.
|
||||
|
@ -18,7 +41,7 @@ Finally you will need to include your new file in `src/sql/statements.h`.
|
|||
### Extending the Grammar
|
||||
|
||||
Related files:
|
||||
````
|
||||
```
|
||||
src/parser/bison_parser.y
|
||||
src/parser/flex_lexer.l
|
||||
src/parser/keywordlist_generator.py
|
||||
|
|
|
@ -13,6 +13,16 @@ namespace hsql {
|
|||
addStatement(stmt);
|
||||
};
|
||||
|
||||
// Move constructor.
|
||||
SQLParserResult::SQLParserResult(SQLParserResult&& moved) {
|
||||
isValid_ = moved.isValid_;
|
||||
errorMsg_ = moved.errorMsg_;
|
||||
statements_ = std::move(moved.statements_);
|
||||
|
||||
moved.errorMsg_ = NULL;
|
||||
moved.reset();
|
||||
}
|
||||
|
||||
SQLParserResult::~SQLParserResult() {
|
||||
reset();
|
||||
}
|
||||
|
|
|
@ -15,6 +15,9 @@ namespace hsql {
|
|||
// Takes ownership of the statement.
|
||||
SQLParserResult(SQLStatement* stmt);
|
||||
|
||||
// Move constructor.
|
||||
SQLParserResult(SQLParserResult&& moved);
|
||||
|
||||
// Deletes all statements in the result.
|
||||
virtual ~SQLParserResult();
|
||||
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
*.output
|
||||
conflict_test.cpp
|
|
@ -3,7 +3,7 @@ all: bison_parser.cpp flex_lexer.cpp
|
|||
|
||||
bison_parser.cpp: bison_parser.y
|
||||
@bison --version | head -n 1
|
||||
bison bison_parser.y -v
|
||||
bison bison_parser.y --output=bison_parser.cpp --defines=bison_parser.h --verbose
|
||||
|
||||
flex_lexer.cpp: flex_lexer.l
|
||||
@flex --version
|
||||
|
@ -14,4 +14,4 @@ clean:
|
|||
|
||||
# Tests if the parser builds correctly and doesn't contain conflicts.
|
||||
test:
|
||||
! bison bison_parser.y -v 2>&1 | grep "conflict" >&2
|
||||
! bison bison_parser.y -v --output=conflict_test.cpp 2>&1 | grep "conflict" >&2
|
||||
|
|
|
@ -2558,7 +2558,7 @@ yyreduce:
|
|||
case 20:
|
||||
#line 315 "bison_parser.y" /* yacc.c:1646 */
|
||||
{
|
||||
(yyval.import_stmt) = new ImportStatement((ImportStatement::ImportType) (yyvsp[-4].uval));
|
||||
(yyval.import_stmt) = new ImportStatement((ImportType) (yyvsp[-4].uval));
|
||||
(yyval.import_stmt)->filePath = (yyvsp[-2].sval);
|
||||
(yyval.import_stmt)->tableName = (yyvsp[0].sval);
|
||||
}
|
||||
|
@ -2567,7 +2567,7 @@ yyreduce:
|
|||
|
||||
case 21:
|
||||
#line 323 "bison_parser.y" /* yacc.c:1646 */
|
||||
{ (yyval.uval) = ImportStatement::kImportCSV; }
|
||||
{ (yyval.uval) = kImportCSV; }
|
||||
#line 2572 "bison_parser.cpp" /* yacc.c:1646 */
|
||||
break;
|
||||
|
||||
|
@ -2580,7 +2580,7 @@ yyreduce:
|
|||
case 23:
|
||||
#line 337 "bison_parser.y" /* yacc.c:1646 */
|
||||
{
|
||||
(yyval.create_stmt) = new CreateStatement(CreateStatement::kTableFromTbl);
|
||||
(yyval.create_stmt) = new CreateStatement(kCreateTableFromTbl);
|
||||
(yyval.create_stmt)->ifNotExists = (yyvsp[-5].bval);
|
||||
(yyval.create_stmt)->tableName = (yyvsp[-4].sval);
|
||||
(yyval.create_stmt)->filePath = (yyvsp[0].sval);
|
||||
|
@ -2591,7 +2591,7 @@ yyreduce:
|
|||
case 24:
|
||||
#line 343 "bison_parser.y" /* yacc.c:1646 */
|
||||
{
|
||||
(yyval.create_stmt) = new CreateStatement(CreateStatement::kTable);
|
||||
(yyval.create_stmt) = new CreateStatement(kCreateTable);
|
||||
(yyval.create_stmt)->ifNotExists = (yyvsp[-4].bval);
|
||||
(yyval.create_stmt)->tableName = (yyvsp[-3].sval);
|
||||
(yyval.create_stmt)->columns = (yyvsp[-1].column_vec);
|
||||
|
@ -2602,7 +2602,7 @@ yyreduce:
|
|||
case 25:
|
||||
#line 349 "bison_parser.y" /* yacc.c:1646 */
|
||||
{
|
||||
(yyval.create_stmt) = new CreateStatement(CreateStatement::kView);
|
||||
(yyval.create_stmt) = new CreateStatement(kCreateView);
|
||||
(yyval.create_stmt)->ifNotExists = (yyvsp[-4].bval);
|
||||
(yyval.create_stmt)->tableName = (yyvsp[-3].sval);
|
||||
(yyval.create_stmt)->viewColumns = (yyvsp[-2].str_vec);
|
||||
|
@ -2670,7 +2670,7 @@ yyreduce:
|
|||
case 35:
|
||||
#line 389 "bison_parser.y" /* yacc.c:1646 */
|
||||
{
|
||||
(yyval.drop_stmt) = new DropStatement(DropStatement::kTable);
|
||||
(yyval.drop_stmt) = new DropStatement(kDropTable);
|
||||
(yyval.drop_stmt)->name = (yyvsp[0].sval);
|
||||
}
|
||||
#line 2677 "bison_parser.cpp" /* yacc.c:1646 */
|
||||
|
@ -2679,7 +2679,7 @@ yyreduce:
|
|||
case 36:
|
||||
#line 393 "bison_parser.y" /* yacc.c:1646 */
|
||||
{
|
||||
(yyval.drop_stmt) = new DropStatement(DropStatement::kView);
|
||||
(yyval.drop_stmt) = new DropStatement(kDropView);
|
||||
(yyval.drop_stmt)->name = (yyvsp[0].sval);
|
||||
}
|
||||
#line 2686 "bison_parser.cpp" /* yacc.c:1646 */
|
||||
|
@ -2688,7 +2688,7 @@ yyreduce:
|
|||
case 37:
|
||||
#line 397 "bison_parser.y" /* yacc.c:1646 */
|
||||
{
|
||||
(yyval.drop_stmt) = new DropStatement(DropStatement::kPreparedStatement);
|
||||
(yyval.drop_stmt) = new DropStatement(kDropPreparedStatement);
|
||||
(yyval.drop_stmt)->name = (yyvsp[0].sval);
|
||||
}
|
||||
#line 2695 "bison_parser.cpp" /* yacc.c:1646 */
|
||||
|
@ -2716,7 +2716,7 @@ yyreduce:
|
|||
case 40:
|
||||
#line 429 "bison_parser.y" /* yacc.c:1646 */
|
||||
{
|
||||
(yyval.insert_stmt) = new InsertStatement(InsertStatement::kInsertValues);
|
||||
(yyval.insert_stmt) = new InsertStatement(kInsertValues);
|
||||
(yyval.insert_stmt)->tableName = (yyvsp[-5].sval);
|
||||
(yyval.insert_stmt)->columns = (yyvsp[-4].str_vec);
|
||||
(yyval.insert_stmt)->values = (yyvsp[-1].expr_vec);
|
||||
|
@ -2727,7 +2727,7 @@ yyreduce:
|
|||
case 41:
|
||||
#line 435 "bison_parser.y" /* yacc.c:1646 */
|
||||
{
|
||||
(yyval.insert_stmt) = new InsertStatement(InsertStatement::kInsertSelect);
|
||||
(yyval.insert_stmt) = new InsertStatement(kInsertSelect);
|
||||
(yyval.insert_stmt)->tableName = (yyvsp[-2].sval);
|
||||
(yyval.insert_stmt)->columns = (yyvsp[-1].str_vec);
|
||||
(yyval.insert_stmt)->select = (yyvsp[0].select_stmt);
|
||||
|
|
|
@ -56,9 +56,9 @@ int yyerror(YYLTYPE* llocp, SQLParserResult* result, yyscan_t scanner, const cha
|
|||
}
|
||||
}
|
||||
|
||||
// Define the names of the created files
|
||||
%output "bison_parser.cpp"
|
||||
%defines "bison_parser.h"
|
||||
// Define the names of the created files (defined in Makefile)
|
||||
// %output "bison_parser.cpp"
|
||||
// %defines "bison_parser.h"
|
||||
|
||||
// Tell bison to create a reentrant parser
|
||||
%define api.pure full
|
||||
|
@ -313,14 +313,14 @@ execute_statement:
|
|||
******************************/
|
||||
import_statement:
|
||||
IMPORT FROM import_file_type FILE file_path INTO table_name {
|
||||
$$ = new ImportStatement((ImportStatement::ImportType) $3);
|
||||
$$ = new ImportStatement((ImportType) $3);
|
||||
$$->filePath = $5;
|
||||
$$->tableName = $7;
|
||||
}
|
||||
;
|
||||
|
||||
import_file_type:
|
||||
CSV { $$ = ImportStatement::kImportCSV; }
|
||||
CSV { $$ = kImportCSV; }
|
||||
;
|
||||
|
||||
file_path:
|
||||
|
@ -335,19 +335,19 @@ file_path:
|
|||
******************************/
|
||||
create_statement:
|
||||
CREATE TABLE opt_not_exists table_name FROM TBL FILE file_path {
|
||||
$$ = new CreateStatement(CreateStatement::kTableFromTbl);
|
||||
$$ = new CreateStatement(kCreateTableFromTbl);
|
||||
$$->ifNotExists = $3;
|
||||
$$->tableName = $4;
|
||||
$$->filePath = $8;
|
||||
}
|
||||
| CREATE TABLE opt_not_exists table_name '(' column_def_commalist ')' {
|
||||
$$ = new CreateStatement(CreateStatement::kTable);
|
||||
$$ = new CreateStatement(kCreateTable);
|
||||
$$->ifNotExists = $3;
|
||||
$$->tableName = $4;
|
||||
$$->columns = $6;
|
||||
}
|
||||
| CREATE VIEW opt_not_exists table_name opt_column_list AS select_statement {
|
||||
$$ = new CreateStatement(CreateStatement::kView);
|
||||
$$ = new CreateStatement(kCreateView);
|
||||
$$->ifNotExists = $3;
|
||||
$$->tableName = $4;
|
||||
$$->viewColumns = $5;
|
||||
|
@ -387,15 +387,15 @@ column_type:
|
|||
|
||||
drop_statement:
|
||||
DROP TABLE table_name {
|
||||
$$ = new DropStatement(DropStatement::kTable);
|
||||
$$ = new DropStatement(kDropTable);
|
||||
$$->name = $3;
|
||||
}
|
||||
| DROP VIEW table_name {
|
||||
$$ = new DropStatement(DropStatement::kView);
|
||||
$$ = new DropStatement(kDropView);
|
||||
$$->name = $3;
|
||||
}
|
||||
| DEALLOCATE PREPARE IDENTIFIER {
|
||||
$$ = new DropStatement(DropStatement::kPreparedStatement);
|
||||
$$ = new DropStatement(kDropPreparedStatement);
|
||||
$$->name = $3;
|
||||
}
|
||||
;
|
||||
|
@ -427,13 +427,13 @@ truncate_statement:
|
|||
******************************/
|
||||
insert_statement:
|
||||
INSERT INTO table_name opt_column_list VALUES '(' literal_list ')' {
|
||||
$$ = new InsertStatement(InsertStatement::kInsertValues);
|
||||
$$ = new InsertStatement(kInsertValues);
|
||||
$$->tableName = $3;
|
||||
$$->columns = $4;
|
||||
$$->values = $7;
|
||||
}
|
||||
| INSERT INTO table_name opt_column_list select_no_paren {
|
||||
$$ = new InsertStatement(InsertStatement::kInsertSelect);
|
||||
$$ = new InsertStatement(kInsertSelect);
|
||||
$$->tableName = $3;
|
||||
$$->columns = $4;
|
||||
$$->select = $5;
|
||||
|
|
|
@ -23,16 +23,15 @@ namespace hsql {
|
|||
DataType type;
|
||||
};
|
||||
|
||||
enum CreateType {
|
||||
kCreateTable,
|
||||
kCreateTableFromTbl, // Hyrise file format
|
||||
kCreateView
|
||||
};
|
||||
|
||||
// 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
|
||||
kView
|
||||
};
|
||||
|
||||
CreateStatement(CreateType type);
|
||||
virtual ~CreateStatement();
|
||||
|
||||
|
@ -46,4 +45,5 @@ namespace hsql {
|
|||
};
|
||||
|
||||
} // namespace hsql
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
// Note: Implementations of constructors and destructors can be found in statements.cpp.
|
||||
namespace hsql {
|
||||
|
||||
// Represents SQL Delete statements.
|
||||
// Example: "DELETE FROM students WHERE grade > 3.0"
|
||||
// Note: if (expr == NULL) => delete all rows (truncate)
|
||||
|
@ -17,4 +18,5 @@ namespace hsql {
|
|||
};
|
||||
|
||||
} // namespace hsql
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,21 +5,23 @@
|
|||
|
||||
// Note: Implementations of constructors and destructors can be found in statements.cpp.
|
||||
namespace hsql {
|
||||
|
||||
enum DropType {
|
||||
kDropTable,
|
||||
kDropSchema,
|
||||
kDropIndex,
|
||||
kDropView,
|
||||
kDropPreparedStatement
|
||||
};
|
||||
|
||||
// Represents SQL Delete statements.
|
||||
// Example "DROP TABLE students;"
|
||||
struct DropStatement : SQLStatement {
|
||||
enum EntityType {
|
||||
kTable,
|
||||
kSchema,
|
||||
kIndex,
|
||||
kView,
|
||||
kPreparedStatement
|
||||
};
|
||||
|
||||
DropStatement(EntityType type);
|
||||
DropStatement(DropType type);
|
||||
virtual ~DropStatement();
|
||||
|
||||
EntityType type;
|
||||
DropType type;
|
||||
char* name;
|
||||
};
|
||||
|
||||
|
|
|
@ -4,10 +4,9 @@
|
|||
#include "SQLStatement.h"
|
||||
|
||||
namespace hsql {
|
||||
/**
|
||||
* Represents SQL Execute statements.
|
||||
* Example: "EXECUTE ins_prep(100, "test", 2.3);"
|
||||
*/
|
||||
|
||||
// Represents SQL Execute statements.
|
||||
// Example: "EXECUTE ins_prep(100, "test", 2.3);"
|
||||
struct ExecuteStatement : SQLStatement {
|
||||
ExecuteStatement();
|
||||
virtual ~ExecuteStatement();
|
||||
|
@ -17,4 +16,5 @@ namespace hsql {
|
|||
};
|
||||
|
||||
} // namsepace hsql
|
||||
|
||||
#endif
|
|
@ -6,7 +6,7 @@
|
|||
#include <vector>
|
||||
|
||||
namespace hsql {
|
||||
class SelectStatement;
|
||||
struct SelectStatement;
|
||||
|
||||
// Helper function used by the lexer.
|
||||
// TODO: move to more appropriate place.
|
||||
|
|
|
@ -4,15 +4,13 @@
|
|||
#include "SQLStatement.h"
|
||||
|
||||
namespace hsql {
|
||||
/**
|
||||
* Represents SQL Import statements.
|
||||
*/
|
||||
struct ImportStatement : SQLStatement {
|
||||
enum ImportType {
|
||||
kImportCSV,
|
||||
kImportTbl, // Hyrise file format
|
||||
};
|
||||
|
||||
// Represents SQL Import statements.
|
||||
struct ImportStatement : SQLStatement {
|
||||
ImportStatement(ImportType type);
|
||||
virtual ~ImportStatement();
|
||||
|
||||
|
@ -23,5 +21,4 @@ namespace hsql {
|
|||
|
||||
} // namespace hsql
|
||||
|
||||
|
||||
#endif
|
|
@ -5,16 +5,14 @@
|
|||
#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
|
||||
};
|
||||
|
||||
// Represents SQL Insert statements.
|
||||
// Example: "INSERT INTO students VALUES ('Max', 1112233, 'Musterhausen', 2.3)"
|
||||
struct InsertStatement : SQLStatement {
|
||||
InsertStatement(InsertType type);
|
||||
virtual ~InsertStatement();
|
||||
|
||||
|
@ -26,4 +24,5 @@ namespace hsql {
|
|||
};
|
||||
|
||||
} // namsepace hsql
|
||||
|
||||
#endif
|
|
@ -7,20 +7,15 @@
|
|||
#include <algorithm>
|
||||
|
||||
namespace hsql {
|
||||
/**
|
||||
* Represents SQL Prepare statements.
|
||||
* Example: "PREPARE ins_prep: SELECT * FROM t1 WHERE c1 = ? AND c2 = ?"
|
||||
*/
|
||||
|
||||
// Represents SQL Prepare statements.
|
||||
// Example: "PREPARE ins_prep: SELECT * FROM t1 WHERE c1 = ? AND c2 = ?"
|
||||
struct PrepareStatement : SQLStatement {
|
||||
PrepareStatement();
|
||||
virtual ~PrepareStatement();
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
// 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<void*> ph);
|
||||
|
||||
char* name;
|
||||
|
@ -35,4 +30,5 @@ namespace hsql {
|
|||
};
|
||||
|
||||
} // namsepace hsql
|
||||
|
||||
#endif
|
|
@ -21,10 +21,9 @@ namespace hsql {
|
|||
kStmtAlter
|
||||
};
|
||||
|
||||
/**
|
||||
* Base struct for every SQL statement
|
||||
*/
|
||||
// Base struct for every SQL statement
|
||||
struct SQLStatement {
|
||||
|
||||
SQLStatement(StatementType type);
|
||||
|
||||
virtual ~SQLStatement();
|
||||
|
@ -33,9 +32,14 @@ namespace hsql {
|
|||
|
||||
bool isType(StatementType type) const;
|
||||
|
||||
// Shorthand for isType(type).
|
||||
bool is(StatementType type) const;
|
||||
|
||||
private:
|
||||
StatementType type_;
|
||||
|
||||
};
|
||||
|
||||
} // namespace hsql
|
||||
|
||||
#endif // __SQLPARSER__SQLSTATEMENT_H__
|
||||
|
|
|
@ -11,9 +11,8 @@ namespace hsql {
|
|||
kOrderDesc
|
||||
};
|
||||
|
||||
/**
|
||||
* Description of the order by clause within a select statement
|
||||
*/
|
||||
|
||||
// Description of the order by clause within a select statement.
|
||||
struct OrderDescription {
|
||||
OrderDescription(OrderType type, Expr* expr);
|
||||
virtual ~OrderDescription();
|
||||
|
@ -25,9 +24,7 @@ namespace hsql {
|
|||
const int64_t kNoLimit = -1;
|
||||
const int64_t kNoOffset = -1;
|
||||
|
||||
/**
|
||||
* Description of the limit clause within a select statement
|
||||
*/
|
||||
// Description of the limit clause within a select statement.
|
||||
struct LimitDescription {
|
||||
LimitDescription(int64_t limit, int64_t offset);
|
||||
|
||||
|
@ -35,9 +32,7 @@ namespace hsql {
|
|||
int64_t offset;
|
||||
};
|
||||
|
||||
/**
|
||||
* Description of the group-by clause within a select statement
|
||||
*/
|
||||
// Description of the group-by clause within a select statement.
|
||||
struct GroupByDescription {
|
||||
GroupByDescription();
|
||||
virtual ~GroupByDescription();
|
||||
|
@ -46,10 +41,8 @@ namespace hsql {
|
|||
Expr* having;
|
||||
};
|
||||
|
||||
/**
|
||||
* Representation of a full SQL select statement.
|
||||
* TODO: add union_order and union_limit
|
||||
*/
|
||||
// Representation of a full SQL select statement.
|
||||
// TODO: add union_order and union_limit.
|
||||
struct SelectStatement : SQLStatement {
|
||||
SelectStatement();
|
||||
virtual ~SelectStatement();
|
||||
|
@ -66,4 +59,5 @@ namespace hsql {
|
|||
};
|
||||
|
||||
} // namespace hsql
|
||||
|
||||
#endif
|
|
@ -4,17 +4,14 @@
|
|||
#include "SQLStatement.h"
|
||||
|
||||
namespace hsql {
|
||||
/**
|
||||
* Represents "column = value" expressions
|
||||
*/
|
||||
|
||||
// Represents "column = value" expressions.
|
||||
struct UpdateClause {
|
||||
char* column;
|
||||
Expr* value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents SQL Update statements.
|
||||
*/
|
||||
// Represents SQL Update statements.
|
||||
struct UpdateStatement : SQLStatement {
|
||||
UpdateStatement();
|
||||
virtual ~UpdateStatement();
|
||||
|
@ -26,4 +23,5 @@ namespace hsql {
|
|||
};
|
||||
|
||||
} // namsepace hsql
|
||||
|
||||
#endif
|
|
@ -17,6 +17,10 @@ namespace hsql {
|
|||
return (type_ == type);
|
||||
}
|
||||
|
||||
bool SQLStatement::is(StatementType type) const {
|
||||
return isType(type);
|
||||
}
|
||||
|
||||
// ColumnDefinition
|
||||
ColumnDefinition::ColumnDefinition(char* name, DataType type) :
|
||||
name(name),
|
||||
|
@ -69,7 +73,7 @@ namespace hsql {
|
|||
}
|
||||
|
||||
// DropStatament
|
||||
DropStatement::DropStatement(EntityType type) :
|
||||
DropStatement::DropStatement(DropType type) :
|
||||
SQLStatement(kStmtDrop),
|
||||
type(type),
|
||||
name(NULL) {}
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace hsql {
|
|||
return std::string(numIndent, '\t');
|
||||
}
|
||||
void inprint(int64_t val, uintmax_t numIndent) {
|
||||
printf("%s%lld \n", indent(numIndent).c_str(), val);
|
||||
printf("%s%ld \n", indent(numIndent).c_str(), val);
|
||||
}
|
||||
void inprint(float val, uintmax_t numIndent) {
|
||||
printf("%s%f\n", indent(numIndent).c_str(), val);
|
||||
|
@ -26,7 +26,7 @@ namespace hsql {
|
|||
printf("%s%c\n", indent(numIndent).c_str(), val);
|
||||
}
|
||||
void inprintU(uint64_t val, uintmax_t numIndent) {
|
||||
printf("%s%llu\n", indent(numIndent).c_str(), val);
|
||||
printf("%s%lu\n", indent(numIndent).c_str(), val);
|
||||
}
|
||||
|
||||
void printTableRefInfo(TableRef* table, uintmax_t numIndent) {
|
||||
|
@ -174,13 +174,13 @@ namespace hsql {
|
|||
}
|
||||
}
|
||||
switch (stmt->type) {
|
||||
case InsertStatement::kInsertValues:
|
||||
case kInsertValues:
|
||||
inprint("Values", numIndent + 1);
|
||||
for (Expr* expr : *stmt->values) {
|
||||
printExpression(expr, numIndent + 2);
|
||||
}
|
||||
break;
|
||||
case InsertStatement::kInsertSelect:
|
||||
case kInsertSelect:
|
||||
printSelectStatementInfo(stmt->select, numIndent + 1);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ using hsql::kStmtInsert;
|
|||
using hsql::kStmtPrepare;
|
||||
using hsql::kStmtSelect;
|
||||
|
||||
using hsql::kDropPreparedStatement;
|
||||
|
||||
using hsql::DropStatement;
|
||||
using hsql::ExecuteStatement;
|
||||
using hsql::InsertStatement;
|
||||
|
@ -69,7 +71,7 @@ TEST(PrepareMultiStatementTest) {
|
|||
ASSERT_EQ(prep2->placeholders.size(), 1);
|
||||
|
||||
// Deallocate Statement
|
||||
ASSERT_EQ(drop->type, DropStatement::kPreparedStatement);
|
||||
ASSERT_EQ(drop->type, kDropPreparedStatement);
|
||||
ASSERT_STREQ(drop->name, "stmt");
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ TEST(CreateStatementTest) {
|
|||
ASSERT_EQ(result.getStatement(0)->type(), kStmtCreate);
|
||||
|
||||
const CreateStatement* stmt = (const CreateStatement*) result.getStatement(0);
|
||||
ASSERT_EQ(stmt->type, CreateStatement::kTable);
|
||||
ASSERT_EQ(stmt->type, kCreateTable);
|
||||
ASSERT_STREQ(stmt->tableName, "students");
|
||||
ASSERT_NOTNULL(stmt->columns);
|
||||
ASSERT_EQ(stmt->columns->size(), 4);
|
||||
|
@ -102,7 +102,7 @@ TEST(DropTableStatementTest) {
|
|||
result,
|
||||
stmt);
|
||||
|
||||
ASSERT_EQ(stmt->type, DropStatement::kTable);
|
||||
ASSERT_EQ(stmt->type, kDropTable);
|
||||
ASSERT_NOTNULL(stmt->name);
|
||||
ASSERT_STREQ(stmt->name, "students");
|
||||
}
|
||||
|
@ -127,4 +127,33 @@ TEST(ReleaseStatementTest) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
SQLParserResult parse_and_move(std::string query) {
|
||||
hsql::SQLParserResult result;
|
||||
hsql::SQLParser::parseSQLString(query, &result);
|
||||
// Moves on return.
|
||||
return result;
|
||||
}
|
||||
|
||||
SQLParserResult move_in_and_back(SQLParserResult res) {
|
||||
// Moves on return.
|
||||
return res;
|
||||
}
|
||||
|
||||
TEST(MoveSQLResultTest) {
|
||||
SQLParserResult res = parse_and_move("SELECT * FROM test;");
|
||||
ASSERT(res.isValid());
|
||||
ASSERT_EQ(1, res.size());
|
||||
|
||||
// Moved around.
|
||||
SQLParserResult new_res = move_in_and_back(std::move(res));
|
||||
|
||||
// Original object should be invalid.
|
||||
ASSERT_FALSE(res.isValid());
|
||||
ASSERT_EQ(0, res.size());
|
||||
|
||||
ASSERT(new_res.isValid());
|
||||
ASSERT_EQ(1, new_res.size());
|
||||
}
|
||||
|
||||
TEST_MAIN();
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
//
|
||||
// microtest
|
||||
// microtest.h
|
||||
//
|
||||
// URL: https://github.com/torpedro/microtest
|
||||
// URL: https://github.com/torpedro/microtest.h
|
||||
// Author: Pedro Flemming (http://torpedro.com/)
|
||||
// License: MIT License (https://github.com/torpedro/microtest/blob/master/LICENSE)
|
||||
// License: MIT License (https://github.com/torpedro/microtest.h/blob/master/LICENSE)
|
||||
// Copyright (c) 2017 Pedro Flemming
|
||||
//
|
||||
// This is a small header-only C++ unit testing framework.
|
||||
|
@ -37,8 +37,18 @@
|
|||
ASSERT_TRUE(value != NULL);
|
||||
|
||||
#define ASSERT_STREQ(a, b)\
|
||||
if (std::string(a).compare(std::string(b)) != 0)\
|
||||
throw mt::AssertFailedException(#a " == " #b, __FILE__, __LINE__);
|
||||
if (std::string(a).compare(std::string(b)) != 0) {\
|
||||
printf("%s{ info} %s", mt::yellow(), mt::def());\
|
||||
std::cout << "Actual values: " << a << " != " << b << std::endl;\
|
||||
throw mt::AssertFailedException(#a " == " #b, __FILE__, __LINE__);\
|
||||
}
|
||||
|
||||
#define ASSERT_STRNEQ(a, b)\
|
||||
if (std::string(a).compare(std::string(b)) !== 0) {\
|
||||
printf("%s{ info} %s", mt::yellow(), mt::def());\
|
||||
std::cout << "Actual values: " << a << " == " << b << std::endl;\
|
||||
throw mt::AssertFailedException(#a " != " #b, __FILE__, __LINE__);\
|
||||
}
|
||||
|
||||
#define ASSERT_EQ(a, b)\
|
||||
if (a != b) {\
|
||||
|
@ -175,7 +185,8 @@ namespace mt {
|
|||
}
|
||||
}
|
||||
|
||||
return num_failed;
|
||||
int return_code = (num_failed > 0) ? 1 : 0;
|
||||
return return_code;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue