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
// https://www.safaribooksonline.com/library/view/flex-bison/9780596805418/ch04.html#id352665
case_expr:
CASE expr case_list END { $$ = Expr::makeCaseExpr($2, $3); }
| CASE expr case_list ELSE expr END { $$ = Expr::makeCaseExpr($2, $3, $5); }
| CASE case_list END { $$ = Expr::makeCase($2); }
| CASE case_list ELSE expr END { $$ = Expr::makeCase($2, $4); }
CASE expr case_list END { $$ = Expr::makeCase($2, $3, nullptr); }
| CASE expr case_list ELSE expr END { $$ = Expr::makeCase($2, $3, $5); }
| CASE case_list END { $$ = Expr::makeCase(nullptr, $2, nullptr); }
| CASE case_list ELSE expr END { $$ = Expr::makeCase(nullptr, $2, $4); }
;
case_list:
WHEN expr THEN expr { $$ = Expr::makeCaseCondition($2, $4); }
| case_list WHEN expr THEN expr { $$ = Expr::joinCaseCondition($1, Expr::makeCaseCondition($3, $5)); }
WHEN expr THEN expr { $$ = Expr::makeCaseList(Expr::makeCaseListElement($2, $4)); }
| case_list WHEN expr THEN expr { $$ = Expr::caseListAppend($1, Expr::makeCaseListElement($3, $5)); }
;
exists_expr:

View File

@ -68,53 +68,35 @@ namespace hsql {
return e;
}
Expr* Expr::makeCaseCondition(Expr* expr, Expr* then) {
Expr* e = new Expr(kExprWhenCondition);
e->expr = expr;
Expr* Expr::makeCaseList(Expr* caseListElement) {
Expr* e = new Expr(kExprOperator);
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;
return e;
}
Expr* Expr::joinCaseCondition(Expr* expr1, Expr* expr2) {
Expr* e = new Expr(kExprOperator);
e->opType = kOpPlus;
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::caseListAppend(Expr* caseList, Expr* caseListElement) {
caseList->exprList->push_back(caseListElement);
return caseList;
}
Expr* Expr::makeCase(Expr* when) {
Expr* Expr::makeCase(Expr* expr, Expr* caseList, Expr* elseExpr) {
Expr* e = new Expr(kExprOperator);
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->expr2 = elseExpr;
e->exprList = caseList->exprList;
caseList->exprList = nullptr;
delete caseList;
return e;
}

View File

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