Add Hints per statement to SQL syntax.

This commit is contained in:
Pedro Flemming 2017-06-06 03:49:41 +02:00 committed by Pedro Flemming
parent f85a5e7b52
commit 1483a4a95a
15 changed files with 198 additions and 119 deletions

View File

@ -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;

View File

@ -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;
} }

View File

@ -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; }
/****************************** /******************************

View File

@ -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;
}; };

View File

@ -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();

View File

@ -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;
} }

View File

@ -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);

View File

@ -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);

32
src/sql/SQLStatement.cpp Normal file
View File

@ -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);
}
}

View File

@ -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_;

View File

@ -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() {

View File

@ -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);

View File

@ -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();

View File

@ -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

View File

@ -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