Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Bug fix: bad code was generated for when the first operand of a CASE was NULL. (CVS 598) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
4debc8db929fdc201759ba211acdeadc |
User & Date: | drh 2002-05-30 02:35:12.000 |
Context
2002-05-30
| ||
12:27 | Once it is opened, leave the checkpoint journal file open for the duration of a transaction, rather than closing it and reopening it for each statement. (Ticket #53) (CVS 599) (check-in: 7a24336d50 user: drh tags: trunk) | |
02:35 | Bug fix: bad code was generated for when the first operand of a CASE was NULL. (CVS 598) (check-in: 4debc8db92 user: drh tags: trunk) | |
2002-05-29
| ||
23:22 | Built-in aggregate functions (MIN, SUM, AVG, etc) should ignore NULL entires. (CVS 597) (check-in: 19ae12bef2 user: drh tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.65 2002/05/30 02:35:12 drh Exp $ */ #include "sqliteInt.h" /* ** Construct a new expression node and return a pointer to it. Memory ** for this node is obtained from sqliteMalloc(). The calling function |
︙ | ︙ | |||
931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 | sqliteExprCode(pParse, pExpr->pLeft); break; } case TK_CASE: { int expr_end_label; int null_result_label; int jumpInst; int addr; int nExpr; int i; assert(pExpr->pList); assert((pExpr->pList->nExpr % 2) == 0); assert(pExpr->pList->nExpr > 0); nExpr = pExpr->pList->nExpr; expr_end_label = sqliteVdbeMakeLabel(v); null_result_label = sqliteVdbeMakeLabel(v); if( pExpr->pLeft ){ sqliteExprCode(pParse, pExpr->pLeft); | > | | 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 | sqliteExprCode(pParse, pExpr->pLeft); break; } case TK_CASE: { int expr_end_label; int null_result_label; int jumpInst; int nullBypassInst; int addr; int nExpr; int i; assert(pExpr->pList); assert((pExpr->pList->nExpr % 2) == 0); assert(pExpr->pList->nExpr > 0); nExpr = pExpr->pList->nExpr; expr_end_label = sqliteVdbeMakeLabel(v); null_result_label = sqliteVdbeMakeLabel(v); if( pExpr->pLeft ){ sqliteExprCode(pParse, pExpr->pLeft); nullBypassInst = sqliteVdbeAddOp(v, OP_IsNull, -1, 0); } for(i=0; i<nExpr; i=i+2){ sqliteExprCode(pParse, pExpr->pList->a[i].pExpr); sqliteVdbeAddOp(v, OP_IsNull, -1, null_result_label); if( pExpr->pLeft ){ sqliteVdbeAddOp(v, OP_Dup, 1, 1); jumpInst = sqliteVdbeAddOp(v, OP_Ne, 0, 0); |
︙ | ︙ | |||
976 977 978 979 980 981 982 983 984 985 986 987 988 989 | }else{ sqliteVdbeAddOp(v, OP_String, 0, 0); } sqliteVdbeResolveLabel(v, expr_end_label); if( pExpr->pLeft ){ sqliteVdbeAddOp(v, OP_Pull, 1, 0); sqliteVdbeAddOp(v, OP_Pop, 1, 0); } } break; } } /* | > | 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 | }else{ sqliteVdbeAddOp(v, OP_String, 0, 0); } sqliteVdbeResolveLabel(v, expr_end_label); if( pExpr->pLeft ){ sqliteVdbeAddOp(v, OP_Pull, 1, 0); sqliteVdbeAddOp(v, OP_Pop, 1, 0); sqliteVdbeChangeP2(v, nullBypassInst, sqliteVdbeCurrentAddr(v)); } } break; } } /* |
︙ | ︙ | |||
1160 1161 1162 1163 1164 1165 1166 | sqliteVdbeAddOp(v, OP_Goto, 0, dest); sqliteExprCode(pParse, pExpr->pList->a[1].pExpr); sqliteVdbeAddOp(v, OP_Gt, jumpIfNull, dest); break; } default: { sqliteExprCode(pParse, pExpr); | | < | 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 | sqliteVdbeAddOp(v, OP_Goto, 0, dest); sqliteExprCode(pParse, pExpr->pList->a[1].pExpr); sqliteVdbeAddOp(v, OP_Gt, jumpIfNull, dest); break; } default: { sqliteExprCode(pParse, pExpr); sqliteVdbeAddOp(v, OP_IfNot, jumpIfNull, dest); break; } } } /* ** Do a deep comparison of two expression trees. Return TRUE (non-zero) |
︙ | ︙ |
Changes to test/expr.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing expressions. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing expressions. # # $Id: expr.test,v 1.22 2002/05/30 02:35:12 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create a table to work with. # execsql {CREATE TABLE test1(i1 int, i2 int, r1 real, r2 real, t1 text, t2 text)} |
︙ | ︙ | |||
348 349 350 351 352 353 354 | {CASE i1 WHEN 1 THEN 'one' WHEN NULL THEN 'two' ELSE 'error' END} {{}} test_expr expr-case.8 {i1=3} \ {CASE i1 WHEN 1 THEN 'one' WHEN NULL THEN 'two' ELSE 'error' END} {{}} test_expr expr-case.9 {i1=3} \ {CASE i1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'error' END} error test_expr expr-case.10 {i1=3} \ {CASE i1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' END} {{}} | | > > | 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 | {CASE i1 WHEN 1 THEN 'one' WHEN NULL THEN 'two' ELSE 'error' END} {{}} test_expr expr-case.8 {i1=3} \ {CASE i1 WHEN 1 THEN 'one' WHEN NULL THEN 'two' ELSE 'error' END} {{}} test_expr expr-case.9 {i1=3} \ {CASE i1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'error' END} error test_expr expr-case.10 {i1=3} \ {CASE i1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' END} {{}} test_expr expr-case.11 {i1=null} \ {CASE i1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 3 END} {{}} test_expr expr-case.12 {i1=7} \ { CASE WHEN i1 < 5 THEN 'low' WHEN i1 < 10 THEN 'medium' WHEN i1 < 15 THEN 'high' ELSE 'error' END} medium # The sqliteExprIfFalse and sqliteExprIfTrue routines are only # executed as part of a WHERE clause. Create a table suitable |
︙ | ︙ |