/ Check-in [a6b45722]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Test cases to improve coverage of vdbe.c. (CVS 2193)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: a6b45722071bde543c4ea28a432339d8708a5cac
User & Date: danielk1977 2005-01-11 13:02:34
Context
2005-01-11
15:28
Improved test coverage for util.c. (CVS 2194) check-in: ad451a2d user: drh tags: trunk
13:02
Test cases to improve coverage of vdbe.c. (CVS 2193) check-in: a6b45722 user: danielk1977 tags: trunk
11:08
Remove a C++ style comment that went in with the previous commit. (CVS 2192) check-in: ce8e4e88 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/func.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
911
912
913
914
915
916
917















918
919
920
921
922
923
924
....
1118
1119
1120
1121
1122
1123
1124

1125
1126
1127
1128
1129
1130
1131
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.91 2004/11/19 05:14:55 danielk1977 Exp $
*/
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "sqliteInt.h"
#include "vdbeInt.h"
................................................................................
      zRet[i*2+1] = ' ';
    }
  }
  sqlite3_result_text(pCtx, zRet, 2*nArg-1, free_test_auxdata);
}
#endif /* SQLITE_TEST */
















/*
** An instance of the following structure holds the context of a
** sum() or avg() aggregate computation.
*/
typedef struct SumCtx SumCtx;
struct SumCtx {
  double sum;     /* Sum of terms */
................................................................................
    { "soundex",            1, 0, SQLITE_UTF8, 0, soundexFunc},
#endif
#ifdef SQLITE_TEST
    { "randstr",               2, 0, SQLITE_UTF8, 0, randStr    },
    { "test_destructor",       1, 1, SQLITE_UTF8, 0, test_destructor},
    { "test_destructor_count", 0, 0, SQLITE_UTF8, 0, test_destructor_count},
    { "test_auxdata",         -1, 0, SQLITE_UTF8, 0, test_auxdata},

#endif
  };
  static const struct {
    char *zName;
    signed char nArg;
    u8 argType;
    u8 needCollSeq;







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
....
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.92 2005/01/11 13:02:34 danielk1977 Exp $
*/
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "sqliteInt.h"
#include "vdbeInt.h"
................................................................................
      zRet[i*2+1] = ' ';
    }
  }
  sqlite3_result_text(pCtx, zRet, 2*nArg-1, free_test_auxdata);
}
#endif /* SQLITE_TEST */

#ifdef SQLITE_TEST
/*
** A function to test error reporting from user functions. This function
** returns a copy of it's first argument as an error.
*/
static void test_error(
  sqlite3_context *pCtx, 
  int nArg,
  sqlite3_value **argv
){
  // sqlite3_result_error(pCtx, sqlite3_value_text(argv[0]), 0);
  sqlite3_result_error(pCtx, 0, 0);
}
#endif /* SQLITE_TEST */

/*
** An instance of the following structure holds the context of a
** sum() or avg() aggregate computation.
*/
typedef struct SumCtx SumCtx;
struct SumCtx {
  double sum;     /* Sum of terms */
................................................................................
    { "soundex",            1, 0, SQLITE_UTF8, 0, soundexFunc},
#endif
#ifdef SQLITE_TEST
    { "randstr",               2, 0, SQLITE_UTF8, 0, randStr    },
    { "test_destructor",       1, 1, SQLITE_UTF8, 0, test_destructor},
    { "test_destructor_count", 0, 0, SQLITE_UTF8, 0, test_destructor_count},
    { "test_auxdata",         -1, 0, SQLITE_UTF8, 0, test_auxdata},
    { "test_error",            1, 0, SQLITE_UTF8, 0, test_error},
#endif
  };
  static const struct {
    char *zName;
    signed char nArg;
    u8 argType;
    u8 needCollSeq;

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
623
624
625
626
627
628
629

630
631
632
633
634
635
636
637
638
639
640
641
....
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
....
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
....
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599

2600
2601
2602
2603
2604
2605
2606
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.439 2005/01/11 11:08:23 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
  p->rc = pOp->p1;
  p->pc = pc;
  p->errorAction = pOp->p2;
  if( pOp->p3 ){
    sqlite3SetString(&p->zErrMsg, pOp->p3, (char*)0);
  }
  rc = sqlite3VdbeHalt(p);

  if( rc==SQLITE_BUSY ){
    p->rc = SQLITE_BUSY;
    return SQLITE_BUSY;
  }else if( rc!=SQLITE_OK ){
    p->rc = rc;
  }
  return p->rc ? SQLITE_ERROR : SQLITE_DONE;
}

/* Opcode: Integer P1 * P3
**
** The integer value P1 is pushed onto the stack.  If P3 is not zero
................................................................................
      pC->aOffset = aOffset;
      pC->cacheValid = 1;
    }
  }

  /* Get the column information.
  */
  if( rc!=SQLITE_OK ){
    goto abort_due_to_error;
  }
  if( zRec ){
    zData = &zRec[aOffset[p2]];
  }else{
    len = sqlite3VdbeSerialTypeLen(aType[p2]);
    rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->keyAsData, &sMem);
    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
................................................................................
  }
  for(pRec=pData0; pRec<=pTos; pRec++){
    zCsr += sqlite3VdbeSerialPut(zCsr, pRec);  /* serial data */
  }
  if( addRowid ){
    zCsr += sqlite3VdbeSerialPut(zCsr, pRowid);
  }

  /* If zCsr has not been advanced exactly nByte bytes, then one
  ** of the sqlite3PutVarint() or sqlite3VdbeSerialPut() calls above
  ** failed. This indicates a corrupted memory cell or code bug.
  */
  if( zCsr!=(zNewRecord+nByte) ){
    rc = SQLITE_INTERNAL;
    goto abort_due_to_error;
  }

  /* Pop entries off the stack if required. Push the new record on. */
  if( !leaveOnStack ){
    popStack(&pTos, nField+addRowid);
  }
  pTos++;
  pTos->n = nByte;
................................................................................
    pC->deferredMoveto = 0;
    pC->cacheValid = 0;
    *pC->pIncrKey = 0;
    sqlite3_search_count++;
    if( oc==OP_MoveGe || oc==OP_MoveGt ){
      if( res<0 ){
        rc = sqlite3BtreeNext(pC->pCursor, &res);
        if( rc!=SQLITE_OK ){
          goto abort_due_to_error;
        }
        pC->recnoIsValid = 0;
      }else{
        res = 0;
      }
    }else{
      assert( oc==OP_MoveLt || oc==OP_MoveLe );
      if( res>=0 ){
        sqlite3BtreePrevious(pC->pCursor, &res);

        pC->recnoIsValid = 0;
      }else{
        /* res might be negative because the table is empty.  Check to
        ** see if this is the case.
        */
        res = sqlite3BtreeEof(pC->pCursor);
      }







|







 







>



<
<







 







|
<
<







 







<
<
<
<
<
|
<
<
<







 







<
|
<







|
>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
623
624
625
626
627
628
629
630
631
632
633


634
635
636
637
638
639
640
....
1867
1868
1869
1870
1871
1872
1873
1874


1875
1876
1877
1878
1879
1880
1881
....
2041
2042
2043
2044
2045
2046
2047





2048



2049
2050
2051
2052
2053
2054
2055
....
2571
2572
2573
2574
2575
2576
2577

2578

2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.440 2005/01/11 13:02:34 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
  p->rc = pOp->p1;
  p->pc = pc;
  p->errorAction = pOp->p2;
  if( pOp->p3 ){
    sqlite3SetString(&p->zErrMsg, pOp->p3, (char*)0);
  }
  rc = sqlite3VdbeHalt(p);
  assert( rc==SQLITE_BUSY || rc==SQLITE_OK );
  if( rc==SQLITE_BUSY ){
    p->rc = SQLITE_BUSY;
    return SQLITE_BUSY;


  }
  return p->rc ? SQLITE_ERROR : SQLITE_DONE;
}

/* Opcode: Integer P1 * P3
**
** The integer value P1 is pushed onto the stack.  If P3 is not zero
................................................................................
      pC->aOffset = aOffset;
      pC->cacheValid = 1;
    }
  }

  /* Get the column information.
  */
  assert( rc==SQLITE_OK );


  if( zRec ){
    zData = &zRec[aOffset[p2]];
  }else{
    len = sqlite3VdbeSerialTypeLen(aType[p2]);
    rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->keyAsData, &sMem);
    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
................................................................................
  }
  for(pRec=pData0; pRec<=pTos; pRec++){
    zCsr += sqlite3VdbeSerialPut(zCsr, pRec);  /* serial data */
  }
  if( addRowid ){
    zCsr += sqlite3VdbeSerialPut(zCsr, pRowid);
  }





  assert( zCsr==(zNewRecord+nByte) );




  /* Pop entries off the stack if required. Push the new record on. */
  if( !leaveOnStack ){
    popStack(&pTos, nField+addRowid);
  }
  pTos++;
  pTos->n = nByte;
................................................................................
    pC->deferredMoveto = 0;
    pC->cacheValid = 0;
    *pC->pIncrKey = 0;
    sqlite3_search_count++;
    if( oc==OP_MoveGe || oc==OP_MoveGt ){
      if( res<0 ){
        rc = sqlite3BtreeNext(pC->pCursor, &res);

        if( rc!=SQLITE_OK ) goto abort_due_to_error;

        pC->recnoIsValid = 0;
      }else{
        res = 0;
      }
    }else{
      assert( oc==OP_MoveLt || oc==OP_MoveLe );
      if( res>=0 ){
        rc = sqlite3BtreePrevious(pC->pCursor, &res);
        if( rc!=SQLITE_OK ) goto abort_due_to_error;
        pC->recnoIsValid = 0;
      }else{
        /* res might be negative because the table is empty.  Check to
        ** see if this is the case.
        */
        res = sqlite3BtreeEof(pC->pCursor);
      }

Changes to test/func.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
448
449
450
451
452
453
454






455
#    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 built-in functions.
#
# $Id: func.test,v 1.29 2004/08/20 18:34:20 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create a table to work with.
#
do_test func-0.0 {
................................................................................
} {0}
do_test func-14.2 {
  catch {
    db function [string repeat X 256] {return "hello"}
  }
} {1}







finish_test







|







 







>
>
>
>
>
>

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
448
449
450
451
452
453
454
455
456
457
458
459
460
461
#    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 built-in functions.
#
# $Id: func.test,v 1.30 2005/01/11 13:02:34 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create a table to work with.
#
do_test func-0.0 {
................................................................................
} {0}
do_test func-14.2 {
  catch {
    db function [string repeat X 256] {return "hello"}
  }
} {1}

do_test func-15.1 {
  catchsql {
    select test_error(NULL);
  }
} {1 {user function error}}

finish_test

Changes to test/ioerr.test.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
163
164
165
166
167
168
169





























170
171
172
173
174
175
176
177
# This file implements regression tests for SQLite library.  The
# focus of this file is testing for correct handling of I/O errors
# such as writes failing because the disk is full.
# 
# The tests in this file use special facilities that are only
# available in the SQLite test fixture.
#
# $Id: ioerr.test,v 1.9 2005/01/11 10:25:07 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

set ::AV [execsql {pragma auto_vacuum}]

set ::go 1
................................................................................
    set r [catch {db eval {
      CREATE TABLE abc2(a);
      BEGIN;
      DELETE FROM abc WHERE length(a)>100;
      UPDATE abc SET a = randstr(90,90);
      COMMIT;
      CREATE TABLE abc3(a);





























    }} msg]
    set ::go [expr {$::sqlite_io_error_pending<=0}]
    expr {$::sqlite_io_error_pending>0 || $r!=0}
  } {1}
}
set ::sqlite_io_error_pending 0

finish_test







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# This file implements regression tests for SQLite library.  The
# focus of this file is testing for correct handling of I/O errors
# such as writes failing because the disk is full.
# 
# The tests in this file use special facilities that are only
# available in the SQLite test fixture.
#
# $Id: ioerr.test,v 1.10 2005/01/11 13:02:34 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

set ::AV [execsql {pragma auto_vacuum}]

set ::go 1
................................................................................
    set r [catch {db eval {
      CREATE TABLE abc2(a);
      BEGIN;
      DELETE FROM abc WHERE length(a)>100;
      UPDATE abc SET a = randstr(90,90);
      COMMIT;
      CREATE TABLE abc3(a);
    }} msg]
    set ::go [expr {$::sqlite_io_error_pending<=0}]
    expr {$::sqlite_io_error_pending>0 || $r!=0}
  } {1}
}
set ::sqlite_io_error_pending 0

set ::go 1
for {set n 1} {$go} {incr n} {
  do_test ioerr-4.$n.1 {
    set ::sqlite_io_error_pending 0
    db close
    catch {file delete -force test.db}
    catch {file delete -force test.db-journal}
    sqlite3 db test.db
    set sql "CREATE TABLE abc(a1"
    for {set i 2} {$i<1300} {incr i} {
      append sql ", a$i"
    }
    append sql ");"
    execsql $sql
    execsql {INSERT INTO abc (a1) VALUES(NULL)}
  } {}
  do_test ioerr-4.$n.2 [subst {
    set ::sqlite_io_error_pending $n
  }] $n
  do_test ioerr-4.$n.3 {
    set r [catch {db eval {
      SELECT * FROM abc;
    }} msg]
    set ::go [expr {$::sqlite_io_error_pending<=0}]
    expr {$::sqlite_io_error_pending>0 || $r!=0}
  } {1}
}
set ::sqlite_io_error_pending 0

finish_test

Changes to test/malloc.test.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
286
287
288
289
290
291
292






























293
294
295
296
297
298
299
#***********************************************************************
# This file attempts to check the library in an out-of-memory situation.
# When compiled with -DSQLITE_DEBUG=1, the SQLite library accepts a special
# command (sqlite_malloc_fail N) which causes the N-th malloc to fail.  This
# special feature is used to see what happens in the library if a malloc
# were to really fail due to an out-of-memory situation.
#
# $Id: malloc.test,v 1.12 2005/01/03 01:33:00 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Only run these tests if memory debugging is turned on.
#
if {[info command sqlite_malloc_stat]==""} {
................................................................................
         INSERT INTO t1 SELECT a*2 FROM t1;
         DELETE FROM t1 where rowid%5 = 0;
         COMMIT;
     }
     sqlite_malloc_fail $i
     set v [catch {execsql {
       VACUUM;






























     }} msg]
     set leftover [lindex [sqlite_malloc_stat] 2]
     if {$leftover>0} {
       if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v  Message=$msg"}
       set ::go 0
       set v {1 1}
     } else {







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
#***********************************************************************
# This file attempts to check the library in an out-of-memory situation.
# When compiled with -DSQLITE_DEBUG=1, the SQLite library accepts a special
# command (sqlite_malloc_fail N) which causes the N-th malloc to fail.  This
# special feature is used to see what happens in the library if a malloc
# were to really fail due to an out-of-memory situation.
#
# $Id: malloc.test,v 1.13 2005/01/11 13:02:34 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Only run these tests if memory debugging is turned on.
#
if {[info command sqlite_malloc_stat]==""} {
................................................................................
         INSERT INTO t1 SELECT a*2 FROM t1;
         DELETE FROM t1 where rowid%5 = 0;
         COMMIT;
     }
     sqlite_malloc_fail $i
     set v [catch {execsql {
       VACUUM;
     }} msg]
     set leftover [lindex [sqlite_malloc_stat] 2]
     if {$leftover>0} {
       if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v  Message=$msg"}
       set ::go 0
       set v {1 1}
     } else {
       set v2 [expr {$msg=="" || $msg=="out of memory"}]
       if {!$v2} {puts "\nError message returned: $msg"}
       lappend v $v2
     }
  } {1 1}
}

for {set go 1; set i 1} {$go} {incr i} {
  do_test malloc-7.$i {
     sqlite_malloc_fail 0
     catch {db close}
     catch {file delete -force test.db}
     catch {file delete -force test.db-journal}
     sqlite3 db test.db
     execsql {
       CREATE TABLE t1(a, b);
       INSERT INTO t1 VALUES(1, 2);
       INSERT INTO t1 VALUES(3, 4);
       INSERT INTO t1 VALUES(5, 6);
     }
     sqlite_malloc_fail $i
     set v [catch {execsql {
       SELECT min(a) FROM t1 GROUP BY b;
     }} msg]
     set leftover [lindex [sqlite_malloc_stat] 2]
     if {$leftover>0} {
       if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v  Message=$msg"}
       set ::go 0
       set v {1 1}
     } else {