1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-01 06:27:03 +03:00

Added support for CASE expressions - patches from Dan Kennedy. (CVS 437)

FossilOrigin-Name: 836b59d057c3fb4087b138c9bfbc03392ddfb89d
This commit is contained in:
drh
2002-03-24 13:13:27 +00:00
parent 6b54e74cf4
commit 17a7f8ddab
7 changed files with 100 additions and 18 deletions

View File

@ -12,7 +12,7 @@
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.56 2002/03/13 18:54:07 drh Exp $
** $Id: expr.c,v 1.57 2002/03/24 13:13:29 drh Exp $
*/
#include "sqliteInt.h"
@ -877,8 +877,49 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
sqliteExprCode(pParse, pExpr->pLeft);
break;
}
case TK_CASE: {
int expr_end_label;
int next_when_label;
int i;
assert(pExpr->pList);
assert((pExpr->pList->nExpr % 2) == 0);
assert(pExpr->pList->nExpr > 0);
expr_end_label = sqliteVdbeMakeLabel(pParse->pVdbe);
if( pExpr->pLeft ){
sqliteExprCode(pParse, pExpr->pLeft);
}
for(i=0; i<pExpr->pList->nExpr; i=i+2){
if( i!=0 ){
sqliteVdbeResolveLabel(pParse->pVdbe, next_when_label);
}
next_when_label = sqliteVdbeMakeLabel(pParse->pVdbe);
if( pExpr->pLeft ){
sqliteVdbeAddOp(pParse->pVdbe, OP_Dup, 0, 1);
sqliteExprCode(pParse, pExpr->pList->a[i].pExpr);
sqliteVdbeAddOp(pParse->pVdbe, OP_Ne, 0, next_when_label);
}else{
sqliteExprIfFalse(pParse, pExpr->pList->a[i].pExpr, next_when_label);
}
if( pExpr->pLeft ){
sqliteVdbeAddOp(pParse->pVdbe, OP_Pop, 1, 0);
}
sqliteExprCode(pParse, pExpr->pList->a[i+1].pExpr);
sqliteVdbeAddOp(pParse->pVdbe, OP_Goto, 0, expr_end_label);
}
sqliteVdbeResolveLabel(pParse->pVdbe, next_when_label);
if( pExpr->pLeft ){
sqliteVdbeAddOp(pParse->pVdbe, OP_Pop, 1, 0);
}
if( pExpr->pRight ){
sqliteExprCode(pParse, pExpr->pRight);
}else{
sqliteVdbeAddOp(pParse->pVdbe, OP_String, 0, 0);
}
sqliteVdbeResolveLabel(pParse->pVdbe, expr_end_label);
}
break;
}
return;
}
/*

View File

@ -14,7 +14,7 @@
** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.57 2002/03/13 18:54:08 drh Exp $
** @(#) $Id: parse.y,v 1.58 2002/03/24 13:13:29 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
@ -520,7 +520,28 @@ expr(A) ::= expr(X) NOT IN LP select(Y) RP(E). {
sqliteExprSpan(A,&X->span,&E);
}
/* CASE expressions */
expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
A = sqliteExpr(TK_CASE, X, Z, 0);
if( A ) A->pList = Y;
sqliteExprSpan(A, &C, &E);
}
%type case_exprlist {ExprList*}
%destructor case_exprlist {sqliteExprListDelete($$);}
case_exprlist(A) ::= case_exprlist(X) WHEN expr(Y) THEN expr(Z). {
A = sqliteExprListAppend(X, Y, 0);
A = sqliteExprListAppend(A, Z, 0);
}
case_exprlist(A) ::= WHEN expr(Y) THEN expr(Z). {
A = sqliteExprListAppend(0, Y, 0);
A = sqliteExprListAppend(A, Z, 0);
}
%type case_else {Expr*}
case_else(A) ::= ELSE expr(X). {A = X;}
case_else(A) ::= . {A = 0;}
%type case_operand {Expr*}
case_operand(A) ::= expr(X). {A = X;}
case_operand(A) ::= . {A = 0;}
%type exprlist {ExprList*}
%destructor exprlist {sqliteExprListDelete($$);}

View File

@ -15,7 +15,7 @@
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.39 2002/03/13 18:54:08 drh Exp $
** $Id: tokenize.c,v 1.40 2002/03/24 13:13:29 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@ -46,6 +46,7 @@ static Keyword aKeywordTable[] = {
{ "BEGIN", 0, TK_BEGIN, 0 },
{ "BETWEEN", 0, TK_BETWEEN, 0 },
{ "BY", 0, TK_BY, 0 },
{ "CASE", 0, TK_CASE, 0 },
{ "CHECK", 0, TK_CHECK, 0 },
{ "CLUSTER", 0, TK_CLUSTER, 0 },
{ "COMMIT", 0, TK_COMMIT, 0 },
@ -60,6 +61,7 @@ static Keyword aKeywordTable[] = {
{ "DISTINCT", 0, TK_DISTINCT, 0 },
{ "DROP", 0, TK_DROP, 0 },
{ "END", 0, TK_END, 0 },
{ "ELSE", 0, TK_ELSE, 0 },
{ "EXCEPT", 0, TK_EXCEPT, 0 },
{ "EXPLAIN", 0, TK_EXPLAIN, 0 },
{ "FAIL", 0, TK_FAIL, 0 },
@ -94,6 +96,7 @@ static Keyword aKeywordTable[] = {
{ "TABLE", 0, TK_TABLE, 0 },
{ "TEMP", 0, TK_TEMP, 0 },
{ "TEMPORARY", 0, TK_TEMP, 0 },
{ "THEN", 0, TK_THEN, 0 },
{ "TRANSACTION", 0, TK_TRANSACTION, 0 },
{ "UNION", 0, TK_UNION, 0 },
{ "UNIQUE", 0, TK_UNIQUE, 0 },
@ -102,6 +105,7 @@ static Keyword aKeywordTable[] = {
{ "VACUUM", 0, TK_VACUUM, 0 },
{ "VALUES", 0, TK_VALUES, 0 },
{ "VIEW", 0, TK_VIEW, 0 },
{ "WHEN", 0, TK_WHEN, 0 },
{ "WHERE", 0, TK_WHERE, 0 },
};