Merge pull request #70 from hyrise/feature/schema_and_if_exists_for_drop

Schema for Table Refs; IF EXISTS for Drop
This commit is contained in:
mrks 2017-10-20 14:51:19 +02:00 committed by GitHub
commit 0c574335cd
15 changed files with 1252 additions and 1105 deletions

File diff suppressed because it is too large Load Diff

View File

@ -237,6 +237,7 @@ union HSQL_STYPE
hsql::ExecuteStatement* exec_stmt; hsql::ExecuteStatement* exec_stmt;
hsql::ShowStatement* show_stmt; hsql::ShowStatement* show_stmt;
hsql::TableName table_name;
hsql::TableRef* table; hsql::TableRef* table;
hsql::Expr* expr; hsql::Expr* expr;
hsql::OrderDescription* order; hsql::OrderDescription* order;
@ -255,7 +256,7 @@ union HSQL_STYPE
std::vector<hsql::Expr*>* expr_vec; std::vector<hsql::Expr*>* expr_vec;
std::vector<hsql::OrderDescription*>* order_vec; std::vector<hsql::OrderDescription*>* order_vec;
#line 259 "bison_parser.h" /* yacc.c:1909 */ #line 260 "bison_parser.h" /* yacc.c:1909 */
}; };
typedef union HSQL_STYPE HSQL_STYPE; typedef union HSQL_STYPE HSQL_STYPE;

62
src/parser/bison_parser.y Normal file → Executable file
View File

@ -109,6 +109,7 @@ int yyerror(YYLTYPE* llocp, SQLParserResult* result, yyscan_t scanner, const cha
hsql::ExecuteStatement* exec_stmt; hsql::ExecuteStatement* exec_stmt;
hsql::ShowStatement* show_stmt; hsql::ShowStatement* show_stmt;
hsql::TableName table_name;
hsql::TableRef* table; hsql::TableRef* table;
hsql::Expr* expr; hsql::Expr* expr;
hsql::OrderDescription* order; hsql::OrderDescription* order;
@ -133,6 +134,7 @@ int yyerror(YYLTYPE* llocp, SQLParserResult* result, yyscan_t scanner, const cha
** Descrutor symbols ** Descrutor symbols
*********************************/ *********************************/
%destructor { } <fval> <ival> <uval> <bval> <order_type> %destructor { } <fval> <ival> <uval> <bval> <order_type>
%destructor { free( ($$.name) ); free( ($$.schema) ); } <table_name>
%destructor { free( ($$) ); } <sval> %destructor { free( ($$) ); } <sval>
%destructor { %destructor {
if (($$) != nullptr) { if (($$) != nullptr) {
@ -184,8 +186,9 @@ int yyerror(YYLTYPE* llocp, SQLParserResult* result, yyscan_t scanner, const cha
%type <update_stmt> update_statement %type <update_stmt> update_statement
%type <drop_stmt> drop_statement %type <drop_stmt> drop_statement
%type <show_stmt> show_statement %type <show_stmt> show_statement
%type <sval> table_name opt_alias alias file_path prepare_target_query %type <table_name> table_name
%type <bval> opt_not_exists opt_distinct %type <sval> opt_alias alias file_path prepare_target_query
%type <bval> opt_not_exists opt_exists opt_distinct
%type <uval> import_file_type opt_join_type column_type %type <uval> import_file_type opt_join_type column_type
%type <table> from_clause table_ref table_ref_atomic table_ref_name nonjoin_table_ref_atomic %type <table> from_clause table_ref table_ref_atomic table_ref_name nonjoin_table_ref_atomic
%type <table> join_clause table_ref_name_no_alias %type <table> join_clause table_ref_name_no_alias
@ -353,7 +356,8 @@ import_statement:
IMPORT FROM import_file_type FILE file_path INTO table_name { IMPORT FROM import_file_type FILE file_path INTO table_name {
$$ = new ImportStatement((ImportType) $3); $$ = new ImportStatement((ImportType) $3);
$$->filePath = $5; $$->filePath = $5;
$$->tableName = $7; $$->schema = $7.schema;
$$->tableName = $7.name;
} }
; ;
@ -377,7 +381,8 @@ show_statement:
} }
| SHOW COLUMNS table_name { | SHOW COLUMNS table_name {
$$ = new ShowStatement(kShowColumns); $$ = new ShowStatement(kShowColumns);
$$->name = $3; $$->schema = $3.schema;
$$->name = $3.name;
} }
; ;
@ -391,19 +396,22 @@ create_statement:
CREATE TABLE opt_not_exists table_name FROM TBL FILE file_path { CREATE TABLE opt_not_exists table_name FROM TBL FILE file_path {
$$ = new CreateStatement(kCreateTableFromTbl); $$ = new CreateStatement(kCreateTableFromTbl);
$$->ifNotExists = $3; $$->ifNotExists = $3;
$$->tableName = $4; $$->schema = $4.schema;
$$->tableName = $4.name;
$$->filePath = $8; $$->filePath = $8;
} }
| CREATE TABLE opt_not_exists table_name '(' column_def_commalist ')' { | CREATE TABLE opt_not_exists table_name '(' column_def_commalist ')' {
$$ = new CreateStatement(kCreateTable); $$ = new CreateStatement(kCreateTable);
$$->ifNotExists = $3; $$->ifNotExists = $3;
$$->tableName = $4; $$->schema = $4.schema;
$$->tableName = $4.name;
$$->columns = $6; $$->columns = $6;
} }
| CREATE VIEW opt_not_exists table_name opt_column_list AS select_statement { | CREATE VIEW opt_not_exists table_name opt_column_list AS select_statement {
$$ = new CreateStatement(kCreateView); $$ = new CreateStatement(kCreateView);
$$->ifNotExists = $3; $$->ifNotExists = $3;
$$->tableName = $4; $$->schema = $4.schema;
$$->tableName = $4.name;
$$->viewColumns = $5; $$->viewColumns = $5;
$$->select = $7; $$->select = $7;
} }
@ -440,20 +448,30 @@ column_type:
******************************/ ******************************/
drop_statement: drop_statement:
DROP TABLE table_name { DROP TABLE opt_exists table_name {
$$ = new DropStatement(kDropTable); $$ = new DropStatement(kDropTable);
$$->name = $3; $$->ifExists = $3;
$$->schema = $4.schema;
$$->name = $4.name;
} }
| DROP VIEW table_name { | DROP VIEW opt_exists table_name {
$$ = new DropStatement(kDropView); $$ = new DropStatement(kDropView);
$$->name = $3; $$->ifExists = $3;
$$->schema = $4.schema;
$$->name = $4.name;
} }
| DEALLOCATE PREPARE IDENTIFIER { | DEALLOCATE PREPARE IDENTIFIER {
$$ = new DropStatement(kDropPreparedStatement); $$ = new DropStatement(kDropPreparedStatement);
$$->ifExists = false;
$$->name = $3; $$->name = $3;
} }
; ;
opt_exists:
IF EXISTS { $$ = true; }
| /* empty */ { $$ = false; }
;
/****************************** /******************************
* Delete Statement / Truncate statement * Delete Statement / Truncate statement
* DELETE FROM students WHERE grade > 3.0 * DELETE FROM students WHERE grade > 3.0
@ -462,7 +480,8 @@ drop_statement:
delete_statement: delete_statement:
DELETE FROM table_name opt_where { DELETE FROM table_name opt_where {
$$ = new DeleteStatement(); $$ = new DeleteStatement();
$$->tableName = $3; $$->schema = $3.schema;
$$->tableName = $3.name;
$$->expr = $4; $$->expr = $4;
} }
; ;
@ -470,7 +489,8 @@ delete_statement:
truncate_statement: truncate_statement:
TRUNCATE table_name { TRUNCATE table_name {
$$ = new DeleteStatement(); $$ = new DeleteStatement();
$$->tableName = $2; $$->schema = $2.schema;
$$->tableName = $2.name;
} }
; ;
@ -482,13 +502,15 @@ truncate_statement:
insert_statement: insert_statement:
INSERT INTO table_name opt_column_list VALUES '(' literal_list ')' { INSERT INTO table_name opt_column_list VALUES '(' literal_list ')' {
$$ = new InsertStatement(kInsertValues); $$ = new InsertStatement(kInsertValues);
$$->tableName = $3; $$->schema = $3.schema;
$$->tableName = $3.name;
$$->columns = $4; $$->columns = $4;
$$->values = $7; $$->values = $7;
} }
| INSERT INTO table_name opt_column_list select_no_paren { | INSERT INTO table_name opt_column_list select_no_paren {
$$ = new InsertStatement(kInsertSelect); $$ = new InsertStatement(kInsertSelect);
$$->tableName = $3; $$->schema = $3.schema;
$$->tableName = $3.name;
$$->columns = $4; $$->columns = $4;
$$->select = $5; $$->select = $5;
} }
@ -876,7 +898,8 @@ table_ref_commalist:
table_ref_name: table_ref_name:
table_name opt_alias { table_name opt_alias {
auto tbl = new TableRef(kTableName); auto tbl = new TableRef(kTableName);
tbl->name = $1; tbl->schema = $1.schema;
tbl->name = $1.name;
tbl->alias = $2; tbl->alias = $2;
$$ = tbl; $$ = tbl;
} }
@ -886,14 +909,15 @@ table_ref_name:
table_ref_name_no_alias: table_ref_name_no_alias:
table_name { table_name {
$$ = new TableRef(kTableName); $$ = new TableRef(kTableName);
$$->name = $1; $$->schema = $1.schema;
$$->name = $1.name;
} }
; ;
table_name: table_name:
IDENTIFIER IDENTIFIER { $$.schema = nullptr; $$.name = $1;}
| IDENTIFIER '.' IDENTIFIER { $$ = $3; } | IDENTIFIER '.' IDENTIFIER { $$.schema = $1; $$.name = $3; }
; ;

5
src/sql/CreateStatement.h Normal file → Executable file
View File

@ -37,8 +37,9 @@ namespace hsql {
CreateType type; CreateType type;
bool ifNotExists; // default: false bool ifNotExists; // default: false
char* filePath; // default: nullptr char* filePath; // default: nullptr
char* tableName; // default: nullptr char* schema; // default: nullptr
char* tableName; // default: nullptr
std::vector<ColumnDefinition*>* columns; // default: nullptr std::vector<ColumnDefinition*>* columns; // default: nullptr
std::vector<char*>* viewColumns; std::vector<char*>* viewColumns;
SelectStatement* select; SelectStatement* select;

1
src/sql/DeleteStatement.h Normal file → Executable file
View File

@ -13,6 +13,7 @@ namespace hsql {
DeleteStatement(); DeleteStatement();
virtual ~DeleteStatement(); virtual ~DeleteStatement();
char* schema;
char* tableName; char* tableName;
Expr* expr; Expr* expr;
}; };

2
src/sql/DropStatement.h Normal file → Executable file
View File

@ -22,6 +22,8 @@ namespace hsql {
virtual ~DropStatement(); virtual ~DropStatement();
DropType type; DropType type;
bool ifExists;
char* schema;
char* name; char* name;
}; };

5
src/sql/ImportStatement.h Normal file → Executable file
View File

@ -15,8 +15,9 @@ namespace hsql {
virtual ~ImportStatement(); virtual ~ImportStatement();
ImportType type; ImportType type;
const char* filePath; char* filePath;
const char* tableName; char* schema;
char* tableName;
}; };
} // namespace hsql } // namespace hsql

1
src/sql/InsertStatement.h Normal file → Executable file
View File

@ -17,6 +17,7 @@ namespace hsql {
virtual ~InsertStatement(); virtual ~InsertStatement();
InsertType type; InsertType type;
char* schema;
char* tableName; char* tableName;
std::vector<char*>* columns; std::vector<char*>* columns;
std::vector<Expr*>* values; std::vector<Expr*>* values;

1
src/sql/ShowStatement.h Normal file → Executable file
View File

@ -19,6 +19,7 @@ namespace hsql {
virtual ~ShowStatement(); virtual ~ShowStatement();
ShowType type; ShowType type;
char* schema;
char* name; char* name;
}; };

5
src/sql/Table.h Normal file → Executable file
View File

@ -19,6 +19,11 @@ namespace hsql {
kTableCrossProduct kTableCrossProduct
}; };
struct TableName {
char* schema;
char* name;
};
// Holds reference to tables. Can be either table names or a select statement. // Holds reference to tables. Can be either table names or a select statement.
struct TableRef { struct TableRef {
TableRef(TableRefType type); TableRef(TableRefType type);

16
src/sql/statements.cpp Normal file → Executable file
View File

@ -18,6 +18,7 @@ namespace hsql {
type(type), type(type),
ifNotExists(false), ifNotExists(false),
filePath(nullptr), filePath(nullptr),
schema(nullptr),
tableName(nullptr), tableName(nullptr),
columns(nullptr), columns(nullptr),
viewColumns(nullptr), viewColumns(nullptr),
@ -25,6 +26,7 @@ namespace hsql {
CreateStatement::~CreateStatement() { CreateStatement::~CreateStatement() {
free(filePath); free(filePath);
free(schema);
free(tableName); free(tableName);
delete select; delete select;
@ -46,10 +48,12 @@ namespace hsql {
// DeleteStatement // DeleteStatement
DeleteStatement::DeleteStatement() : DeleteStatement::DeleteStatement() :
SQLStatement(kStmtDelete), SQLStatement(kStmtDelete),
schema(nullptr),
tableName(nullptr), tableName(nullptr),
expr(nullptr) {}; expr(nullptr) {};
DeleteStatement::~DeleteStatement() { DeleteStatement::~DeleteStatement() {
free(schema);
free(tableName); free(tableName);
delete expr; delete expr;
} }
@ -58,9 +62,11 @@ namespace hsql {
DropStatement::DropStatement(DropType type) : DropStatement::DropStatement(DropType type) :
SQLStatement(kStmtDrop), SQLStatement(kStmtDrop),
type(type), type(type),
schema(nullptr),
name(nullptr) {} name(nullptr) {}
DropStatement::~DropStatement() { DropStatement::~DropStatement() {
free(schema);
free(name); free(name);
} }
@ -86,23 +92,27 @@ namespace hsql {
SQLStatement(kStmtImport), SQLStatement(kStmtImport),
type(type), type(type),
filePath(nullptr), filePath(nullptr),
schema(nullptr),
tableName(nullptr) {}; tableName(nullptr) {};
ImportStatement::~ImportStatement() { ImportStatement::~ImportStatement() {
delete filePath; free(filePath);
delete tableName; free(schema);
free(tableName);
} }
// InsertStatement // InsertStatement
InsertStatement::InsertStatement(InsertType type) : InsertStatement::InsertStatement(InsertType type) :
SQLStatement(kStmtInsert), SQLStatement(kStmtInsert),
type(type), type(type),
schema(nullptr),
tableName(nullptr), tableName(nullptr),
columns(nullptr), columns(nullptr),
values(nullptr), values(nullptr),
select(nullptr) {} select(nullptr) {}
InsertStatement::~InsertStatement() { InsertStatement::~InsertStatement() {
free(schema);
free(tableName); free(tableName);
delete select; delete select;
@ -125,9 +135,11 @@ namespace hsql {
ShowStatement::ShowStatement(ShowType type) : ShowStatement::ShowStatement(ShowType type) :
SQLStatement(kStmtShow), SQLStatement(kStmtShow),
type(type), type(type),
schema(nullptr),
name(nullptr) {} name(nullptr) {}
ShowStatement::~ShowStatement() { ShowStatement::~ShowStatement() {
free(schema);
free(name); free(name);
} }

29
src/util/sqlhelper.cpp Normal file → Executable file
View File

@ -33,6 +33,10 @@ namespace hsql {
switch (table->type) { switch (table->type) {
case kTableName: case kTableName:
inprint(table->name, numIndent); inprint(table->name, numIndent);
if(table->schema) {
inprint("Schema", numIndent + 1);
inprint(table->schema, numIndent + 2);
}
break; break;
case kTableSelect: case kTableSelect:
printSelectStatementInfo(table->select, numIndent); printSelectStatementInfo(table->select, numIndent);
@ -87,6 +91,10 @@ namespace hsql {
break; break;
case kExprColumnRef: case kExprColumnRef:
inprint(expr->name, numIndent); inprint(expr->name, numIndent);
if(expr->table) {
inprint("Table:", numIndent+1);
inprint(expr->table, numIndent+2);
}
break; break;
// case kExprTableColumnRef: inprint(expr->table, expr->name, numIndent); break; // case kExprTableColumnRef: inprint(expr->table, expr->name, numIndent); break;
case kExprLiteralFloat: case kExprLiteralFloat:
@ -100,11 +108,24 @@ namespace hsql {
break; break;
case kExprFunctionRef: case kExprFunctionRef:
inprint(expr->name, numIndent); inprint(expr->name, numIndent);
for (Expr* e : *expr->exprList) inprint(e->name, numIndent + 1); for (Expr* e : *expr->exprList) printExpression(e, numIndent + 1);
break; break;
case kExprOperator: case kExprOperator:
printOperatorExpression(expr, numIndent); printOperatorExpression(expr, numIndent);
break; break;
case kExprSelect:
printSelectStatementInfo(expr->select, numIndent);
break;
case kExprParameter:
inprint(expr->ival, numIndent);
break;
case kExprArray:
for (Expr* e : *expr->exprList) printExpression(e, numIndent + 1);
break;
case kExprArrayIndex:
printExpression(expr->expr, numIndent + 1);
inprint(expr->ival, numIndent);
break;
default: default:
std::cerr << "Unrecognized expression type " << expr->type << std::endl; std::cerr << "Unrecognized expression type " << expr->type << std::endl;
return; return;
@ -120,8 +141,10 @@ namespace hsql {
inprint("Fields:", numIndent + 1); inprint("Fields:", numIndent + 1);
for (Expr* expr : *stmt->selectList) printExpression(expr, numIndent + 2); for (Expr* expr : *stmt->selectList) printExpression(expr, numIndent + 2);
inprint("Sources:", numIndent + 1); if (stmt->fromTable != nullptr) {
printTableRefInfo(stmt->fromTable, numIndent + 2); inprint("Sources:", numIndent + 1);
printTableRefInfo(stmt->fromTable, numIndent + 2);
}
if (stmt->whereClause != nullptr) { if (stmt->whereClause != nullptr) {
inprint("Search Conditions:", numIndent + 1); inprint("Search Conditions:", numIndent + 1);

5
test/queries/queries-good.sql Normal file → Executable file
View File

@ -3,6 +3,7 @@
# SELECT statement # SELECT statement
SELECT * FROM orders; SELECT * FROM orders;
SELECT a FROM foo WHERE a > 12 OR b > 3 AND NOT c LIMIT 10 SELECT a FROM foo WHERE a > 12 OR b > 3 AND NOT c LIMIT 10
SELECT a FROM some_schema.foo WHERE a > 12 OR b > 3 AND NOT c LIMIT 10
SELECT col1 AS myname, col2, 'test' FROM "table", foo AS t WHERE age > 12 AND zipcode = 12345 GROUP BY col1; SELECT col1 AS myname, col2, 'test' FROM "table", foo AS t WHERE age > 12 AND zipcode = 12345 GROUP BY col1;
SELECT * from "table" JOIN table2 ON a = b WHERE (b OR NOT a) AND a = 12.5 SELECT * from "table" JOIN table2 ON a = b WHERE (b OR NOT a) AND a = 12.5
(SELECT a FROM foo WHERE a > 12 OR b > 3 AND c NOT LIKE 's%' LIMIT 10); (SELECT a FROM foo WHERE a > 12 OR b > 3 AND c NOT LIKE 's%' LIMIT 10);
@ -29,6 +30,7 @@ CREATE TABLE "table" FROM TBL FILE 'students.tbl'; SELECT * FROM "table";
INSERT INTO test_table VALUES (1, 2, 'test'); INSERT INTO test_table VALUES (1, 2, 'test');
INSERT INTO test_table (id, value, name) VALUES (1, 2, 'test'); INSERT INTO test_table (id, value, name) VALUES (1, 2, 'test');
INSERT INTO test_table SELECT * FROM students; INSERT INTO test_table SELECT * FROM students;
INSERT INTO some_schema.test_table SELECT * FROM another_schema.students;
# DELETE # DELETE
DELETE FROM students WHERE grade > 3.0 DELETE FROM students WHERE grade > 3.0
DELETE FROM students DELETE FROM students
@ -37,8 +39,11 @@ TRUNCATE students
UPDATE students SET grade = 1.3 WHERE name = 'Max Mustermann'; UPDATE students SET grade = 1.3 WHERE name = 'Max Mustermann';
UPDATE students SET grade = 1.3, name='Felix Fürstenberg' WHERE name = 'Max Mustermann'; UPDATE students SET grade = 1.3, name='Felix Fürstenberg' WHERE name = 'Max Mustermann';
UPDATE students SET grade = 1.0; UPDATE students SET grade = 1.0;
UPDATE some_schema.students SET grade = 1.0;
# DROP # DROP
DROP TABLE students; DROP TABLE students;
DROP TABLE IF EXISTS students;
DROP VIEW IF EXISTS students;
# PREPARE # PREPARE
PREPARE prep_inst FROM 'INSERT INTO test VALUES (?, ?, ?)'; PREPARE prep_inst FROM 'INSERT INTO test VALUES (?, ?, ?)';
PREPARE prep2 FROM 'INSERT INTO test VALUES (?, 0, 0); INSERT INTO test VALUES (0, ?, 0); INSERT INTO test VALUES (0, 0, ?);'; PREPARE prep2 FROM 'INSERT INTO test VALUES (?, 0, 0); INSERT INTO test VALUES (0, ?, 0); INSERT INTO test VALUES (0, 0, ?);';

View File

@ -88,6 +88,18 @@ TEST(SelectDistinctTest) {
ASSERT_NULL(stmt->whereClause); ASSERT_NULL(stmt->whereClause);
} }
TEST(SelectSchemaTest) {
TEST_PARSE_SINGLE_SQL(
"SELECT grade FROM some_schema.students;",
kStmtSelect,
SelectStatement,
result,
stmt);
ASSERT(stmt->fromTable);
ASSERT_EQ(std::string(stmt->fromTable->schema), "some_schema");
}
TEST(SelectGroupDistinctTest) { TEST(SelectGroupDistinctTest) {
TEST_PARSE_SINGLE_SQL( TEST_PARSE_SINGLE_SQL(
"SELECT city, COUNT(name), COUNT(DISTINCT grade) FROM students GROUP BY city;", "SELECT city, COUNT(name), COUNT(DISTINCT grade) FROM students GROUP BY city;",

View File

@ -102,6 +102,21 @@ TEST(DropTableStatementTest) {
result, result,
stmt); stmt);
ASSERT_FALSE(stmt->ifExists);
ASSERT_EQ(stmt->type, kDropTable);
ASSERT_NOTNULL(stmt->name);
ASSERT_STREQ(stmt->name, "students");
}
TEST(DropTableIfExistsStatementTest) {
TEST_PARSE_SINGLE_SQL(
"DROP TABLE IF EXISTS students",
kStmtDrop,
DropStatement,
result,
stmt);
ASSERT_TRUE(stmt->ifExists);
ASSERT_EQ(stmt->type, kDropTable); ASSERT_EQ(stmt->type, kDropTable);
ASSERT_NOTNULL(stmt->name); ASSERT_NOTNULL(stmt->name);
ASSERT_STREQ(stmt->name, "students"); ASSERT_STREQ(stmt->name, "students");