Added support for CASE expressions - patches from Dan Kennedy. (CVS 437)
FossilOrigin-Name: 836b59d057c3fb4087b138c9bfbc03392ddfb89d
This commit is contained in:
parent
6b54e74cf4
commit
17a7f8ddab
20
manifest
20
manifest
@ -1,9 +1,9 @@
|
||||
C Version\s2.4.3\s(CVS\s440)
|
||||
D 2002-03-23T01:00:00
|
||||
C Added\ssupport\sfor\sCASE\sexpressions\s-\spatches\sfrom\sDan\sKennedy.\s(CVS\s437)
|
||||
D 2002-03-24T13:13:28
|
||||
F Makefile.in 50f1b3351df109b5774771350d8c1b8d3640130d
|
||||
F Makefile.template 89e373b2dad0321df00400fa968dc14b61a03296
|
||||
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
|
||||
F VERSION 50919ab26b7c119efb3f2fa5000696e75a9fb378
|
||||
F VERSION 709d6814e7f7be60eddfd0c173f583061695e9b6
|
||||
F aclocal.m4 11faa843caa38fd451bc6aeb43e248d1723a269d
|
||||
F config.guess f38b1e93d1e0fa6f5a6913e9e7b12774b9232588
|
||||
F config.log 6a73d03433669b10a3f0c221198c3f26b9413914
|
||||
@ -23,7 +23,7 @@ F src/btree.c 7dd7ddc66459982dd0cb9800958c1f8d65a32d9f
|
||||
F src/btree.h 8abeabfe6e0b1a990b64fa457592a6482f6674f3
|
||||
F src/build.c d01b81f41481e733e27ab2fa8e1bfcc64f24257d
|
||||
F src/delete.c 577da499162291c1855f0b304b211bffcf9da945
|
||||
F src/expr.c 0752b45ac5913575c9dfb47ef2d5ac4705df7f3b
|
||||
F src/expr.c e7a1e22bc2ebcd789f0f8c0db544cf16ad664054
|
||||
F src/func.c 87516e7dc37190c24af77593931a5d09d797520a
|
||||
F src/hash.c cc259475e358baaf299b00a2c7370f2b03dda892
|
||||
F src/hash.h dca065dda89d4575f3176e75e9a3dc0f4b4fb8b9
|
||||
@ -34,7 +34,7 @@ F src/os.c 5ab8b6b4590d0c1ab8e96c67996c170e4462e0fc
|
||||
F src/os.h 4a361fccfbc4e7609b3e1557f604f94c1e96ad10
|
||||
F src/pager.c f136f5ba82c896d500a10b6a2e5caea62abf716b
|
||||
F src/pager.h 6fddfddd3b73aa8abc081b973886320e3c614f0e
|
||||
F src/parse.y 9a8be2eebad16f636292967d328882c2d07e30a9
|
||||
F src/parse.y e6f300a355459fb29a71c30246be4cdb6ed5b6a7
|
||||
F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d
|
||||
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
|
||||
F src/select.c 9323800e2937e84b52c198fffc51995d822b1779
|
||||
@ -48,7 +48,7 @@ F src/test1.c d46ab7a82a9c16a3b1ee363cb4c0f98c5ff65743
|
||||
F src/test2.c d410dbd8a90faa466c3ab694fa0aa57f5a773aa6
|
||||
F src/test3.c 4e52fff8b01f08bd202f7633feda5639b7ba2b5e
|
||||
F src/threadtest.c 81f0598e0f031c1bd506af337fdc1b7e8dff263f
|
||||
F src/tokenize.c 5015a5d4e65afb8cc6d18083d5f19a008e3842ce
|
||||
F src/tokenize.c 5624d342601f616157ba266abccc1368a5afee70
|
||||
F src/update.c 7dd714a6a7fa47f849ebb36b6d915974d6c6accb
|
||||
F src/util.c b34cd91387bbfdc79319ea451a7d120cef478120
|
||||
F src/vdbe.c 9fbe84ea33dddb08d95f3288d995376d32863fa4
|
||||
@ -62,7 +62,7 @@ F test/btree3.test 9caa9e22491dd8cd8aa36d7ac3b48b089817c895
|
||||
F test/conflict.test c794c6c8f6e59918107dbab2d201ae454bb47db8
|
||||
F test/copy.test b3cefcb520c64d7e7dfedbab06b4d4c31fa5b99a
|
||||
F test/delete.test c904a62129fe102b314a96111a8417f10249e4d8
|
||||
F test/expr.test c8a495050dcec3f9e68538c3ef466726933302c1
|
||||
F test/expr.test 846795016b5993a7411f772eebe82ab67bd7230a
|
||||
F test/func.test 4359344586067e79abf4c710c4737d67ed3cf963
|
||||
F test/in.test c09312672e3f0709fa02c8e2e9cd8fb4bd6269aa
|
||||
F test/index.test c8a471243bbf878974b99baf5badd59407237cf3
|
||||
@ -130,7 +130,7 @@ F www/speed.tcl da8afcc1d3ccc5696cfb388a68982bc3d9f7f00f
|
||||
F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
|
||||
F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49
|
||||
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
||||
P e2558c34034cf49524084ec819df58934a8af983
|
||||
R b3affb1ebed689441f43f9512795f044
|
||||
P 99d6764e57ddc7f0a321229cc1b7aa9a76f1aae5
|
||||
R 2c07c24bb32189e5643cb9ff23369e12
|
||||
U drh
|
||||
Z d8af9dfdacb01b6b9297504ec54586e1
|
||||
Z efaaf0dd01ae4aa4e97af0ad8b65ddc7
|
||||
|
@ -1 +1 @@
|
||||
99d6764e57ddc7f0a321229cc1b7aa9a76f1aae5
|
||||
836b59d057c3fb4087b138c9bfbc03392ddfb89d
|
45
src/expr.c
45
src/expr.c
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
25
src/parse.y
25
src/parse.y
@ -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($$);}
|
||||
|
@ -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 },
|
||||
};
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing expressions.
|
||||
#
|
||||
# $Id: expr.test,v 1.18 2002/01/15 18:39:45 drh Exp $
|
||||
# $Id: expr.test,v 1.19 2002/03/24 13:13:29 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -233,6 +233,22 @@ test_expr expr-6.23 {t1='abcdefg', t2='a*?g'} {t1 GLOB t2} 1
|
||||
test_expr expr-6.24 {t1='ac', t2='a*c'} {t1 GLOB t2} 1
|
||||
test_expr expr-6.25 {t1='ac', t2='a*?c'} {t1 GLOB t2} 0
|
||||
|
||||
test_expr expr-case.1 {i1=1, i2=2} \
|
||||
{CASE WHEN i1 = i2 THEN 'eq' ELSE 'ne' END} ne
|
||||
test_expr expr-case.2 {i1=2, i2=2} \
|
||||
{CASE WHEN i1 = i2 THEN 'eq' ELSE 'ne' END} eq
|
||||
test_expr expr-case.3 {i1=2} \
|
||||
{CASE i1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'error' END} two
|
||||
test_expr expr-case.4 {i1=3} \
|
||||
{CASE i1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'error' END} error
|
||||
test_expr expr-case.5 {i1=3} \
|
||||
{CASE i1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' END} {{}}
|
||||
test_expr expr-case.6 {i1=7} \
|
||||
{ CASE WHEN i1 < 5 THEN 'low'
|
||||
WHEN i1 < 10 THEN 'medium'
|
||||
WHEN i1 < 15 THEN 'high' ELSE 'error' END} medium
|
||||
|
||||
|
||||
# These tests only work on versions of TCL that support Unicode
|
||||
#
|
||||
if {"\u1234"!="u1234" && [sqlite -encoding]=="UTF-8"} {
|
||||
|
Loading…
Reference in New Issue
Block a user