Add select statement as possible operand in expressions
This commit is contained in:
parent
35b8b569eb
commit
cf1c84d46d
|
@ -612,6 +612,7 @@ operand:
|
||||||
| unary_expr
|
| unary_expr
|
||||||
| binary_expr
|
| binary_expr
|
||||||
| function_expr
|
| function_expr
|
||||||
|
| '(' select_no_paren ')' { $$ = Expr::makeSelect($2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
scalar_expr:
|
scalar_expr:
|
||||||
|
@ -633,7 +634,7 @@ binary_expr:
|
||||||
| operand '*' operand { $$ = Expr::makeOpBinary($1, '*', $3); }
|
| operand '*' operand { $$ = Expr::makeOpBinary($1, '*', $3); }
|
||||||
| operand '%' operand { $$ = Expr::makeOpBinary($1, '%', $3); }
|
| operand '%' operand { $$ = Expr::makeOpBinary($1, '%', $3); }
|
||||||
| operand '^' operand { $$ = Expr::makeOpBinary($1, '^', $3); }
|
| operand '^' operand { $$ = Expr::makeOpBinary($1, '^', $3); }
|
||||||
| operand LIKE operand { $$ = Expr::makeOpBinary($1, Expr::LIKE, $3); }
|
| operand LIKE operand { $$ = Expr::makeOpBinary($1, Expr::LIKE, $3); }
|
||||||
| operand NOT LIKE operand { $$ = Expr::makeOpBinary($1, Expr::NOT_LIKE, $4); }
|
| operand NOT LIKE operand { $$ = Expr::makeOpBinary($1, Expr::NOT_LIKE, $4); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -643,11 +644,11 @@ logic_expr:
|
||||||
;
|
;
|
||||||
|
|
||||||
comp_expr:
|
comp_expr:
|
||||||
operand '=' operand { $$ = Expr::makeOpBinary($1, '=', $3); }
|
operand '=' operand { $$ = Expr::makeOpBinary($1, '=', $3); }
|
||||||
| operand NOTEQUALS operand { $$ = Expr::makeOpBinary($1, Expr::NOT_EQUALS, $3); }
|
| operand NOTEQUALS operand { $$ = Expr::makeOpBinary($1, Expr::NOT_EQUALS, $3); }
|
||||||
| operand '<' operand { $$ = Expr::makeOpBinary($1, '<', $3); }
|
| operand '<' operand { $$ = Expr::makeOpBinary($1, '<', $3); }
|
||||||
| operand '>' operand { $$ = Expr::makeOpBinary($1, '>', $3); }
|
| operand '>' operand { $$ = Expr::makeOpBinary($1, '>', $3); }
|
||||||
| operand LESSEQ operand { $$ = Expr::makeOpBinary($1, Expr::LESS_EQ, $3); }
|
| operand LESSEQ operand { $$ = Expr::makeOpBinary($1, Expr::LESS_EQ, $3); }
|
||||||
| operand GREATEREQ operand { $$ = Expr::makeOpBinary($1, Expr::GREATER_EQ, $3); }
|
| operand GREATEREQ operand { $$ = Expr::makeOpBinary($1, Expr::GREATER_EQ, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -102,6 +102,12 @@ namespace hsql {
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Expr* Expr::makeSelect(SelectStatement* select) {
|
||||||
|
Expr* e = new Expr(kExprSelect);
|
||||||
|
e->select = select;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
bool Expr::isType(ExprType e_type) {
|
bool Expr::isType(ExprType e_type) {
|
||||||
return e_type == type;
|
return e_type == type;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace hsql {
|
namespace hsql {
|
||||||
|
class SelectStatement;
|
||||||
|
|
||||||
// Helper function used by the lexer.
|
// Helper function used by the lexer.
|
||||||
// TODO: move to more appropriate place.
|
// TODO: move to more appropriate place.
|
||||||
|
@ -19,7 +20,8 @@ namespace hsql {
|
||||||
kExprPlaceholder,
|
kExprPlaceholder,
|
||||||
kExprColumnRef,
|
kExprColumnRef,
|
||||||
kExprFunctionRef,
|
kExprFunctionRef,
|
||||||
kExprOperator
|
kExprOperator,
|
||||||
|
kExprSelect
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Expr Expr;
|
typedef struct Expr Expr;
|
||||||
|
@ -66,6 +68,7 @@ namespace hsql {
|
||||||
Expr* expr;
|
Expr* expr;
|
||||||
Expr* expr2;
|
Expr* expr2;
|
||||||
std::vector<Expr*>* exprList;
|
std::vector<Expr*>* exprList;
|
||||||
|
SelectStatement* select;
|
||||||
char* name;
|
char* name;
|
||||||
char* table;
|
char* table;
|
||||||
char* alias;
|
char* alias;
|
||||||
|
@ -77,6 +80,7 @@ namespace hsql {
|
||||||
char opChar;
|
char opChar;
|
||||||
bool distinct;
|
bool distinct;
|
||||||
|
|
||||||
|
|
||||||
// Convenience accessor methods.
|
// Convenience accessor methods.
|
||||||
|
|
||||||
bool isType(ExprType e_type);
|
bool isType(ExprType e_type);
|
||||||
|
@ -117,6 +121,8 @@ namespace hsql {
|
||||||
static Expr* makeFunctionRef(char* func_name, std::vector<Expr*>* exprList, bool distinct);
|
static Expr* makeFunctionRef(char* func_name, std::vector<Expr*>* exprList, bool distinct);
|
||||||
|
|
||||||
static Expr* makePlaceholder(int id);
|
static Expr* makePlaceholder(int id);
|
||||||
|
|
||||||
|
static Expr* makeSelect(SelectStatement* select);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Zero initializes an Expr object and assigns it to a space in the heap
|
// Zero initializes an Expr object and assigns it to a space in the heap
|
||||||
|
|
|
@ -157,3 +157,30 @@ TEST(SelectBetweenTest) {
|
||||||
|
|
||||||
delete result;
|
delete result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(SelectConditionalSelectTest) {
|
||||||
|
TEST_PARSE_SINGLE_SQL(
|
||||||
|
"SELECT * FROM t WHERE a = (SELECT MIN(v) FROM tt);",
|
||||||
|
kStmtSelect,
|
||||||
|
SelectStatement,
|
||||||
|
result,
|
||||||
|
stmt);
|
||||||
|
|
||||||
|
Expr* where = stmt->whereClause;
|
||||||
|
ASSERT_NOTNULL(where);
|
||||||
|
ASSERT(where->isType(kExprOperator));
|
||||||
|
ASSERT(where->isSimpleOp('='));
|
||||||
|
|
||||||
|
ASSERT_NOTNULL(where->expr);
|
||||||
|
ASSERT_STREQ(where->expr->getName(), "a");
|
||||||
|
ASSERT(where->expr->isType(kExprColumnRef));
|
||||||
|
|
||||||
|
ASSERT_NOTNULL(where->expr2);
|
||||||
|
ASSERT(where->expr2->isType(kExprSelect));
|
||||||
|
|
||||||
|
SelectStatement* select2 = where->expr2->select;
|
||||||
|
ASSERT_NOTNULL(select2);
|
||||||
|
ASSERT_STREQ(select2->fromTable->getName(), "tt")
|
||||||
|
|
||||||
|
delete result;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue