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::ShowStatement* show_stmt;
hsql::TableName table_name;
hsql::TableRef* table;
hsql::Expr* expr;
hsql::OrderDescription* order;
@ -255,7 +256,7 @@ union HSQL_STYPE
std::vector<hsql::Expr*>* expr_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;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -3,6 +3,7 @@
# SELECT statement
SELECT * FROM orders;
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 * 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);
@ -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 (id, value, name) VALUES (1, 2, 'test');
INSERT INTO test_table SELECT * FROM students;
INSERT INTO some_schema.test_table SELECT * FROM another_schema.students;
# DELETE
DELETE FROM students WHERE grade > 3.0
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, name='Felix Fürstenberg' WHERE name = 'Max Mustermann';
UPDATE students SET grade = 1.0;
UPDATE some_schema.students SET grade = 1.0;
# DROP
DROP TABLE students;
DROP TABLE IF EXISTS students;
DROP VIEW IF EXISTS students;
# PREPARE
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, ?);';

View File

@ -88,6 +88,18 @@ TEST(SelectDistinctTest) {
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_PARSE_SINGLE_SQL(
"SELECT city, COUNT(name), COUNT(DISTINCT grade) FROM students GROUP BY city;",

View File

@ -102,6 +102,21 @@ TEST(DropTableStatementTest) {
result,
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_NOTNULL(stmt->name);
ASSERT_STREQ(stmt->name, "students");