/ Check-in [2498d3ea]
Login

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

Overview
Comment:Add a completely new testing system for the Bitvec object. The new testing system uses sqlite3_test_control() instead of unpublished APIs. Now provides 100% condition/decision coverage. Obscure bugs in Bitvec found and fixed as a result of the enhanced coverage. (CVS 4902)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:2498d3ea36ecab6d9c0f04ef1c49d76a7a215a4f
User & Date: drh 2008-03-21 16:45:47
Context
2008-03-21
17:13
Make sure the text result of an aggregate function has the correct encoding. Ticket #3009. (CVS 4903) check-in: 13e388ce user: drh tags: trunk
16:45
Add a completely new testing system for the Bitvec object. The new testing system uses sqlite3_test_control() instead of unpublished APIs. Now provides 100% condition/decision coverage. Obscure bugs in Bitvec found and fixed as a result of the enhanced coverage. (CVS 4902) check-in: 2498d3ea user: drh tags: trunk
14:22
Add some more logging to the malloc system used when SQLITE_MEMDEBUG is defined. (CVS 4901) check-in: 79738f58 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/bitvec.c.

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
..
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
...
126
127
128
129
130
131
132

133
134
135
136
137
138
139
...
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
...
171
172
173
174
175
176
177

178
179
180
181
182
183
184
...
187
188
189
190
191
192
193
194


195
196
197
198
199
200
201
...
205
206
207
208
209
210
211














































































































** Clear operations are exceedingly rare.  There are usually between
** 5 and 500 set operations per Bitvec object, though the number of sets can
** sometimes grow into tens of thousands or larger.  The size of the
** Bitvec object is the number of pages in the database file at the
** start of a transaction, and is thus usually less than a few thousand,
** but can be as large as 2 billion for a really big database.
**
** @(#) $Id: bitvec.c,v 1.2 2008/03/14 13:02:08 mlcreech Exp $
*/
#include "sqliteInt.h"

#define BITVEC_SZ        512
/* Round the union size down to the nearest pointer boundary, since that's how 
** it will be aligned within the Bitvec struct. */
#define BITVEC_USIZE     (((BITVEC_SZ-12)/sizeof(Bitvec *))*sizeof(Bitvec *))
#define BITVEC_NCHAR     BITVEC_USIZE
#define BITVEC_NBIT      (BITVEC_NCHAR*8)
#define BITVEC_NINT      (BITVEC_USIZE/4)
#define BITVEC_MXHASH    (BITVEC_NINT/2)
#define BITVEC_NPTR      (BITVEC_USIZE/sizeof(Bitvec *))

#define BITVEC_HASH(X)   (((X)*37)%BITVEC_NINT)
................................................................................

/*
** Check to see if the i-th bit is set.  Return true or false.
** If p is NULL (if the bitmap has not been created) or if
** i is out of range, then return false.
*/
int sqlite3BitvecTest(Bitvec *p, u32 i){
  assert( i>0 );
  if( p==0 ) return 0;
  if( i>p->iSize ) return 0;
  if( p->iSize<=BITVEC_NBIT ){
    i--;
    return (p->u.aBitmap[i/8] & (1<<(i&7)))!=0;
  }
  if( p->iDivisor>0 ){
    u32 bin = (i-1)/p->iDivisor;
    i = (i-1)%p->iDivisor + 1;
................................................................................
/*
** Set the i-th bit.  Return 0 on success and an error code if
** anything goes wrong.
*/
int sqlite3BitvecSet(Bitvec *p, u32 i){
  u32 h;
  assert( p!=0 );

  if( p->iSize<=BITVEC_NBIT ){
    i--;
    p->u.aBitmap[i/8] |= 1 << (i&7);
    return SQLITE_OK;
  }
  if( p->iDivisor ){
    u32 bin = (i-1)/p->iDivisor;
................................................................................
  p->nSet++;
  if( p->nSet>=BITVEC_MXHASH ){
    int j, rc;
    u32 aiValues[BITVEC_NINT];
    memcpy(aiValues, p->u.aHash, sizeof(aiValues));
    memset(p->u.apSub, 0, sizeof(p->u.apSub[0])*BITVEC_NPTR);
    p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR;
    sqlite3BitvecSet(p, i);
    for(rc=j=0; j<BITVEC_NINT; j++){
      if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]);
    }
    return rc;
  }
  p->u.aHash[h] = i;
  return SQLITE_OK;
}
................................................................................

/*
** Clear the i-th bit.  Return 0 on success and an error code if
** anything goes wrong.
*/
void sqlite3BitvecClear(Bitvec *p, u32 i){
  assert( p!=0 );

  if( p->iSize<=BITVEC_NBIT ){
    i--;
    p->u.aBitmap[i/8] &= ~(1 << (i&7));
  }else if( p->iDivisor ){
    u32 bin = (i-1)/p->iDivisor;
    i = (i-1)%p->iDivisor + 1;
    if( p->u.apSub[bin] ){
................................................................................
  }else{
    int j;
    u32 aiValues[BITVEC_NINT];
    memcpy(aiValues, p->u.aHash, sizeof(aiValues));
    memset(p->u.aHash, 0, sizeof(p->u.aHash[0])*BITVEC_NINT);
    p->nSet = 0;
    for(j=0; j<BITVEC_NINT; j++){
      if( aiValues[j] && aiValues[j]!=i ) sqlite3BitvecSet(p, aiValues[j]);


    }
  }
}

/*
** Destroy a bitmap object.  Reclaim all memory used.
*/
................................................................................
    int i;
    for(i=0; i<BITVEC_NPTR; i++){
      sqlite3BitvecDestroy(p->u.apSub[i]);
    }
  }
  sqlite3_free(p);
}





















































































































|






|







 







<

|







 







>







 







|
|







 







>







 







|
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
..
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111
112
...
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
...
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
...
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
...
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
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
** Clear operations are exceedingly rare.  There are usually between
** 5 and 500 set operations per Bitvec object, though the number of sets can
** sometimes grow into tens of thousands or larger.  The size of the
** Bitvec object is the number of pages in the database file at the
** start of a transaction, and is thus usually less than a few thousand,
** but can be as large as 2 billion for a really big database.
**
** @(#) $Id: bitvec.c,v 1.3 2008/03/21 16:45:47 drh Exp $
*/
#include "sqliteInt.h"

#define BITVEC_SZ        512
/* Round the union size down to the nearest pointer boundary, since that's how 
** it will be aligned within the Bitvec struct. */
#define BITVEC_USIZE     (((BITVEC_SZ-12)/sizeof(Bitvec*))*sizeof(Bitvec*))
#define BITVEC_NCHAR     BITVEC_USIZE
#define BITVEC_NBIT      (BITVEC_NCHAR*8)
#define BITVEC_NINT      (BITVEC_USIZE/4)
#define BITVEC_MXHASH    (BITVEC_NINT/2)
#define BITVEC_NPTR      (BITVEC_USIZE/sizeof(Bitvec *))

#define BITVEC_HASH(X)   (((X)*37)%BITVEC_NINT)
................................................................................

/*
** Check to see if the i-th bit is set.  Return true or false.
** If p is NULL (if the bitmap has not been created) or if
** i is out of range, then return false.
*/
int sqlite3BitvecTest(Bitvec *p, u32 i){

  if( p==0 ) return 0;
  if( i>p->iSize || i==0 ) return 0;
  if( p->iSize<=BITVEC_NBIT ){
    i--;
    return (p->u.aBitmap[i/8] & (1<<(i&7)))!=0;
  }
  if( p->iDivisor>0 ){
    u32 bin = (i-1)/p->iDivisor;
    i = (i-1)%p->iDivisor + 1;
................................................................................
/*
** Set the i-th bit.  Return 0 on success and an error code if
** anything goes wrong.
*/
int sqlite3BitvecSet(Bitvec *p, u32 i){
  u32 h;
  assert( p!=0 );
  assert( i>0 );
  if( p->iSize<=BITVEC_NBIT ){
    i--;
    p->u.aBitmap[i/8] |= 1 << (i&7);
    return SQLITE_OK;
  }
  if( p->iDivisor ){
    u32 bin = (i-1)/p->iDivisor;
................................................................................
  p->nSet++;
  if( p->nSet>=BITVEC_MXHASH ){
    int j, rc;
    u32 aiValues[BITVEC_NINT];
    memcpy(aiValues, p->u.aHash, sizeof(aiValues));
    memset(p->u.apSub, 0, sizeof(p->u.apSub[0])*BITVEC_NPTR);
    p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR;
    rc = sqlite3BitvecSet(p, i);
    for(j=0; j<BITVEC_NINT; j++){
      if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]);
    }
    return rc;
  }
  p->u.aHash[h] = i;
  return SQLITE_OK;
}
................................................................................

/*
** Clear the i-th bit.  Return 0 on success and an error code if
** anything goes wrong.
*/
void sqlite3BitvecClear(Bitvec *p, u32 i){
  assert( p!=0 );
  assert( i>0 );
  if( p->iSize<=BITVEC_NBIT ){
    i--;
    p->u.aBitmap[i/8] &= ~(1 << (i&7));
  }else if( p->iDivisor ){
    u32 bin = (i-1)/p->iDivisor;
    i = (i-1)%p->iDivisor + 1;
    if( p->u.apSub[bin] ){
................................................................................
  }else{
    int j;
    u32 aiValues[BITVEC_NINT];
    memcpy(aiValues, p->u.aHash, sizeof(aiValues));
    memset(p->u.aHash, 0, sizeof(p->u.aHash[0])*BITVEC_NINT);
    p->nSet = 0;
    for(j=0; j<BITVEC_NINT; j++){
      if( aiValues[j] && aiValues[j]!=i ){
        sqlite3BitvecSet(p, aiValues[j]);
      }
    }
  }
}

/*
** Destroy a bitmap object.  Reclaim all memory used.
*/
................................................................................
    int i;
    for(i=0; i<BITVEC_NPTR; i++){
      sqlite3BitvecDestroy(p->u.apSub[i]);
    }
  }
  sqlite3_free(p);
}

#ifndef SQLITE_OMIT_BUILTIN_TEST
/*
** Let V[] be an array of unsigned characters sufficient to hold
** up to N bits.  Let I be an integer between 0 and N.  0<=I<N.
** Then the following macros can be used to set, clear, or test
** individual bits within V.
*/
#define SETBIT(V,I)      V[I>>3] |= (1<<(I&7))
#define CLEARBIT(V,I)    V[I>>3] &= ~(1<<(I&7))
#define TESTBIT(V,I)     (V[I>>3]&(1<<(I&7)))!=0

/*
** This routine runs an extensive test of the Bitvec code.
**
** The input is an array of integers that acts as a program
** to test the Bitvec.  The integers are opcodes followed
** by 0, 1, or 3 operands, depending on the opcode.  Another
** opcode follows immediately after the last operand.
**
** There are 6 opcodes numbered from 0 through 5.  0 is the
** "halt" opcode and causes the test to end.
**
**    0          Halt and return the number of errors
**    1 N S X    Set N bits beginning with S and incrementing by X
**    2 N S X    Clear N bits beginning with S and incrementing by X
**    3 N        Set N randomly chosen bits
**    4 N        Clear N randomly chosen bits
**    5 N S X    Set N bits from S increment X in array only, not in bitvec
**
** The opcodes 1 through 4 perform set and clear operations are performed
** on both a Bitvec object and on a linear array of bits obtained from malloc.
** Opcode 5 works on the linear array only, not on the Bitvec.
** Opcode 5 is used to deliberately induce a fault in order to
** confirm that error detection works.
**
** At the conclusion of the test the linear array is compared
** against the Bitvec object.  If there are any differences,
** an error is returned.  If they are the same, zero is returned.
**
** If a memory allocation error occurs, return -1.
*/
int sqlite3BitvecBuiltinTest(int sz, int *aOp){
  Bitvec *pBitvec = 0;
  unsigned char *pV = 0;
  int rc = -1;
  int i, nx, pc, op;

  /* Allocate the Bitvec to be tested and a linear array of
  ** bits to act as the reference */
  pBitvec = sqlite3BitvecCreate( sz );
  pV = sqlite3_malloc( (sz+7)/8 + 1 );
  if( pBitvec==0 || pV==0 ) goto bitvec_end;
  memset(pV, 0, (sz+7)/8 + 1);

  /* Run the program */
  pc = 0;
  while( (op = aOp[pc])!=0 ){
    switch( op ){
      case 1:
      case 2:
      case 5: {
        nx = 4;
        i = aOp[pc+2] - 1;
        aOp[pc+2] += aOp[pc+3];
        break;
      }
      case 3:
      case 4: 
      default: {
        nx = 2;
        sqlite3_randomness(sizeof(i), &i);
        break;
      }
    }
    if( (--aOp[pc+1]) > 0 ) nx = 0;
    pc += nx;
    i = (i & 0x7fffffff)%sz;
    if( (op & 1)!=0 ){
      SETBIT(pV, (i+1));
      if( op!=5 ){
        if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end;
      }
    }else{
      CLEARBIT(pV, (i+1));
      sqlite3BitvecClear(pBitvec, i+1);
    }
  }

  /* Test to make sure the linear array exactly matches the
  ** Bitvec object.  Start with the assumption that they do
  ** match (rc==0).  Change rc to non-zero if a discrepancy
  ** is found.
  */
  rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1)
          + sqlite3BitvecTest(pBitvec, 0);
  for(i=1; i<=sz; i++){
    if(  (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){
      rc = i;
      break;
    }
  }

  /* Free allocated structure */
bitvec_end:
  sqlite3_free(pV);
  sqlite3BitvecDestroy(pBitvec);
  return rc;
}
#endif /* SQLITE_OMIT_BUILTIN_TEST */

Changes to src/fault.c.

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
...
140
141
142
143
144
145
146
147
** Subsystems within SQLite can call sqlite3FaultStep() to see if
** they should simulate a fault.  sqlite3FaultStep() normally returns
** zero but will return non-zero if a fault should be simulated.
** Fault injectors can be used, for example, to simulate memory
** allocation failures or I/O errors.
**
** The fault injector is omitted from the code if SQLite is
** compiled with -DSQLITE_OMIT_TESTLOGIC=1.  There is a very
** small performance hit for leaving the fault injector in the code.
** Commerical products will probably want to omit the fault injector
** from production builds.  But safety-critical systems who work
** under the motto "fly what you test and test what you fly" may
** choose to leave the fault injector enabled even in production.
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_TESTLOGIC

/*
** There can be various kinds of faults.  For example, there can be
** a memory allocation failure.  Or an I/O failure.  For each different
** fault type, there is a separate FaultInjector structure to keep track
** of the status of that fault.
*/
................................................................................
  aFault[id].nRepeat--;
  if( aFault[id].nRepeat<=0 ){
    aFault[id].enable = 0;
  }
  return 1;  
}

#endif /* SQLITE_OMIT_TESTLOGIC */







|








|







 







|
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
...
140
141
142
143
144
145
146
147
** Subsystems within SQLite can call sqlite3FaultStep() to see if
** they should simulate a fault.  sqlite3FaultStep() normally returns
** zero but will return non-zero if a fault should be simulated.
** Fault injectors can be used, for example, to simulate memory
** allocation failures or I/O errors.
**
** The fault injector is omitted from the code if SQLite is
** compiled with -DSQLITE_OMIT_BUILTIN_TEST=1.  There is a very
** small performance hit for leaving the fault injector in the code.
** Commerical products will probably want to omit the fault injector
** from production builds.  But safety-critical systems who work
** under the motto "fly what you test and test what you fly" may
** choose to leave the fault injector enabled even in production.
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_BUILTIN_TEST

/*
** There can be various kinds of faults.  For example, there can be
** a memory allocation failure.  Or an I/O failure.  For each different
** fault type, there is a separate FaultInjector structure to keep track
** of the status of that fault.
*/
................................................................................
  aFault[id].nRepeat--;
  if( aFault[id].nRepeat<=0 ){
    aFault[id].enable = 0;
  }
  return 1;  
}

#endif /* SQLITE_OMIT_BUILTIN_TEST */

Changes to src/main.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
....
1654
1655
1656
1657
1658
1659
1660
1661















1662
1663
1664
1665
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.428 2008/03/20 18:00:49 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#ifdef SQLITE_ENABLE_FTS3
# include "fts3.h"
#endif

................................................................................
}

/*
** Interface to the testing logic.
*/
int sqlite3_test_control(int op, ...){
  int rc = 0;
#ifndef SQLITE_OMIT_TESTLOGIC
  va_list ap;
  va_start(ap, op);
  switch( op ){
    /*
    ** sqlite3_test_control(FAULT_CONFIG, fault_id, nDelay, nRepeat)
    **
    ** Configure a fault injector.  The specific fault injector is
................................................................................
    ** to sqlite3_randomness() will reseed the PRNG using a single call
    ** to the xRandomness method of the default VFS.
    */
    case SQLITE_TESTCTRL_PRNG_RESET: {
      sqlite3PrngResetState();
      break;
    }
  }















  va_end(ap);
#endif /* SQLITE_OMIT_TESTLOGIC */
  return rc;
}







|







 







|







 







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
....
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.429 2008/03/21 16:45:47 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#ifdef SQLITE_ENABLE_FTS3
# include "fts3.h"
#endif

................................................................................
}

/*
** Interface to the testing logic.
*/
int sqlite3_test_control(int op, ...){
  int rc = 0;
#ifndef SQLITE_OMIT_BUILTIN_TEST
  va_list ap;
  va_start(ap, op);
  switch( op ){
    /*
    ** sqlite3_test_control(FAULT_CONFIG, fault_id, nDelay, nRepeat)
    **
    ** Configure a fault injector.  The specific fault injector is
................................................................................
    ** to sqlite3_randomness() will reseed the PRNG using a single call
    ** to the xRandomness method of the default VFS.
    */
    case SQLITE_TESTCTRL_PRNG_RESET: {
      sqlite3PrngResetState();
      break;
    }

    /*
    **  sqlite3_test_control(BITVEC_TEST, size, program)
    **
    ** Run a test against a Bitvec object of size.  The program argument
    ** is an array of integers that defines the test.  Return -1 on a
    ** memory allocation error, 0 on success, or non-zero for an error.
    ** See the sqlite3BitvecBuiltinTest() for additional information.
    */
    case SQLITE_TESTCTRL_BITVEC_TEST: {
      int sz = va_arg(ap, int);
      int *aProg = va_arg(ap, int*);
      rc = sqlite3BitvecBuiltinTest(sz, aProg);
      break;
    }
  }
  va_end(ap);
#endif /* SQLITE_OMIT_BUILTIN_TEST */
  return rc;
}

Changes to src/random.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
...
116
117
118
119
120
121
122
123
*************************************************************************
** This file contains code to implement a pseudo-random number
** generator (PRNG) for SQLite.
**
** Random numbers are used by some of the database backends in order
** to generate random integer keys for tables or random filenames.
**
** $Id: random.c,v 1.22 2008/03/19 14:15:35 drh Exp $
*/
#include "sqliteInt.h"


/* All threads share a single random number generator.
** This structure is the current state of the generator.
*/
................................................................................
  sqlite3_mutex_enter(mutex);
  while( N-- ){
    *(zBuf++) = randomByte();
  }
  sqlite3_mutex_leave(mutex);
}

#ifndef SQLITE_OMIT_TESTLOGIC
/*
** For testing purposes, we sometimes want to preserve the state of
** PRNG and restore the PRNG to its saved state at a later time.
** The sqlite3_test_control() interface calls these routines to
** control the PRNG.
*/
static struct sqlite3PrngType sqlite3SavedPrng;
................................................................................
}
void sqlite3PrngRestoreState(void){
  memcpy(&sqlite3Prng, &sqlite3SavedPrng, sizeof(sqlite3Prng));
}
void sqlite3PrngResetState(void){
  sqlite3Prng.isInit = 0;
}
#endif /* SQLITE_OMIT_TESTLOGIC */







|







 







|







 







|
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
...
116
117
118
119
120
121
122
123
*************************************************************************
** This file contains code to implement a pseudo-random number
** generator (PRNG) for SQLite.
**
** Random numbers are used by some of the database backends in order
** to generate random integer keys for tables or random filenames.
**
** $Id: random.c,v 1.23 2008/03/21 16:45:47 drh Exp $
*/
#include "sqliteInt.h"


/* All threads share a single random number generator.
** This structure is the current state of the generator.
*/
................................................................................
  sqlite3_mutex_enter(mutex);
  while( N-- ){
    *(zBuf++) = randomByte();
  }
  sqlite3_mutex_leave(mutex);
}

#ifndef SQLITE_OMIT_BUILTIN_TEST
/*
** For testing purposes, we sometimes want to preserve the state of
** PRNG and restore the PRNG to its saved state at a later time.
** The sqlite3_test_control() interface calls these routines to
** control the PRNG.
*/
static struct sqlite3PrngType sqlite3SavedPrng;
................................................................................
}
void sqlite3PrngRestoreState(void){
  memcpy(&sqlite3Prng, &sqlite3SavedPrng, sizeof(sqlite3Prng));
}
void sqlite3PrngResetState(void){
  sqlite3Prng.isInit = 0;
}
#endif /* SQLITE_OMIT_BUILTIN_TEST */

Changes to src/sqlite.h.in.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
....
5606
5607
5608
5609
5610
5611
5612

5613
5614
5615
5616
5617
5618
5619
** on how SQLite interfaces are suppose to operate.
**
** The name of this file under configuration management is "sqlite.h.in".
** The makefile makes some minor changes to this file (such as inserting
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
**
** @(#) $Id: sqlite.h.in,v 1.298 2008/03/20 18:00:49 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
#define SQLITE_TESTCTRL_FAULT_CONFIG             1
#define SQLITE_TESTCTRL_FAULT_FAILURES           2
#define SQLITE_TESTCTRL_FAULT_BENIGN_FAILURES    3
#define SQLITE_TESTCTRL_FAULT_PENDING            4
#define SQLITE_TESTCTRL_PRNG_SAVE                5
#define SQLITE_TESTCTRL_PRNG_RESTORE             6
#define SQLITE_TESTCTRL_PRNG_RESET               7



/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT







|







 







>







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
....
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
** on how SQLite interfaces are suppose to operate.
**
** The name of this file under configuration management is "sqlite.h.in".
** The makefile makes some minor changes to this file (such as inserting
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
**
** @(#) $Id: sqlite.h.in,v 1.299 2008/03/21 16:45:47 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
#define SQLITE_TESTCTRL_FAULT_CONFIG             1
#define SQLITE_TESTCTRL_FAULT_FAILURES           2
#define SQLITE_TESTCTRL_FAULT_BENIGN_FAILURES    3
#define SQLITE_TESTCTRL_FAULT_PENDING            4
#define SQLITE_TESTCTRL_PRNG_SAVE                5
#define SQLITE_TESTCTRL_PRNG_RESTORE             6
#define SQLITE_TESTCTRL_PRNG_RESET               7
#define SQLITE_TESTCTRL_BITVEC_TEST              8


/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1786
1787
1788
1789
1790
1791
1792

1793
1794
1795
1796
1797
1798
1799
....
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.678 2008/03/20 16:30:18 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Include the configuration header output by 'configure' if it was run
** (otherwise we get an empty default).
................................................................................
void sqlite3EndTable(Parse*,Token*,Token*,Select*);

Bitvec *sqlite3BitvecCreate(u32);
int sqlite3BitvecTest(Bitvec*, u32);
int sqlite3BitvecSet(Bitvec*, u32);
void sqlite3BitvecClear(Bitvec*, u32);
void sqlite3BitvecDestroy(Bitvec*);


void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);

#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
  int sqlite3ViewGetColumnNames(Parse*,Table*);
#else
# define sqlite3ViewGetColumnNames(A,B) 0
................................................................................
#define SQLITE_FAULTINJECTOR_COUNT      1

/*
** The interface to the fault injector subsystem.  If the fault injector
** mechanism is disabled at compile-time then set up macros so that no
** unnecessary code is generated.
*/
#ifndef SQLITE_OMIT_TESTLOGIC
  void sqlite3FaultConfig(int,int,int);
  int sqlite3FaultFailures(int);
  int sqlite3FaultBenignFailures(int);
  int sqlite3FaultPending(int);
  void sqlite3FaultBenign(int,int);
  int sqlite3FaultStep(int);
#else







|







 







>







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
....
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.679 2008/03/21 16:45:47 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Include the configuration header output by 'configure' if it was run
** (otherwise we get an empty default).
................................................................................
void sqlite3EndTable(Parse*,Token*,Token*,Select*);

Bitvec *sqlite3BitvecCreate(u32);
int sqlite3BitvecTest(Bitvec*, u32);
int sqlite3BitvecSet(Bitvec*, u32);
void sqlite3BitvecClear(Bitvec*, u32);
void sqlite3BitvecDestroy(Bitvec*);
int sqlite3BitvecBuiltinTest(int,int*);

void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);

#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
  int sqlite3ViewGetColumnNames(Parse*,Table*);
#else
# define sqlite3ViewGetColumnNames(A,B) 0
................................................................................
#define SQLITE_FAULTINJECTOR_COUNT      1

/*
** The interface to the fault injector subsystem.  If the fault injector
** mechanism is disabled at compile-time then set up macros so that no
** unnecessary code is generated.
*/
#ifndef SQLITE_OMIT_BUILTIN_TEST
  void sqlite3FaultConfig(int,int,int);
  int sqlite3FaultFailures(int);
  int sqlite3FaultBenignFailures(int);
  int sqlite3FaultPending(int);
  void sqlite3FaultBenign(int,int);
  int sqlite3FaultStep(int);
#else

Changes to src/test2.c.

9
10
11
12
13
14
15
16
17
18
19
20
21

22
23
24
25
26
27
28
...
556
557
558
559
560
561
562
563

564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607






608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624


625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
...
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the pager.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test2.c,v 1.56 2008/03/20 11:04:21 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>


/*
** Interpret an SQLite error number
*/
static char *errorName(int rc){
  char *zName;
  switch( rc ){
................................................................................
  if( rc ){
    Tcl_AppendResult(interp, "write failed: ", errorName(rc), 0);
    return TCL_ERROR;
  }
  return TCL_OK;
}
#endif


/*
**   sqlite3BitvecCreate SIZE
**   sqlite3BitvecTest POINTER N
**   sqlite3BitvecSet POINTER N
**   sqlite3BitvecClear POINTER N
**   sqlite3BitvecDestroy POINTER
*/
static int testBitvecCreate(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  int size;
  Bitvec *p;
  char zBuf[100];
  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " N\"", 
           (void*)0);
  }
  if( Tcl_GetInt(interp, argv[1], &size) ) return TCL_ERROR;
  p = sqlite3BitvecCreate(size);
  sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",p);
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;
}  
static int testBitvecTest(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  int N;
  Bitvec *p;
  char zBuf[100];
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " PTR N\"", 
           (void*)0);
  }
  p = (Bitvec*)sqlite3TextToPtr(argv[1]);
  if( Tcl_GetInt(interp, argv[2], &N) ) return TCL_ERROR;
  sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",sqlite3BitvecTest(p,N));
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;






}  
static int testBitvecSet(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  int N;
  Bitvec *p;
  char zBuf[100];
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " PTR N\"", 
           (void*)0);
  }
  p = (Bitvec*)sqlite3TextToPtr(argv[1]);
  if( Tcl_GetInt(interp, argv[2], &N) ) return TCL_ERROR;
  sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",sqlite3BitvecSet(p,N));


  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;
}  
static int testBitvecClear(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  int N;
  Bitvec *p;
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " PTR N\"", 
           (void*)0);
  }
  p = (Bitvec*)sqlite3TextToPtr(argv[1]);
  if( Tcl_GetInt(interp, argv[2], &N) ) return TCL_ERROR;
  sqlite3BitvecClear(p,N);
  return TCL_OK;
}  
static int testBitvecDestroy(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Bitvec *p;
  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " PTR\"", 
           (void*)0);
  }
  p = (Bitvec*)sqlite3TextToPtr(argv[1]);
  sqlite3BitvecDestroy(p);
  return TCL_OK;
}  
       

/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest2_Init(Tcl_Interp *interp){
  extern int sqlite3_io_error_persist;
  extern int sqlite3_io_error_pending;
................................................................................
    { "page_read",               (Tcl_CmdProc*)page_read           },
    { "page_write",              (Tcl_CmdProc*)page_write          },
    { "page_number",             (Tcl_CmdProc*)page_number         },
    { "pager_truncate",          (Tcl_CmdProc*)pager_truncate      },
#ifndef SQLITE_OMIT_DISKIO
    { "fake_big_file",           (Tcl_CmdProc*)fake_big_file       },
#endif
    { "sqlite3BitvecCreate",     (Tcl_CmdProc*)testBitvecCreate    },
    { "sqlite3BitvecTest",       (Tcl_CmdProc*)testBitvecTest      },
    { "sqlite3BitvecSet",        (Tcl_CmdProc*)testBitvecSet       },
    { "sqlite3BitvecClear",      (Tcl_CmdProc*)testBitvecClear     },
    { "sqlite3BitvecDestroy",    (Tcl_CmdProc*)testBitvecDestroy   },
  };
  int i;
  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }
  Tcl_LinkVar(interp, "sqlite_io_error_pending",
     (char*)&sqlite3_io_error_pending, TCL_LINK_INT);







|





>







 








>

|
<
|
|
|

|





|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<

|
|

<
|
<
<
<
>
>
>
>
>
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
>
|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|
<
<
<
<







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
...
557
558
559
560
561
562
563
564
565
566
567

568
569
570
571
572
573
574
575
576
577
578
579
580














581




582
583
584
585

586



587
588
589
590
591
592
593
















594
595
596
597
598

































599
600
601
602
603
604
605
...
627
628
629
630
631
632
633
634




635
636
637
638
639
640
641
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the pager.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test2.c,v 1.57 2008/03/21 16:45:48 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

/*
** Interpret an SQLite error number
*/
static char *errorName(int rc){
  char *zName;
  switch( rc ){
................................................................................
  if( rc ){
    Tcl_AppendResult(interp, "write failed: ", errorName(rc), 0);
    return TCL_ERROR;
  }
  return TCL_OK;
}
#endif


/*
** sqlite3BitvecBuiltinTest SIZE PROGRAM

**
** Invoke the SQLITE_TESTCTRL_BITVEC_TEST operator on test_control.
** See comments on sqlite3BitvecBuiltinTest() for additional information.
*/
static int testBitvecBuiltinTest(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  int sz, rc;
  int nProg = 0;
  int aProg[100];














  const char *z;




  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                     " SIZE PROGRAM\"", (void*)0);
  }

  if( Tcl_GetInt(interp, argv[1], &sz) ) return TCL_ERROR;



  z = argv[2];
  while( nProg<99 && *z ){
    while( *z && !isdigit(*z) ){ z++; }
    if( *z==0 ) break;
    aProg[nProg++] = atoi(z);
    while( isdigit(*z) ){ z++; }
  }
















  aProg[nProg] = 0;
  rc = sqlite3_test_control(SQLITE_TESTCTRL_BITVEC_TEST, sz, aProg);
  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
  return TCL_OK;
}  


































/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest2_Init(Tcl_Interp *interp){
  extern int sqlite3_io_error_persist;
  extern int sqlite3_io_error_pending;
................................................................................
    { "page_read",               (Tcl_CmdProc*)page_read           },
    { "page_write",              (Tcl_CmdProc*)page_write          },
    { "page_number",             (Tcl_CmdProc*)page_number         },
    { "pager_truncate",          (Tcl_CmdProc*)pager_truncate      },
#ifndef SQLITE_OMIT_DISKIO
    { "fake_big_file",           (Tcl_CmdProc*)fake_big_file       },
#endif
    { "sqlite3BitvecBuiltinTest",(Tcl_CmdProc*)testBitvecBuiltinTest},




  };
  int i;
  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }
  Tcl_LinkVar(interp, "sqlite_io_error_pending",
     (char*)&sqlite3_io_error_pending, TCL_LINK_INT);

Changes to src/test_config.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
130
131
132
133
134
135
136






137
138
139
140
141
142
143
...
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
** 
** This file contains code used for testing the SQLite system.
** None of the code in this file goes into a deliverable build.
** 
** The focus of this file is providing the TCL testing layer
** access to compile-time constants.
**
** $Id: test_config.c,v 1.22 2008/03/20 14:03:29 drh Exp $
*/

#include "sqliteLimit.h"

#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
................................................................................
#endif

#ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION
  Tcl_SetVar2(interp, "sqlite_options", "between_opt", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "between_opt", "1", TCL_GLOBAL_ONLY);
#endif







#ifdef SQLITE_OMIT_BLOB_LITERAL
  Tcl_SetVar2(interp, "sqlite_options", "bloblit", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "bloblit", "1", TCL_GLOBAL_ONLY);
#endif

................................................................................

#ifdef SQLITE_OMIT_TCL_VARIABLE
  Tcl_SetVar2(interp, "sqlite_options", "tclvar", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "tclvar", "1", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_OMIT_TESTLOGIC
  Tcl_SetVar2(interp, "sqlite_options", "testlogic", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "testlogic", "1", TCL_GLOBAL_ONLY);
#endif

  rc = sqlite3_threadsafe();
#if SQLITE_THREADSAFE
  Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "1", TCL_GLOBAL_ONLY);
  assert( rc );
#else
  Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "0", TCL_GLOBAL_ONLY);
  assert( !rc );







|







 







>
>
>
>
>
>







 







<
<
<
<
<
<







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
...
358
359
360
361
362
363
364






365
366
367
368
369
370
371
** 
** This file contains code used for testing the SQLite system.
** None of the code in this file goes into a deliverable build.
** 
** The focus of this file is providing the TCL testing layer
** access to compile-time constants.
**
** $Id: test_config.c,v 1.23 2008/03/21 16:45:48 drh Exp $
*/

#include "sqliteLimit.h"

#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
................................................................................
#endif

#ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION
  Tcl_SetVar2(interp, "sqlite_options", "between_opt", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "between_opt", "1", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_OMIT_BUILTIN_TEST
  Tcl_SetVar2(interp, "sqlite_options", "builtin_test", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "builtin_test", "1", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_OMIT_BLOB_LITERAL
  Tcl_SetVar2(interp, "sqlite_options", "bloblit", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "bloblit", "1", TCL_GLOBAL_ONLY);
#endif

................................................................................

#ifdef SQLITE_OMIT_TCL_VARIABLE
  Tcl_SetVar2(interp, "sqlite_options", "tclvar", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "tclvar", "1", TCL_GLOBAL_ONLY);
#endif







  rc = sqlite3_threadsafe();
#if SQLITE_THREADSAFE
  Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "1", TCL_GLOBAL_ONLY);
  assert( rc );
#else
  Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "0", TCL_GLOBAL_ONLY);
  assert( !rc );

Changes to test/bitvec.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
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
207
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Unit testing of the Bitvec object.
#
# $Id: bitvec.test,v 1.1 2008/02/18 14:47:34 drh Exp $
#

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

#ifcapable !subquery {
#  finish_test
#  return
#}

do_test bitvec-1.1 {
  set PTR [sqlite3BitvecCreate 4000]
  for {set i 1} {$i<=4000} {incr i} {
    if {$i%1000==999} continue
    sqlite3BitvecSet $PTR $i
  }
  set r {}
  for {set i 1} {$i<=4000} {incr i} {
    if {![sqlite3BitvecTest $PTR $i]} {lappend r $i}
  }
  sqlite3BitvecDestroy $PTR
  set r
} {999 1999 2999 3999}
do_test bitvec-1.2 {
  set PTR [sqlite3BitvecCreate 4001]
  for {set i 1} {$i<=4001} {incr i} {
    if {$i%1000==999} continue
    sqlite3BitvecSet $PTR $i
  }
  set r {}
  for {set i 1} {$i<=4001} {incr i} {
    if {![sqlite3BitvecTest $PTR $i]} {lappend r $i}
  }
  sqlite3BitvecDestroy $PTR
  set r
} {999 1999 2999 3999}
do_test bitvec-1.3 {
  set PTR [sqlite3BitvecCreate 40000]
  for {set i 1} {$i<=40000} {incr i} {
    if {$i%10000==9999} continue
    sqlite3BitvecSet $PTR $i
  }
  set r {}
  for {set i 1} {$i<=40000} {incr i} {
    if {![sqlite3BitvecTest $PTR $i]} {lappend r $i}
  }
  sqlite3BitvecDestroy $PTR
  set r
} {9999 19999 29999 39999}
do_test bitvec-1.4 {
  set PTR [sqlite3BitvecCreate 2000000000]
  for {set i 1000000} {$i<=1001000} {incr i} {
    if {$i%1000==789} continue
    sqlite3BitvecSet $PTR $i
  }
  set r {}
  for {set i 1000000} {$i<=1001000} {incr i} {
    if {![sqlite3BitvecTest $PTR $i]} {lappend r $i}
  }
  sqlite3BitvecDestroy $PTR
  set r
} {1000789}

do_test bitvec-2.1 {
  set PTR [sqlite3BitvecCreate 4000]
  for {set i 1} {$i<=4000} {incr i 2} {
    sqlite3BitvecSet $PTR $i
  }
  for {set i 1} {$i<=4000} {incr i} {
    sqlite3BitvecClear $PTR $i
  }
  set r {}
  for {set i 1} {$i<=4000} {incr i} {
    if {[sqlite3BitvecTest $PTR $i]} {lappend r $i}
  }
  sqlite3BitvecDestroy $PTR
  set r
} {}
do_test bitvec-2.2 {
  set PTR [sqlite3BitvecCreate 4001]
  for {set i 1} {$i<=101} {incr i 2} {
    sqlite3BitvecSet $PTR $i
  }
  for {set i 1} {$i<=99} {incr i} {
    sqlite3BitvecClear $PTR $i
  }
  set r {}
  for {set i 1} {$i<=4000} {incr i} {
    if {[sqlite3BitvecTest $PTR $i]} {lappend r $i}
  }
  sqlite3BitvecDestroy $PTR
  set r
} {101}
do_test bitvec-2.3 {
  set PTR [sqlite3BitvecCreate 4001]
  for {set i 1} {$i<=101} {incr i} {
    sqlite3BitvecSet $PTR $i
  }
  for {set i 1} {$i<=99} {incr i} {
    sqlite3BitvecClear $PTR $i
  }
  set r {}
  for {set i 1} {$i<=4000} {incr i} {
    if {[sqlite3BitvecTest $PTR $i]} {lappend r $i}
  }
  sqlite3BitvecDestroy $PTR
  set r
} {100 101}
do_test bitvec-2.4 {
  set PTR [sqlite3BitvecCreate 5000]
  for {set i 1} {$i<=5000} {incr i} {
    sqlite3BitvecSet $PTR $i
    if {$i%1000!=456} {sqlite3BitvecClear $PTR $i}
  }
  set r {}
  for {set i 1} {$i<=5000} {incr i} {
    if {[sqlite3BitvecTest $PTR $i]} {lappend r $i}
  }
  sqlite3BitvecDestroy $PTR
  set r
} {456 1456 2456 3456 4456}

do_test bitvec-3.1 {
  set PTR [sqlite3BitvecCreate 2000000000]
  for {set i 2000000} {$i<=3000000} {incr i 100000} {
    for {set j $i} {$j<=$i+50} {incr j} {
      sqlite3BitvecSet $PTR $i
    }
    for {set j $i} {$j<=$i+50} {incr j} {
      sqlite3BitvecClear $PTR $i
    }
  }
  set r {}
  for {set i 2000000} {$i<=3000000} {incr i} {
    if {[sqlite3BitvecTest $PTR $i]} {lappend r $i}
  }
  sqlite3BitvecDestroy $PTR
  set r
} {}
do_test bitvec-3.2 {
  set PTR [sqlite3BitvecCreate 200000]
  for {set i 1000} {$i<=190000} {incr i 10000} {
    for {set j $i} {$j<=$i+50} {incr j} {
      sqlite3BitvecSet $PTR $i
    }
    for {set j $i} {$j<=$i+50} {incr j} {
      sqlite3BitvecClear $PTR $i
    }
  }
  set r {}
  for {set i 1} {$i<=200000} {incr i} {
    if {[sqlite3BitvecTest $PTR $i]} {lappend r $i}
  }
  sqlite3BitvecDestroy $PTR
  set r
} {}
do_test bitvec-3.3 {
  set PTR [sqlite3BitvecCreate 200000]
  for {set i 1000} {$i<=190000} {incr i 10000} {
    for {set j $i} {$j<=$i+500} {incr j} {
      sqlite3BitvecSet $PTR $i
    }
    for {set j $i} {$j<=$i+500} {incr j} {
      sqlite3BitvecClear $PTR $i
    }
  }
  set r {}
  for {set i 1} {$i<=200000} {incr i} {
    if {[sqlite3BitvecTest $PTR $i]} {lappend r $i}
  }
  sqlite3BitvecDestroy $PTR
  set r
} {}
do_test bitvec-3.4 {
  set PTR [sqlite3BitvecCreate 2000]
  for {set i 10} {$i<=1900} {incr i 100} {
    for {set j $i} {$j<=$i+50} {incr j} {
      sqlite3BitvecSet $PTR $i
    }
    for {set j $i} {$j<=$i+50} {incr j} {
      sqlite3BitvecClear $PTR $i
    }
  }
  set r {}
  for {set i 1} {$i<=2000} {incr i} {
    if {[sqlite3BitvecTest $PTR $i]} {lappend r $i}
  }
  sqlite3BitvecDestroy $PTR
  set r
} {}


finish_test







|





|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
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
















#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Unit testing of the Bitvec object.
#
# $Id: bitvec.test,v 1.2 2008/03/21 16:45:48 drh Exp $
#

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

# The built-in test logic must be operational in order for
# this test to work.
ifcapable !builtin_test {
  finish_test
  return
}

# Test that sqlite3BitvecBuiltinTest correctly reports errors
# that are deliberately introduced.
#
do_test bitvec-1.0.1 {
  sqlite3BitvecBuiltinTest 400 {5 1 1 1 0}
} 1
do_test bitvec-1.0.2 {
  sqlite3BitvecBuiltinTest 400 {5 1 234 1 0}
} 234

# Run test cases that set every bit in vectors of various sizes.
# for larger cases, this should cycle the bit vector representation
# from hashing into subbitmaps.  The subbitmaps should start as
# hashes then change to either subbitmaps or linear maps, depending
# on their size.
#
do_test bitvec-1.1 {
  sqlite3BitvecBuiltinTest 400 {1 400 1 1 0}
} 0
do_test bitvec-1.2 {
  sqlite3BitvecBuiltinTest 4000 {1 4000 1 1 0}
} 0
do_test bitvec-1.3 {
  sqlite3BitvecBuiltinTest 40000 {1 40000 1 1 0}
} 0
do_test bitvec-1.4 {
  sqlite3BitvecBuiltinTest 400000 {1 400000 1 1 0}
} 0

# By specifying a larger increments, we spread the load around.
#
do_test bitvec-1.5 {
  sqlite3BitvecBuiltinTest 400 {1 400 1 7 0}
} 0
do_test bitvec-1.6 {
  sqlite3BitvecBuiltinTest 4000 {1 4000 1 7 0}
} 0
do_test bitvec-1.7 {
  sqlite3BitvecBuiltinTest 40000 {1 40000 1 7 0}
} 0
do_test bitvec-1.8 {
  sqlite3BitvecBuiltinTest 400000 {1 400000 1 7 0}
} 0

# First fill up the bitmap with ones,  then go through and
# clear all the bits.  This will stress the clearing mechanism.
#
do_test bitvec-1.9 {
  sqlite3BitvecBuiltinTest 400 {1 400 1 1 2 400 1 1 0}
} 0
do_test bitvec-1.10 {
  sqlite3BitvecBuiltinTest 4000 {1 4000 1 1 2 4000 1 1 0}
} 0
do_test bitvec-1.11 {
  sqlite3BitvecBuiltinTest 40000 {1 40000 1 1 2 40000 1 1 0}
} 0
do_test bitvec-1.12 {
  sqlite3BitvecBuiltinTest 400000 {1 400000 1 1 2 400000 1 1 0}
} 0

do_test bitvec-1.13 {
  sqlite3BitvecBuiltinTest 400 {1 400 1 1 2 400 1 7 0}
} 0
do_test bitvec-1.15 {
  sqlite3BitvecBuiltinTest 4000 {1 4000 1 1 2 4000 1 7 0}
} 0
do_test bitvec-1.16 {
  sqlite3BitvecBuiltinTest 40000 {1 40000 1 1 2 40000 1 77 0}
} 0
do_test bitvec-1.17 {
  sqlite3BitvecBuiltinTest 400000 {1 400000 1 1 2 400000 1 777 0}
} 0

do_test bitvec-1.18 {
  sqlite3BitvecBuiltinTest 400000 {1 5000 100000 1 2 400000 1 37 0}
} 0

# Attempt to induce hash collisions.  
#
unset -nocomplain start
unset -nocomplain incr
foreach start {1 2 3 4 5 6 7 8} {
  foreach incr {124 125} {
    do_test bitvec-1.20.$start.$incr {
      set prog [list 1 60 $::start $::incr 2 5000 1 1 0]
      sqlite3BitvecBuiltinTest 5000 $prog
    } 0
  }
}

do_test bitvec-1.30.big_and_slow {
  sqlite3BitvecBuiltinTest 17000000 {1 17000000 1 1 2 17000000 1 1 0}
} 0


# Test setting and clearing a random subset of bits.
#
do_test bitvec-2.1 {
  sqlite3BitvecBuiltinTest 4000 {3 2000 4 2000 0}
} 0
do_test bitvec-2.2 {
  sqlite3BitvecBuiltinTest 4000 {3 1000 4 1000 3 1000 4 1000 3 1000 4 1000
                                 3 1000 4 1000 3 1000 4 1000 3 1000 4 1000 0}
} 0
do_test bitvec-2.3 {
  sqlite3BitvecBuiltinTest 400000 {3 10 0}
} 0
do_test bitvec-2.4 {
  sqlite3BitvecBuiltinTest 4000 {3 10 2 4000 1 1 0}
} 0
do_test bitvec-2.5 {
  sqlite3BitvecBuiltinTest 5000 {3 20 2 5000 1 1 0}
} 0
do_test bitvec-2.6 {
  sqlite3BitvecBuiltinTest 50000 {3 60 2 50000 1 1 0}
} 0

# This procedure runs sqlite3BitvecBuiltinTest with argments "n" and
# "program".  But it also causes a malloc error to occur after the
# "failcnt"-th malloc.  The result should be "0" if no malloc failure
# occurs or "-1" if there is a malloc failure.
#
proc bitvec_malloc_test {label failcnt n program} {
  do_test $label [subst {
    sqlite3_memdebug_fail $failcnt
    set x \[sqlite3BitvecBuiltinTest $n [list $program]\]
    set nFail \[sqlite3_memdebug_fail -1\]
    if {\$nFail==0} {
      set ::go 0
      set x -1
    }
    set x
  }] -1
}

# Make sure malloc failures are handled sanily.
#
unset -nocomplain n
unset -nocomplain go
set go 1
save_prng_state
for {set n 0} {$go} {incr n} {
  restore_prng_state
  bitvec_malloc_test bitvec-3.1.$n $n 5000 {
      3 60 2 5000 1 1 3 60 2 5000 1 1 3 60 2 5000 1 1 0
  }
}
set go 1
for {set n 0} {$go} {incr n} {
  restore_prng_state
  bitvec_malloc_test bitvec-3.2.$n $n 5000 {
      3 600 2 5000 1 1 3 600 2 5000 1 1 3 600 2 5000 1 1 0
  }
}
set go 1
for {set n 1} {$go} {incr n} {
  bitvec_malloc_test bitvec-3.3.$n $n 50000 {1 50000 1 1 0}
}

finish_test
return



finish_test
















Changes to test/malloc_common.tcl.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains common code used by many different malloc tests
# within the test suite.
#
# $Id: malloc_common.tcl,v 1.15 2008/03/19 14:15:35 drh Exp $

# If we did not compile with malloc testing enabled, then do nothing.
#
ifcapable testlogic {
  set MEMDEBUG 1
} else {
  set MEMDEBUG 0
  return 0
}

# Usage: do_malloc_test <test number> <options...>







|



|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains common code used by many different malloc tests
# within the test suite.
#
# $Id: malloc_common.tcl,v 1.16 2008/03/21 16:45:48 drh Exp $

# If we did not compile with malloc testing enabled, then do nothing.
#
ifcapable builtin_test {
  set MEMDEBUG 1
} else {
  set MEMDEBUG 0
  return 0
}

# Usage: do_malloc_test <test number> <options...>