Add Hints per statement to SQL syntax.
This commit is contained in:
parent
f85a5e7b52
commit
1483a4a95a
|
@ -48,7 +48,7 @@ namespace hsql {
|
||||||
|
|
||||||
if (!SQLParser::parseSQLString(text, result)) {
|
if (!SQLParser::parseSQLString(text, result)) {
|
||||||
delete result;
|
delete result;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -6,11 +6,11 @@ namespace hsql {
|
||||||
|
|
||||||
SQLParserResult::SQLParserResult() :
|
SQLParserResult::SQLParserResult() :
|
||||||
isValid_(false),
|
isValid_(false),
|
||||||
errorMsg_(NULL) {};
|
errorMsg_(nullptr) {};
|
||||||
|
|
||||||
SQLParserResult::SQLParserResult(SQLStatement* stmt) :
|
SQLParserResult::SQLParserResult(SQLStatement* stmt) :
|
||||||
isValid_(false),
|
isValid_(false),
|
||||||
errorMsg_(NULL) {
|
errorMsg_(nullptr) {
|
||||||
addStatement(stmt);
|
addStatement(stmt);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ namespace hsql {
|
||||||
errorMsg_ = moved.errorMsg_;
|
errorMsg_ = moved.errorMsg_;
|
||||||
statements_ = std::move(moved.statements_);
|
statements_ = std::move(moved.statements_);
|
||||||
|
|
||||||
moved.errorMsg_ = NULL;
|
moved.errorMsg_ = nullptr;
|
||||||
moved.reset();
|
moved.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ namespace hsql {
|
||||||
isValid_ = false;
|
isValid_ = false;
|
||||||
|
|
||||||
free(errorMsg_);
|
free(errorMsg_);
|
||||||
errorMsg_ = NULL;
|
errorMsg_ = nullptr;
|
||||||
errorLine_ = -1;
|
errorLine_ = -1;
|
||||||
errorColumn_ = -1;
|
errorColumn_ = -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,7 @@ int yyerror(YYLTYPE* llocp, SQLParserResult* result, yyscan_t scanner, const cha
|
||||||
%destructor { } <fval> <ival> <uval> <bval> <order_type>
|
%destructor { } <fval> <ival> <uval> <bval> <order_type>
|
||||||
%destructor { free( ($$) ); } <sval>
|
%destructor { free( ($$) ); } <sval>
|
||||||
%destructor {
|
%destructor {
|
||||||
if (($$) != NULL) {
|
if (($$) != nullptr) {
|
||||||
for (auto ptr : *($$)) {
|
for (auto ptr : *($$)) {
|
||||||
delete ptr;
|
delete ptr;
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,6 @@ int yyerror(YYLTYPE* llocp, SQLParserResult* result, yyscan_t scanner, const cha
|
||||||
%token <sval> IDENTIFIER STRING
|
%token <sval> IDENTIFIER STRING
|
||||||
%token <fval> FLOATVAL
|
%token <fval> FLOATVAL
|
||||||
%token <ival> INTVAL
|
%token <ival> INTVAL
|
||||||
%token <uval> NOTEQUALS LESSEQ GREATEREQ
|
|
||||||
|
|
||||||
/* SQL Keywords */
|
/* SQL Keywords */
|
||||||
%token DEALLOCATE PARAMETERS INTERSECT TEMPORARY TIMESTAMP
|
%token DEALLOCATE PARAMETERS INTERSECT TEMPORARY TIMESTAMP
|
||||||
|
@ -189,7 +188,7 @@ int yyerror(YYLTYPE* llocp, SQLParserResult* result, yyscan_t scanner, const cha
|
||||||
%type <expr> expr operand scalar_expr unary_expr binary_expr logic_expr exists_expr
|
%type <expr> expr operand scalar_expr unary_expr binary_expr logic_expr exists_expr
|
||||||
%type <expr> function_expr between_expr star_expr expr_alias param_expr
|
%type <expr> function_expr between_expr star_expr expr_alias param_expr
|
||||||
%type <expr> column_name literal int_literal num_literal string_literal
|
%type <expr> column_name literal int_literal num_literal string_literal
|
||||||
%type <expr> comp_expr opt_where join_condition opt_having case_expr in_expr
|
%type <expr> comp_expr opt_where join_condition opt_having case_expr in_expr hint
|
||||||
%type <limit> opt_limit opt_top
|
%type <limit> opt_limit opt_top
|
||||||
%type <order> order_desc
|
%type <order> order_desc
|
||||||
%type <order_type> opt_order_type
|
%type <order_type> opt_order_type
|
||||||
|
@ -198,7 +197,7 @@ int yyerror(YYLTYPE* llocp, SQLParserResult* result, yyscan_t scanner, const cha
|
||||||
%type <group_t> opt_group
|
%type <group_t> opt_group
|
||||||
|
|
||||||
%type <str_vec> ident_commalist opt_column_list
|
%type <str_vec> ident_commalist opt_column_list
|
||||||
%type <expr_vec> expr_list select_list literal_list
|
%type <expr_vec> expr_list select_list literal_list hint_list opt_hints
|
||||||
%type <table_vec> table_ref_commalist
|
%type <table_vec> table_ref_commalist
|
||||||
%type <order_vec> opt_order order_list
|
%type <order_vec> opt_order order_list
|
||||||
%type <update_vec> update_clause_commalist
|
%type <update_vec> update_clause_commalist
|
||||||
|
@ -260,8 +259,14 @@ statement_list:
|
||||||
;
|
;
|
||||||
|
|
||||||
statement:
|
statement:
|
||||||
prepare_statement
|
prepare_statement opt_hints {
|
||||||
| preparable_statement
|
$$ = $1;
|
||||||
|
$$->hints = $2;
|
||||||
|
}
|
||||||
|
| preparable_statement opt_hints {
|
||||||
|
$$ = $1;
|
||||||
|
$$->hints = $2;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
@ -278,6 +283,34 @@ preparable_statement:
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
/******************************
|
||||||
|
* Hints
|
||||||
|
******************************/
|
||||||
|
|
||||||
|
opt_hints:
|
||||||
|
WITH HINT '(' hint_list ')' { $$ = $4; }
|
||||||
|
| /* empty */ { $$ = nullptr; }
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
hint_list:
|
||||||
|
hint { $$ = new std::vector<Expr*>(); $$->push_back($1); }
|
||||||
|
| hint_list ',' hint { $1->push_back($3); $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
hint:
|
||||||
|
IDENTIFIER {
|
||||||
|
$$ = Expr::make(kExprHint);
|
||||||
|
$$->name = $1;
|
||||||
|
}
|
||||||
|
| IDENTIFIER '(' literal_list ')' {
|
||||||
|
$$ = Expr::make(kExprHint);
|
||||||
|
$$->name = $1;
|
||||||
|
$$->exprList = $3;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
/******************************
|
/******************************
|
||||||
* Prepared Statement
|
* Prepared Statement
|
||||||
******************************/
|
******************************/
|
||||||
|
@ -439,7 +472,7 @@ insert_statement:
|
||||||
|
|
||||||
opt_column_list:
|
opt_column_list:
|
||||||
'(' ident_commalist ')' { $$ = $2; }
|
'(' ident_commalist ')' { $$ = $2; }
|
||||||
| /* empty */ { $$ = NULL; }
|
| /* empty */ { $$ = nullptr; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
@ -490,7 +523,7 @@ select_no_paren:
|
||||||
$$->order = $2;
|
$$->order = $2;
|
||||||
|
|
||||||
// Limit could have been set by TOP.
|
// Limit could have been set by TOP.
|
||||||
if ($3 != NULL) {
|
if ($3 != nullptr) {
|
||||||
delete $$->limit;
|
delete $$->limit;
|
||||||
$$->limit = $3;
|
$$->limit = $3;
|
||||||
}
|
}
|
||||||
|
@ -504,7 +537,7 @@ select_no_paren:
|
||||||
$$->order = $4;
|
$$->order = $4;
|
||||||
|
|
||||||
// Limit could have been set by TOP.
|
// Limit could have been set by TOP.
|
||||||
if ($5 != NULL) {
|
if ($5 != nullptr) {
|
||||||
delete $$->limit;
|
delete $$->limit;
|
||||||
$$->limit = $5;
|
$$->limit = $5;
|
||||||
}
|
}
|
||||||
|
@ -515,7 +548,7 @@ select_no_paren:
|
||||||
$$->order = $4;
|
$$->order = $4;
|
||||||
|
|
||||||
// Limit could have been set by TOP.
|
// Limit could have been set by TOP.
|
||||||
if ($5 != NULL) {
|
if ($5 != nullptr) {
|
||||||
delete $$->limit;
|
delete $$->limit;
|
||||||
$$->limit = $5;
|
$$->limit = $5;
|
||||||
}
|
}
|
||||||
|
@ -556,7 +589,7 @@ from_clause:
|
||||||
|
|
||||||
opt_where:
|
opt_where:
|
||||||
WHERE expr { $$ = $2; }
|
WHERE expr { $$ = $2; }
|
||||||
| /* empty */ { $$ = NULL; }
|
| /* empty */ { $$ = nullptr; }
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_group:
|
opt_group:
|
||||||
|
@ -565,16 +598,16 @@ opt_group:
|
||||||
$$->columns = $3;
|
$$->columns = $3;
|
||||||
$$->having = $4;
|
$$->having = $4;
|
||||||
}
|
}
|
||||||
| /* empty */ { $$ = NULL; }
|
| /* empty */ { $$ = nullptr; }
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_having:
|
opt_having:
|
||||||
HAVING expr { $$ = $2; }
|
HAVING expr { $$ = $2; }
|
||||||
| /* empty */ { $$ = NULL; }
|
| /* empty */ { $$ = nullptr; }
|
||||||
|
|
||||||
opt_order:
|
opt_order:
|
||||||
ORDER BY order_list { $$ = $3; }
|
ORDER BY order_list { $$ = $3; }
|
||||||
| /* empty */ { $$ = NULL; }
|
| /* empty */ { $$ = nullptr; }
|
||||||
;
|
;
|
||||||
|
|
||||||
order_list:
|
order_list:
|
||||||
|
@ -596,13 +629,13 @@ opt_order_type:
|
||||||
|
|
||||||
opt_top:
|
opt_top:
|
||||||
TOP int_literal { $$ = new LimitDescription($2->ival, kNoOffset); delete $2; }
|
TOP int_literal { $$ = new LimitDescription($2->ival, kNoOffset); delete $2; }
|
||||||
| /* empty */ { $$ = NULL; }
|
| /* empty */ { $$ = nullptr; }
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_limit:
|
opt_limit:
|
||||||
LIMIT int_literal { $$ = new LimitDescription($2->ival, kNoOffset); delete $2; }
|
LIMIT int_literal { $$ = new LimitDescription($2->ival, kNoOffset); delete $2; }
|
||||||
| LIMIT int_literal OFFSET int_literal { $$ = new LimitDescription($2->ival, $4->ival); delete $2; delete $4; }
|
| LIMIT int_literal OFFSET int_literal { $$ = new LimitDescription($2->ival, $4->ival); delete $2; delete $4; }
|
||||||
| /* empty */ { $$ = NULL; }
|
| /* empty */ { $$ = nullptr; }
|
||||||
;
|
;
|
||||||
|
|
||||||
/******************************
|
/******************************
|
||||||
|
@ -731,7 +764,7 @@ int_literal:
|
||||||
;
|
;
|
||||||
|
|
||||||
star_expr:
|
star_expr:
|
||||||
'*' { $$ = new Expr(kExprStar); }
|
'*' { $$ = Expr::make(kExprStar); }
|
||||||
;
|
;
|
||||||
|
|
||||||
param_expr:
|
param_expr:
|
||||||
|
@ -795,7 +828,7 @@ table_ref_name_no_alias:
|
||||||
|
|
||||||
table_name:
|
table_name:
|
||||||
IDENTIFIER
|
IDENTIFIER
|
||||||
| IDENTIFIER '.' IDENTIFIER
|
| IDENTIFIER '.' IDENTIFIER { $$ = $3; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
@ -806,7 +839,7 @@ alias:
|
||||||
|
|
||||||
opt_alias:
|
opt_alias:
|
||||||
alias
|
alias
|
||||||
| /* empty */ { $$ = NULL; }
|
| /* empty */ { $$ = nullptr; }
|
||||||
|
|
||||||
|
|
||||||
/******************************
|
/******************************
|
||||||
|
|
|
@ -37,9 +37,9 @@ namespace hsql {
|
||||||
|
|
||||||
CreateType type;
|
CreateType type;
|
||||||
bool ifNotExists; // default: false
|
bool ifNotExists; // default: false
|
||||||
char* filePath; // default: NULL
|
char* filePath; // default: nullptr
|
||||||
char* tableName; // default: NULL
|
char* tableName; // default: nullptr
|
||||||
std::vector<ColumnDefinition*>* columns; // default: NULL
|
std::vector<ColumnDefinition*>* columns; // default: nullptr
|
||||||
std::vector<char*>* viewColumns;
|
std::vector<char*>* viewColumns;
|
||||||
SelectStatement* select;
|
SelectStatement* select;
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace hsql {
|
||||||
|
|
||||||
// Represents SQL Delete statements.
|
// Represents SQL Delete statements.
|
||||||
// Example: "DELETE FROM students WHERE grade > 3.0"
|
// Example: "DELETE FROM students WHERE grade > 3.0"
|
||||||
// Note: if (expr == NULL) => delete all rows (truncate)
|
// Note: if (expr == nullptr) => delete all rows (truncate)
|
||||||
struct DeleteStatement : SQLStatement {
|
struct DeleteStatement : SQLStatement {
|
||||||
DeleteStatement();
|
DeleteStatement();
|
||||||
virtual ~DeleteStatement();
|
virtual ~DeleteStatement();
|
||||||
|
|
|
@ -8,13 +8,13 @@ namespace hsql {
|
||||||
|
|
||||||
Expr::Expr(ExprType type) :
|
Expr::Expr(ExprType type) :
|
||||||
type(type),
|
type(type),
|
||||||
expr(NULL),
|
expr(nullptr),
|
||||||
expr2(NULL),
|
expr2(nullptr),
|
||||||
exprList(NULL),
|
exprList(nullptr),
|
||||||
select(NULL),
|
select(nullptr),
|
||||||
name(NULL),
|
name(nullptr),
|
||||||
table(NULL),
|
table(nullptr),
|
||||||
alias(NULL) {};
|
alias(nullptr) {};
|
||||||
|
|
||||||
Expr::~Expr() {
|
Expr::~Expr() {
|
||||||
delete expr;
|
delete expr;
|
||||||
|
@ -24,7 +24,7 @@ namespace hsql {
|
||||||
free(table);
|
free(table);
|
||||||
free(alias);
|
free(alias);
|
||||||
|
|
||||||
if (exprList != NULL) {
|
if (exprList != nullptr) {
|
||||||
for (Expr* e : *exprList) {
|
for (Expr* e : *exprList) {
|
||||||
delete e;
|
delete e;
|
||||||
}
|
}
|
||||||
|
@ -32,11 +32,16 @@ namespace hsql {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Expr* Expr::make(ExprType type) {
|
||||||
|
Expr* e = new Expr(type);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
Expr* Expr::makeOpUnary(OperatorType op, Expr* expr) {
|
Expr* Expr::makeOpUnary(OperatorType op, Expr* expr) {
|
||||||
Expr* e = new Expr(kExprOperator);
|
Expr* e = new Expr(kExprOperator);
|
||||||
e->opType = op;
|
e->opType = op;
|
||||||
e->expr = expr;
|
e->expr = expr;
|
||||||
e->expr2 = NULL;
|
e->expr2 = nullptr;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,15 +169,15 @@ namespace hsql {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Expr::hasAlias() const {
|
bool Expr::hasAlias() const {
|
||||||
return alias != NULL;
|
return alias != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Expr::hasTable() const {
|
bool Expr::hasTable() const {
|
||||||
return table != NULL;
|
return table != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Expr::getName() const {
|
const char* Expr::getName() const {
|
||||||
if (alias != NULL) return alias;
|
if (alias != nullptr) return alias;
|
||||||
else return name;
|
else return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,8 @@ namespace hsql {
|
||||||
kExprColumnRef,
|
kExprColumnRef,
|
||||||
kExprFunctionRef,
|
kExprFunctionRef,
|
||||||
kExprOperator,
|
kExprOperator,
|
||||||
kExprSelect
|
kExprSelect,
|
||||||
|
kExprHint
|
||||||
};
|
};
|
||||||
|
|
||||||
// Operator types. These are important for expressions of type kExprOperator.
|
// Operator types. These are important for expressions of type kExprOperator.
|
||||||
|
@ -102,6 +103,8 @@ namespace hsql {
|
||||||
|
|
||||||
// Static constructors.
|
// Static constructors.
|
||||||
|
|
||||||
|
static Expr* make(ExprType type);
|
||||||
|
|
||||||
static Expr* makeOpUnary(OperatorType op, Expr* expr);
|
static Expr* makeOpUnary(OperatorType op, Expr* expr);
|
||||||
|
|
||||||
static Expr* makeOpBinary(Expr* expr1, char op, Expr* expr2);
|
static Expr* makeOpBinary(Expr* expr1, char op, Expr* expr2);
|
||||||
|
|
|
@ -5,8 +5,8 @@ namespace hsql {
|
||||||
// PrepareStatement
|
// PrepareStatement
|
||||||
PrepareStatement::PrepareStatement() :
|
PrepareStatement::PrepareStatement() :
|
||||||
SQLStatement(kStmtPrepare),
|
SQLStatement(kStmtPrepare),
|
||||||
name(NULL),
|
name(nullptr),
|
||||||
query(NULL) {}
|
query(nullptr) {}
|
||||||
|
|
||||||
PrepareStatement::~PrepareStatement() {
|
PrepareStatement::~PrepareStatement() {
|
||||||
free(name);
|
free(name);
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
|
||||||
|
#include "SQLStatement.h"
|
||||||
|
|
||||||
|
namespace hsql {
|
||||||
|
|
||||||
|
// SQLStatement
|
||||||
|
SQLStatement::SQLStatement(StatementType type) :
|
||||||
|
hints(nullptr),
|
||||||
|
type_(type) {};
|
||||||
|
|
||||||
|
SQLStatement::~SQLStatement() {
|
||||||
|
if (hints != nullptr) {
|
||||||
|
for (Expr* hint : *hints) {
|
||||||
|
delete hint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
StatementType SQLStatement::type() const {
|
||||||
|
return type_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SQLStatement::isType(StatementType type) const {
|
||||||
|
return (type_ == type);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SQLStatement::is(StatementType type) const {
|
||||||
|
return isType(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -35,6 +35,8 @@ namespace hsql {
|
||||||
// Shorthand for isType(type).
|
// Shorthand for isType(type).
|
||||||
bool is(StatementType type) const;
|
bool is(StatementType type) const;
|
||||||
|
|
||||||
|
std::vector<Expr*>* hints;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StatementType type_;
|
StatementType type_;
|
||||||
|
|
||||||
|
|
|
@ -3,24 +3,6 @@
|
||||||
|
|
||||||
namespace hsql {
|
namespace hsql {
|
||||||
|
|
||||||
// SQLStatement
|
|
||||||
SQLStatement::SQLStatement(StatementType type) :
|
|
||||||
type_(type) {};
|
|
||||||
|
|
||||||
SQLStatement::~SQLStatement() {}
|
|
||||||
|
|
||||||
StatementType SQLStatement::type() const {
|
|
||||||
return type_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SQLStatement::isType(StatementType type) const {
|
|
||||||
return (type_ == type);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SQLStatement::is(StatementType type) const {
|
|
||||||
return isType(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ColumnDefinition
|
// ColumnDefinition
|
||||||
ColumnDefinition::ColumnDefinition(char* name, DataType type) :
|
ColumnDefinition::ColumnDefinition(char* name, DataType type) :
|
||||||
name(name),
|
name(name),
|
||||||
|
@ -35,25 +17,25 @@ namespace hsql {
|
||||||
SQLStatement(kStmtCreate),
|
SQLStatement(kStmtCreate),
|
||||||
type(type),
|
type(type),
|
||||||
ifNotExists(false),
|
ifNotExists(false),
|
||||||
filePath(NULL),
|
filePath(nullptr),
|
||||||
tableName(NULL),
|
tableName(nullptr),
|
||||||
columns(NULL),
|
columns(nullptr),
|
||||||
viewColumns(NULL),
|
viewColumns(nullptr),
|
||||||
select(NULL) {};
|
select(nullptr) {};
|
||||||
|
|
||||||
CreateStatement::~CreateStatement() {
|
CreateStatement::~CreateStatement() {
|
||||||
free(filePath);
|
free(filePath);
|
||||||
free(tableName);
|
free(tableName);
|
||||||
delete select;
|
delete select;
|
||||||
|
|
||||||
if (columns != NULL) {
|
if (columns != nullptr) {
|
||||||
for (ColumnDefinition* def : *columns) {
|
for (ColumnDefinition* def : *columns) {
|
||||||
delete def;
|
delete def;
|
||||||
}
|
}
|
||||||
delete columns;
|
delete columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (viewColumns != NULL) {
|
if (viewColumns != nullptr) {
|
||||||
for (char* column : *viewColumns) {
|
for (char* column : *viewColumns) {
|
||||||
free(column);
|
free(column);
|
||||||
}
|
}
|
||||||
|
@ -64,8 +46,8 @@ namespace hsql {
|
||||||
// DeleteStatement
|
// DeleteStatement
|
||||||
DeleteStatement::DeleteStatement() :
|
DeleteStatement::DeleteStatement() :
|
||||||
SQLStatement(kStmtDelete),
|
SQLStatement(kStmtDelete),
|
||||||
tableName(NULL),
|
tableName(nullptr),
|
||||||
expr(NULL) {};
|
expr(nullptr) {};
|
||||||
|
|
||||||
DeleteStatement::~DeleteStatement() {
|
DeleteStatement::~DeleteStatement() {
|
||||||
free(tableName);
|
free(tableName);
|
||||||
|
@ -76,7 +58,7 @@ namespace hsql {
|
||||||
DropStatement::DropStatement(DropType type) :
|
DropStatement::DropStatement(DropType type) :
|
||||||
SQLStatement(kStmtDrop),
|
SQLStatement(kStmtDrop),
|
||||||
type(type),
|
type(type),
|
||||||
name(NULL) {}
|
name(nullptr) {}
|
||||||
|
|
||||||
DropStatement::~DropStatement() {
|
DropStatement::~DropStatement() {
|
||||||
free(name);
|
free(name);
|
||||||
|
@ -85,13 +67,13 @@ namespace hsql {
|
||||||
// ExecuteStatement
|
// ExecuteStatement
|
||||||
ExecuteStatement::ExecuteStatement() :
|
ExecuteStatement::ExecuteStatement() :
|
||||||
SQLStatement(kStmtExecute),
|
SQLStatement(kStmtExecute),
|
||||||
name(NULL),
|
name(nullptr),
|
||||||
parameters(NULL) {}
|
parameters(nullptr) {}
|
||||||
|
|
||||||
ExecuteStatement::~ExecuteStatement() {
|
ExecuteStatement::~ExecuteStatement() {
|
||||||
free(name);
|
free(name);
|
||||||
|
|
||||||
if (parameters != NULL) {
|
if (parameters != nullptr) {
|
||||||
for (Expr* param : *parameters) {
|
for (Expr* param : *parameters) {
|
||||||
delete param;
|
delete param;
|
||||||
}
|
}
|
||||||
|
@ -103,8 +85,8 @@ namespace hsql {
|
||||||
ImportStatement::ImportStatement(ImportType type) :
|
ImportStatement::ImportStatement(ImportType type) :
|
||||||
SQLStatement(kStmtImport),
|
SQLStatement(kStmtImport),
|
||||||
type(type),
|
type(type),
|
||||||
filePath(NULL),
|
filePath(nullptr),
|
||||||
tableName(NULL) {};
|
tableName(nullptr) {};
|
||||||
|
|
||||||
ImportStatement::~ImportStatement() {
|
ImportStatement::~ImportStatement() {
|
||||||
delete filePath;
|
delete filePath;
|
||||||
|
@ -115,23 +97,23 @@ namespace hsql {
|
||||||
InsertStatement::InsertStatement(InsertType type) :
|
InsertStatement::InsertStatement(InsertType type) :
|
||||||
SQLStatement(kStmtInsert),
|
SQLStatement(kStmtInsert),
|
||||||
type(type),
|
type(type),
|
||||||
tableName(NULL),
|
tableName(nullptr),
|
||||||
columns(NULL),
|
columns(nullptr),
|
||||||
values(NULL),
|
values(nullptr),
|
||||||
select(NULL) {}
|
select(nullptr) {}
|
||||||
|
|
||||||
InsertStatement::~InsertStatement() {
|
InsertStatement::~InsertStatement() {
|
||||||
free(tableName);
|
free(tableName);
|
||||||
delete select;
|
delete select;
|
||||||
|
|
||||||
if (columns != NULL) {
|
if (columns != nullptr) {
|
||||||
for (char* column : *columns) {
|
for (char* column : *columns) {
|
||||||
free(column);
|
free(column);
|
||||||
}
|
}
|
||||||
delete columns;
|
delete columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (values != NULL) {
|
if (values != nullptr) {
|
||||||
for (Expr* expr : *values) {
|
for (Expr* expr : *values) {
|
||||||
delete expr;
|
delete expr;
|
||||||
}
|
}
|
||||||
|
@ -157,13 +139,13 @@ namespace hsql {
|
||||||
|
|
||||||
// GroypByDescription
|
// GroypByDescription
|
||||||
GroupByDescription::GroupByDescription() :
|
GroupByDescription::GroupByDescription() :
|
||||||
columns(NULL),
|
columns(nullptr),
|
||||||
having(NULL) {}
|
having(nullptr) {}
|
||||||
|
|
||||||
GroupByDescription::~GroupByDescription() {
|
GroupByDescription::~GroupByDescription() {
|
||||||
delete having;
|
delete having;
|
||||||
|
|
||||||
if (columns != NULL) {
|
if (columns != nullptr) {
|
||||||
for (Expr* expr : *columns) {
|
for (Expr* expr : *columns) {
|
||||||
delete expr;
|
delete expr;
|
||||||
}
|
}
|
||||||
|
@ -174,14 +156,14 @@ namespace hsql {
|
||||||
// SelectStatement
|
// SelectStatement
|
||||||
SelectStatement::SelectStatement() :
|
SelectStatement::SelectStatement() :
|
||||||
SQLStatement(kStmtSelect),
|
SQLStatement(kStmtSelect),
|
||||||
fromTable(NULL),
|
fromTable(nullptr),
|
||||||
selectDistinct(false),
|
selectDistinct(false),
|
||||||
selectList(NULL),
|
selectList(nullptr),
|
||||||
whereClause(NULL),
|
whereClause(nullptr),
|
||||||
groupBy(NULL),
|
groupBy(nullptr),
|
||||||
unionSelect(NULL),
|
unionSelect(nullptr),
|
||||||
order(NULL),
|
order(nullptr),
|
||||||
limit(NULL) {};
|
limit(nullptr) {};
|
||||||
|
|
||||||
SelectStatement::~SelectStatement() {
|
SelectStatement::~SelectStatement() {
|
||||||
delete fromTable;
|
delete fromTable;
|
||||||
|
@ -191,14 +173,14 @@ namespace hsql {
|
||||||
delete limit;
|
delete limit;
|
||||||
|
|
||||||
// Delete each element in the select list.
|
// Delete each element in the select list.
|
||||||
if (selectList != NULL) {
|
if (selectList != nullptr) {
|
||||||
for (Expr* expr : *selectList) {
|
for (Expr* expr : *selectList) {
|
||||||
delete expr;
|
delete expr;
|
||||||
}
|
}
|
||||||
delete selectList;
|
delete selectList;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (order != NULL) {
|
if (order != nullptr) {
|
||||||
for (OrderDescription* desc : *order) {
|
for (OrderDescription* desc : *order) {
|
||||||
delete desc;
|
delete desc;
|
||||||
}
|
}
|
||||||
|
@ -209,15 +191,15 @@ namespace hsql {
|
||||||
// UpdateStatement
|
// UpdateStatement
|
||||||
UpdateStatement::UpdateStatement() :
|
UpdateStatement::UpdateStatement() :
|
||||||
SQLStatement(kStmtUpdate),
|
SQLStatement(kStmtUpdate),
|
||||||
table(NULL),
|
table(nullptr),
|
||||||
updates(NULL),
|
updates(nullptr),
|
||||||
where(NULL) {}
|
where(nullptr) {}
|
||||||
|
|
||||||
UpdateStatement::~UpdateStatement() {
|
UpdateStatement::~UpdateStatement() {
|
||||||
delete table;
|
delete table;
|
||||||
delete where;
|
delete where;
|
||||||
|
|
||||||
if (updates != NULL) {
|
if (updates != nullptr) {
|
||||||
for (UpdateClause* update : *updates) {
|
for (UpdateClause* update : *updates) {
|
||||||
free(update->column);
|
free(update->column);
|
||||||
delete update->value;
|
delete update->value;
|
||||||
|
@ -230,12 +212,12 @@ namespace hsql {
|
||||||
// TableRef
|
// TableRef
|
||||||
TableRef::TableRef(TableRefType type) :
|
TableRef::TableRef(TableRefType type) :
|
||||||
type(type),
|
type(type),
|
||||||
schema(NULL),
|
schema(nullptr),
|
||||||
name(NULL),
|
name(nullptr),
|
||||||
alias(NULL),
|
alias(nullptr),
|
||||||
select(NULL),
|
select(nullptr),
|
||||||
list(NULL),
|
list(nullptr),
|
||||||
join(NULL) {}
|
join(nullptr) {}
|
||||||
|
|
||||||
TableRef::~TableRef() {
|
TableRef::~TableRef() {
|
||||||
free(schema);
|
free(schema);
|
||||||
|
@ -245,7 +227,7 @@ namespace hsql {
|
||||||
delete select;
|
delete select;
|
||||||
delete join;
|
delete join;
|
||||||
|
|
||||||
if (list != NULL) {
|
if (list != nullptr) {
|
||||||
for (TableRef* table : *list) {
|
for (TableRef* table : *list) {
|
||||||
delete table;
|
delete table;
|
||||||
}
|
}
|
||||||
|
@ -254,19 +236,19 @@ namespace hsql {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TableRef::hasSchema() const {
|
bool TableRef::hasSchema() const {
|
||||||
return schema != NULL;
|
return schema != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* TableRef::getName() const {
|
const char* TableRef::getName() const {
|
||||||
if (alias != NULL) return alias;
|
if (alias != nullptr) return alias;
|
||||||
else return name;
|
else return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// JoinDefinition
|
// JoinDefinition
|
||||||
JoinDefinition::JoinDefinition() :
|
JoinDefinition::JoinDefinition() :
|
||||||
left(NULL),
|
left(nullptr),
|
||||||
right(NULL),
|
right(nullptr),
|
||||||
condition(NULL),
|
condition(nullptr),
|
||||||
type(kJoinInner) {}
|
type(kJoinInner) {}
|
||||||
|
|
||||||
JoinDefinition::~JoinDefinition() {
|
JoinDefinition::~JoinDefinition() {
|
||||||
|
|
|
@ -50,14 +50,14 @@ namespace hsql {
|
||||||
for (TableRef* tbl : *table->list) printTableRefInfo(tbl, numIndent);
|
for (TableRef* tbl : *table->list) printTableRefInfo(tbl, numIndent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (table->alias != NULL) {
|
if (table->alias != nullptr) {
|
||||||
inprint("Alias", numIndent + 1);
|
inprint("Alias", numIndent + 1);
|
||||||
inprint(table->alias, numIndent + 2);
|
inprint(table->alias, numIndent + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void printOperatorExpression(Expr* expr, uintmax_t numIndent) {
|
void printOperatorExpression(Expr* expr, uintmax_t numIndent) {
|
||||||
if (expr == NULL) {
|
if (expr == nullptr) {
|
||||||
inprint("null", numIndent);
|
inprint("null", numIndent);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ namespace hsql {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printExpression(expr->expr, numIndent + 1);
|
printExpression(expr->expr, numIndent + 1);
|
||||||
if (expr->expr2 != NULL) printExpression(expr->expr2, numIndent + 1);
|
if (expr->expr2 != nullptr) printExpression(expr->expr2, numIndent + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void printExpression(Expr* expr, uintmax_t numIndent) {
|
void printExpression(Expr* expr, uintmax_t numIndent) {
|
||||||
|
@ -112,7 +112,7 @@ namespace hsql {
|
||||||
fprintf(stderr, "Unrecognized expression type %d\n", expr->type);
|
fprintf(stderr, "Unrecognized expression type %d\n", expr->type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (expr->alias != NULL) {
|
if (expr->alias != nullptr) {
|
||||||
inprint("Alias", numIndent + 1);
|
inprint("Alias", numIndent + 1);
|
||||||
inprint(expr->alias, numIndent + 2);
|
inprint(expr->alias, numIndent + 2);
|
||||||
}
|
}
|
||||||
|
@ -126,25 +126,25 @@ namespace hsql {
|
||||||
inprint("Sources:", numIndent + 1);
|
inprint("Sources:", numIndent + 1);
|
||||||
printTableRefInfo(stmt->fromTable, numIndent + 2);
|
printTableRefInfo(stmt->fromTable, numIndent + 2);
|
||||||
|
|
||||||
if (stmt->whereClause != NULL) {
|
if (stmt->whereClause != nullptr) {
|
||||||
inprint("Search Conditions:", numIndent + 1);
|
inprint("Search Conditions:", numIndent + 1);
|
||||||
printExpression(stmt->whereClause, numIndent + 2);
|
printExpression(stmt->whereClause, numIndent + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (stmt->unionSelect != NULL) {
|
if (stmt->unionSelect != nullptr) {
|
||||||
inprint("Union:", numIndent + 1);
|
inprint("Union:", numIndent + 1);
|
||||||
printSelectStatementInfo(stmt->unionSelect, numIndent + 2);
|
printSelectStatementInfo(stmt->unionSelect, numIndent + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stmt->order != NULL) {
|
if (stmt->order != nullptr) {
|
||||||
inprint("OrderBy:", numIndent + 1);
|
inprint("OrderBy:", numIndent + 1);
|
||||||
printExpression(stmt->order->at(0)->expr, numIndent + 2);
|
printExpression(stmt->order->at(0)->expr, numIndent + 2);
|
||||||
if (stmt->order->at(0)->type == kOrderAsc) inprint("ascending", numIndent + 2);
|
if (stmt->order->at(0)->type == kOrderAsc) inprint("ascending", numIndent + 2);
|
||||||
else inprint("descending", numIndent + 2);
|
else inprint("descending", numIndent + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stmt->limit != NULL) {
|
if (stmt->limit != nullptr) {
|
||||||
inprint("Limit:", numIndent + 1);
|
inprint("Limit:", numIndent + 1);
|
||||||
inprint(stmt->limit->limit, numIndent + 2);
|
inprint(stmt->limit->limit, numIndent + 2);
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ namespace hsql {
|
||||||
void printInsertStatementInfo(const InsertStatement* stmt, uintmax_t numIndent) {
|
void printInsertStatementInfo(const InsertStatement* stmt, uintmax_t numIndent) {
|
||||||
inprint("InsertStatment", numIndent);
|
inprint("InsertStatment", numIndent);
|
||||||
inprint(stmt->tableName, numIndent + 1);
|
inprint(stmt->tableName, numIndent + 1);
|
||||||
if (stmt->columns != NULL) {
|
if (stmt->columns != nullptr) {
|
||||||
inprint("Columns", numIndent + 1);
|
inprint("Columns", numIndent + 1);
|
||||||
for (char* col_name : *stmt->columns) {
|
for (char* col_name : *stmt->columns) {
|
||||||
inprint(col_name, numIndent + 2);
|
inprint(col_name, numIndent + 2);
|
||||||
|
|
|
@ -156,4 +156,21 @@ TEST(MoveSQLResultTest) {
|
||||||
ASSERT_EQ(1, new_res.size());
|
ASSERT_EQ(1, new_res.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(HintTest) {
|
||||||
|
TEST_PARSE_SINGLE_SQL(
|
||||||
|
"SELECT * FROM students WITH HINT(NO_CACHE, SAMPLE_RATE(10));",
|
||||||
|
kStmtSelect,
|
||||||
|
SelectStatement,
|
||||||
|
result,
|
||||||
|
stmt);
|
||||||
|
|
||||||
|
|
||||||
|
ASSERT_NOTNULL(stmt->hints);
|
||||||
|
ASSERT_EQ(2, stmt->hints->size());
|
||||||
|
ASSERT_STREQ("NO_CACHE", stmt->hints->at(0)->name);
|
||||||
|
ASSERT_STREQ("SAMPLE_RATE", stmt->hints->at(1)->name);
|
||||||
|
ASSERT_EQ(1, stmt->hints->at(1)->exprList->size());
|
||||||
|
ASSERT_EQ(10, stmt->hints->at(1)->exprList->at(0)->ival);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_MAIN();
|
TEST_MAIN();
|
||||||
|
|
|
@ -36,6 +36,7 @@ MEM_LEAK_RET=$?
|
||||||
|
|
||||||
if [ $MEM_LEAK_RET -ne 200 ]; then
|
if [ $MEM_LEAK_RET -ne 200 ]; then
|
||||||
printf "${GREEN}Memory leak check succeeded!${NC}\n"
|
printf "${GREEN}Memory leak check succeeded!${NC}\n"
|
||||||
|
MEM_LEAK_RET=0
|
||||||
else
|
else
|
||||||
MEM_LEAK_RET=1
|
MEM_LEAK_RET=1
|
||||||
RET=1
|
RET=1
|
||||||
|
|
|
@ -43,6 +43,10 @@ PREPARE prep2 FROM 'INSERT INTO test VALUES (?, 0, 0); INSERT INTO test VALUES (
|
||||||
EXECUTE prep_inst(1, 2, 3);
|
EXECUTE prep_inst(1, 2, 3);
|
||||||
EXECUTE prep;
|
EXECUTE prep;
|
||||||
DEALLOCATE PREPARE prep;
|
DEALLOCATE PREPARE prep;
|
||||||
|
# HINTS
|
||||||
|
SELECT * FROM test WITH HINT(NO_CACHE);
|
||||||
|
SELECT * FROM test WITH HINT(NO_CACHE, NO_SAMPLING);
|
||||||
|
SELECT * FROM test WITH HINT(NO_CACHE, SAMPLE_RATE(0.1), OMW(1.0, 'test'));
|
||||||
# Error expeced
|
# Error expeced
|
||||||
!
|
!
|
||||||
!1
|
!1
|
||||||
|
|
Loading…
Reference in New Issue