SQLite

Check-in [4debc8db92]
Login

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: 4debc8db929fdc201759ba211acdeadc4e30e8af
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
Unified Diff Ignore Whitespace Patch
Changes to src/expr.c.
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.64 2002/05/26 20:54:33 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







|







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
950
951
952
953
954
955
956
957
      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);
        sqliteVdbeAddOp(v, OP_IsNull, -1, expr_end_label);
      }
      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);







>












|







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
1167
1168
1169
1170
1171
1172
1173
1174
1175
      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_Not, 0, 0);
      sqliteVdbeAddOp(v, OP_If, jumpIfNull, dest);
      break;
    }
  }
}

/*
** Do a deep comparison of two expression trees.  Return TRUE (non-zero)







|
<







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
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.21 2002/05/27 01:04:51 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)}













|







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
355


356
357
358
359
360
361
362
	{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=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







|
>
>







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