SQLite

Check-in [fd4da6b134]
Login

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

Overview
Comment:Changes to increase test coverage. (CVS 3819)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: fd4da6b13499af2397d52cb0f25f8ff6f2192431
User & Date: drh 2007-04-06 01:04:40.000
Context
2007-04-06
02:32
Test coverage improvements. Over 90% of branches are now executed in both directions. (CVS 3820) (check-in: a776d93cca user: drh tags: trunk)
01:04
Changes to increase test coverage. (CVS 3819) (check-in: fd4da6b134 user: drh tags: trunk)
01:03
Make sure the sqlite3BtreePrevious() routine terminates properly if the table is deleted out from under it. Ticket #2286. This bug was discovered while trying to increase test coverage from 98.5% to 99% - once again showing the value of full coverage testing. (CVS 3818) (check-in: bebf8d2f88 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/select.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 C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.332 2007/04/01 23:49:52 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.







|







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 C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.333 2007/04/06 01:04:40 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
  }

  sqliteFree(sAggInfo.aCol);
  sqliteFree(sAggInfo.aFunc);
  return rc;
}

#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
/*
*******************************************************************************
** The following code is used for testing and debugging only.  The code
** that follows does not appear in normal builds.
**
** These routines are used to print out the content of all or part of a 
** parse structures such as Select or Expr.  Such printouts are useful







|







3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
  }

  sqliteFree(sAggInfo.aCol);
  sqliteFree(sAggInfo.aFunc);
  return rc;
}

#if defined(SQLITE_DEBUG)
/*
*******************************************************************************
** The following code is used for testing and debugging only.  The code
** that follows does not appear in normal builds.
**
** These routines are used to print out the content of all or part of a 
** parse structures such as Select or Expr.  Such printouts are useful
Changes to src/where.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  This module is reponsible for
** generating the code that loops through a table looking for applicable
** rows.  Indices are selected and used to speed the search when doing
** so is applicable.  Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
** $Id: where.c,v 1.245 2007/03/31 01:34:45 drh Exp $
*/
#include "sqliteInt.h"

/*
** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
*/
#define BMS  (sizeof(Bitmask)*8)







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  This module is reponsible for
** generating the code that loops through a table looking for applicable
** rows.  Indices are selected and used to speed the search when doing
** so is applicable.  Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
** $Id: where.c,v 1.246 2007/04/06 01:04:40 drh Exp $
*/
#include "sqliteInt.h"

/*
** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
*/
#define BMS  (sizeof(Bitmask)*8)
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149

/*
** Two routines for printing the content of an sqlite3_index_info
** structure.  Used for testing and debugging only.  If neither
** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines
** are no-ops.
*/
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && \
        (defined(SQLITE_TEST) || defined(SQLITE_DEBUG))
static void TRACE_IDX_INPUTS(sqlite3_index_info *p){
  int i;
  if( !sqlite3_where_trace ) return;
  for(i=0; i<p->nConstraint; i++){
    sqlite3DebugPrintf("  constraint[%d]: col=%d termid=%d op=%d usabled=%d\n",
       i,
       p->aConstraint[i].iColumn,







|
<







1134
1135
1136
1137
1138
1139
1140
1141

1142
1143
1144
1145
1146
1147
1148

/*
** Two routines for printing the content of an sqlite3_index_info
** structure.  Used for testing and debugging only.  If neither
** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines
** are no-ops.
*/
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_DEBUG)

static void TRACE_IDX_INPUTS(sqlite3_index_info *p){
  int i;
  if( !sqlite3_where_trace ) return;
  for(i=0; i<p->nConstraint; i++){
    sqlite3DebugPrintf("  constraint[%d]: col=%d termid=%d op=%d usabled=%d\n",
       i,
       p->aConstraint[i].iColumn,
Changes to test/shared_err.test.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
#
# The focus of the tests in this file are IO errors that occur in a shared
# cache context. What happens to connection B if one connection A encounters
# an IO-error whilst reading or writing the file-system?
#
# $Id: shared_err.test,v 1.10 2007/03/19 13:53:38 danielk1977 Exp $

proc skip {args} {}


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







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
#
# The focus of the tests in this file are IO errors that occur in a shared
# cache context. What happens to connection B if one connection A encounters
# an IO-error whilst reading or writing the file-system?
#
# $Id: shared_err.test,v 1.11 2007/04/06 01:04:40 drh Exp $

proc skip {args} {}


set testdir [file dirname $argv0]
source $testdir/tester.tcl
db close
287
288
289
290
291
292
293
















































































294
295
296
297
298
299
300
    expr {
      ($::steprc eq "SQLITE_ROW" && $::column eq "002.002.002.002.002") ||
      ($::steprc eq "SQLITE_ERROR" && $::column eq "") ||
      ($::steprc eq "SQLITE_ABORT" && $::column eq "001.001.001.001.001") 
    }
  } {1}
  do_test shared_ioerr-3.$n.cleanup.3 {
















































































    expr {
      ($::steprc eq "SQLITE_ROW" && $::finalrc eq "SQLITE_OK") ||
      ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_IOERR") ||
      ($::steprc eq "SQLITE_ABORT" && $::finalrc eq "SQLITE_OK")
    }
  } {1}








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







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
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
    expr {
      ($::steprc eq "SQLITE_ROW" && $::column eq "002.002.002.002.002") ||
      ($::steprc eq "SQLITE_ERROR" && $::column eq "") ||
      ($::steprc eq "SQLITE_ABORT" && $::column eq "001.001.001.001.001") 
    }
  } {1}
  do_test shared_ioerr-3.$n.cleanup.3 {
    expr {
      ($::steprc eq "SQLITE_ROW" && $::finalrc eq "SQLITE_OK") ||
      ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_IOERR") ||
      ($::steprc eq "SQLITE_ABORT" && $::finalrc eq "SQLITE_OK")
    }
  } {1}

# db2 eval {select * from sqlite_master}
  db2 close
}

# This is a repeat of the previous test except that this time we
# are doing a reverse-order scan of the table when the cursor is
# "saved".
# 
do_ioerr_test shared_ioerr-3rev -tclprep {
  sqlite3 db2 test.db
  execsql {
    PRAGMA read_uncommitted = 1;
    PRAGMA cache_size = 10;
    BEGIN;
    CREATE TABLE t1(a, b, UNIQUE(a, b));
  } db2
  for {set i 0} {$i < 200} {incr i} {
    set a [string range [string repeat "[format %03d $i]." 5] 0 end-1]

    set b [string repeat $i 2000]
    execsql {INSERT INTO t1 VALUES($a, $b)} db2
  }
  execsql {COMMIT} db2
  set ::DB2 [sqlite3_connection_pointer db2]
  set ::STMT [sqlite3_prepare $::DB2 \
           "SELECT a FROM t1 ORDER BY a DESC" -1 DUMMY]
  sqlite3_step $::STMT       ;# Cursor points at 199.199.199.199.199
  sqlite3_step $::STMT       ;# Cursor points at 198.198.198.198.198

} -tclbody {
  execsql {
    BEGIN;
    INSERT INTO t1 VALUES('201.201.201.201.201', NULL);
    UPDATE t1 SET a = '202.202.202.202.202' WHERE a LIKE '201%';
    COMMIT;
  }
} -cleanup {
  set ::steprc  [sqlite3_step $::STMT]
  set ::column  [sqlite3_column_text $::STMT 0]
  set ::finalrc [sqlite3_finalize $::STMT]

  # There are three possible outcomes here (assuming persistent IO errors):
  #
  # 1. If the [sqlite3_step] did not require any IO (required pages in
  #    the cache), then the next row ("002...") may be retrieved 
  #    successfully.
  #
  # 2. If the [sqlite3_step] does require IO, then [sqlite3_step] returns
  #    SQLITE_ERROR and [sqlite3_finalize] returns IOERR.
  #
  # 3. If, after the initial IO error, SQLite tried to rollback the
  #    active transaction and a second IO error was encountered, then
  #    statement $::STMT will have been aborted. This means [sqlite3_stmt]
  #    returns SQLITE_ABORT, and the statement cursor does not move. i.e.
  #    [sqlite3_column] still returns the current row ("001...") and
  #    [sqlite3_finalize] returns SQLITE_OK.
  #

  do_test shared_ioerr-3rev.$n.cleanup.1 {
    expr {
      $::steprc eq "SQLITE_ROW" || 
      $::steprc eq "SQLITE_ERROR" ||
      $::steprc eq "SQLITE_ABORT" 
    }
  } {1}
  do_test shared_ioerr-3rev.$n.cleanup.2 {
    expr {
      ($::steprc eq "SQLITE_ROW" && $::column eq "197.197.197.197.197") ||
      ($::steprc eq "SQLITE_ERROR" && $::column eq "") ||
      ($::steprc eq "SQLITE_ABORT" && $::column eq "198.198.198.198.198") 
    }
  } {1}
  do_test shared_ioerr-3rev.$n.cleanup.3 {
    expr {
      ($::steprc eq "SQLITE_ROW" && $::finalrc eq "SQLITE_OK") ||
      ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_IOERR") ||
      ($::steprc eq "SQLITE_ABORT" && $::finalrc eq "SQLITE_OK")
    }
  } {1}