dix and adapt casecasewhen

This commit is contained in:
Moritz Eyssen 2018-01-17 13:11:39 +01:00
parent daf8fe7a45
commit 074bce4d90
4 changed files with 714 additions and 699 deletions

File diff suppressed because it is too large Load Diff

View File

@ -784,15 +784,15 @@ in_expr:
// CASE grammar based on: flex & bison by John Levine // CASE grammar based on: flex & bison by John Levine
// https://www.safaribooksonline.com/library/view/flex-bison/9780596805418/ch04.html#id352665 // https://www.safaribooksonline.com/library/view/flex-bison/9780596805418/ch04.html#id352665
case_expr: case_expr:
CASE expr case_list END { $$ = Expr::makeCaseExpr($2, $3); } CASE expr case_list END { $$ = Expr::makeCase($2, $3, nullptr); }
| CASE expr case_list ELSE expr END { $$ = Expr::makeCaseExpr($2, $3, $5); } | CASE expr case_list ELSE expr END { $$ = Expr::makeCase($2, $3, $5); }
| CASE case_list END { $$ = Expr::makeCase($2); } | CASE case_list END { $$ = Expr::makeCase(nullptr, $2, nullptr); }
| CASE case_list ELSE expr END { $$ = Expr::makeCase($2, $4); } | CASE case_list ELSE expr END { $$ = Expr::makeCase(nullptr, $2, $4); }
; ;
case_list: case_list:
WHEN expr THEN expr { $$ = Expr::makeCaseCondition($2, $4); } WHEN expr THEN expr { $$ = Expr::makeCaseList(Expr::makeCaseListElement($2, $4)); }
| case_list WHEN expr THEN expr { $$ = Expr::joinCaseCondition($1, Expr::makeCaseCondition($3, $5)); } | case_list WHEN expr THEN expr { $$ = Expr::caseListAppend($1, Expr::makeCaseListElement($3, $5)); }
; ;
exists_expr: exists_expr:

View File

@ -68,53 +68,35 @@ namespace hsql {
return e; return e;
} }
Expr* Expr::makeCaseCondition(Expr* expr, Expr* then) { Expr* Expr::makeCaseList(Expr* caseListElement) {
Expr* e = new Expr(kExprWhenCondition); Expr* e = new Expr(kExprOperator);
e->expr = expr; e->opType = kOpCaseList;
e->exprList = new std::vector<Expr*>();
e->exprList->push_back(caseListElement);
return e;
}
Expr* Expr::makeCaseListElement(Expr* when, Expr* then) {
Expr* e = new Expr(kExprOperator);
e->opType = kOpCaseListElement;
e->expr = when;
e->expr2 = then; e->expr2 = then;
return e; return e;
} }
Expr* Expr::joinCaseCondition(Expr* expr1, Expr* expr2) { Expr* Expr::caseListAppend(Expr* caseList, Expr* caseListElement) {
Expr* e = new Expr(kExprOperator); caseList->exprList->push_back(caseListElement);
e->opType = kOpPlus; return caseList;
if (expr1->exprList != nullptr) {
e->exprList = expr1->exprList;
} else {
e->exprList = new std::vector<Expr*>();
e->exprList->push_back(expr1);
}
e->exprList->push_back(expr2);
return e;
} }
Expr* Expr::makeCase(Expr* when) { Expr* Expr::makeCase(Expr* expr, Expr* caseList, Expr* elseExpr) {
Expr* e = new Expr(kExprOperator); Expr* e = new Expr(kExprOperator);
e->opType = kOpCase; e->opType = kOpCase;
if (when->exprList != nullptr) {
e->exprList = when->exprList;
} else {
e->exprList = new std::vector<Expr*>();
e->exprList->push_back(when);
}
return e;
}
Expr* Expr::makeCase(Expr* when, Expr* other) {
Expr* e = Expr::makeCase(when);
e->expr2 = other;
return e;
}
Expr* Expr::makeCaseExpr(Expr* expr, Expr* when) {
Expr* e = Expr::makeCase(when);
e->expr = expr;
return e;
}
Expr* Expr::makeCaseExpr(Expr* expr, Expr* when, Expr* other) {
Expr* e = Expr::makeCase(when, other);
e->expr = expr; e->expr = expr;
e->expr2 = elseExpr;
e->exprList = caseList->exprList;
caseList->exprList = nullptr;
delete caseList;
return e; return e;
} }

View File

@ -26,16 +26,21 @@ namespace hsql {
kExprHint, kExprHint,
kExprArray, kExprArray,
kExprArrayIndex, kExprArrayIndex,
kExprWhenCondition kExprCaseList,
kExprCaseListElement
}; };
// Operator types. These are important for expressions of type kExprOperator. // Operator types. These are important for expressions of type kExprOperator.
enum OperatorType { enum OperatorType {
kOpNone, kOpNone,
// Ternary operators // Ternary operator
kOpBetween, kOpBetween,
// n-nary special case
kOpCase, kOpCase,
kOpCaseList, // Contains n >= 1 kExprCaseListElement in its exprList
kOpCaseListElement, // `WHEN expr THEN expr`
// Binary operators. // Binary operators.
kOpPlus, kOpPlus,
@ -114,17 +119,13 @@ namespace hsql {
static Expr* makeBetween(Expr* expr, Expr* left, Expr* right); static Expr* makeBetween(Expr* expr, Expr* left, Expr* right);
static Expr* makeCaseCondition(Expr* expr, Expr* then); static Expr* makeCaseList(Expr* caseListElement);
static Expr* joinCaseCondition(Expr* expr, Expr* then); static Expr* makeCaseListElement(Expr* when, Expr* then);
static Expr* makeCase(Expr* when); static Expr* caseListAppend(Expr* caseList, Expr* caseListElement);
static Expr* makeCase(Expr* when, Expr* other); static Expr* makeCase(Expr* expr, Expr* when, Expr* elseExpr);
static Expr* makeCaseExpr(Expr* expr, Expr* when);
static Expr* makeCaseExpr(Expr* expr, Expr* when, Expr* other);
static Expr* makeLiteral(int64_t val); static Expr* makeLiteral(int64_t val);