SQLite

Check-in [264ace50bb]
Login

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

Overview
Comment:Changes to build.c to help facilitate full coverage testing. (CVS 6634)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 264ace50bbaec3468de0e42b2b8cebf9ce1d6682
User & Date: drh 2009-05-13 17:21:14.000
Context
2009-05-13
17:35
Remove incorrect NEVER() macro in the previous check-in (6634). (CVS 6635) (check-in: c684957991 user: drh tags: trunk)
17:21
Changes to build.c to help facilitate full coverage testing. (CVS 6634) (check-in: 264ace50bb user: drh tags: trunk)
14:46
Do not run async4.test as part of the "journaltest" permutation. It specifically tests that the asynchronous IO backend can be configured to violate the assumptions made by journaltest. (CVS 6633) (check-in: b19bf39bba user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/build.c.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.541 2009/05/12 18:00:38 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
*/







|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.542 2009/05/13 17:21:14 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
*/
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
  u8 isWriteLock,    /* True for a write lock */
  const char *zName  /* Name of the table to be locked */
){
  int i;
  int nBytes;
  TableLock *p;

  if( iDb<0 ){
    return;
  }

  for(i=0; i<pParse->nTableLock; i++){
    p = &pParse->aTableLock[i];
    if( p->iDb==iDb && p->iTab==iTab ){
      p->isWriteLock = (p->isWriteLock || isWriteLock);
      return;
    }
  }







<
|
<
<







64
65
66
67
68
69
70

71


72
73
74
75
76
77
78
  u8 isWriteLock,    /* True for a write lock */
  const char *zName  /* Name of the table to be locked */
){
  int i;
  int nBytes;
  TableLock *p;


  if( NEVER(iDb<0) ) return;


  for(i=0; i<pParse->nTableLock; i++){
    p = &pParse->aTableLock[i];
    if( p->iDb==iDb && p->iTab==iTab ){
      p->isWriteLock = (p->isWriteLock || isWriteLock);
      return;
    }
  }
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
** Code an OP_TableLock instruction for each table locked by the
** statement (configured by calls to sqlite3TableLock()).
*/
static void codeTableLocks(Parse *pParse){
  int i;
  Vdbe *pVdbe; 

  if( 0==(pVdbe = sqlite3GetVdbe(pParse)) ){
    return;
  }

  for(i=0; i<pParse->nTableLock; i++){
    TableLock *p = &pParse->aTableLock[i];
    int p1 = p->iDb;
    sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock,
                      p->zName, P4_STATIC);
  }







|
|
<







96
97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
** Code an OP_TableLock instruction for each table locked by the
** statement (configured by calls to sqlite3TableLock()).
*/
static void codeTableLocks(Parse *pParse){
  int i;
  Vdbe *pVdbe; 

  pVdbe = sqlite3GetVdbe(pParse);
  assert( pVdbe!=0 ); /* sqlite3GetVdbe cannot fail: VDBE already allocated */


  for(i=0; i<pParse->nTableLock; i++){
    TableLock *p = &pParse->aTableLock[i];
    int p1 = p->iDb;
    sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock,
                      p->zName, P4_STATIC);
  }
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
      sqlite3VdbeAddOp2(v, OP_Goto, 0, pParse->cookieGoto);
    }
  }


  /* Get the VDBE program ready for execution
  */
  if( v && pParse->nErr==0 && !db->mallocFailed ){
#ifdef SQLITE_DEBUG
    FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
    sqlite3VdbeTrace(v, trace);
#endif
    assert( pParse->iCacheLevel==0 );  /* Disables and re-enables match */
    sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem,
                         pParse->nTab, pParse->explain);







|







177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
      sqlite3VdbeAddOp2(v, OP_Goto, 0, pParse->cookieGoto);
    }
  }


  /* Get the VDBE program ready for execution
  */
  if( v && ALWAYS(pParse->nErr==0) && !db->mallocFailed ){
#ifdef SQLITE_DEBUG
    FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
    sqlite3VdbeTrace(v, trace);
#endif
    assert( pParse->iCacheLevel==0 );  /* Disables and re-enables match */
    sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem,
                         pParse->nTab, pParse->explain);
323
324
325
326
327
328
329

330
331
332
333
334
335
336
337
338
339
340
341
Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
  Index *p = 0;
  int i;
  int nName = sqlite3Strlen30(zName);
  for(i=OMIT_TEMPDB; i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
    Schema *pSchema = db->aDb[j].pSchema;

    if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
    assert( pSchema || (j==1 && !db->aDb[1].pBt) );
    if( pSchema ){
      p = sqlite3HashFind(&pSchema->idxHash, zName, nName);
    }
    if( p ) break;
  }
  return p;
}

/*
** Reclaim the memory used by an index







>

<
<
|
<







319
320
321
322
323
324
325
326
327


328

329
330
331
332
333
334
335
Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
  Index *p = 0;
  int i;
  int nName = sqlite3Strlen30(zName);
  for(i=OMIT_TEMPDB; i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
    Schema *pSchema = db->aDb[j].pSchema;
    assert( pSchema );
    if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;


    p = sqlite3HashFind(&pSchema->idxHash, zName, nName);

    if( p ) break;
  }
  return p;
}

/*
** Reclaim the memory used by an index
374
375
376
377
378
379
380



381
382
383
384
385


386

387
388
389
390
391
392
393
394
void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){
  Index *pIndex;
  int len;
  Hash *pHash = &db->aDb[iDb].pSchema->idxHash;

  len = sqlite3Strlen30(zIdxName);
  pIndex = sqlite3HashInsert(pHash, zIdxName, len, 0);



  if( pIndex ){
    if( pIndex->pTable->pIndex==pIndex ){
      pIndex->pTable->pIndex = pIndex->pNext;
    }else{
      Index *p;


      for(p=pIndex->pTable->pIndex; p && p->pNext!=pIndex; p=p->pNext){}

      if( p && p->pNext==pIndex ){
        p->pNext = pIndex->pNext;
      }
    }
    freeIndex(pIndex);
  }
  db->flags |= SQLITE_InternChanges;
}







>
>
>
|




>
>
|
>
|







368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){
  Index *pIndex;
  int len;
  Hash *pHash = &db->aDb[iDb].pSchema->idxHash;

  len = sqlite3Strlen30(zIdxName);
  pIndex = sqlite3HashInsert(pHash, zIdxName, len, 0);
  /* Justification of ALWAYS():  This routine is only called from the
  ** OP_DropIndex opcode.  And there is no way that opcode will ever run
  ** unless the corresponding index is in the symbol table. */
  if( ALWAYS(pIndex) ){
    if( pIndex->pTable->pIndex==pIndex ){
      pIndex->pTable->pIndex = pIndex->pNext;
    }else{
      Index *p;
      /* Justification of ALWAYS();  The index must be on the list of
      ** indices. */
      p = pIndex->pTable->pIndex;
      while( ALWAYS(p) && p->pNext!=pIndex ){ p = p->pNext; }
      if( ALWAYS(p && p->pNext==pIndex) ){
        p->pNext = pIndex->pNext;
      }
    }
    freeIndex(pIndex);
  }
  db->flags |= SQLITE_InternChanges;
}
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445

  /* If one or more of the auxiliary database files has been closed,
  ** then remove them from the auxiliary database list.  We take the
  ** opportunity to do this here since we have just deleted all of the
  ** schema hash tables and therefore do not have to make any changes
  ** to any of those tables.
  */
  for(i=0; i<db->nDb; i++){
    struct Db *pDb = &db->aDb[i];
    if( pDb->pBt==0 ){
      if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux);
      pDb->pAux = 0;
    }
  }
  for(i=j=2; i<db->nDb; i++){
    struct Db *pDb = &db->aDb[i];
    if( pDb->pBt==0 ){
      sqlite3DbFree(db, pDb->zName);
      pDb->zName = 0;
      continue;
    }







<
<
<
<
<
<
<







425
426
427
428
429
430
431







432
433
434
435
436
437
438

  /* If one or more of the auxiliary database files has been closed,
  ** then remove them from the auxiliary database list.  We take the
  ** opportunity to do this here since we have just deleted all of the
  ** schema hash tables and therefore do not have to make any changes
  ** to any of those tables.
  */







  for(i=j=2; i<db->nDb; i++){
    struct Db *pDb = &db->aDb[i];
    if( pDb->pBt==0 ){
      sqlite3DbFree(db, pDb->zName);
      pDb->zName = 0;
      continue;
    }
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
  Token *pEnd,            /* The final ')' token in the CREATE TABLE */
  Select *pSelect         /* Select from a "CREATE ... AS SELECT" */
){
  Table *p;
  sqlite3 *db = pParse->db;
  int iDb;

  if( (pEnd==0 && pSelect==0) || pParse->nErr || db->mallocFailed ) {
    return;
  }
  p = pParse->pNewTable;
  if( p==0 ) return;

  assert( !db->init.busy || !pSelect );








|







1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
  Token *pEnd,            /* The final ')' token in the CREATE TABLE */
  Select *pSelect         /* Select from a "CREATE ... AS SELECT" */
){
  Table *p;
  sqlite3 *db = pParse->db;
  int iDb;

  if( (pEnd==0 && pSelect==0) || NEVER(pParse->nErr) || db->mallocFailed ) {
    return;
  }
  p = pParse->pNewTable;
  if( p==0 ) return;

  assert( !db->init.busy || !pSelect );

1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
*/
void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
  Table *pTab;
  Vdbe *v;
  sqlite3 *db = pParse->db;
  int iDb;

  if( pParse->nErr || db->mallocFailed ){
    goto exit_drop_table;
  }
  assert( pName->nSrc==1 );
  pTab = sqlite3LocateTable(pParse, isView, 
                            pName->a[0].zName, pName->a[0].zDatabase);

  if( pTab==0 ){







|







1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
*/
void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
  Table *pTab;
  Vdbe *v;
  sqlite3 *db = pParse->db;
  int iDb;

  if( NEVER(pParse->nErr) || db->mallocFailed ){
    goto exit_drop_table;
  }
  assert( pName->nSrc==1 );
  pTab = sqlite3LocateTable(pParse, isView, 
                            pName->a[0].zName, pName->a[0].zDatabase);

  if( pTab==0 ){
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
      nExtra -= nColl;
    }else{
      zColl = pTab->aCol[j].zColl;
      if( !zColl ){
        zColl = db->pDfltColl->zName;
      }
    }
    if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){
      goto exit_create_index;
    }
    pIndex->azColl[i] = zColl;
    requestedSortOrder = pListItem->sortOrder & sortOrderMask;
    pIndex->aSortOrder[i] = (u8)requestedSortOrder;
  }
  sqlite3DefaultRowEst(pIndex);







|







2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
      nExtra -= nColl;
    }else{
      zColl = pTab->aCol[j].zColl;
      if( !zColl ){
        zColl = db->pDfltColl->zName;
      }
    }
    if( NEVER(!db->init.busy && !sqlite3LocateCollSeq(pParse, zColl)) ){
      goto exit_create_index;
    }
    pIndex->azColl[i] = zColl;
    requestedSortOrder = pListItem->sortOrder & sortOrderMask;
    pIndex->aSortOrder[i] = (u8)requestedSortOrder;
  }
  sqlite3DefaultRowEst(pIndex);
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
  sqlite3 *db;
  Vdbe *v;
  int i;

  assert( pParse!=0 );
  db = pParse->db;
  assert( db!=0 );
  if( db->aDb[0].pBt==0 ) return;
  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){
    return;
  }
  v = sqlite3GetVdbe(pParse);
  if( !v ) return;
  if( type!=TK_DEFERRED ){
    for(i=0; i<db->nDb; i++){







|







3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
  sqlite3 *db;
  Vdbe *v;
  int i;

  assert( pParse!=0 );
  db = pParse->db;
  assert( db!=0 );
/*  if( db->aDb[0].pBt==0 ) return; */
  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){
    return;
  }
  v = sqlite3GetVdbe(pParse);
  if( !v ) return;
  if( type!=TK_DEFERRED ){
    for(i=0; i<db->nDb; i++){
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
void sqlite3CommitTransaction(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  assert( pParse!=0 );
  db = pParse->db;
  assert( db!=0 );
  if( db->aDb[0].pBt==0 ) return;
  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ){
    return;
  }
  v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 0);
  }
}

/*
** Rollback a transaction
*/
void sqlite3RollbackTransaction(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  assert( pParse!=0 );
  db = pParse->db;
  assert( db!=0 );
  if( db->aDb[0].pBt==0 ) return;
  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ){
    return;
  }
  v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 1);
  }







|



















|







3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
void sqlite3CommitTransaction(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  assert( pParse!=0 );
  db = pParse->db;
  assert( db!=0 );
/*  if( db->aDb[0].pBt==0 ) return; */
  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ){
    return;
  }
  v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 0);
  }
}

/*
** Rollback a transaction
*/
void sqlite3RollbackTransaction(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  assert( pParse!=0 );
  db = pParse->db;
  assert( db!=0 );
/*  if( db->aDb[0].pBt==0 ) return; */
  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ){
    return;
  }
  v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 1);
  }
3463
3464
3465
3466
3467
3468
3469

3470
3471

3472
3473
3474
3475
3476
3477
3478
3479
/*
** Check to see if pIndex uses the collating sequence pColl.  Return
** true if it does and false if it does not.
*/
#ifndef SQLITE_OMIT_REINDEX
static int collationMatch(const char *zColl, Index *pIndex){
  int i;

  for(i=0; i<pIndex->nColumn; i++){
    const char *z = pIndex->azColl[i];

    if( z==zColl || (z && zColl && 0==sqlite3StrICmp(z, zColl)) ){
      return 1;
    }
  }
  return 0;
}
#endif








>


>
|







3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
/*
** Check to see if pIndex uses the collating sequence pColl.  Return
** true if it does and false if it does not.
*/
#ifndef SQLITE_OMIT_REINDEX
static int collationMatch(const char *zColl, Index *pIndex){
  int i;
  assert( zColl!=0 );
  for(i=0; i<pIndex->nColumn; i++){
    const char *z = pIndex->azColl[i];
    assert( z!=0 );
    if( 0==sqlite3StrICmp(z, zColl) ){
      return 1;
    }
  }
  return 0;
}
#endif

Changes to src/sqliteInt.h.
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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.870 2009/05/11 20:53:29 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build













|







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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.871 2009/05/13 17:21:14 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
** databases may be attached.
*/
struct Db {
  char *zName;         /* Name of this database */
  Btree *pBt;          /* The B*Tree structure for this database file */
  u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
  u8 safety_level;     /* How aggressive at syncing data to disk */
  void *pAux;               /* Auxiliary data.  Usually NULL */
  void (*xFreeAux)(void*);  /* Routine to free pAux */
  Schema *pSchema;     /* Pointer to database schema (possibly shared) */
};

/*
** An instance of the following structure stores a database schema.
**
** If there are no virtual tables configured in this schema, the







<
<







614
615
616
617
618
619
620


621
622
623
624
625
626
627
** databases may be attached.
*/
struct Db {
  char *zName;         /* Name of this database */
  Btree *pBt;          /* The B*Tree structure for this database file */
  u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
  u8 safety_level;     /* How aggressive at syncing data to disk */


  Schema *pSchema;     /* Pointer to database schema (possibly shared) */
};

/*
** An instance of the following structure stores a database schema.
**
** If there are no virtual tables configured in this schema, the