/ Check-in [82b81f69]
Login

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

Overview
Comment:Rename DbSchema to "Schema" and SqliteTsd to "ThreadData". (CVS 2893)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:82b81f69c78cb3f54634d9aea4f6a838474dc5e5
User & Date: danielk1977 2006-01-09 06:29:48
Context
2006-01-09
09:59
Add a runtime interface to enable memory-management features. (CVS 2894) check-in: 44f8e313 user: danielk1977 tags: trunk
06:29
Rename DbSchema to "Schema" and SqliteTsd to "ThreadData". (CVS 2893) check-in: 82b81f69 user: danielk1977 tags: trunk
05:36
Minor changes so that OMIT_SHARED_CACHE works. (CVS 2892) check-in: cc963f8c user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/alter.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
...
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
...
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
**    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 used to generate VDBE code
** that implements the ALTER TABLE command.
**
** $Id: alter.c,v 1.14 2006/01/05 11:34:33 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The code in this file only exists if we are not omitting the
** ALTER TABLE logic from the build.
................................................................................
** table pTab has no temporary triggers, or is itself stored in the 
** temporary database, NULL is returned.
*/
static char *whereTempTriggers(Parse *pParse, Table *pTab){
  Trigger *pTrig;
  char *zWhere = 0;
  char *tmp = 0;
  const DbSchema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */

  /* If the table is not located in the temp-db (in which case NULL is 
  ** returned, loop through the tables list of triggers. For each trigger
  ** that is not part of the temp-db schema, add a clause to the WHERE 
  ** expression being built up in zWhere.
  */
  if( pTab->pSchema!=pTempSchema ){
................................................................................
  char *zName = 0;          /* NULL-terminated version of pName */ 
  sqlite3 *db = pParse->db; /* Database connection */
  Vdbe *v;
#ifndef SQLITE_OMIT_TRIGGER
  char *zWhere = 0;         /* Where clause to locate temp triggers */
#endif
  
  if( sqlite3Tsd()->mallocFailed ) goto exit_rename_table;
  assert( pSrc->nSrc==1 );

  pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
  if( !pTab ) goto exit_rename_table;
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
  zDb = db->aDb[iDb].zName;

................................................................................
  Vdbe *v;
  int iDb;
  int i;
  int nAlloc;

  /* Look up the table being altered. */
  assert( pParse->pNewTable==0 );
  if( sqlite3Tsd()->mallocFailed ) goto exit_begin_add_column;
  pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
  if( !pTab ) goto exit_begin_add_column;

  /* Make sure this is not an attempt to ALTER a view. */
  if( pTab->pSelect ){
    sqlite3ErrorMsg(pParse, "Cannot add a column to a view");
    goto exit_begin_add_column;







|







 







|







 







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
...
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
...
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
**    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 used to generate VDBE code
** that implements the ALTER TABLE command.
**
** $Id: alter.c,v 1.15 2006/01/09 06:29:48 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The code in this file only exists if we are not omitting the
** ALTER TABLE logic from the build.
................................................................................
** table pTab has no temporary triggers, or is itself stored in the 
** temporary database, NULL is returned.
*/
static char *whereTempTriggers(Parse *pParse, Table *pTab){
  Trigger *pTrig;
  char *zWhere = 0;
  char *tmp = 0;
  const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */

  /* If the table is not located in the temp-db (in which case NULL is 
  ** returned, loop through the tables list of triggers. For each trigger
  ** that is not part of the temp-db schema, add a clause to the WHERE 
  ** expression being built up in zWhere.
  */
  if( pTab->pSchema!=pTempSchema ){
................................................................................
  char *zName = 0;          /* NULL-terminated version of pName */ 
  sqlite3 *db = pParse->db; /* Database connection */
  Vdbe *v;
#ifndef SQLITE_OMIT_TRIGGER
  char *zWhere = 0;         /* Where clause to locate temp triggers */
#endif
  
  if( sqlite3ThreadData()->mallocFailed ) goto exit_rename_table;
  assert( pSrc->nSrc==1 );

  pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
  if( !pTab ) goto exit_rename_table;
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
  zDb = db->aDb[iDb].zName;

................................................................................
  Vdbe *v;
  int iDb;
  int i;
  int nAlloc;

  /* Look up the table being altered. */
  assert( pParse->pNewTable==0 );
  if( sqlite3ThreadData()->mallocFailed ) goto exit_begin_add_column;
  pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
  if( !pTab ) goto exit_begin_add_column;

  /* Make sure this is not an attempt to ALTER a view. */
  if( pTab->pSelect ){
    sqlite3ErrorMsg(pParse, "Cannot add a column to a view");
    goto exit_begin_add_column;

Changes to src/analyze.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code associated with the ANALYZE command.
**
** @(#) $Id: analyze.c,v 1.14 2006/01/08 18:10:18 drh Exp $
*/
#ifndef SQLITE_OMIT_ANALYZE
#include "sqliteInt.h"

/*
** This routine generates code that opens the sqlite_stat1 table on cursor
** iStatCur.
................................................................................
}

/*
** Generate code that will do an analysis of an entire database
*/
static void analyzeDatabase(Parse *pParse, int iDb){
  sqlite3 *db = pParse->db;
  DbSchema *pSchema = db->aDb[iDb].pSchema;    /* Schema of database iDb */
  HashElem *k;
  int iStatCur;
  int iMem;

  sqlite3BeginWriteOperation(pParse, 0, iDb);
  iStatCur = pParse->nTab++;
  openStatTable(pParse, iDb, iStatCur, 0);







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code associated with the ANALYZE command.
**
** @(#) $Id: analyze.c,v 1.15 2006/01/09 06:29:48 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_ANALYZE
#include "sqliteInt.h"

/*
** This routine generates code that opens the sqlite_stat1 table on cursor
** iStatCur.
................................................................................
}

/*
** Generate code that will do an analysis of an entire database
*/
static void analyzeDatabase(Parse *pParse, int iDb){
  sqlite3 *db = pParse->db;
  Schema *pSchema = db->aDb[iDb].pSchema;    /* Schema of database iDb */
  HashElem *k;
  int iStatCur;
  int iMem;

  sqlite3BeginWriteOperation(pParse, 0, iDb);
  iStatCur = pParse->nTab++;
  openStatTable(pParse, iDb, iStatCur, 0);

Changes to src/attach.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
...
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.40 2006/01/06 21:52:50 drh Exp $
*/
#include "sqliteInt.h"

/*
** Resolve an expression that was part of an ATTACH or DETACH statement. This
** is slightly different from resolving a normal SQL expression, because simple
** identifiers are treated as strings, not possible column names or aliases.
................................................................................
  int rc;
  NameContext sName;
  Vdbe *v;
  FuncDef *pFunc;
  sqlite3* db = pParse->db;

#ifndef SQLITE_OMIT_AUTHORIZATION
  assert( sqlite3Tsd()->mallocFailed || pAuthArg );
  if( pAuthArg ){
    char *zAuthArg = sqlite3NameFromToken(&pAuthArg->span);
    if( !zAuthArg ){
      goto attach_end;
    }
    rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
    sqliteFree(zAuthArg);
................................................................................
  }

  v = sqlite3GetVdbe(pParse);
  sqlite3ExprCode(pParse, pFilename);
  sqlite3ExprCode(pParse, pDbname);
  sqlite3ExprCode(pParse, pKey);

  assert(v || sqlite3Tsd()->mallocFailed);
  if( v ){
    sqlite3VdbeAddOp(v, OP_Function, 0, nFunc);
    pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0);
    sqlite3VdbeChangeP3(v, -1, (char *)pFunc, P3_FUNCDEF);

    /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
    ** statement only). For DETACH, set it to false (expire all existing







|







 







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
...
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.41 2006/01/09 06:29:48 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** Resolve an expression that was part of an ATTACH or DETACH statement. This
** is slightly different from resolving a normal SQL expression, because simple
** identifiers are treated as strings, not possible column names or aliases.
................................................................................
  int rc;
  NameContext sName;
  Vdbe *v;
  FuncDef *pFunc;
  sqlite3* db = pParse->db;

#ifndef SQLITE_OMIT_AUTHORIZATION
  assert( sqlite3ThreadData()->mallocFailed || pAuthArg );
  if( pAuthArg ){
    char *zAuthArg = sqlite3NameFromToken(&pAuthArg->span);
    if( !zAuthArg ){
      goto attach_end;
    }
    rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
    sqliteFree(zAuthArg);
................................................................................
  }

  v = sqlite3GetVdbe(pParse);
  sqlite3ExprCode(pParse, pFilename);
  sqlite3ExprCode(pParse, pDbname);
  sqlite3ExprCode(pParse, pKey);

  assert(v || sqlite3ThreadData()->mallocFailed);
  if( v ){
    sqlite3VdbeAddOp(v, OP_Function, 0, nFunc);
    pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0);
    sqlite3VdbeChangeP3(v, -1, (char *)pFunc, P3_FUNCDEF);

    /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
    ** statement only). For DETACH, set it to false (expire all existing

Changes to src/btree.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
341
342
343
344
345
346
347
348
349
350
351
352
353
354

355
356
357
358
359
360
361
...
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
...
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
...
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
...
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
...
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
....
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
....
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
....
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
....
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
....
2388
2389
2390
2391
2392
2393
2394






2395
2396
2397
2398
2399
2400
2401
....
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
** 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.
**
*************************************************************************
** $Id: btree.c,v 1.286 2006/01/09 05:36:27 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
................................................................................
  u16 usableSize;       /* Number of usable bytes on each page */
  int maxLocal;         /* Maximum local payload in non-LEAFDATA tables */
  int minLocal;         /* Minimum local payload in non-LEAFDATA tables */
  int maxLeaf;          /* Maximum local payload in a LEAFDATA table */
  int minLeaf;          /* Minimum local payload in a LEAFDATA table */
  BusyHandler *pBusyHandler;   /* Callback for when there is lock contention */
  u8 inTransaction;     /* Transaction state */
  BtShared *pNext;      /* Next in SqliteTsd.pBtree linked list */
  int nRef;             /* Number of references to this structure */
  int nTransaction;     /* Number of open transactions (read + write) */
  void *pSchema;        /* Pointer to space allocated by sqlite3BtreeSchema() */
  void (*xFreeSchema)(void*);  /* Destructor for BtShared.pSchema */
#ifndef SQLITE_OMIT_SHARED_CACHE
  BtLock *pLock;        /* List of locks held on this shared-btree struct */

#endif
};

/*
** An instance of the following structure is used to hold information
** about a cell.  The parseCellPtr() function fills in this structure
** based on information extract from the raw disk page.
................................................................................
/*
** Save the positions of all cursors except pExcept open on the table 
** with root-page iRoot. Usually, this is called just before cursor
** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()).
*/
static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
  BtCursor *p;
  if( sqlite3Tsd()->useSharedData ){
    for(p=pBt->pCursor; p; p=p->pNext){
      if( p!=pExcept && p->pgnoRoot==iRoot && p->eState==CURSOR_VALID ){
        int rc = saveCursorPosition(p);
        if( SQLITE_OK!=rc ){
          return rc;
        }
      }
................................................................................
** If the second argument argument - doSeek - is false, then instead of 
** returning the cursor to it's saved position, any saved position is deleted
** and the cursor state set to CURSOR_INVALID.
*/
static int restoreCursorPosition(BtCursor *pCur, int doSeek){
  int rc = SQLITE_OK;
  if( pCur->eState==CURSOR_REQUIRESEEK ){
    assert( sqlite3Tsd()->useSharedData );
    if( doSeek ){
      rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, &pCur->skip);
    }else{
      pCur->eState = CURSOR_INVALID;
    }
    if( rc==SQLITE_OK ){
      sqliteFree(pCur->pKey);
................................................................................
** SQLITE_LOCKED if not.
*/
static int queryTableLock(Btree *p, Pgno iTab, u8 eLock){
  BtShared *pBt = p->pBt;
  BtLock *pIter;

  /* This is a no-op if the shared-cache is not enabled */
  if( 0==sqlite3Tsd()->useSharedData ){
    return SQLITE_OK;
  }

  /* This (along with lockTable()) is where the ReadUncommitted flag is
  ** dealt with. If the caller is querying for a read-lock and the flag is
  ** set, it is unconditionally granted - even if there are write-locks
  ** on the table. If a write-lock is requested, the ReadUncommitted flag
................................................................................
*/
static int lockTable(Btree *p, Pgno iTable, u8 eLock){
  BtShared *pBt = p->pBt;
  BtLock *pLock = 0;
  BtLock *pIter;

  /* This is a no-op if the shared-cache is not enabled */
  if( 0==sqlite3Tsd()->useSharedData ){
    return SQLITE_OK;
  }

  assert( SQLITE_OK==queryTableLock(p, iTable, eLock) );

  /* If the read-uncommitted flag is set and a read-lock is requested,
  ** return early without adding an entry to the BtShared.pLock list. See
................................................................................
static void unlockAllTables(Btree *p){
  BtLock **ppIter = &p->pBt->pLock;

  /* If the shared-cache extension is not enabled, there should be no
  ** locks in the BtShared.pLock list, making this procedure a no-op. Assert
  ** that this is the case.
  */
  assert( sqlite3Tsd()->useSharedData || 0==*ppIter );

  while( *ppIter ){
    BtLock *pLock = *ppIter;
    if( pLock->pBtree==p ){
      *ppIter = pLock->pNext;
      sqliteFree(pLock);
    }else{
................................................................................
){
  BtShared *pBt;          /* Shared part of btree structure */
  Btree *p;               /* Handle to return */
  int rc;
  int nReserve;
  unsigned char zDbHeader[100];
#ifndef SQLITE_OMIT_SHARED_CACHE
  SqliteTsd *pTsd = sqlite3Tsd();
#endif

  /* Set the variable isMemdb to true for an in-memory database, or 
  ** false for a file-based database. This symbol is only required if
  ** either of the shared-data or autovacuum features are compiled 
  ** into the library.
  */
................................................................................
#endif
  }
  pBt->usableSize = pBt->pageSize - nReserve;
  assert( (pBt->pageSize & 7)==0 );  /* 8-byte alignment of pageSize */
  sqlite3pager_set_pagesize(pBt->pPager, pBt->pageSize);

#ifndef SQLITE_OMIT_SHARED_CACHE
  /* Add the new btree to the linked list starting at SqliteTsd.pBtree */
  if( pTsd->useSharedData && zFilename && !isMemdb ){
    pBt->pNext = pTsd->pBtree;
    pTsd->pBtree = pBt;
  }
#endif
  pBt->nRef = 1;
  *ppBtree = p;
................................................................................
** Close an open database and invalidate all cursors.
*/
int sqlite3BtreeClose(Btree *p){
  BtShared *pBt = p->pBt;
  BtCursor *pCur;

#ifndef SQLITE_OMIT_SHARED_CACHE
  SqliteTsd *pTsd = sqlite3Tsd();
#endif

  /* Drop any table-locks */
  unlockAllTables(p);

  /* Close all cursors opened via this handle.  */
  pCur = pBt->pCursor;
................................................................................

/*
** This routine is called prior to sqlite3pager_commit when a transaction
** is commited for an auto-vacuum database.
*/
static int autoVacuumCommit(BtShared *pBt, Pgno *nTrunc){
  Pager *pPager = pBt->pPager;
  Pgno nFreeList;   /* Number of pages remaining on the free-list. */
  int nPtrMap;      /* Number of pointer-map pages deallocated */
  Pgno origSize;  /* Pages in the database file */
  Pgno finSize;   /* Pages in the database file after truncation */
  int rc;           /* Return code */
  u8 eType;
  int pgsz = pBt->pageSize;  /* Page size for this database */
  Pgno iDbPage;              /* The database page to move */
  MemPage *pDbMemPage = 0;   /* "" */
  Pgno iPtrPage;             /* The page that contains a pointer to iDbPage */
  Pgno iFreePage;            /* The free-list page to move iDbPage to */
  MemPage *pFreeMemPage = 0; /* "" */
................................................................................
        goto autovacuum_out;
      }
      assert( iFreePage<=origSize );
    }while( iFreePage>finSize );
    releasePage(pFreeMemPage);
    pFreeMemPage = 0;







    rc = relocatePage(pBt, pDbMemPage, eType, iPtrPage, iFreePage);
    releasePage(pDbMemPage);
    if( rc!=SQLITE_OK ) goto autovacuum_out;
  }

  /* The entire free-list has been swapped to the end of the file. So
  ** truncate the database file to finSize pages and consider the
................................................................................
}

#ifndef SQLITE_OMIT_SHARED_CACHE
/*
** Enable the shared pager and schema features.
*/
int sqlite3_enable_shared_cache(int enable){
  SqliteTsd *pTsd = sqlite3Tsd();
  if( pTsd->pPager ){
    return SQLITE_MISUSE;
  }
  pTsd->useSharedData = enable;
  return SQLITE_OK;
}
#endif







|







 







<






>







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|
|
|
|
|







 







>
>
>
>
>
>







 







|







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
341
342
343
344
345
346
347

348
349
350
351
352
353
354
355
356
357
358
359
360
361
...
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
...
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
...
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
...
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
...
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
....
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
....
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
....
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
....
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
....
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
....
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
** 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.
**
*************************************************************************
** $Id: btree.c,v 1.287 2006/01/09 06:29:48 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
................................................................................
  u16 usableSize;       /* Number of usable bytes on each page */
  int maxLocal;         /* Maximum local payload in non-LEAFDATA tables */
  int minLocal;         /* Minimum local payload in non-LEAFDATA tables */
  int maxLeaf;          /* Maximum local payload in a LEAFDATA table */
  int minLeaf;          /* Minimum local payload in a LEAFDATA table */
  BusyHandler *pBusyHandler;   /* Callback for when there is lock contention */
  u8 inTransaction;     /* Transaction state */

  int nRef;             /* Number of references to this structure */
  int nTransaction;     /* Number of open transactions (read + write) */
  void *pSchema;        /* Pointer to space allocated by sqlite3BtreeSchema() */
  void (*xFreeSchema)(void*);  /* Destructor for BtShared.pSchema */
#ifndef SQLITE_OMIT_SHARED_CACHE
  BtLock *pLock;        /* List of locks held on this shared-btree struct */
  BtShared *pNext;      /* Next in ThreadData.pBtree linked list */
#endif
};

/*
** An instance of the following structure is used to hold information
** about a cell.  The parseCellPtr() function fills in this structure
** based on information extract from the raw disk page.
................................................................................
/*
** Save the positions of all cursors except pExcept open on the table 
** with root-page iRoot. Usually, this is called just before cursor
** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()).
*/
static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
  BtCursor *p;
  if( sqlite3ThreadData()->useSharedData ){
    for(p=pBt->pCursor; p; p=p->pNext){
      if( p!=pExcept && p->pgnoRoot==iRoot && p->eState==CURSOR_VALID ){
        int rc = saveCursorPosition(p);
        if( SQLITE_OK!=rc ){
          return rc;
        }
      }
................................................................................
** If the second argument argument - doSeek - is false, then instead of 
** returning the cursor to it's saved position, any saved position is deleted
** and the cursor state set to CURSOR_INVALID.
*/
static int restoreCursorPosition(BtCursor *pCur, int doSeek){
  int rc = SQLITE_OK;
  if( pCur->eState==CURSOR_REQUIRESEEK ){
    assert( sqlite3ThreadData()->useSharedData );
    if( doSeek ){
      rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, &pCur->skip);
    }else{
      pCur->eState = CURSOR_INVALID;
    }
    if( rc==SQLITE_OK ){
      sqliteFree(pCur->pKey);
................................................................................
** SQLITE_LOCKED if not.
*/
static int queryTableLock(Btree *p, Pgno iTab, u8 eLock){
  BtShared *pBt = p->pBt;
  BtLock *pIter;

  /* This is a no-op if the shared-cache is not enabled */
  if( 0==sqlite3ThreadData()->useSharedData ){
    return SQLITE_OK;
  }

  /* This (along with lockTable()) is where the ReadUncommitted flag is
  ** dealt with. If the caller is querying for a read-lock and the flag is
  ** set, it is unconditionally granted - even if there are write-locks
  ** on the table. If a write-lock is requested, the ReadUncommitted flag
................................................................................
*/
static int lockTable(Btree *p, Pgno iTable, u8 eLock){
  BtShared *pBt = p->pBt;
  BtLock *pLock = 0;
  BtLock *pIter;

  /* This is a no-op if the shared-cache is not enabled */
  if( 0==sqlite3ThreadData()->useSharedData ){
    return SQLITE_OK;
  }

  assert( SQLITE_OK==queryTableLock(p, iTable, eLock) );

  /* If the read-uncommitted flag is set and a read-lock is requested,
  ** return early without adding an entry to the BtShared.pLock list. See
................................................................................
static void unlockAllTables(Btree *p){
  BtLock **ppIter = &p->pBt->pLock;

  /* If the shared-cache extension is not enabled, there should be no
  ** locks in the BtShared.pLock list, making this procedure a no-op. Assert
  ** that this is the case.
  */
  assert( sqlite3ThreadData()->useSharedData || 0==*ppIter );

  while( *ppIter ){
    BtLock *pLock = *ppIter;
    if( pLock->pBtree==p ){
      *ppIter = pLock->pNext;
      sqliteFree(pLock);
    }else{
................................................................................
){
  BtShared *pBt;          /* Shared part of btree structure */
  Btree *p;               /* Handle to return */
  int rc;
  int nReserve;
  unsigned char zDbHeader[100];
#ifndef SQLITE_OMIT_SHARED_CACHE
  ThreadData *pTsd = sqlite3ThreadData();
#endif

  /* Set the variable isMemdb to true for an in-memory database, or 
  ** false for a file-based database. This symbol is only required if
  ** either of the shared-data or autovacuum features are compiled 
  ** into the library.
  */
................................................................................
#endif
  }
  pBt->usableSize = pBt->pageSize - nReserve;
  assert( (pBt->pageSize & 7)==0 );  /* 8-byte alignment of pageSize */
  sqlite3pager_set_pagesize(pBt->pPager, pBt->pageSize);

#ifndef SQLITE_OMIT_SHARED_CACHE
  /* Add the new btree to the linked list starting at ThreadData.pBtree */
  if( pTsd->useSharedData && zFilename && !isMemdb ){
    pBt->pNext = pTsd->pBtree;
    pTsd->pBtree = pBt;
  }
#endif
  pBt->nRef = 1;
  *ppBtree = p;
................................................................................
** Close an open database and invalidate all cursors.
*/
int sqlite3BtreeClose(Btree *p){
  BtShared *pBt = p->pBt;
  BtCursor *pCur;

#ifndef SQLITE_OMIT_SHARED_CACHE
  ThreadData *pTsd = sqlite3ThreadData();
#endif

  /* Drop any table-locks */
  unlockAllTables(p);

  /* Close all cursors opened via this handle.  */
  pCur = pBt->pCursor;
................................................................................

/*
** This routine is called prior to sqlite3pager_commit when a transaction
** is commited for an auto-vacuum database.
*/
static int autoVacuumCommit(BtShared *pBt, Pgno *nTrunc){
  Pager *pPager = pBt->pPager;
  Pgno nFreeList;            /* Number of pages remaining on the free-list. */
  int nPtrMap;               /* Number of pointer-map pages deallocated */
  Pgno origSize;             /* Pages in the database file */
  Pgno finSize;              /* Pages in the database file after truncation */
  int rc;                    /* Return code */
  u8 eType;
  int pgsz = pBt->pageSize;  /* Page size for this database */
  Pgno iDbPage;              /* The database page to move */
  MemPage *pDbMemPage = 0;   /* "" */
  Pgno iPtrPage;             /* The page that contains a pointer to iDbPage */
  Pgno iFreePage;            /* The free-list page to move iDbPage to */
  MemPage *pFreeMemPage = 0; /* "" */
................................................................................
        goto autovacuum_out;
      }
      assert( iFreePage<=origSize );
    }while( iFreePage>finSize );
    releasePage(pFreeMemPage);
    pFreeMemPage = 0;

    /* Relocate the page into the body of the file. Note that although the 
    ** page has moved within the database file, the pDbMemPage pointer 
    ** remains valid. This means that this function can run without
    ** invalidating cursors open on the btree. This is important in 
    ** shared-cache mode.
    */
    rc = relocatePage(pBt, pDbMemPage, eType, iPtrPage, iFreePage);
    releasePage(pDbMemPage);
    if( rc!=SQLITE_OK ) goto autovacuum_out;
  }

  /* The entire free-list has been swapped to the end of the file. So
  ** truncate the database file to finSize pages and consider the
................................................................................
}

#ifndef SQLITE_OMIT_SHARED_CACHE
/*
** Enable the shared pager and schema features.
*/
int sqlite3_enable_shared_cache(int enable){
  ThreadData *pTsd = sqlite3ThreadData();
  if( pTsd->pPager ){
    return SQLITE_MISUSE;
  }
  pTsd->useSharedData = enable;
  return SQLITE_OK;
}
#endif

Changes to src/build.c.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
..
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
..
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
...
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
...
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
....
1375
1376
1377
1378
1379
1380
1381
1382

1383
1384
1385
1386
1387
1388
1389
....
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
....
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
....
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
....
2216
2217
2218
2219
2220
2221
2222

2223

2224
2225
2226
2227
2228
2229
2230
....
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
....
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
....
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
....
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
....
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
....
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.370 2006/01/09 05:36:27 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
................................................................................
  int iTab, 
  u8 isWriteLock,  
  const char *zName
){
  int i;
  int nBytes;
  TableLock *p;
  SqliteTsd *pTsd = sqlite3Tsd();

  if( 0==pTsd->useSharedData ){
    return;
  }

  for(i=0; i<pParse->nTableLock; i++){
    p = &pParse->aTableLock[i];
................................................................................
/*
** 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; 
  assert( sqlite3Tsd()->useSharedData || pParse->nTableLock==0 );

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

  for(i=0; i<pParse->nTableLock; i++){
    TableLock *p = &pParse->aTableLock[i];
................................................................................
** Note that if an error occurred, it might be the case that
** no VDBE code was generated.
*/
void sqlite3FinishCoding(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  if( sqlite3Tsd()->mallocFailed ) return;
  if( pParse->nested ) return;
  if( !pParse->pVdbe ){
    if( pParse->rc==SQLITE_OK && pParse->nErr ){
      pParse->rc = SQLITE_ERROR;
    }
    return;
  }
................................................................................
*/
Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
  Index *p = 0;
  int i;
  assert( (db->flags & SQLITE_Initialized) || db->init.busy );
  for(i=OMIT_TEMPDB; i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
    DbSchema *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, strlen(zName)+1);
    }
    if( p ) break;
  }
................................................................................
  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 || sqlite3Tsd()->mallocFailed ) {

    return;
  }
  p = pParse->pNewTable;
  if( p==0 ) return;

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

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


  /* Add the table to the in-memory representation of the database.
  */
  if( db->init.busy && pParse->nErr==0 ){
    Table *pOld;
    FKey *pFKey; 
    DbSchema *pSchema = p->pSchema;
    pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, strlen(p->zName)+1,p);
    if( pOld ){
      assert( p==pOld );  /* Malloc must have failed inside HashInsert() */
      return;
    }
#ifndef SQLITE_OMIT_FOREIGN_KEY
    for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){
................................................................................
  /* Make a copy of the entire SELECT statement that defines the view.
  ** This will force all the Expr.token.z values to be dynamically
  ** allocated rather than point to the input string - which means that
  ** they will persist after the current sqlite3_exec() call returns.
  */
  p->pSelect = sqlite3SelectDup(pSelect);
  sqlite3SelectDelete(pSelect);
  if( sqlite3Tsd()->mallocFailed ){
    return;
  }
  if( !pParse->db->init.busy ){
    sqlite3ViewGetColumnNames(pParse, p);
  }

  /* Locate the end of the CREATE VIEW statement.  Make sEnd point to
................................................................................
*/
void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
  Table *pTab;
  Vdbe *v;
  sqlite3 *db = pParse->db;
  int iDb;

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

  if( pTab==0 ){
    if( noErr ){
      sqlite3ErrorClear(pParse);
    }
................................................................................
  int sortOrderMask;   /* 1 to honor DESC in index.  0 to ignore. */
  sqlite3 *db = pParse->db;
  Db *pDb;             /* The specific table containing the indexed database */
  int iDb;             /* Index of the database that is being written */
  Token *pName = 0;    /* Unqualified name of the index to create */
  struct ExprList_item *pListItem; /* For looping over pList */


  if( pParse->nErr || sqlite3Tsd()->mallocFailed ) goto exit_create_index;


  /*
  ** Find the table that is to be indexed.  Return early if not found.
  */
  if( pTblName!=0 ){

    /* Use the two-part index name to determine the database 
................................................................................

  /* 
  ** Allocate the index structure. 
  */
  nName = strlen(zName);
  pIndex = sqliteMalloc( sizeof(Index) + nName + 2 + sizeof(int) +
                        (sizeof(int)*2 + sizeof(CollSeq*) + 1)*pList->nExpr );
  if( sqlite3Tsd()->mallocFailed ) goto exit_create_index;
  pIndex->aiColumn = (int*)&pIndex->keyInfo.aColl[pList->nExpr];
  pIndex->aiRowEst = (unsigned*)&pIndex->aiColumn[pList->nExpr];
  pIndex->zName = (char*)&pIndex->aiRowEst[pList->nExpr+1];
  pIndex->keyInfo.aSortOrder = &pIndex->zName[nName+1];
  strcpy(pIndex->zName, zName);
  pIndex->pTable = pTab;
  pIndex->nColumn = pList->nExpr;
................................................................................
*/
void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
  Index *pIndex;
  Vdbe *v;
  sqlite3 *db = pParse->db;
  int iDb;

  if( pParse->nErr || sqlite3Tsd()->mallocFailed ){
    goto exit_drop_index;
  }
  assert( pName->nSrc==1 );
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    goto exit_drop_index;
  }
  pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
................................................................................

/*
** Assign cursors to all tables in a SrcList
*/
void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
  int i;
  struct SrcList_item *pItem;
  assert(pList || sqlite3Tsd()->mallocFailed);
  if( pList ){
    for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
      if( pItem->iCursor>=0 ) break;
      pItem->iCursor = pParse->nTab++;
      if( pItem->pSelect ){
        sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc);
      }
................................................................................
*/
void sqlite3BeginTransaction(Parse *pParse, int type){
  sqlite3 *db;
  Vdbe *v;
  int i;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite3Tsd()->mallocFailed ) 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++){
      sqlite3VdbeAddOp(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1);
................................................................................
** Commit a transaction
*/
void sqlite3CommitTransaction(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite3Tsd()->mallocFailed ) return;
  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ) return;

  v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 0);
  }
}
................................................................................
** Rollback a transaction
*/
void sqlite3RollbackTransaction(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite3Tsd()->mallocFailed ) return;
  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return;

  v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 1);
  }
}







|







 







|







 







|







 







|







 







|







 







|
>







 







|







 







|







 







|







 







>
|
>







 







|







 







|







 







|







 







|







 







|







 







|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
..
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
..
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
...
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
...
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
....
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
....
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
....
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
....
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
....
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
....
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
....
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
....
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
....
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
....
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
....
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.371 2006/01/09 06:29:48 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
................................................................................
  int iTab, 
  u8 isWriteLock,  
  const char *zName
){
  int i;
  int nBytes;
  TableLock *p;
  ThreadData *pTsd = sqlite3ThreadData();

  if( 0==pTsd->useSharedData ){
    return;
  }

  for(i=0; i<pParse->nTableLock; i++){
    p = &pParse->aTableLock[i];
................................................................................
/*
** 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; 
  assert( sqlite3ThreadData()->useSharedData || pParse->nTableLock==0 );

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

  for(i=0; i<pParse->nTableLock; i++){
    TableLock *p = &pParse->aTableLock[i];
................................................................................
** Note that if an error occurred, it might be the case that
** no VDBE code was generated.
*/
void sqlite3FinishCoding(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  if( sqlite3ThreadData()->mallocFailed ) return;
  if( pParse->nested ) return;
  if( !pParse->pVdbe ){
    if( pParse->rc==SQLITE_OK && pParse->nErr ){
      pParse->rc = SQLITE_ERROR;
    }
    return;
  }
................................................................................
*/
Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
  Index *p = 0;
  int i;
  assert( (db->flags & SQLITE_Initialized) || db->init.busy );
  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, strlen(zName)+1);
    }
    if( p ) break;
  }
................................................................................
  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 || sqlite3ThreadData()->mallocFailed ) {
    return;
  }
  p = pParse->pNewTable;
  if( p==0 ) return;

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

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


  /* Add the table to the in-memory representation of the database.
  */
  if( db->init.busy && pParse->nErr==0 ){
    Table *pOld;
    FKey *pFKey; 
    Schema *pSchema = p->pSchema;
    pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, strlen(p->zName)+1,p);
    if( pOld ){
      assert( p==pOld );  /* Malloc must have failed inside HashInsert() */
      return;
    }
#ifndef SQLITE_OMIT_FOREIGN_KEY
    for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){
................................................................................
  /* Make a copy of the entire SELECT statement that defines the view.
  ** This will force all the Expr.token.z values to be dynamically
  ** allocated rather than point to the input string - which means that
  ** they will persist after the current sqlite3_exec() call returns.
  */
  p->pSelect = sqlite3SelectDup(pSelect);
  sqlite3SelectDelete(pSelect);
  if( sqlite3ThreadData()->mallocFailed ){
    return;
  }
  if( !pParse->db->init.busy ){
    sqlite3ViewGetColumnNames(pParse, p);
  }

  /* Locate the end of the CREATE VIEW statement.  Make sEnd point to
................................................................................
*/
void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
  Table *pTab;
  Vdbe *v;
  sqlite3 *db = pParse->db;
  int iDb;

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

  if( pTab==0 ){
    if( noErr ){
      sqlite3ErrorClear(pParse);
    }
................................................................................
  int sortOrderMask;   /* 1 to honor DESC in index.  0 to ignore. */
  sqlite3 *db = pParse->db;
  Db *pDb;             /* The specific table containing the indexed database */
  int iDb;             /* Index of the database that is being written */
  Token *pName = 0;    /* Unqualified name of the index to create */
  struct ExprList_item *pListItem; /* For looping over pList */

  if( pParse->nErr || sqlite3ThreadData()->mallocFailed ){
    goto exit_create_index;
  }

  /*
  ** Find the table that is to be indexed.  Return early if not found.
  */
  if( pTblName!=0 ){

    /* Use the two-part index name to determine the database 
................................................................................

  /* 
  ** Allocate the index structure. 
  */
  nName = strlen(zName);
  pIndex = sqliteMalloc( sizeof(Index) + nName + 2 + sizeof(int) +
                        (sizeof(int)*2 + sizeof(CollSeq*) + 1)*pList->nExpr );
  if( sqlite3ThreadData()->mallocFailed ) goto exit_create_index;
  pIndex->aiColumn = (int*)&pIndex->keyInfo.aColl[pList->nExpr];
  pIndex->aiRowEst = (unsigned*)&pIndex->aiColumn[pList->nExpr];
  pIndex->zName = (char*)&pIndex->aiRowEst[pList->nExpr+1];
  pIndex->keyInfo.aSortOrder = &pIndex->zName[nName+1];
  strcpy(pIndex->zName, zName);
  pIndex->pTable = pTab;
  pIndex->nColumn = pList->nExpr;
................................................................................
*/
void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
  Index *pIndex;
  Vdbe *v;
  sqlite3 *db = pParse->db;
  int iDb;

  if( pParse->nErr || sqlite3ThreadData()->mallocFailed ){
    goto exit_drop_index;
  }
  assert( pName->nSrc==1 );
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    goto exit_drop_index;
  }
  pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
................................................................................

/*
** Assign cursors to all tables in a SrcList
*/
void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
  int i;
  struct SrcList_item *pItem;
  assert(pList || sqlite3ThreadData()->mallocFailed);
  if( pList ){
    for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
      if( pItem->iCursor>=0 ) break;
      pItem->iCursor = pParse->nTab++;
      if( pItem->pSelect ){
        sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc);
      }
................................................................................
*/
void sqlite3BeginTransaction(Parse *pParse, int type){
  sqlite3 *db;
  Vdbe *v;
  int i;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite3ThreadData()->mallocFailed ) 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++){
      sqlite3VdbeAddOp(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1);
................................................................................
** Commit a transaction
*/
void sqlite3CommitTransaction(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite3ThreadData()->mallocFailed ) return;
  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ) return;

  v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 0);
  }
}
................................................................................
** Rollback a transaction
*/
void sqlite3RollbackTransaction(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite3ThreadData()->mallocFailed ) return;
  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return;

  v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 1);
  }
}

Changes to src/callback.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains functions used to access the internal hash tables
** of user defined functions and collation sequences.
**
** $Id: callback.c,v 1.7 2005/12/14 22:51:17 drh Exp $
*/

#include "sqliteInt.h"

/*
** Invoke the 'collation needed' callback to request a collation sequence
** in the database text encoding of name zName, length nName.
................................................................................
      pColl[0].zName[nName] = 0;
      pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl);

      /* If a malloc() failure occured in sqlite3HashInsert(), it will 
      ** return the pColl pointer to be deleted (because it wasn't added
      ** to the hash table).
      */
      assert( !pDel || (sqlite3Tsd()->mallocFailed && pDel==pColl) );
      sqliteFree(pDel);
    }
  }
  return pColl;
}

/*







|







 







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains functions used to access the internal hash tables
** of user defined functions and collation sequences.
**
** $Id: callback.c,v 1.8 2006/01/09 06:29:48 danielk1977 Exp $
*/

#include "sqliteInt.h"

/*
** Invoke the 'collation needed' callback to request a collation sequence
** in the database text encoding of name zName, length nName.
................................................................................
      pColl[0].zName[nName] = 0;
      pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl);

      /* If a malloc() failure occured in sqlite3HashInsert(), it will 
      ** return the pColl pointer to be deleted (because it wasn't added
      ** to the hash table).
      */
      assert( !pDel || (sqlite3ThreadData()->mallocFailed && pDel==pColl) );
      sqliteFree(pDel);
    }
  }
  return pColl;
}

/*

Changes to src/delete.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
**    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
** in order to generate code for DELETE FROM statements.
**
** $Id: delete.c,v 1.115 2006/01/07 13:21:04 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
................................................................................

#ifndef SQLITE_OMIT_TRIGGER
  int isView;                  /* True if attempting to delete from a view */
  int triggers_exist = 0;      /* True if any triggers exist */
#endif

  sContext.pParse = 0;
  if( pParse->nErr || sqlite3Tsd()->mallocFailed ){
    goto delete_from_cleanup;
  }
  db = pParse->db;
  assert( pTabList->nSrc==1 );

  /* Locate the table which we want to delete.  This table has to be
  ** put in an SrcList structure because some of the subroutines we







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
**    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
** in order to generate code for DELETE FROM statements.
**
** $Id: delete.c,v 1.116 2006/01/09 06:29:48 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
................................................................................

#ifndef SQLITE_OMIT_TRIGGER
  int isView;                  /* True if attempting to delete from a view */
  int triggers_exist = 0;      /* True if any triggers exist */
#endif

  sContext.pParse = 0;
  if( pParse->nErr || sqlite3ThreadData()->mallocFailed ){
    goto delete_from_cleanup;
  }
  db = pParse->db;
  assert( pTabList->nSrc==1 );

  /* Locate the table which we want to delete.  This table has to be
  ** put in an SrcList structure because some of the subroutines we

Changes to src/expr.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
...
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
...
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
...
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
....
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.244 2006/01/05 11:34:34 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
/*
** Set the Expr.span field of the given expression to span all
** text between the two given tokens.
*/
void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
  assert( pRight!=0 );
  assert( pLeft!=0 );
  if( !sqlite3Tsd()->mallocFailed && pRight->z && pLeft->z ){
    assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 );
    if( pLeft->dyn==0 && pRight->dyn==0 ){
      pExpr->span.z = pLeft->z;
      pExpr->span.n = pRight->n + (pRight->z - pLeft->z);
    }else{
      pExpr->span.z = 0;
    }
................................................................................
    if( i>=pParse->nVarExpr ){
      pExpr->iTable = ++pParse->nVar;
      if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){
        pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10;
        sqlite3ReallocOrFree((void**)&pParse->apVarExpr,
                       pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) );
      }
      if( !sqlite3Tsd()->mallocFailed ){
        assert( pParse->apVarExpr!=0 );
        pParse->apVarExpr[pParse->nVarExpr++] = pExpr;
      }
    }
  } 
}

................................................................................
    if( pOldExpr->span.z!=0 && pNewExpr ){
      /* Always make a copy of the span for top-level expressions in the
      ** expression list.  The logic in SELECT processing that determines
      ** the names of columns in the result set needs this information */
      sqlite3TokenCopy(&pNewExpr->span, &pOldExpr->span);
    }
    assert( pNewExpr==0 || pNewExpr->span.z!=0 
            || pOldExpr->span.z==0 || sqlite3Tsd()->mallocFailed );
    pItem->zName = sqliteStrDup(pOldItem->zName);
    pItem->sortOrder = pOldItem->sortOrder;
    pItem->isAgg = pOldItem->isAgg;
    pItem->done = 0;
  }
  return pNew;
}
................................................................................
  struct SrcList_item *pMatch = 0;  /* The matching pSrcList item */
  NameContext *pTopNC = pNC;        /* First namecontext in the list */

  assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */
  zDb = sqlite3NameFromToken(pDbToken);
  zTab = sqlite3NameFromToken(pTableToken);
  zCol = sqlite3NameFromToken(pColumnToken);
  if( sqlite3Tsd()->mallocFailed ){
    goto lookupname_end;
  }

  pExpr->iTable = -1;
  while( pNC && cnt==0 ){
    ExprList *pEList;
    SrcList *pSrcList = pNC->pSrcList;
................................................................................
  ** If all of the above are false, then we can run this code just once
  ** save the results, and reuse the same result on subsequent invocations.
  */
  if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){
    int mem = pParse->nMem++;
    sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0);
    testAddr = sqlite3VdbeAddOp(v, OP_If, 0, 0);
    assert( testAddr>0 || sqlite3Tsd()->mallocFailed );
    sqlite3VdbeAddOp(v, OP_MemInt, 1, mem);
  }

  switch( pExpr->op ){
    case TK_IN: {
      char affinity;
      KeyInfo keyInfo;







|







 







|







 







|







 







|







 







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
...
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
...
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
...
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
....
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.245 2006/01/09 06:29:48 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
/*
** Set the Expr.span field of the given expression to span all
** text between the two given tokens.
*/
void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
  assert( pRight!=0 );
  assert( pLeft!=0 );
  if( !sqlite3ThreadData()->mallocFailed && pRight->z && pLeft->z ){
    assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 );
    if( pLeft->dyn==0 && pRight->dyn==0 ){
      pExpr->span.z = pLeft->z;
      pExpr->span.n = pRight->n + (pRight->z - pLeft->z);
    }else{
      pExpr->span.z = 0;
    }
................................................................................
    if( i>=pParse->nVarExpr ){
      pExpr->iTable = ++pParse->nVar;
      if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){
        pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10;
        sqlite3ReallocOrFree((void**)&pParse->apVarExpr,
                       pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) );
      }
      if( !sqlite3ThreadData()->mallocFailed ){
        assert( pParse->apVarExpr!=0 );
        pParse->apVarExpr[pParse->nVarExpr++] = pExpr;
      }
    }
  } 
}

................................................................................
    if( pOldExpr->span.z!=0 && pNewExpr ){
      /* Always make a copy of the span for top-level expressions in the
      ** expression list.  The logic in SELECT processing that determines
      ** the names of columns in the result set needs this information */
      sqlite3TokenCopy(&pNewExpr->span, &pOldExpr->span);
    }
    assert( pNewExpr==0 || pNewExpr->span.z!=0 
            || pOldExpr->span.z==0 || sqlite3ThreadData()->mallocFailed );
    pItem->zName = sqliteStrDup(pOldItem->zName);
    pItem->sortOrder = pOldItem->sortOrder;
    pItem->isAgg = pOldItem->isAgg;
    pItem->done = 0;
  }
  return pNew;
}
................................................................................
  struct SrcList_item *pMatch = 0;  /* The matching pSrcList item */
  NameContext *pTopNC = pNC;        /* First namecontext in the list */

  assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */
  zDb = sqlite3NameFromToken(pDbToken);
  zTab = sqlite3NameFromToken(pTableToken);
  zCol = sqlite3NameFromToken(pColumnToken);
  if( sqlite3ThreadData()->mallocFailed ){
    goto lookupname_end;
  }

  pExpr->iTable = -1;
  while( pNC && cnt==0 ){
    ExprList *pEList;
    SrcList *pSrcList = pNC->pSrcList;
................................................................................
  ** If all of the above are false, then we can run this code just once
  ** save the results, and reuse the same result on subsequent invocations.
  */
  if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){
    int mem = pParse->nMem++;
    sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0);
    testAddr = sqlite3VdbeAddOp(v, OP_If, 0, 0);
    assert( testAddr>0 || sqlite3ThreadData()->mallocFailed );
    sqlite3VdbeAddOp(v, OP_MemInt, 1, mem);
  }

  switch( pExpr->op ){
    case TK_IN: {
      char affinity;
      KeyInfo keyInfo;

Changes to src/insert.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
...
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
...
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
**    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 INSERT statements in SQLite.
**
** $Id: insert.c,v 1.154 2006/01/08 18:10:18 drh Exp $
*/
#include "sqliteInt.h"

/*
** Set P3 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
................................................................................
** Return non-zero if SELECT statement p opens the table with rootpage
** iTab in database iDb.  This is used to see if a statement of the form 
** "INSERT INTO <iDb, iTab> SELECT ..." can run without using temporary
** table for the results of the SELECT. 
**
** No checking is done for sub-selects that are part of expressions.
*/
static int selectReadsTable(Select *p, DbSchema *pSchema, int iTab){
  int i;
  struct SrcList_item *pItem;
  if( p->pSrc==0 ) return 0;
  for(i=0, pItem=p->pSrc->a; i<p->pSrc->nSrc; i++, pItem++){
    if( pItem->pSelect ){
      if( selectReadsTable(pItem->pSelect, pSchema, iTab) ) return 1;
    }else{
................................................................................
  int triggers_exist = 0;     /* True if there are FOR EACH ROW triggers */
#endif

#ifndef SQLITE_OMIT_AUTOINCREMENT
  int counterRowid;     /* Memory cell holding rowid of autoinc counter */
#endif

  if( pParse->nErr || sqlite3Tsd()->mallocFailed ) goto insert_cleanup;
  db = pParse->db;

  /* Locate the table into which we will be inserting new information.
  */
  assert( pTabList->nSrc==1 );
  zTab = pTabList->a[0].zName;
  if( zTab==0 ) goto insert_cleanup;
................................................................................
    int rc, iInitCode;
    iInitCode = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
    iSelectLoop = sqlite3VdbeCurrentAddr(v);
    iInsertBlock = sqlite3VdbeMakeLabel(v);

    /* Resolve the expressions in the SELECT statement and execute it. */
    rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock,0,0,0,0);
    if( rc || pParse->nErr || sqlite3Tsd()->mallocFailed ) goto insert_cleanup;

    iCleanup = sqlite3VdbeMakeLabel(v);
    sqlite3VdbeAddOp(v, OP_Goto, 0, iCleanup);
    assert( pSelect->pEList );
    nColumn = pSelect->pEList->nExpr;

    /* Set useTempTable to TRUE if the result of the SELECT statement







|







 







|







 







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
...
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
...
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
**    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 INSERT statements in SQLite.
**
** $Id: insert.c,v 1.155 2006/01/09 06:29:48 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** Set P3 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
................................................................................
** Return non-zero if SELECT statement p opens the table with rootpage
** iTab in database iDb.  This is used to see if a statement of the form 
** "INSERT INTO <iDb, iTab> SELECT ..." can run without using temporary
** table for the results of the SELECT. 
**
** No checking is done for sub-selects that are part of expressions.
*/
static int selectReadsTable(Select *p, Schema *pSchema, int iTab){
  int i;
  struct SrcList_item *pItem;
  if( p->pSrc==0 ) return 0;
  for(i=0, pItem=p->pSrc->a; i<p->pSrc->nSrc; i++, pItem++){
    if( pItem->pSelect ){
      if( selectReadsTable(pItem->pSelect, pSchema, iTab) ) return 1;
    }else{
................................................................................
  int triggers_exist = 0;     /* True if there are FOR EACH ROW triggers */
#endif

#ifndef SQLITE_OMIT_AUTOINCREMENT
  int counterRowid;     /* Memory cell holding rowid of autoinc counter */
#endif

  if( pParse->nErr || sqlite3ThreadData()->mallocFailed ) goto insert_cleanup;
  db = pParse->db;

  /* Locate the table into which we will be inserting new information.
  */
  assert( pTabList->nSrc==1 );
  zTab = pTabList->a[0].zName;
  if( zTab==0 ) goto insert_cleanup;
................................................................................
    int rc, iInitCode;
    iInitCode = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
    iSelectLoop = sqlite3VdbeCurrentAddr(v);
    iInsertBlock = sqlite3VdbeMakeLabel(v);

    /* Resolve the expressions in the SELECT statement and execute it. */
    rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock,0,0,0,0);
    if( rc || pParse->nErr || sqlite3ThreadData()->mallocFailed ) goto insert_cleanup;

    iCleanup = sqlite3VdbeMakeLabel(v);
    sqlite3VdbeAddOp(v, OP_Goto, 0, iCleanup);
    assert( pSelect->pEList );
    nColumn = pSelect->pEList->nExpr;

    /* Set useTempTable to TRUE if the result of the SELECT statement

Changes to src/legacy.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
**
*************************************************************************
** 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: legacy.c,v 1.9 2005/12/12 06:53:04 danielk1977 Exp $
*/

#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
................................................................................
    azCols = 0;
  }

exec_out:
  if( pStmt ) sqlite3_finalize(pStmt);
  if( azCols ) sqliteFree(azCols);

  if( sqlite3Tsd()->mallocFailed ){
    rc = SQLITE_NOMEM;
    sqlite3MallocClearFailed();
  }

  if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){
    *pzErrMsg = malloc(1+strlen(sqlite3_errmsg(db)));
    if( *pzErrMsg ){







|







 







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
**
*************************************************************************
** 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: legacy.c,v 1.10 2006/01/09 06:29:49 danielk1977 Exp $
*/

#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
................................................................................
    azCols = 0;
  }

exec_out:
  if( pStmt ) sqlite3_finalize(pStmt);
  if( azCols ) sqliteFree(azCols);

  if( sqlite3ThreadData()->mallocFailed ){
    rc = SQLITE_NOMEM;
    sqlite3MallocClearFailed();
  }

  if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){
    *pzErrMsg = malloc(1+strlen(sqlite3_errmsg(db)));
    if( *pzErrMsg ){

Changes to src/main.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
...
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
...
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
...
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
...
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
...
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
**
*************************************************************************
** 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.318 2006/01/06 21:52:50 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** The following constant value is used by the SQLITE_BIGENDIAN and
................................................................................

/*
** Return UTF-8 encoded English language explanation of the most recent
** error.
*/
const char *sqlite3_errmsg(sqlite3 *db){
  const char *z;
  if( sqlite3Tsd()->mallocFailed ){
    return sqlite3ErrStr(SQLITE_NOMEM);
  }
  if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
    return sqlite3ErrStr(SQLITE_MISUSE);
  }
  z = (char*)sqlite3_value_text(db->pErr);
  if( z==0 ){
................................................................................
    0, 'c', 0, 'a', 0, 'l', 0, 'l', 0, 'e', 0, 'd', 0, ' ', 
    0, 'o', 0, 'u', 0, 't', 0, ' ', 
    0, 'o', 0, 'f', 0, ' ', 
    0, 's', 0, 'e', 0, 'q', 0, 'u', 0, 'e', 0, 'n', 0, 'c', 0, 'e', 0, 0, 0
  };

  const void *z;
  if( sqlite3Tsd()->mallocFailed ){
    return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
  }
  if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
    return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
  }
  z = sqlite3_value_text16(db->pErr);
  if( z==0 ){
................................................................................
#endif /* SQLITE_OMIT_UTF16 */

/*
** Return the most recent error code generated by an SQLite routine. If NULL is
** passed to this function, we assume a malloc() failed during sqlite3_open().
*/
int sqlite3_errcode(sqlite3 *db){
  if( !db || sqlite3Tsd()->mallocFailed ){
    return SQLITE_NOMEM;
  }
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  return db->errCode;
}
................................................................................
  const char *zFilename, /* Database filename UTF-8 encoded */
  sqlite3 **ppDb         /* OUT: Returned database handle */
){
  sqlite3 *db;
  int rc;
  CollSeq *pColl;

  assert( !sqlite3Tsd()->mallocFailed );

  /* Allocate the sqlite data structure */
  db = sqliteMalloc( sizeof(sqlite3) );
  if( db==0 ) goto opendb_out;
  db->priorNewRowid = 0;
  db->magic = SQLITE_MAGIC_BUSY;
  db->nDb = 2;
................................................................................
  if( sqlite3_create_collation(db, "BINARY", SQLITE_UTF8, 0,binCollFunc) ||
      sqlite3_create_collation(db, "BINARY", SQLITE_UTF16, 0,binCollFunc) ||
      (db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0))==0 
  ){
    /* sqlite3_create_collation() is an external API. So the mallocFailed flag
    ** will have been cleared before returning. So set it explicitly here.
    */
    sqlite3Tsd()->mallocFailed = 1;
    db->magic = SQLITE_MAGIC_CLOSED;
    goto opendb_out;
  }

  /* Also add a UTF-8 case-insensitive collation sequence. */
  sqlite3_create_collation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc);

................................................................................
  zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
  if( zFilename8 ){
    rc = openDatabase(zFilename8, ppDb);
    if( rc==SQLITE_OK && *ppDb ){
      rc = sqlite3_exec(*ppDb, "PRAGMA encoding = 'UTF-16'", 0, 0, 0);
    }
  }else{
    assert( sqlite3Tsd()->mallocFailed );
    sqlite3MallocClearFailed();
  }
  sqlite3ValueFree(pVal);

  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */







|







 







|







 







|







 







|







 







|







 







|







 







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
...
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
...
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
...
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
...
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
...
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
**
*************************************************************************
** 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.319 2006/01/09 06:29:49 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** The following constant value is used by the SQLITE_BIGENDIAN and
................................................................................

/*
** Return UTF-8 encoded English language explanation of the most recent
** error.
*/
const char *sqlite3_errmsg(sqlite3 *db){
  const char *z;
  if( sqlite3ThreadData()->mallocFailed ){
    return sqlite3ErrStr(SQLITE_NOMEM);
  }
  if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
    return sqlite3ErrStr(SQLITE_MISUSE);
  }
  z = (char*)sqlite3_value_text(db->pErr);
  if( z==0 ){
................................................................................
    0, 'c', 0, 'a', 0, 'l', 0, 'l', 0, 'e', 0, 'd', 0, ' ', 
    0, 'o', 0, 'u', 0, 't', 0, ' ', 
    0, 'o', 0, 'f', 0, ' ', 
    0, 's', 0, 'e', 0, 'q', 0, 'u', 0, 'e', 0, 'n', 0, 'c', 0, 'e', 0, 0, 0
  };

  const void *z;
  if( sqlite3ThreadData()->mallocFailed ){
    return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
  }
  if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
    return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
  }
  z = sqlite3_value_text16(db->pErr);
  if( z==0 ){
................................................................................
#endif /* SQLITE_OMIT_UTF16 */

/*
** Return the most recent error code generated by an SQLite routine. If NULL is
** passed to this function, we assume a malloc() failed during sqlite3_open().
*/
int sqlite3_errcode(sqlite3 *db){
  if( !db || sqlite3ThreadData()->mallocFailed ){
    return SQLITE_NOMEM;
  }
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  return db->errCode;
}
................................................................................
  const char *zFilename, /* Database filename UTF-8 encoded */
  sqlite3 **ppDb         /* OUT: Returned database handle */
){
  sqlite3 *db;
  int rc;
  CollSeq *pColl;

  assert( !sqlite3ThreadData()->mallocFailed );

  /* Allocate the sqlite data structure */
  db = sqliteMalloc( sizeof(sqlite3) );
  if( db==0 ) goto opendb_out;
  db->priorNewRowid = 0;
  db->magic = SQLITE_MAGIC_BUSY;
  db->nDb = 2;
................................................................................
  if( sqlite3_create_collation(db, "BINARY", SQLITE_UTF8, 0,binCollFunc) ||
      sqlite3_create_collation(db, "BINARY", SQLITE_UTF16, 0,binCollFunc) ||
      (db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0))==0 
  ){
    /* sqlite3_create_collation() is an external API. So the mallocFailed flag
    ** will have been cleared before returning. So set it explicitly here.
    */
    sqlite3ThreadData()->mallocFailed = 1;
    db->magic = SQLITE_MAGIC_CLOSED;
    goto opendb_out;
  }

  /* Also add a UTF-8 case-insensitive collation sequence. */
  sqlite3_create_collation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc);

................................................................................
  zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
  if( zFilename8 ){
    rc = openDatabase(zFilename8, ppDb);
    if( rc==SQLITE_OK && *ppDb ){
      rc = sqlite3_exec(*ppDb, "PRAGMA encoding = 'UTF-16'", 0, 0, 0);
    }
  }else{
    assert( sqlite3ThreadData()->mallocFailed );
    sqlite3MallocClearFailed();
  }
  sqlite3ValueFree(pVal);

  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */

Changes to src/os_unix.c.

498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
....
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
....
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
){
  int rc;
  struct lockKey key1;
  struct openKey key2;
  struct stat statbuf;
  struct lockInfo *pLock;
  struct openCnt *pOpen;
  SqliteTsd *pTsd = sqlite3Tsd();
  rc = fstat(fd, &statbuf);
  if( rc!=0 ) return 1;

  /* Disable the sqlite3_release_memory() function */
  assert( !pTsd->disableReleaseMemory );
  pTsd->disableReleaseMemory = 1;

................................................................................
  return rc;
}

/*
** Close a file.
*/
static int unixClose(OsFile **pId){
  SqliteTsd *pTsd = sqlite3Tsd();
  unixFile *id = (unixFile*)*pId;
  if( !id ) return SQLITE_OK;
  if( CHECK_THREADID(id) ) return SQLITE_MISUSE;
  unixUnlock(*pId, NO_LOCK);
  if( id->dirfd>=0 ) close(id->dirfd);
  id->dirfd = -1;
  sqlite3OsEnterMutex();
................................................................................
*/
int sqlite3UnixInMutex(){
  return inMutex;
}

/*
** This function is called automatically when a thread exists to delete
** the threads SqliteTsd structure. 
**
** Because the SqliteTsd structure is required by higher level routines
** such as sqliteMalloc() we use OsFree() and OsMalloc() directly to
** allocate the thread specific data.
*/
#ifdef SQLITE_UNIX_THREADS
static void deleteTsd(void *pTsd){
  sqlite3OsFree(pTsd);
}







|







 







|







 







|

|







498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
....
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
....
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
){
  int rc;
  struct lockKey key1;
  struct openKey key2;
  struct stat statbuf;
  struct lockInfo *pLock;
  struct openCnt *pOpen;
  ThreadData *pTsd = sqlite3ThreadData();
  rc = fstat(fd, &statbuf);
  if( rc!=0 ) return 1;

  /* Disable the sqlite3_release_memory() function */
  assert( !pTsd->disableReleaseMemory );
  pTsd->disableReleaseMemory = 1;

................................................................................
  return rc;
}

/*
** Close a file.
*/
static int unixClose(OsFile **pId){
  ThreadData *pTsd = sqlite3ThreadData();
  unixFile *id = (unixFile*)*pId;
  if( !id ) return SQLITE_OK;
  if( CHECK_THREADID(id) ) return SQLITE_MISUSE;
  unixUnlock(*pId, NO_LOCK);
  if( id->dirfd>=0 ) close(id->dirfd);
  id->dirfd = -1;
  sqlite3OsEnterMutex();
................................................................................
*/
int sqlite3UnixInMutex(){
  return inMutex;
}

/*
** This function is called automatically when a thread exists to delete
** the threads ThreadData structure. 
**
** Because the ThreadData structure is required by higher level routines
** such as sqliteMalloc() we use OsFree() and OsMalloc() directly to
** allocate the thread specific data.
*/
#ifdef SQLITE_UNIX_THREADS
static void deleteTsd(void *pTsd){
  sqlite3OsFree(pTsd);
}

Changes to src/pager.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
....
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
....
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
....
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
....
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.231 2006/01/06 14:32:20 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include <assert.h>
#include <string.h>
................................................................................
  int i;
  int tempFile = 0;
  int memDb = 0;
  int readOnly = 0;
  int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
  int noReadlock = (flags & PAGER_NO_READLOCK)!=0;
  char zTemp[SQLITE_TEMPNAME_SIZE];
  SqliteTsd *pTsd = sqlite3Tsd();

  /* If malloc() has already failed return SQLITE_NOMEM. Before even
  ** testing for this, set *ppPager to NULL so the caller knows the pager
  ** structure was never allocated. 
  */
  *ppPager = 0;
  if( sqlite3Tsd()->mallocFailed ){
    return SQLITE_NOMEM;
  }
  memset(&fd, 0, sizeof(fd));

  /* Open the pager file and set zFullPathname to point at malloc()ed 
  ** memory containing the complete filename (i.e. including the directory).
  */
................................................................................
** is made to roll it back. If an error occurs during the rollback 
** a hot journal may be left in the filesystem but no error is returned
** to the caller.
*/
int sqlite3pager_close(Pager *pPager){
  PgHdr *pPg, *pNext;
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
  SqliteTsd *pTsd = sqlite3Tsd();
#endif

  switch( pPager->state ){
    case PAGER_RESERVED:
    case PAGER_SYNCED: 
    case PAGER_EXCLUSIVE: {
      /* We ignore any IO errors that occur during the rollback
................................................................................
  ** if( pPager->tempFile ){
  **   sqlite3OsDelete(pPager->zFilename);
  ** }
  */

#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
  /* Remove the pager from the linked list of pagers starting at 
  ** SqliteTsd.pPager.
  */
  if( pPager==pTsd->pPager ){
    pTsd->pPager = pPager->pNext;
  }else{
    Pager *pTmp;
    for(pTmp = pTsd->pPager; pTmp->pNext!=pPager; pTmp=pTmp->pNext);
    pTmp->pNext = pPager->pNext;
................................................................................
** nReq is the number of bytes of memory required. Once this much has
** been released, the function returns. A negative value for nReq means
** free as much memory as possible. The return value is the total number 
** of bytes of memory released.
*/
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
int sqlite3pager_release_memory(int nReq){
  SqliteTsd *pTsd = sqlite3Tsd();
  Pager *p;
  int nReleased = 0;
  int i;

  /* If the disableReleaseMemory memory flag is set, this operation is
  ** a no-op; zero bytes of memory are freed. The flag is set before
  ** malloc() is called while the global mutex (see sqlite3OsEnterMutex) 







|







 







|






|







 







|







 







|







 







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
....
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
....
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
....
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
....
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.232 2006/01/09 06:29:49 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include <assert.h>
#include <string.h>
................................................................................
  int i;
  int tempFile = 0;
  int memDb = 0;
  int readOnly = 0;
  int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
  int noReadlock = (flags & PAGER_NO_READLOCK)!=0;
  char zTemp[SQLITE_TEMPNAME_SIZE];
  ThreadData *pTsd = sqlite3ThreadData();

  /* If malloc() has already failed return SQLITE_NOMEM. Before even
  ** testing for this, set *ppPager to NULL so the caller knows the pager
  ** structure was never allocated. 
  */
  *ppPager = 0;
  if( sqlite3ThreadData()->mallocFailed ){
    return SQLITE_NOMEM;
  }
  memset(&fd, 0, sizeof(fd));

  /* Open the pager file and set zFullPathname to point at malloc()ed 
  ** memory containing the complete filename (i.e. including the directory).
  */
................................................................................
** is made to roll it back. If an error occurs during the rollback 
** a hot journal may be left in the filesystem but no error is returned
** to the caller.
*/
int sqlite3pager_close(Pager *pPager){
  PgHdr *pPg, *pNext;
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
  ThreadData *pTsd = sqlite3ThreadData();
#endif

  switch( pPager->state ){
    case PAGER_RESERVED:
    case PAGER_SYNCED: 
    case PAGER_EXCLUSIVE: {
      /* We ignore any IO errors that occur during the rollback
................................................................................
  ** if( pPager->tempFile ){
  **   sqlite3OsDelete(pPager->zFilename);
  ** }
  */

#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
  /* Remove the pager from the linked list of pagers starting at 
  ** ThreadData.pPager.
  */
  if( pPager==pTsd->pPager ){
    pTsd->pPager = pPager->pNext;
  }else{
    Pager *pTmp;
    for(pTmp = pTsd->pPager; pTmp->pNext!=pPager; pTmp=pTmp->pNext);
    pTmp->pNext = pPager->pNext;
................................................................................
** nReq is the number of bytes of memory required. Once this much has
** been released, the function returns. A negative value for nReq means
** free as much memory as possible. The return value is the total number 
** of bytes of memory released.
*/
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
int sqlite3pager_release_memory(int nReq){
  ThreadData *pTsd = sqlite3ThreadData();
  Pager *p;
  int nReleased = 0;
  int i;

  /* If the disableReleaseMemory memory flag is set, this operation is
  ** a no-op; zero bytes of memory are freed. The flag is set before
  ** malloc() is called while the global mutex (see sqlite3OsEnterMutex) 

Changes to src/prepare.c.

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
..
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
..
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
...
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
...
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
...
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
...
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
...
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
...
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
...
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the implementation of the sqlite3_prepare()
** interface, and routines that contribute to loading the database schema
** from disk.
**
** $Id: prepare.c,v 1.15 2006/01/06 21:52:50 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** Fill the InitData structure with an error message that indicates
** that the database is corrupt.
*/
static void corruptSchema(InitData *pData, const char *zExtra){
  if( !sqlite3Tsd()->mallocFailed ){
    sqlite3SetString(pData->pzErrMsg, "malformed database schema",
       zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0);
  }
}

/*
** This is the callback routine for the code that initializes the
................................................................................
**
*/
int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){
  InitData *pData = (InitData*)pInit;
  sqlite3 *db = pData->db;
  int iDb;

  if( sqlite3Tsd()->mallocFailed ){
    return SQLITE_NOMEM;
  }

  assert( argc==4 );
  if( argv==0 ) return 0;   /* Might happen if EMPTY_RESULT_CALLBACKS are on */
  if( argv[1]==0 || argv[3]==0 ){
    corruptSchema(pData, 0);
................................................................................
    assert( db->init.busy );
    db->init.iDb = iDb;
    db->init.newTnum = atoi(argv[1]);
    rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
    db->init.iDb = 0;
    if( SQLITE_OK!=rc ){
      if( rc==SQLITE_NOMEM ){
          sqlite3Tsd()->mallocFailed = 1;
      }else{
          corruptSchema(pData, zErr);
      }
      sqlite3_free(zErr);
      return rc;
    }
  }else{
................................................................................
#else
  #define temp_master_schema 0
#endif

  assert( iDb>=0 && iDb<db->nDb );

  if( 0==db->aDb[iDb].pSchema ){
    DbSchema *pS = sqlite3BtreeSchema(db->aDb[iDb].pBt, sizeof(DbSchema), 
        sqlite3SchemaFree);
    db->aDb[iDb].pSchema = pS;
    if( !pS ){
      return SQLITE_NOMEM;
    }else if( pS->file_format!=0 ){
      return SQLITE_OK;
    }else{
................................................................................
#ifndef SQLITE_OMIT_ANALYZE
    if( rc==SQLITE_OK ){
      sqlite3AnalysisLoad(db, iDb);
    }
#endif
    sqlite3BtreeCloseCursor(curMain);
  }
  if( sqlite3Tsd()->mallocFailed ){
    sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
    rc = SQLITE_NOMEM;
    sqlite3ResetInternalSchema(db, 0);
  }
  if( rc==SQLITE_OK ){
    DbSetProperty(db, iDb, DB_SchemaLoaded);
  }else{
................................................................................
    }
  }
  return allOk;
}

/*
** Free all resources held by the schema structure. The void* argument points
** at a DbSchema struct. This function does not call sqliteFree() on the 
** pointer itself, it just cleans up subsiduary resources (i.e. the contents
** of the schema hash tables).
*/
void sqlite3SchemaFree(void *p){
  Hash temp1;
  Hash temp2;
  HashElem *pElem;
  DbSchema *pSchema = (DbSchema *)p;

  temp1 = pSchema->tblHash;
  temp2 = pSchema->trigHash;
  sqlite3HashInit(&pSchema->trigHash, SQLITE_HASH_STRING, 0);
  sqlite3HashClear(&pSchema->aFKey);
  sqlite3HashClear(&pSchema->idxHash);
  for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
................................................................................
    sqlite3DeleteTable(0, pTab);
  }
  sqlite3HashClear(&temp1);
  pSchema->pSeqTab = 0;
  pSchema->flags &= ~DB_SchemaLoaded;
}

DbSchema *sqlite3SchemaGet(Btree *pBt){
  DbSchema * p;
  if( pBt ){
    p = (DbSchema *)sqlite3BtreeSchema(pBt,sizeof(DbSchema),sqlite3SchemaFree);
  }else{
    p = (DbSchema *)sqliteMalloc(sizeof(DbSchema));
  }
  if( p && 0==p->file_format ){
    sqlite3HashInit(&p->tblHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&p->idxHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&p->trigHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&p->aFKey, SQLITE_HASH_STRING, 1);
  }
  return p;
}

int sqlite3SchemaToIndex(sqlite3 *db, DbSchema *pSchema){
  int i = -1000000;

  /* If pSchema is NULL, then return -1000000. This happens when code in 
  ** expr.c is trying to resolve a reference to a transient table (i.e. one
  ** created by a sub-select). In this case the return value of this 
  ** function should never be used.
  **
................................................................................
  const char** pzTail       /* OUT: End of parsed string */
){
  Parse sParse;
  char *zErrMsg = 0;
  int rc = SQLITE_OK;
  int i;

  assert( !sqlite3Tsd()->mallocFailed );

  assert( ppStmt );
  *ppStmt = 0;
  if( sqlite3SafetyOn(db) ){
    return SQLITE_MISUSE;
  }

................................................................................
    }
  }
  
  memset(&sParse, 0, sizeof(sParse));
  sParse.db = db;
  sqlite3RunParser(&sParse, zSql, &zErrMsg);

  if( sqlite3Tsd()->mallocFailed ){
    sParse.rc = SQLITE_NOMEM;
  }
  if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
  if( sParse.checkSchema && !schemaIsValid(db) ){
    sParse.rc = SQLITE_SCHEMA;
  }
  if( sParse.rc==SQLITE_SCHEMA ){
................................................................................
  }else{
    sqlite3Error(db, rc, 0);
  }

  /* We must check for malloc failure last of all, in case malloc() failed
  ** inside of the sqlite3Error() call above or something.
  */
  if( sqlite3Tsd()->mallocFailed ){
    rc = SQLITE_NOMEM;
    sqlite3Error(db, rc, 0);
  }

  sqlite3MallocClearFailed();
  return rc;
}







|










|







 







|







 







|







 







|







 







|







 







|







|







 







|
|

|

|










|







 







|







 







|







 







|







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
..
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
..
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
...
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
...
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
...
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
...
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
...
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
...
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
...
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the implementation of the sqlite3_prepare()
** interface, and routines that contribute to loading the database schema
** from disk.
**
** $Id: prepare.c,v 1.16 2006/01/09 06:29:49 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** Fill the InitData structure with an error message that indicates
** that the database is corrupt.
*/
static void corruptSchema(InitData *pData, const char *zExtra){
  if( !sqlite3ThreadData()->mallocFailed ){
    sqlite3SetString(pData->pzErrMsg, "malformed database schema",
       zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0);
  }
}

/*
** This is the callback routine for the code that initializes the
................................................................................
**
*/
int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){
  InitData *pData = (InitData*)pInit;
  sqlite3 *db = pData->db;
  int iDb;

  if( sqlite3ThreadData()->mallocFailed ){
    return SQLITE_NOMEM;
  }

  assert( argc==4 );
  if( argv==0 ) return 0;   /* Might happen if EMPTY_RESULT_CALLBACKS are on */
  if( argv[1]==0 || argv[3]==0 ){
    corruptSchema(pData, 0);
................................................................................
    assert( db->init.busy );
    db->init.iDb = iDb;
    db->init.newTnum = atoi(argv[1]);
    rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
    db->init.iDb = 0;
    if( SQLITE_OK!=rc ){
      if( rc==SQLITE_NOMEM ){
          sqlite3ThreadData()->mallocFailed = 1;
      }else{
          corruptSchema(pData, zErr);
      }
      sqlite3_free(zErr);
      return rc;
    }
  }else{
................................................................................
#else
  #define temp_master_schema 0
#endif

  assert( iDb>=0 && iDb<db->nDb );

  if( 0==db->aDb[iDb].pSchema ){
    Schema *pS = sqlite3BtreeSchema(db->aDb[iDb].pBt, sizeof(Schema), 
        sqlite3SchemaFree);
    db->aDb[iDb].pSchema = pS;
    if( !pS ){
      return SQLITE_NOMEM;
    }else if( pS->file_format!=0 ){
      return SQLITE_OK;
    }else{
................................................................................
#ifndef SQLITE_OMIT_ANALYZE
    if( rc==SQLITE_OK ){
      sqlite3AnalysisLoad(db, iDb);
    }
#endif
    sqlite3BtreeCloseCursor(curMain);
  }
  if( sqlite3ThreadData()->mallocFailed ){
    sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
    rc = SQLITE_NOMEM;
    sqlite3ResetInternalSchema(db, 0);
  }
  if( rc==SQLITE_OK ){
    DbSetProperty(db, iDb, DB_SchemaLoaded);
  }else{
................................................................................
    }
  }
  return allOk;
}

/*
** Free all resources held by the schema structure. The void* argument points
** at a Schema struct. This function does not call sqliteFree() on the 
** pointer itself, it just cleans up subsiduary resources (i.e. the contents
** of the schema hash tables).
*/
void sqlite3SchemaFree(void *p){
  Hash temp1;
  Hash temp2;
  HashElem *pElem;
  Schema *pSchema = (Schema *)p;

  temp1 = pSchema->tblHash;
  temp2 = pSchema->trigHash;
  sqlite3HashInit(&pSchema->trigHash, SQLITE_HASH_STRING, 0);
  sqlite3HashClear(&pSchema->aFKey);
  sqlite3HashClear(&pSchema->idxHash);
  for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
................................................................................
    sqlite3DeleteTable(0, pTab);
  }
  sqlite3HashClear(&temp1);
  pSchema->pSeqTab = 0;
  pSchema->flags &= ~DB_SchemaLoaded;
}

Schema *sqlite3SchemaGet(Btree *pBt){
  Schema * p;
  if( pBt ){
    p = (Schema *)sqlite3BtreeSchema(pBt,sizeof(Schema),sqlite3SchemaFree);
  }else{
    p = (Schema *)sqliteMalloc(sizeof(Schema));
  }
  if( p && 0==p->file_format ){
    sqlite3HashInit(&p->tblHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&p->idxHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&p->trigHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&p->aFKey, SQLITE_HASH_STRING, 1);
  }
  return p;
}

int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
  int i = -1000000;

  /* If pSchema is NULL, then return -1000000. This happens when code in 
  ** expr.c is trying to resolve a reference to a transient table (i.e. one
  ** created by a sub-select). In this case the return value of this 
  ** function should never be used.
  **
................................................................................
  const char** pzTail       /* OUT: End of parsed string */
){
  Parse sParse;
  char *zErrMsg = 0;
  int rc = SQLITE_OK;
  int i;

  assert( !sqlite3ThreadData()->mallocFailed );

  assert( ppStmt );
  *ppStmt = 0;
  if( sqlite3SafetyOn(db) ){
    return SQLITE_MISUSE;
  }

................................................................................
    }
  }
  
  memset(&sParse, 0, sizeof(sParse));
  sParse.db = db;
  sqlite3RunParser(&sParse, zSql, &zErrMsg);

  if( sqlite3ThreadData()->mallocFailed ){
    sParse.rc = SQLITE_NOMEM;
  }
  if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
  if( sParse.checkSchema && !schemaIsValid(db) ){
    sParse.rc = SQLITE_SCHEMA;
  }
  if( sParse.rc==SQLITE_SCHEMA ){
................................................................................
  }else{
    sqlite3Error(db, rc, 0);
  }

  /* We must check for malloc failure last of all, in case malloc() failed
  ** inside of the sqlite3Error() call above or something.
  */
  if( sqlite3ThreadData()->mallocFailed ){
    rc = SQLITE_NOMEM;
    sqlite3Error(db, rc, 0);
  }

  sqlite3MallocClearFailed();
  return rc;
}

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
...
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
....
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
....
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
....
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
**    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.289 2006/01/09 00:09:02 drh Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
................................................................................
  /* If this is an EXPLAIN, skip this step */
  if( pParse->explain ){
    return;
  }
#endif

  assert( v!=0 );
  if( pParse->colNamesSet || v==0 || sqlite3Tsd()->mallocFailed ) return;
  pParse->colNamesSet = 1;
  fullNames = (db->flags & SQLITE_FullColNames)!=0;
  shortNames = (db->flags & SQLITE_ShortColNames)!=0;
  sqlite3VdbeSetNumCols(v, pEList->nExpr);
  for(i=0; i<pEList->nExpr; i++){
    Expr *p;
    p = pEList->a[i].pExpr;
................................................................................
      /* Use the original text of the column expression as its name */
      zName = sqlite3MPrintf("%T", &p->span);
    }else{
      /* If all else fails, make up a name */
      zName = sqlite3MPrintf("column%d", i+1);
    }
    sqlite3Dequote(zName);
    if( sqlite3Tsd()->mallocFailed ){
      sqliteFree(zName);
      sqlite3DeleteTable(0, pTab);
      return 0;
    }

    /* Make sure the column name is unique.  If the name is not unique,
    ** append a integer to the name so that it becomes unique.
................................................................................
static int prepSelectStmt(Parse *pParse, Select *p){
  int i, j, k, rc;
  SrcList *pTabList;
  ExprList *pEList;
  Table *pTab;
  struct SrcList_item *pFrom;

  if( p==0 || p->pSrc==0 || sqlite3Tsd()->mallocFailed ) return 1;
  pTabList = p->pSrc;
  pEList = p->pEList;

  /* Make sure cursor numbers have been assigned to all entries in
  ** the FROM clause of the SELECT statement.
  */
  sqlite3SrcListAssignCursors(pParse, p->pSrc);
................................................................................
  int isDistinct;        /* True if the DISTINCT keyword is present */
  int distinct;          /* Table to use for the distinct set */
  int rc = 1;            /* Value to return from this function */
  int addrSortIndex;     /* Address of an OP_OpenVirtual instruction */
  AggInfo sAggInfo;      /* Information used by aggregate queries */
  int iEnd;              /* Address of the end of the query */

  if( sqlite3Tsd()->mallocFailed || pParse->nErr || p==0 ) return 1;
  if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
  memset(&sAggInfo, 0, sizeof(sAggInfo));

#ifndef SQLITE_OMIT_COMPOUND_SELECT
  /* If there is are a sequence of queries, do the earlier ones first.
  */
  if( p->pPrior ){
................................................................................
    }
    sAggInfo.nAccumulator = sAggInfo.nColumn;
    for(i=0; i<sAggInfo.nFunc; i++){
      if( sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->pList) ){
        goto select_end;
      }
    }
    if( sqlite3Tsd()->mallocFailed ) goto select_end;

    /* Processing for aggregates with GROUP BY is very different and
    ** much more complex tha aggregates without a GROUP BY.
    */
    if( pGroupBy ){
      KeyInfo *pKeyInfo;  /* Keying information for the group by clause */








|







 







|







 







|







 







|







 







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
...
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
....
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
....
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
....
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
**    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.290 2006/01/09 06:29:49 danielk1977 Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
................................................................................
  /* If this is an EXPLAIN, skip this step */
  if( pParse->explain ){
    return;
  }
#endif

  assert( v!=0 );
  if( pParse->colNamesSet || v==0 || sqlite3ThreadData()->mallocFailed ) return;
  pParse->colNamesSet = 1;
  fullNames = (db->flags & SQLITE_FullColNames)!=0;
  shortNames = (db->flags & SQLITE_ShortColNames)!=0;
  sqlite3VdbeSetNumCols(v, pEList->nExpr);
  for(i=0; i<pEList->nExpr; i++){
    Expr *p;
    p = pEList->a[i].pExpr;
................................................................................
      /* Use the original text of the column expression as its name */
      zName = sqlite3MPrintf("%T", &p->span);
    }else{
      /* If all else fails, make up a name */
      zName = sqlite3MPrintf("column%d", i+1);
    }
    sqlite3Dequote(zName);
    if( sqlite3ThreadData()->mallocFailed ){
      sqliteFree(zName);
      sqlite3DeleteTable(0, pTab);
      return 0;
    }

    /* Make sure the column name is unique.  If the name is not unique,
    ** append a integer to the name so that it becomes unique.
................................................................................
static int prepSelectStmt(Parse *pParse, Select *p){
  int i, j, k, rc;
  SrcList *pTabList;
  ExprList *pEList;
  Table *pTab;
  struct SrcList_item *pFrom;

  if( p==0 || p->pSrc==0 || sqlite3ThreadData()->mallocFailed ) return 1;
  pTabList = p->pSrc;
  pEList = p->pEList;

  /* Make sure cursor numbers have been assigned to all entries in
  ** the FROM clause of the SELECT statement.
  */
  sqlite3SrcListAssignCursors(pParse, p->pSrc);
................................................................................
  int isDistinct;        /* True if the DISTINCT keyword is present */
  int distinct;          /* Table to use for the distinct set */
  int rc = 1;            /* Value to return from this function */
  int addrSortIndex;     /* Address of an OP_OpenVirtual instruction */
  AggInfo sAggInfo;      /* Information used by aggregate queries */
  int iEnd;              /* Address of the end of the query */

  if( sqlite3ThreadData()->mallocFailed || pParse->nErr || p==0 ) return 1;
  if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
  memset(&sAggInfo, 0, sizeof(sAggInfo));

#ifndef SQLITE_OMIT_COMPOUND_SELECT
  /* If there is are a sequence of queries, do the earlier ones first.
  */
  if( p->pPrior ){
................................................................................
    }
    sAggInfo.nAccumulator = sAggInfo.nColumn;
    for(i=0; i<sAggInfo.nFunc; i++){
      if( sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->pList) ){
        goto select_end;
      }
    }
    if( sqlite3ThreadData()->mallocFailed ) goto select_end;

    /* Processing for aggregates with GROUP BY is very different and
    ** much more complex tha aggregates without a GROUP BY.
    */
    if( pGroupBy ){
      KeyInfo *pKeyInfo;  /* Keying information for the group by clause */

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
...
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
...
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
...
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
...
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
...
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
...
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
...
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
....
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
....
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
**    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.453 2006/01/07 13:21:04 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Extra interface definitions for those who need them
*/
................................................................................
** only.  They only work if SQLITE_MEMDEBUG is defined.
*/
extern int sqlite3_nMalloc;      /* Number of sqliteMalloc() calls */
extern int sqlite3_nFree;        /* Number of sqliteFree() calls */
extern int sqlite3_iMallocFail;  /* Fail sqliteMalloc() after this many calls */
extern int sqlite3_iMallocReset; /* Set iMallocFail to this when it reaches 0 */
#define ENTER_MALLOC (\
  sqlite3Tsd()->zFile = __FILE__, sqlite3Tsd()->iLine = __LINE__ \
)
#define sqliteMalloc(x)          (ENTER_MALLOC, sqlite3Malloc(x))
#define sqliteMallocRaw(x)       (ENTER_MALLOC, sqlite3MallocRaw(x))
#define sqliteRealloc(x,y)       (ENTER_MALLOC, sqlite3Realloc(x,y))
#define sqliteStrDup(x)          (ENTER_MALLOC, sqlite3StrDup(x))
#define sqliteStrNDup(x,y)       (ENTER_MALLOC, sqlite3StrNDup(x,y))
#define sqliteReallocOrFree(x,y) (ENTER_MALLOC, sqlite3ReallocOrFree(x,y))
................................................................................

#define sqliteFree(x)          sqlite3FreeX(x)
#define sqliteAllocSize(x)     sqlite3AllocSize(x)

/*
** An instance of this structure is allocated for each thread that uses SQLite.
*/
struct SqliteTsd {
  u8 isInit;               /* True if structure has been initialised */
  u8 mallocFailed;         /* True after a malloc() has failed */
  u8 disableReleaseMemory; /* True to make sqlite3_release_memory() a no-op */

#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
  i64 nSoftHeapLimit;      /* Suggested max mem allocation.  No limit if <0 */
  i64 nAlloc;              /* Number of bytes currently allocated */
................................................................................

#ifndef SQLITE_OMIT_SHARED_CACHE
  u8 useSharedData;        /* True if shared pagers and schemas are enabled */
  BtShared *pBtree;        /* Linked list of all currently open BTrees */
#endif

#ifdef SQLITE_MEMDEBUG
  i64 nMaxAlloc;           /* High water mark of SqliteTsd.nAlloc */
  int mallocAllowed;       /* assert() in sqlite3Malloc() if not set */
  int isFail;              /* True if all malloc() calls should fail */
  const char *zFile;       /* Filename to associate debugging info with */
  int iLine;               /* Line number to associate debugging info with */
  void *pFirst;            /* Pointer to linked list of allocations */
#endif
};
................................................................................
** Forward references to structures
*/
typedef struct AggInfo AggInfo;
typedef struct AuthContext AuthContext;
typedef struct CollSeq CollSeq;
typedef struct Column Column;
typedef struct Db Db;
typedef struct DbSchema DbSchema;
typedef struct Expr Expr;
typedef struct ExprList ExprList;
typedef struct FKey FKey;
typedef struct FuncDef FuncDef;
typedef struct IdList IdList;
typedef struct Index Index;
typedef struct KeyClass KeyClass;
typedef struct KeyInfo KeyInfo;
typedef struct NameContext NameContext;
typedef struct Parse Parse;
typedef struct Select Select;
typedef struct SrcList SrcList;
typedef struct SqliteTsd SqliteTsd;
typedef struct Table Table;
typedef struct TableLock TableLock;
typedef struct Token Token;
typedef struct TriggerStack TriggerStack;
typedef struct TriggerStep TriggerStep;
typedef struct Trigger Trigger;
typedef struct WhereInfo WhereInfo;
................................................................................
  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 synching data to disk */
  int cache_size;      /* Number of pages to use in the cache */
  void *pAux;               /* Auxiliary data.  Usually NULL */
  void (*xFreeAux)(void*);  /* Routine to free pAux */
  DbSchema *pSchema;   /* Pointer to database schema (possibly shared) */
};

/*
** An instance of the following structure stores a database schema.
*/
struct DbSchema {
  int schema_cookie;   /* Database schema version number for this file */
  Hash tblHash;        /* All tables indexed by name */
  Hash idxHash;        /* All (named) indices indexed by name */
  Hash trigHash;       /* All triggers indexed by name */
  Hash aFKey;          /* Foreign keys indexed by to-table */
  Table *pSeqTab;      /* The sqlite_sequence table used by AUTOINCREMENT */
  u8 file_format;      /* Schema format version for this file */
................................................................................
  char *zColAff;     /* String defining the affinity of each column */
#ifndef SQLITE_OMIT_CHECK
  Expr *pCheck;      /* The AND of all CHECK constraints */
#endif
#ifndef SQLITE_OMIT_ALTERTABLE
  int addColOffset;  /* Offset in CREATE TABLE statement to add a new column */
#endif
  DbSchema *pSchema;
};

/*
** Each foreign key constraint is an instance of the following structure.
**
** A foreign key is associated with two tables.  The "from" table is
** the table that contains the REFERENCES clause that creates the foreign
................................................................................
  Table *pTable;   /* The SQL table being indexed */
  int tnum;        /* Page containing root of this index in database file */
  u8 onError;      /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  u8 autoIndex;    /* True if is automatically created (ex: by UNIQUE) */
  // u8 iDb;          /* Index in sqlite.aDb[] of where this index is stored */
  char *zColAff;   /* String defining the affinity of each column */
  Index *pNext;    /* The next index associated with the same table */
  DbSchema *pSchema;
  KeyInfo keyInfo; /* Info on how to order keys.  MUST BE LAST */
};

/*
** Each token coming out of the lexer is an instance of
** this structure.  Tokens are also used as part of an expression.
**
................................................................................
                         ** iColumn-th field of the iTable-th table. */
  AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
  int iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
  int iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
  Select *pSelect;       /* When the expression is a sub-select.  Also the
                         ** right side of "<expr> IN (<select>)" */
  Table *pTab;           /* Table for OP_Column expressions. */
  DbSchema *pSchema;
};

/*
** The following are the meanings of bits in the Expr.flags field.
*/
#define EP_FromJoin     0x01  /* Originated in ON or USING clause of a join */
#define EP_Agg          0x02  /* Contains one or more aggregate functions */
................................................................................
  u8 op;                  /* One of TK_DELETE, TK_UPDATE, TK_INSERT         */
  u8 tr_tm;               /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
  Expr *pWhen;            /* The WHEN clause of the expresion (may be NULL) */
  IdList *pColumns;       /* If this is an UPDATE OF <column-list> trigger,
                             the <column-list> is stored here */
  int foreach;            /* One of TK_ROW or TK_STATEMENT */
  Token nameToken;        /* Token containing zName. Use during parsing only */
  DbSchema *pSchema;      /* Schema containing the trigger */
  DbSchema *pTabSchema;   /* Schema containing the table */
  TriggerStep *step_list; /* Link list of trigger program steps             */
  Trigger *pNext;         /* Next trigger associated with the table */
};

/*
** A trigger is either a BEFORE or an AFTER trigger.  The following constants
** determine which. 
................................................................................
void sqlite3Analyze(Parse*, Token*, Token*);
int sqlite3InvokeBusyHandler(BusyHandler*);
int sqlite3FindDb(sqlite3*, Token*);
void sqlite3AnalysisLoad(sqlite3*,int iDB);
void sqlite3DefaultRowEst(Index*);
void sqlite3RegisterLikeFunctions(sqlite3*, int);
int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
SqliteTsd *sqlite3Tsd();
void sqlite3AttachFunctions(sqlite3 *);
void sqlite3MinimumFileFormat(Parse*, int, int);
void sqlite3SchemaFree(void *);
DbSchema *sqlite3SchemaGet(Btree *);
int sqlite3SchemaToIndex(sqlite3 *db, DbSchema *);

#ifndef SQLITE_OMIT_SHARED_CACHE
  void sqlite3TableLock(Parse *, int, int, u8, const char *);
#else
  #define sqlite3TableLock(v,w,x,y,z)
#endif








|







 







|







 







|







 







|







 







|












|







 







|





|







 







|







 







|







 







|







 







|
|







 







|



|
|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
...
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
...
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
...
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
...
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
...
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
...
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
...
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
....
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
....
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
**    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.454 2006/01/09 06:29:49 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Extra interface definitions for those who need them
*/
................................................................................
** only.  They only work if SQLITE_MEMDEBUG is defined.
*/
extern int sqlite3_nMalloc;      /* Number of sqliteMalloc() calls */
extern int sqlite3_nFree;        /* Number of sqliteFree() calls */
extern int sqlite3_iMallocFail;  /* Fail sqliteMalloc() after this many calls */
extern int sqlite3_iMallocReset; /* Set iMallocFail to this when it reaches 0 */
#define ENTER_MALLOC (\
  sqlite3ThreadData()->zFile = __FILE__, sqlite3ThreadData()->iLine = __LINE__ \
)
#define sqliteMalloc(x)          (ENTER_MALLOC, sqlite3Malloc(x))
#define sqliteMallocRaw(x)       (ENTER_MALLOC, sqlite3MallocRaw(x))
#define sqliteRealloc(x,y)       (ENTER_MALLOC, sqlite3Realloc(x,y))
#define sqliteStrDup(x)          (ENTER_MALLOC, sqlite3StrDup(x))
#define sqliteStrNDup(x,y)       (ENTER_MALLOC, sqlite3StrNDup(x,y))
#define sqliteReallocOrFree(x,y) (ENTER_MALLOC, sqlite3ReallocOrFree(x,y))
................................................................................

#define sqliteFree(x)          sqlite3FreeX(x)
#define sqliteAllocSize(x)     sqlite3AllocSize(x)

/*
** An instance of this structure is allocated for each thread that uses SQLite.
*/
struct ThreadData {
  u8 isInit;               /* True if structure has been initialised */
  u8 mallocFailed;         /* True after a malloc() has failed */
  u8 disableReleaseMemory; /* True to make sqlite3_release_memory() a no-op */

#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
  i64 nSoftHeapLimit;      /* Suggested max mem allocation.  No limit if <0 */
  i64 nAlloc;              /* Number of bytes currently allocated */
................................................................................

#ifndef SQLITE_OMIT_SHARED_CACHE
  u8 useSharedData;        /* True if shared pagers and schemas are enabled */
  BtShared *pBtree;        /* Linked list of all currently open BTrees */
#endif

#ifdef SQLITE_MEMDEBUG
  i64 nMaxAlloc;           /* High water mark of ThreadData.nAlloc */
  int mallocAllowed;       /* assert() in sqlite3Malloc() if not set */
  int isFail;              /* True if all malloc() calls should fail */
  const char *zFile;       /* Filename to associate debugging info with */
  int iLine;               /* Line number to associate debugging info with */
  void *pFirst;            /* Pointer to linked list of allocations */
#endif
};
................................................................................
** Forward references to structures
*/
typedef struct AggInfo AggInfo;
typedef struct AuthContext AuthContext;
typedef struct CollSeq CollSeq;
typedef struct Column Column;
typedef struct Db Db;
typedef struct Schema Schema;
typedef struct Expr Expr;
typedef struct ExprList ExprList;
typedef struct FKey FKey;
typedef struct FuncDef FuncDef;
typedef struct IdList IdList;
typedef struct Index Index;
typedef struct KeyClass KeyClass;
typedef struct KeyInfo KeyInfo;
typedef struct NameContext NameContext;
typedef struct Parse Parse;
typedef struct Select Select;
typedef struct SrcList SrcList;
typedef struct ThreadData ThreadData;
typedef struct Table Table;
typedef struct TableLock TableLock;
typedef struct Token Token;
typedef struct TriggerStack TriggerStack;
typedef struct TriggerStep TriggerStep;
typedef struct Trigger Trigger;
typedef struct WhereInfo WhereInfo;
................................................................................
  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 synching data to disk */
  int cache_size;      /* Number of pages to use in the cache */
  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.
*/
struct Schema {
  int schema_cookie;   /* Database schema version number for this file */
  Hash tblHash;        /* All tables indexed by name */
  Hash idxHash;        /* All (named) indices indexed by name */
  Hash trigHash;       /* All triggers indexed by name */
  Hash aFKey;          /* Foreign keys indexed by to-table */
  Table *pSeqTab;      /* The sqlite_sequence table used by AUTOINCREMENT */
  u8 file_format;      /* Schema format version for this file */
................................................................................
  char *zColAff;     /* String defining the affinity of each column */
#ifndef SQLITE_OMIT_CHECK
  Expr *pCheck;      /* The AND of all CHECK constraints */
#endif
#ifndef SQLITE_OMIT_ALTERTABLE
  int addColOffset;  /* Offset in CREATE TABLE statement to add a new column */
#endif
  Schema *pSchema;
};

/*
** Each foreign key constraint is an instance of the following structure.
**
** A foreign key is associated with two tables.  The "from" table is
** the table that contains the REFERENCES clause that creates the foreign
................................................................................
  Table *pTable;   /* The SQL table being indexed */
  int tnum;        /* Page containing root of this index in database file */
  u8 onError;      /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  u8 autoIndex;    /* True if is automatically created (ex: by UNIQUE) */
  // u8 iDb;          /* Index in sqlite.aDb[] of where this index is stored */
  char *zColAff;   /* String defining the affinity of each column */
  Index *pNext;    /* The next index associated with the same table */
  Schema *pSchema;
  KeyInfo keyInfo; /* Info on how to order keys.  MUST BE LAST */
};

/*
** Each token coming out of the lexer is an instance of
** this structure.  Tokens are also used as part of an expression.
**
................................................................................
                         ** iColumn-th field of the iTable-th table. */
  AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
  int iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
  int iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
  Select *pSelect;       /* When the expression is a sub-select.  Also the
                         ** right side of "<expr> IN (<select>)" */
  Table *pTab;           /* Table for OP_Column expressions. */
  Schema *pSchema;
};

/*
** The following are the meanings of bits in the Expr.flags field.
*/
#define EP_FromJoin     0x01  /* Originated in ON or USING clause of a join */
#define EP_Agg          0x02  /* Contains one or more aggregate functions */
................................................................................
  u8 op;                  /* One of TK_DELETE, TK_UPDATE, TK_INSERT         */
  u8 tr_tm;               /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
  Expr *pWhen;            /* The WHEN clause of the expresion (may be NULL) */
  IdList *pColumns;       /* If this is an UPDATE OF <column-list> trigger,
                             the <column-list> is stored here */
  int foreach;            /* One of TK_ROW or TK_STATEMENT */
  Token nameToken;        /* Token containing zName. Use during parsing only */
  Schema *pSchema;        /* Schema containing the trigger */
  Schema *pTabSchema;     /* Schema containing the table */
  TriggerStep *step_list; /* Link list of trigger program steps             */
  Trigger *pNext;         /* Next trigger associated with the table */
};

/*
** A trigger is either a BEFORE or an AFTER trigger.  The following constants
** determine which. 
................................................................................
void sqlite3Analyze(Parse*, Token*, Token*);
int sqlite3InvokeBusyHandler(BusyHandler*);
int sqlite3FindDb(sqlite3*, Token*);
void sqlite3AnalysisLoad(sqlite3*,int iDB);
void sqlite3DefaultRowEst(Index*);
void sqlite3RegisterLikeFunctions(sqlite3*, int);
int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
ThreadData *sqlite3ThreadData();
void sqlite3AttachFunctions(sqlite3 *);
void sqlite3MinimumFileFormat(Parse*, int, int);
void sqlite3SchemaFree(void *);
Schema *sqlite3SchemaGet(Btree *);
int sqlite3SchemaToIndex(sqlite3 *db, Schema *);

#ifndef SQLITE_OMIT_SHARED_CACHE
  void sqlite3TableLock(Parse *, int, int, u8, const char *);
#else
  #define sqlite3TableLock(v,w,x,y,z)
#endif

Changes to src/test1.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
...
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
...
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
....
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.183 2006/01/07 16:06:07 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
**
** Rig sqliteMalloc() to fail on the N-th call and every REPEAT-INTERVAL call
** after that.  If REPEAT-INTERVAL is 0 or is omitted, then only a single
** malloc will fail.  If REPEAT-INTERVAL is 1 then all mallocs after the
** first failure will continue to fail on every call.  If REPEAT-INTERVAL is
** 2 then every other malloc will fail.  And so forth.
**
** Turn off this mechanism and reset the sqlite3Tsd()->mallocFailed variable is N==0.
*/
#ifdef SQLITE_MEMDEBUG
static int sqlite_malloc_fail(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
................................................................................
    Tcl_WrongNumArgs(interp, 1, objv, "?-bytes?");
    return TCL_ERROR;
  }

  if( objc==2 ){
    const char *zArg = Tcl_GetString(objv[1]);
    if( 0==strcmp(zArg, "-bytes") ){
      Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3Tsd()->nAlloc));
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
    }else if( 0==strcmp(zArg, "-maxbytes") ){
      Tcl_SetObjResult(interp, Tcl_NewWideIntObj(sqlite3Tsd()->nMaxAlloc));
    }else if( 0==strcmp(zArg, "-clearmaxbytes") ){
      sqlite3Tsd()->nMaxAlloc = sqlite3Tsd()->nAlloc;
#endif
    }else{
      Tcl_AppendResult(interp, "bad option \"", zArg, 
        "\": must be -bytes, -maxbytes or -clearmaxbytes", 0
      );
      return TCL_ERROR;
    }
................................................................................
  ClientData clientData,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  int rc;
  int enable;
  SqliteTsd *pTsd = sqlite3Tsd();
  Tcl_SetObjResult(interp, Tcl_NewBooleanObj(pTsd->useSharedData));

  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN");
    return TCL_ERROR;
  }
  if( Tcl_GetBooleanFromObj(interp, objv[1], &enable) ){
................................................................................
){
#if !defined(SQLITE_OMIT_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
  int amt;
  if( objc!=1 && objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "?N?");
    return TCL_ERROR;
  }
  amt = sqlite3Tsd()->nSoftHeapLimit;
  if( objc==2 ){
    int N;
    if( Tcl_GetIntFromObj(interp, objv[1], &N) ) return TCL_ERROR;
    sqlite3_soft_heap_limit(N);
  }
  Tcl_SetObjResult(interp, Tcl_NewIntObj(amt));
#endif







|







 







|







 







|


|

|







 







|







 







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
...
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
...
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
....
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.184 2006/01/09 06:29:49 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
**
** Rig sqliteMalloc() to fail on the N-th call and every REPEAT-INTERVAL call
** after that.  If REPEAT-INTERVAL is 0 or is omitted, then only a single
** malloc will fail.  If REPEAT-INTERVAL is 1 then all mallocs after the
** first failure will continue to fail on every call.  If REPEAT-INTERVAL is
** 2 then every other malloc will fail.  And so forth.
**
** Turn off this mechanism and reset the sqlite3ThreadData()->mallocFailed variable is N==0.
*/
#ifdef SQLITE_MEMDEBUG
static int sqlite_malloc_fail(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
................................................................................
    Tcl_WrongNumArgs(interp, 1, objv, "?-bytes?");
    return TCL_ERROR;
  }

  if( objc==2 ){
    const char *zArg = Tcl_GetString(objv[1]);
    if( 0==strcmp(zArg, "-bytes") ){
      Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3ThreadData()->nAlloc));
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
    }else if( 0==strcmp(zArg, "-maxbytes") ){
      Tcl_SetObjResult(interp, Tcl_NewWideIntObj(sqlite3ThreadData()->nMaxAlloc));
    }else if( 0==strcmp(zArg, "-clearmaxbytes") ){
      sqlite3ThreadData()->nMaxAlloc = sqlite3ThreadData()->nAlloc;
#endif
    }else{
      Tcl_AppendResult(interp, "bad option \"", zArg, 
        "\": must be -bytes, -maxbytes or -clearmaxbytes", 0
      );
      return TCL_ERROR;
    }
................................................................................
  ClientData clientData,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  int rc;
  int enable;
  ThreadData *pTsd = sqlite3ThreadData();
  Tcl_SetObjResult(interp, Tcl_NewBooleanObj(pTsd->useSharedData));

  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN");
    return TCL_ERROR;
  }
  if( Tcl_GetBooleanFromObj(interp, objv[1], &enable) ){
................................................................................
){
#if !defined(SQLITE_OMIT_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
  int amt;
  if( objc!=1 && objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "?N?");
    return TCL_ERROR;
  }
  amt = sqlite3ThreadData()->nSoftHeapLimit;
  if( objc==2 ){
    int N;
    if( Tcl_GetIntFromObj(interp, objv[1], &N) ) return TCL_ERROR;
    sqlite3_soft_heap_limit(N);
  }
  Tcl_SetObjResult(interp, Tcl_NewIntObj(amt));
#endif

Changes to src/tokenize.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
...
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.111 2006/01/07 13:21:04 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
  assert( pParse->pNewTable==0 );
  assert( pParse->pNewTrigger==0 );
  assert( pParse->nVar==0 );
  assert( pParse->nVarExpr==0 );
  assert( pParse->nVarExprAlloc==0 );
  assert( pParse->apVarExpr==0 );
  pParse->zTail = pParse->zSql = zSql;
  while( sqlite3Tsd()->mallocFailed==0 && zSql[i]!=0 ){
    assert( i>=0 );
    pParse->sLastToken.z = (u8*)&zSql[i];
    assert( pParse->sLastToken.dyn==0 );
    pParse->sLastToken.n = getToken((unsigned char*)&zSql[i],&tokenType);
    i += pParse->sLastToken.n;
    switch( tokenType ){
      case TK_SPACE:
................................................................................
    if( lastTokenParsed!=TK_SEMI ){
      sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
      pParse->zTail = &zSql[i];
    }
    sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
  }
  sqlite3ParserFree(pEngine, sqlite3FreeX);
  if( sqlite3Tsd()->mallocFailed ){
    pParse->rc = SQLITE_NOMEM;
  }
  if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
    sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc), (char*)0);
  }
  if( pParse->zErrMsg ){
    if( pzErrMsg && *pzErrMsg==0 ){







|







 







|







 







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
...
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.112 2006/01/09 06:29:49 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
  assert( pParse->pNewTable==0 );
  assert( pParse->pNewTrigger==0 );
  assert( pParse->nVar==0 );
  assert( pParse->nVarExpr==0 );
  assert( pParse->nVarExprAlloc==0 );
  assert( pParse->apVarExpr==0 );
  pParse->zTail = pParse->zSql = zSql;
  while( sqlite3ThreadData()->mallocFailed==0 && zSql[i]!=0 ){
    assert( i>=0 );
    pParse->sLastToken.z = (u8*)&zSql[i];
    assert( pParse->sLastToken.dyn==0 );
    pParse->sLastToken.n = getToken((unsigned char*)&zSql[i],&tokenType);
    i += pParse->sLastToken.n;
    switch( tokenType ){
      case TK_SPACE:
................................................................................
    if( lastTokenParsed!=TK_SEMI ){
      sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
      pParse->zTail = &zSql[i];
    }
    sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
  }
  sqlite3ParserFree(pEngine, sqlite3FreeX);
  if( sqlite3ThreadData()->mallocFailed ){
    pParse->rc = SQLITE_NOMEM;
  }
  if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
    sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc), (char*)0);
  }
  if( pParse->zErrMsg ){
    if( pzErrMsg && *pzErrMsg==0 ){

Changes to src/trigger.c.

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
...
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
...
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
  }

  /* If the trigger name was unqualified, and the table is a temp table,
  ** then set iDb to 1 to create the trigger in the temporary database.
  ** If sqlite3SrcListLookup() returns 0, indicating the table does not
  ** exist, the error is caught by the block below.
  */
  if( !pTableName || sqlite3Tsd()->mallocFailed ) goto trigger_cleanup;
  pTab = sqlite3SrcListLookup(pParse, pTableName);
  if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){
    iDb = 1;
  }

  /* Ensure the table name matches database name and that the table exists */
  if( sqlite3Tsd()->mallocFailed ) goto trigger_cleanup;
  assert( pTableName->nSrc==1 );
  if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) && 
      sqlite3FixSrcList(&sFix, pTableName) ){
    goto trigger_cleanup;
  }
  pTab = sqlite3SrcListLookup(pParse, pTableName);
  if( !pTab ){
................................................................................
  if( db->init.busy ){
    int n;
    Table *pTab;
    Trigger *pDel;
    pDel = sqlite3HashInsert(&db->aDb[iDb].pSchema->trigHash, 
                     pTrig->name, strlen(pTrig->name)+1, pTrig);
    if( pDel ){
      assert( sqlite3Tsd()->mallocFailed && pDel==pTrig );
      goto triggerfinish_cleanup;
    }
    n = strlen(pTrig->table) + 1;
    pTab = sqlite3HashFind(&pTrig->pTabSchema->tblHash, pTrig->table, n);
    assert( pTab!=0 );
    pTrig->pNext = pTab->pTrigger;
    pTab->pTrigger = pTrig;
................................................................................
  Trigger *pTrigger = 0;
  int i;
  const char *zDb;
  const char *zName;
  int nName;
  sqlite3 *db = pParse->db;

  if( sqlite3Tsd()->mallocFailed ) goto drop_trigger_cleanup;
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    goto drop_trigger_cleanup;
  }

  assert( pName->nSrc==1 );
  zDb = pName->a[0].zDatabase;
  zName = pName->a[0].zName;







|






|







 







|







 







|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
...
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
...
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
  }

  /* If the trigger name was unqualified, and the table is a temp table,
  ** then set iDb to 1 to create the trigger in the temporary database.
  ** If sqlite3SrcListLookup() returns 0, indicating the table does not
  ** exist, the error is caught by the block below.
  */
  if( !pTableName || sqlite3ThreadData()->mallocFailed ) goto trigger_cleanup;
  pTab = sqlite3SrcListLookup(pParse, pTableName);
  if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){
    iDb = 1;
  }

  /* Ensure the table name matches database name and that the table exists */
  if( sqlite3ThreadData()->mallocFailed ) goto trigger_cleanup;
  assert( pTableName->nSrc==1 );
  if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) && 
      sqlite3FixSrcList(&sFix, pTableName) ){
    goto trigger_cleanup;
  }
  pTab = sqlite3SrcListLookup(pParse, pTableName);
  if( !pTab ){
................................................................................
  if( db->init.busy ){
    int n;
    Table *pTab;
    Trigger *pDel;
    pDel = sqlite3HashInsert(&db->aDb[iDb].pSchema->trigHash, 
                     pTrig->name, strlen(pTrig->name)+1, pTrig);
    if( pDel ){
      assert( sqlite3ThreadData()->mallocFailed && pDel==pTrig );
      goto triggerfinish_cleanup;
    }
    n = strlen(pTrig->table) + 1;
    pTab = sqlite3HashFind(&pTrig->pTabSchema->tblHash, pTrig->table, n);
    assert( pTab!=0 );
    pTrig->pNext = pTab->pTrigger;
    pTab->pTrigger = pTrig;
................................................................................
  Trigger *pTrigger = 0;
  int i;
  const char *zDb;
  const char *zName;
  int nName;
  sqlite3 *db = pParse->db;

  if( sqlite3ThreadData()->mallocFailed ) goto drop_trigger_cleanup;
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    goto drop_trigger_cleanup;
  }

  assert( pName->nSrc==1 );
  zDb = pName->a[0].zDatabase;
  zName = pName->a[0].zName;

Changes to src/update.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
**    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 UPDATE statements.
**
** $Id: update.c,v 1.116 2006/01/07 13:21:04 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** The most recently coded instruction was an OP_Column to retrieve the
** i-th column of table pTab. This routine sets the P3 parameter of the 
** OP_Column to the default value, if any.
................................................................................
  int triggers_exist = 0;      /* True if any row triggers exist */
#endif

  int newIdx      = -1;  /* index of trigger "new" temp table       */
  int oldIdx      = -1;  /* index of trigger "old" temp table       */

  sContext.pParse = 0;
  if( pParse->nErr || sqlite3Tsd()->mallocFailed ) goto update_cleanup;
  db = pParse->db;
  assert( pTabList->nSrc==1 );

  /* Locate the table which we want to update. 
  */
  pTab = sqlite3SrcListLookup(pParse, pTabList);
  if( pTab==0 ) goto update_cleanup;







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
**    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 UPDATE statements.
**
** $Id: update.c,v 1.117 2006/01/09 06:29:49 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** The most recently coded instruction was an OP_Column to retrieve the
** i-th column of table pTab. This routine sets the P3 parameter of the 
** OP_Column to the default value, if any.
................................................................................
  int triggers_exist = 0;      /* True if any row triggers exist */
#endif

  int newIdx      = -1;  /* index of trigger "new" temp table       */
  int oldIdx      = -1;  /* index of trigger "old" temp table       */

  sContext.pParse = 0;
  if( pParse->nErr || sqlite3ThreadData()->mallocFailed ) goto update_cleanup;
  db = pParse->db;
  assert( pTabList->nSrc==1 );

  /* Locate the table which we want to update. 
  */
  pTab = sqlite3SrcListLookup(pParse, pTabList);
  if( pTab==0 ) goto update_cleanup;

Changes to src/util.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
...
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
...
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
...
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
...
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
...
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
...
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
...
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
...
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
...
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
...
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
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
...
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
....
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
....
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.162 2006/01/06 21:52:50 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <stdarg.h>
#include <ctype.h>

/*
................................................................................

#if !defined(SQLITE_OMIT_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
/*
** Set the soft heap-size limit for the current thread. Passing a negative
** value indicates no limit.
*/
void sqlite3_soft_heap_limit(sqlite_int64 n){
  sqlite3Tsd()->nSoftHeapLimit = n;
}

/*
** Release memory held by SQLite instances created by the current thread.
*/
int sqlite3_release_memory(int n){
  return sqlite3pager_release_memory(n);
................................................................................
int sqlite3_iMallocReset = -1; /* When iMallocFail reaches 0, set to this */

/*
** Check for a simulated memory allocation failure.  Return true if
** the failure should be simulated.  Return false to proceed as normal.
*/
static int failMalloc(){
  SqliteTsd *pTsd = sqlite3Tsd();
  if( pTsd->isFail ){
    return 1;
  }
  if( sqlite3_iMallocFail>=0 ){
    sqlite3_iMallocFail--;
    if( sqlite3_iMallocFail==0 ){
      sqlite3_iMallocFail = sqlite3_iMallocReset;
................................................................................
    static const int guard = 0xdead3344;
    memcpy(&z[i*sizeof(u32)], &guard, sizeof(u32));
  }

  /* Line number */
  z = &((char *)z)[TESTALLOC_NGUARD*sizeof(u32)];             /* Guard words */
  z = &zAlloc[TESTALLOC_OFFSET_LINENUMBER(p)];
  memcpy(z, &sqlite3Tsd()->iLine, sizeof(u32));

  /* File name */
  z = &zAlloc[TESTALLOC_OFFSET_FILENAME(p)];
  strncpy(z, sqlite3Tsd()->zFile, TESTALLOC_FILESIZE);
  z[TESTALLOC_FILESIZE - 1] = '\0';

  /* User string */
  z = &zAlloc[TESTALLOC_OFFSET_USER(p)];
  z[0] = 0;
  if( sqlite3_malloc_id ){
    strncpy(z, sqlite3_malloc_id, TESTALLOC_USERSIZE);
................................................................................

#if SQLITE_MEMDEBUG>1
/*
** The argument points to an Os level allocation. Link it into the threads list
** of allocations.
*/
static void linkAlloc(void *p){
  SqliteTsd *pTsd = sqlite3Tsd();
  void **pp = (void **)p;
  pp[0] = 0;
  pp[1] = pTsd->pFirst;
  if( pTsd->pFirst ){
    ((void **)pTsd->pFirst)[0] = p;
  }
  pTsd->pFirst = p;
................................................................................

/*
** The argument points to an Os level allocation. Unlinke it from the threads
** list of allocations.
*/
static void unlinkAlloc(void *p)
{
  SqliteTsd *pTsd = sqlite3Tsd();
  void **pp = (void **)p;
  if( p==pTsd->pFirst ){
    assert(!pp[0]);
    assert(!pp[1] || ((void **)(pp[1]))[0]==p);
    pTsd->pFirst = pp[1];
    if( pTsd->pFirst ){
      ((void **)pTsd->pFirst)[0] = 0;
................................................................................
*/
static void relinkAlloc(void *p)
{
  void **pp = (void **)p;
  if( pp[0] ){
    ((void **)(pp[0]))[1] = p;
  }else{
    SqliteTsd *pTsd = sqlite3Tsd();
    pTsd->pFirst = p;
  }
  if( pp[1] ){
    ((void **)(pp[1]))[0] = p;
  }
}
#else
................................................................................
** Todo: We could have a version of this function that outputs to stdout, 
** to debug memory leaks when Tcl is not available.
*/
#ifdef TCLSH
#include <tcl.h>
int sqlite3OutstandingMallocs(Tcl_Interp *interp){
  void *p;
  SqliteTsd *pTsd = sqlite3Tsd();
  Tcl_Obj *pRes = Tcl_NewObj();
  Tcl_IncrRefCount(pRes);

  for(p=pTsd->pFirst; p; p=((void **)p)[1]){
    Tcl_Obj *pEntry = Tcl_NewObj();
    Tcl_Obj *pStack = Tcl_NewObj();
    char *z;
................................................................................
#endif

/*
** This is the test layer's wrapper around sqlite3OsMalloc().
*/
static void * OSMALLOC(int n){
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
  SqliteTsd *pTsd = sqlite3Tsd();
  pTsd->nMaxAlloc = MAX(pTsd->nMaxAlloc, pTsd->nAlloc);
#endif
  if( !failMalloc() ){
    u32 *p;
    p = (u32 *)sqlite3OsMalloc(n + TESTALLOC_OVERHEAD);
    assert(p);
    sqlite3_nMalloc++;
................................................................................
}

/*
** This is the test layer's wrapper around sqlite3OsRealloc().
*/
void * OSREALLOC(void *pRealloc, int n){
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
  SqliteTsd *pTsd = sqlite3Tsd();
  pTsd->nMaxAlloc = MAX(pTsd->nMaxAlloc, pTsd->nAlloc);
#endif
  if( !failMalloc() ){
    u32 *p = (u32 *)getOsPointer(pRealloc);
    checkGuards(p);
    p = sqlite3OsRealloc(p, n + TESTALLOC_OVERHEAD);
    applyGuards(p);
................................................................................
    relinkAlloc(p);
    return (void *)(&p[TESTALLOC_NGUARD + 2*sizeof(void *)/sizeof(u32)]);
  }
  return 0;
}

void OSMALLOC_FAILED(){
  sqlite3Tsd()->isFail = 0;
}

int OSSIZEOF(void *p){
  if( p ){
    u32 *pOs = (u32 *)getOsPointer(p);
    return sqlite3OsAllocationSize(pOs) - TESTALLOC_OVERHEAD;
  }
................................................................................
** called to try to avoid this. No indication of whether or not this is
** successful is returned to the caller.
**
** If SQLITE_OMIT_MEMORY_MANAGEMENT is defined, this function is a no-op.
*/
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
static void handleSoftLimit(int n){
  SqliteTsd *pTsd = sqlite3Tsd();
  pTsd->nAlloc += (i64)n;
  if( n>0 && pTsd->nSoftHeapLimit>0 ){
    while( pTsd->nAlloc>pTsd->nSoftHeapLimit && sqlite3_release_memory(n) );
  }
}
#else
#define handleSoftLimit()
................................................................................

/*
** Allocate and return N bytes of uninitialised memory by calling
** sqlite3OsMalloc(). If the Malloc() call fails, attempt to free memory 
** by calling sqlite3_release_memory().
*/
void *sqlite3MallocRaw(int n){
  SqliteTsd *pTsd = sqlite3Tsd();
  void *p = 0;
  if( n>0 && !pTsd->mallocFailed ){
    handleSoftLimit(n);
    while( !(p = OSMALLOC(n)) && sqlite3_release_memory(n) );
    if( !p ){
      /* If the allocation failed, call handleSoftLimit() again, this time
      ** with the additive inverse of the argument passed to 
      ** handleSoftLimit() above. This is so the SqliteTsd.nAlloc variable is
      ** still correct after a malloc() failure. 
      */
      handleSoftLimit(n * -1);
      sqlite3Tsd()->mallocFailed = 1;
      OSMALLOC_FAILED();
    }
  }
  return p;
}

/*
** Resize the allocation at p to n bytes by calling sqlite3OsRealloc(). The
** pointer to the new allocation is returned.  If the Realloc() call fails,
** attempt to free memory by calling sqlite3_release_memory().
*/
void *sqlite3Realloc(void *p, int n){
  SqliteTsd *pTsd = sqlite3Tsd();
  if( pTsd->mallocFailed ){
    return 0;
  }

  if( !p ){
    return sqlite3Malloc(n);
  }else{
    void *np = 0;
    handleSoftLimit(n - OSSIZEOF(p));
    while( !(np = OSREALLOC(p, n)) && sqlite3_release_memory(n) );
    if( !np ){
      /* If the allocation failed, call handleSoftLimit() again, this time
      ** with the additive inverse of the argument passed to 
      ** handleSoftLimit() above. This is so the SqliteTsd.nAlloc variable is
      ** still correct after a malloc() failure. 
      */
      handleSoftLimit(OSSIZEOF(p) - n);
      pTsd->mallocFailed = 1;
      OSMALLOC_FAILED();
    }
    return np;
................................................................................
}

/*
** Make a copy of a string in memory obtained from sqliteMalloc(). These 
** functions call sqlite3MallocRaw() directly instead of sqliteMalloc(). This
** is because when memory debugging is turned on, these two functions are 
** called via macros that record the current file and line number in the
** SqliteTsd structure.
*/
char *sqlite3StrDup(const char *z){
  char *zNew;
  if( z==0 ) return 0;
  zNew = sqlite3MallocRaw(strlen(z)+1);
  if( zNew ) strcpy(zNew, z);
  return zNew;
................................................................................
    p = *(void**)&v2;
  }
  return p;
}
#endif

/*
** Return a pointer to the SqliteTsd associated with the calling thread.
*/
SqliteTsd *sqlite3Tsd(){
  SqliteTsd *pTsd = sqlite3OsThreadSpecificData(sizeof(SqliteTsd));
  if( pTsd && !pTsd->isInit ){
    pTsd->nSoftHeapLimit = -1;
#ifndef NDEBUG
    pTsd->mallocAllowed = 1;
#endif
    pTsd->isInit = 1;
  }
................................................................................
}

/*
** Clear the "mallocFailed" flag. This should be invoked before exiting any
** entry points that may have called sqliteMalloc().
*/
void sqlite3MallocClearFailed(){
  sqlite3Tsd()->mallocFailed = 0;
}


#ifndef NDEBUG
/*
** This function sets a flag in the thread-specific-data structure that will
** cause an assert to fail if sqliteMalloc() or sqliteRealloc() is called.
*/
void sqlite3MallocDisallow(){
  assert(sqlite3Tsd()->mallocAllowed);
  sqlite3Tsd()->mallocAllowed = 0;
}

/*
** This function clears the flag set in the thread-specific-data structure set
** by sqlite3MallocDisallow().
*/
void sqlite3MallocAllow(){
  assert(!sqlite3Tsd()->mallocAllowed);
  sqlite3Tsd()->mallocAllowed = 1;
}
#endif







|







 







|







 







|







 







|



|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







|



|












|













|







 







|







 







|

|
|







 







|









|
|







|
|


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
...
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
...
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
...
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
...
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
...
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
...
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
...
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
...
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
...
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
...
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
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
...
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
....
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
....
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.163 2006/01/09 06:29:49 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <stdarg.h>
#include <ctype.h>

/*
................................................................................

#if !defined(SQLITE_OMIT_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
/*
** Set the soft heap-size limit for the current thread. Passing a negative
** value indicates no limit.
*/
void sqlite3_soft_heap_limit(sqlite_int64 n){
  sqlite3ThreadData()->nSoftHeapLimit = n;
}

/*
** Release memory held by SQLite instances created by the current thread.
*/
int sqlite3_release_memory(int n){
  return sqlite3pager_release_memory(n);
................................................................................
int sqlite3_iMallocReset = -1; /* When iMallocFail reaches 0, set to this */

/*
** Check for a simulated memory allocation failure.  Return true if
** the failure should be simulated.  Return false to proceed as normal.
*/
static int failMalloc(){
  ThreadData *pTsd = sqlite3ThreadData();
  if( pTsd->isFail ){
    return 1;
  }
  if( sqlite3_iMallocFail>=0 ){
    sqlite3_iMallocFail--;
    if( sqlite3_iMallocFail==0 ){
      sqlite3_iMallocFail = sqlite3_iMallocReset;
................................................................................
    static const int guard = 0xdead3344;
    memcpy(&z[i*sizeof(u32)], &guard, sizeof(u32));
  }

  /* Line number */
  z = &((char *)z)[TESTALLOC_NGUARD*sizeof(u32)];             /* Guard words */
  z = &zAlloc[TESTALLOC_OFFSET_LINENUMBER(p)];
  memcpy(z, &sqlite3ThreadData()->iLine, sizeof(u32));

  /* File name */
  z = &zAlloc[TESTALLOC_OFFSET_FILENAME(p)];
  strncpy(z, sqlite3ThreadData()->zFile, TESTALLOC_FILESIZE);
  z[TESTALLOC_FILESIZE - 1] = '\0';

  /* User string */
  z = &zAlloc[TESTALLOC_OFFSET_USER(p)];
  z[0] = 0;
  if( sqlite3_malloc_id ){
    strncpy(z, sqlite3_malloc_id, TESTALLOC_USERSIZE);
................................................................................

#if SQLITE_MEMDEBUG>1
/*
** The argument points to an Os level allocation. Link it into the threads list
** of allocations.
*/
static void linkAlloc(void *p){
  ThreadData *pTsd = sqlite3ThreadData();
  void **pp = (void **)p;
  pp[0] = 0;
  pp[1] = pTsd->pFirst;
  if( pTsd->pFirst ){
    ((void **)pTsd->pFirst)[0] = p;
  }
  pTsd->pFirst = p;
................................................................................

/*
** The argument points to an Os level allocation. Unlinke it from the threads
** list of allocations.
*/
static void unlinkAlloc(void *p)
{
  ThreadData *pTsd = sqlite3ThreadData();
  void **pp = (void **)p;
  if( p==pTsd->pFirst ){
    assert(!pp[0]);
    assert(!pp[1] || ((void **)(pp[1]))[0]==p);
    pTsd->pFirst = pp[1];
    if( pTsd->pFirst ){
      ((void **)pTsd->pFirst)[0] = 0;
................................................................................
*/
static void relinkAlloc(void *p)
{
  void **pp = (void **)p;
  if( pp[0] ){
    ((void **)(pp[0]))[1] = p;
  }else{
    ThreadData *pTsd = sqlite3ThreadData();
    pTsd->pFirst = p;
  }
  if( pp[1] ){
    ((void **)(pp[1]))[0] = p;
  }
}
#else
................................................................................
** Todo: We could have a version of this function that outputs to stdout, 
** to debug memory leaks when Tcl is not available.
*/
#ifdef TCLSH
#include <tcl.h>
int sqlite3OutstandingMallocs(Tcl_Interp *interp){
  void *p;
  ThreadData *pTsd = sqlite3ThreadData();
  Tcl_Obj *pRes = Tcl_NewObj();
  Tcl_IncrRefCount(pRes);

  for(p=pTsd->pFirst; p; p=((void **)p)[1]){
    Tcl_Obj *pEntry = Tcl_NewObj();
    Tcl_Obj *pStack = Tcl_NewObj();
    char *z;
................................................................................
#endif

/*
** This is the test layer's wrapper around sqlite3OsMalloc().
*/
static void * OSMALLOC(int n){
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
  ThreadData *pTsd = sqlite3ThreadData();
  pTsd->nMaxAlloc = MAX(pTsd->nMaxAlloc, pTsd->nAlloc);
#endif
  if( !failMalloc() ){
    u32 *p;
    p = (u32 *)sqlite3OsMalloc(n + TESTALLOC_OVERHEAD);
    assert(p);
    sqlite3_nMalloc++;
................................................................................
}

/*
** This is the test layer's wrapper around sqlite3OsRealloc().
*/
void * OSREALLOC(void *pRealloc, int n){
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
  ThreadData *pTsd = sqlite3ThreadData();
  pTsd->nMaxAlloc = MAX(pTsd->nMaxAlloc, pTsd->nAlloc);
#endif
  if( !failMalloc() ){
    u32 *p = (u32 *)getOsPointer(pRealloc);
    checkGuards(p);
    p = sqlite3OsRealloc(p, n + TESTALLOC_OVERHEAD);
    applyGuards(p);
................................................................................
    relinkAlloc(p);
    return (void *)(&p[TESTALLOC_NGUARD + 2*sizeof(void *)/sizeof(u32)]);
  }
  return 0;
}

void OSMALLOC_FAILED(){
  sqlite3ThreadData()->isFail = 0;
}

int OSSIZEOF(void *p){
  if( p ){
    u32 *pOs = (u32 *)getOsPointer(p);
    return sqlite3OsAllocationSize(pOs) - TESTALLOC_OVERHEAD;
  }
................................................................................
** called to try to avoid this. No indication of whether or not this is
** successful is returned to the caller.
**
** If SQLITE_OMIT_MEMORY_MANAGEMENT is defined, this function is a no-op.
*/
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
static void handleSoftLimit(int n){
  ThreadData *pTsd = sqlite3ThreadData();
  pTsd->nAlloc += (i64)n;
  if( n>0 && pTsd->nSoftHeapLimit>0 ){
    while( pTsd->nAlloc>pTsd->nSoftHeapLimit && sqlite3_release_memory(n) );
  }
}
#else
#define handleSoftLimit()
................................................................................

/*
** Allocate and return N bytes of uninitialised memory by calling
** sqlite3OsMalloc(). If the Malloc() call fails, attempt to free memory 
** by calling sqlite3_release_memory().
*/
void *sqlite3MallocRaw(int n){
  ThreadData *pTsd = sqlite3ThreadData();
  void *p = 0;
  if( n>0 && !pTsd->mallocFailed ){
    handleSoftLimit(n);
    while( !(p = OSMALLOC(n)) && sqlite3_release_memory(n) );
    if( !p ){
      /* If the allocation failed, call handleSoftLimit() again, this time
      ** with the additive inverse of the argument passed to 
      ** handleSoftLimit() above. This is so the ThreadData.nAlloc variable is
      ** still correct after a malloc() failure. 
      */
      handleSoftLimit(n * -1);
      sqlite3ThreadData()->mallocFailed = 1;
      OSMALLOC_FAILED();
    }
  }
  return p;
}

/*
** Resize the allocation at p to n bytes by calling sqlite3OsRealloc(). The
** pointer to the new allocation is returned.  If the Realloc() call fails,
** attempt to free memory by calling sqlite3_release_memory().
*/
void *sqlite3Realloc(void *p, int n){
  ThreadData *pTsd = sqlite3ThreadData();
  if( pTsd->mallocFailed ){
    return 0;
  }

  if( !p ){
    return sqlite3Malloc(n);
  }else{
    void *np = 0;
    handleSoftLimit(n - OSSIZEOF(p));
    while( !(np = OSREALLOC(p, n)) && sqlite3_release_memory(n) );
    if( !np ){
      /* If the allocation failed, call handleSoftLimit() again, this time
      ** with the additive inverse of the argument passed to 
      ** handleSoftLimit() above. This is so the ThreadData.nAlloc variable is
      ** still correct after a malloc() failure. 
      */
      handleSoftLimit(OSSIZEOF(p) - n);
      pTsd->mallocFailed = 1;
      OSMALLOC_FAILED();
    }
    return np;
................................................................................
}

/*
** Make a copy of a string in memory obtained from sqliteMalloc(). These 
** functions call sqlite3MallocRaw() directly instead of sqliteMalloc(). This
** is because when memory debugging is turned on, these two functions are 
** called via macros that record the current file and line number in the
** ThreadData structure.
*/
char *sqlite3StrDup(const char *z){
  char *zNew;
  if( z==0 ) return 0;
  zNew = sqlite3MallocRaw(strlen(z)+1);
  if( zNew ) strcpy(zNew, z);
  return zNew;
................................................................................
    p = *(void**)&v2;
  }
  return p;
}
#endif

/*
** Return a pointer to the ThreadData associated with the calling thread.
*/
ThreadData *sqlite3ThreadData(){
  ThreadData *pTsd = sqlite3OsThreadSpecificData(sizeof(ThreadData));
  if( pTsd && !pTsd->isInit ){
    pTsd->nSoftHeapLimit = -1;
#ifndef NDEBUG
    pTsd->mallocAllowed = 1;
#endif
    pTsd->isInit = 1;
  }
................................................................................
}

/*
** Clear the "mallocFailed" flag. This should be invoked before exiting any
** entry points that may have called sqliteMalloc().
*/
void sqlite3MallocClearFailed(){
  sqlite3ThreadData()->mallocFailed = 0;
}


#ifndef NDEBUG
/*
** This function sets a flag in the thread-specific-data structure that will
** cause an assert to fail if sqliteMalloc() or sqliteRealloc() is called.
*/
void sqlite3MallocDisallow(){
  assert(sqlite3ThreadData()->mallocAllowed);
  sqlite3ThreadData()->mallocAllowed = 0;
}

/*
** This function clears the flag set in the thread-specific-data structure set
** by sqlite3MallocDisallow().
*/
void sqlite3MallocAllow(){
  assert(!sqlite3ThreadData()->mallocAllowed);
  sqlite3ThreadData()->mallocAllowed = 1;
}
#endif

Changes to src/vacuum.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
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
**
*************************************************************************
** This file contains code used to implement the VACUUM command.
**
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
** $Id: vacuum.c,v 1.54 2006/01/06 14:32:20 drh Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"
#include "os.h"

#ifndef SQLITE_OMIT_VACUUM
/*
................................................................................
  ** by manually setting the autoCommit flag to true and detaching the
  ** vacuum database. The vacuum_db journal file is deleted when the pager
  ** is closed by the DETACH.
  */
  db->autoCommit = 1;

  if( pDetach ){
    int mf = sqlite3Tsd()->mallocFailed;
    sqlite3Tsd()->mallocFailed = 0;
    sqlite3MallocDisallow();
    ((Vdbe *)pDetach)->expired = 0;
    sqlite3_step(pDetach);
    rc2 = sqlite3_finalize(pDetach);
    if( rc==SQLITE_OK ){
      rc = rc2;
    }
    sqlite3MallocAllow();
    sqlite3Tsd()->mallocFailed = mf;
  }

  /* If one of the execSql() calls above returned SQLITE_NOMEM, then the
  ** mallocFailed flag will be clear (because execSql() calls sqlite3_exec()).
  ** Fix this so the flag and return code match.
  */
  if( rc==SQLITE_NOMEM ){
    sqlite3Tsd()->mallocFailed = 1;
  }

  if( zTemp ){
    sqlite3OsDelete(zTemp);
    sqliteFree(zTemp);
  }
  sqliteFree( zSql );
  sqlite3ResetInternalSchema(db, 0);
#endif

  return rc;
}







|







 







|
|








|







|












10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
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
**
*************************************************************************
** This file contains code used to implement the VACUUM command.
**
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
** $Id: vacuum.c,v 1.55 2006/01/09 06:29:49 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"
#include "os.h"

#ifndef SQLITE_OMIT_VACUUM
/*
................................................................................
  ** by manually setting the autoCommit flag to true and detaching the
  ** vacuum database. The vacuum_db journal file is deleted when the pager
  ** is closed by the DETACH.
  */
  db->autoCommit = 1;

  if( pDetach ){
    int mf = sqlite3ThreadData()->mallocFailed;
    sqlite3ThreadData()->mallocFailed = 0;
    sqlite3MallocDisallow();
    ((Vdbe *)pDetach)->expired = 0;
    sqlite3_step(pDetach);
    rc2 = sqlite3_finalize(pDetach);
    if( rc==SQLITE_OK ){
      rc = rc2;
    }
    sqlite3MallocAllow();
    sqlite3ThreadData()->mallocFailed = mf;
  }

  /* If one of the execSql() calls above returned SQLITE_NOMEM, then the
  ** mallocFailed flag will be clear (because execSql() calls sqlite3_exec()).
  ** Fix this so the flag and return code match.
  */
  if( rc==SQLITE_NOMEM ){
    sqlite3ThreadData()->mallocFailed = 1;
  }

  if( zTemp ){
    sqlite3OsDelete(zTemp);
    sqliteFree(zTemp);
  }
  sqliteFree( zSql );
  sqlite3ResetInternalSchema(db, 0);
#endif

  return rc;
}

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
....
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
....
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
....
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
**
** 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.518 2006/01/08 18:10:18 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
  }
  p->resOnStack = 0;
  db->busyHandler.nBusy = 0;
  CHECK_FOR_INTERRUPT;
  for(pc=p->pc; rc==SQLITE_OK; pc++){
    assert( pc>=0 && pc<p->nOp );
    assert( pTos<=&p->aStack[pc] );
    if( sqlite3Tsd()->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE
    origPc = pc;
    start = hwtime();
#endif
    pOp = &p->aOp[pc];

    /* Only allow tracing if SQLITE_DEBUG is defined.
................................................................................
    assert( pOp[-1].p3type==P3_COLLSEQ );
    assert( pOp[-1].opcode==OP_CollSeq );
    ctx.pColl = (CollSeq *)pOp[-1].p3;
  }
  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
  (*ctx.pFunc->xFunc)(&ctx, n, apVal);
  if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
  if( sqlite3Tsd()->mallocFailed ) goto no_mem;
  popStack(&pTos, n);

  /* If any auxilary data functions have been called by this user function,
  ** immediately call the destructor for any non-static values.
  */
  if( ctx.pVdbeFunc ){
    sqlite3VdbeDeleteAuxData(ctx.pVdbeFunc, pOp->p1);
................................................................................
  zSql = sqlite3MPrintf(
     "SELECT name, rootpage, sql, %d FROM '%q'.%s WHERE %s",
     pOp->p1, db->aDb[iDb].zName, zMaster, pOp->p3);
  if( zSql==0 ) goto no_mem;
  sqlite3SafetyOff(db);
  assert( db->init.busy==0 );
  db->init.busy = 1;
  assert(0==sqlite3Tsd()->mallocFailed);
  rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
  sqliteFree(zSql);
  db->init.busy = 0;
  sqlite3SafetyOn(db);
  if( rc==SQLITE_NOMEM ){
    sqlite3Tsd()->mallocFailed = 1;
    goto no_mem;
  }
  break;  
}

#ifndef SQLITE_OMIT_ANALYZE
/* Opcode: LoadAnalysis P1 * *
................................................................................
  /* Fall thru into abort_due_to_error */

  /* Jump to here for any other kind of fatal error.  The "rc" variable
  ** should hold the error number.
  */
abort_due_to_error:
  if( p->zErrMsg==0 ){
    if( sqlite3Tsd()->mallocFailed ) rc = SQLITE_NOMEM;
    sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
  }
  goto vdbe_halt;

  /* Jump to here if the sqlite3_interrupt() API sets the interrupt
  ** flag.
  */







|







 







|







 







|







 







|





|







 







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
....
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
....
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
....
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
**
** 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.519 2006/01/09 06:29:49 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
  }
  p->resOnStack = 0;
  db->busyHandler.nBusy = 0;
  CHECK_FOR_INTERRUPT;
  for(pc=p->pc; rc==SQLITE_OK; pc++){
    assert( pc>=0 && pc<p->nOp );
    assert( pTos<=&p->aStack[pc] );
    if( sqlite3ThreadData()->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE
    origPc = pc;
    start = hwtime();
#endif
    pOp = &p->aOp[pc];

    /* Only allow tracing if SQLITE_DEBUG is defined.
................................................................................
    assert( pOp[-1].p3type==P3_COLLSEQ );
    assert( pOp[-1].opcode==OP_CollSeq );
    ctx.pColl = (CollSeq *)pOp[-1].p3;
  }
  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
  (*ctx.pFunc->xFunc)(&ctx, n, apVal);
  if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
  if( sqlite3ThreadData()->mallocFailed ) goto no_mem;
  popStack(&pTos, n);

  /* If any auxilary data functions have been called by this user function,
  ** immediately call the destructor for any non-static values.
  */
  if( ctx.pVdbeFunc ){
    sqlite3VdbeDeleteAuxData(ctx.pVdbeFunc, pOp->p1);
................................................................................
  zSql = sqlite3MPrintf(
     "SELECT name, rootpage, sql, %d FROM '%q'.%s WHERE %s",
     pOp->p1, db->aDb[iDb].zName, zMaster, pOp->p3);
  if( zSql==0 ) goto no_mem;
  sqlite3SafetyOff(db);
  assert( db->init.busy==0 );
  db->init.busy = 1;
  assert(0==sqlite3ThreadData()->mallocFailed);
  rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
  sqliteFree(zSql);
  db->init.busy = 0;
  sqlite3SafetyOn(db);
  if( rc==SQLITE_NOMEM ){
    sqlite3ThreadData()->mallocFailed = 1;
    goto no_mem;
  }
  break;  
}

#ifndef SQLITE_OMIT_ANALYZE
/* Opcode: LoadAnalysis P1 * *
................................................................................
  /* Fall thru into abort_due_to_error */

  /* Jump to here for any other kind of fatal error.  The "rc" variable
  ** should hold the error number.
  */
abort_due_to_error:
  if( p->zErrMsg==0 ){
    if( sqlite3ThreadData()->mallocFailed ) rc = SQLITE_NOMEM;
    sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
  }
  goto vdbe_halt;

  /* Jump to here if the sqlite3_interrupt() API sets the interrupt
  ** flag.
  */

Changes to src/vdbeapi.c.

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
...
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
** statement is completely executed or an error occurs.
*/
int sqlite3_step(sqlite3_stmt *pStmt){
  Vdbe *p = (Vdbe*)pStmt;
  sqlite3 *db;
  int rc;

  assert(!sqlite3Tsd()->mallocFailed);

  if( p==0 || p->magic!=VDBE_MAGIC_RUN ){
    return SQLITE_MISUSE;
  }
  if( p->aborted ){
    return SQLITE_ABORT;
  }
................................................................................
static void columnMallocFailure(sqlite3_stmt *pStmt)
{
  /* If malloc() failed during an encoding conversion within an
  ** sqlite3_column_XXX API, then set the return code of the statement to
  ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR
  ** and _finalize() will return NOMEM.
  */
  if( sqlite3Tsd()->mallocFailed ){
    ((Vdbe *)pStmt)->rc = SQLITE_NOMEM;
    sqlite3MallocClearFailed();
  }
}

/**************************** sqlite3_column_  *******************************
** The following routines are used to access elements of the current row







|







 







|







152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
...
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
** statement is completely executed or an error occurs.
*/
int sqlite3_step(sqlite3_stmt *pStmt){
  Vdbe *p = (Vdbe*)pStmt;
  sqlite3 *db;
  int rc;

  assert(!sqlite3ThreadData()->mallocFailed);

  if( p==0 || p->magic!=VDBE_MAGIC_RUN ){
    return SQLITE_MISUSE;
  }
  if( p->aborted ){
    return SQLITE_ABORT;
  }
................................................................................
static void columnMallocFailure(sqlite3_stmt *pStmt)
{
  /* If malloc() failed during an encoding conversion within an
  ** sqlite3_column_XXX API, then set the return code of the statement to
  ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR
  ** and _finalize() will return NOMEM.
  */
  if( sqlite3ThreadData()->mallocFailed ){
    ((Vdbe *)pStmt)->rc = SQLITE_NOMEM;
    sqlite3MallocClearFailed();
  }
}

/**************************** sqlite3_column_  *******************************
** The following routines are used to access elements of the current row

Changes to src/vdbeaux.c.

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
...
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
...
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
...
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
...
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
...
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
....
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
  int i;
  VdbeOp *pOp;

  i = p->nOp;
  p->nOp++;
  assert( p->magic==VDBE_MAGIC_INIT );
  resizeOpArray(p, i+1);
  if( sqlite3Tsd()->mallocFailed ){
    return 0;
  }
  pOp = &p->aOp[i];
  pOp->opcode = op;
  pOp->p1 = p1;
  pOp->p2 = p2;
  pOp->p3 = 0;
................................................................................
** Add a whole list of operations to the operation stack.  Return the
** address of the first operation added.
*/
int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
  int addr;
  assert( p->magic==VDBE_MAGIC_INIT );
  resizeOpArray(p, p->nOp + nOp);
  if( sqlite3Tsd()->mallocFailed ){
    return 0;
  }
  addr = p->nOp;
  if( nOp>0 ){
    int i;
    VdbeOpList const *pIn = aOp;
    for(i=0; i<nOp; i++, pIn++){
................................................................................
** the Vdbe. In these cases we can just copy the pointer.
**
** If addr<0 then change P3 on the most recently inserted instruction.
*/
void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
  Op *pOp;
  assert( p->magic==VDBE_MAGIC_INIT );
  if( p==0 || p->aOp==0 || sqlite3Tsd()->mallocFailed ){
    if (n != P3_KEYINFO) {
      freeP3(n, (void*)*(char**)&zP3);
    }
    return;
  }
  if( addr<0 || addr>=p->nOp ){
    addr = p->nOp - 1;
................................................................................
/*
** Replace the P3 field of the most recently coded instruction with
** comment text.
*/
void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
  va_list ap;
  assert( p->nOp>0 );
  assert( p->aOp==0 || p->aOp[p->nOp-1].p3==0 || sqlite3Tsd()->mallocFailed );
  va_start(ap, zFormat);
  sqlite3VdbeChangeP3(p, -1, sqlite3VMPrintf(zFormat, ap), P3_DYNAMIC);
  va_end(ap);
}
#endif

/*
................................................................................
        nStack*sizeof(p->aStack[0])    /* aStack */
      + nArg*sizeof(Mem*)              /* apArg */
      + nVar*sizeof(Mem)               /* aVar */
      + nVar*sizeof(char*)             /* azVar */
      + nMem*sizeof(Mem)               /* aMem */
      + nCursor*sizeof(Cursor*)        /* apCsr */
    );
    if( !sqlite3Tsd()->mallocFailed ){
      p->aMem = &p->aStack[nStack];
      p->nMem = nMem;
      p->aVar = &p->aMem[nMem];
      p->nVar = nVar;
      p->okVar = 0;
      p->apArg = (Mem**)&p->aVar[nVar];
      p->azVar = (char**)&p->apArg[nArg];
................................................................................
** the string is freed using sqliteFree() when the vdbe is finished with
** it. Otherwise, N bytes of zName are copied.
*/
int sqlite3VdbeSetColName(Vdbe *p, int idx, const char *zName, int N){
  int rc;
  Mem *pColName;
  assert( idx<(2*p->nResColumn) );
  if( sqlite3Tsd()->mallocFailed ) return SQLITE_NOMEM;
  assert( p->aColName!=0 );
  pColName = &(p->aColName[idx]);
  if( N==P3_DYNAMIC || N==P3_STATIC ){
    rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
  }else{
    rc = sqlite3VdbeMemSetStr(pColName, zName, N, SQLITE_UTF8,SQLITE_TRANSIENT);
  }
................................................................................
** means the close did not happen and needs to be repeated.
*/
int sqlite3VdbeHalt(Vdbe *p){
  sqlite3 *db = p->db;
  int i;
  int (*xFunc)(Btree *pBt) = 0;  /* Function to call on each btree backend */

  if( sqlite3Tsd()->mallocFailed ){
    p->rc = SQLITE_NOMEM;
  }

  if( p->magic!=VDBE_MAGIC_RUN ){
    /* Already halted.  Nothing to do. */
    assert( p->magic==VDBE_MAGIC_HALT );
    return SQLITE_OK;







|







 







|







 







|







 







|







 







|







 







|







 







|







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
...
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
...
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
...
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
...
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
...
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
....
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
  int i;
  VdbeOp *pOp;

  i = p->nOp;
  p->nOp++;
  assert( p->magic==VDBE_MAGIC_INIT );
  resizeOpArray(p, i+1);
  if( sqlite3ThreadData()->mallocFailed ){
    return 0;
  }
  pOp = &p->aOp[i];
  pOp->opcode = op;
  pOp->p1 = p1;
  pOp->p2 = p2;
  pOp->p3 = 0;
................................................................................
** Add a whole list of operations to the operation stack.  Return the
** address of the first operation added.
*/
int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
  int addr;
  assert( p->magic==VDBE_MAGIC_INIT );
  resizeOpArray(p, p->nOp + nOp);
  if( sqlite3ThreadData()->mallocFailed ){
    return 0;
  }
  addr = p->nOp;
  if( nOp>0 ){
    int i;
    VdbeOpList const *pIn = aOp;
    for(i=0; i<nOp; i++, pIn++){
................................................................................
** the Vdbe. In these cases we can just copy the pointer.
**
** If addr<0 then change P3 on the most recently inserted instruction.
*/
void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
  Op *pOp;
  assert( p->magic==VDBE_MAGIC_INIT );
  if( p==0 || p->aOp==0 || sqlite3ThreadData()->mallocFailed ){
    if (n != P3_KEYINFO) {
      freeP3(n, (void*)*(char**)&zP3);
    }
    return;
  }
  if( addr<0 || addr>=p->nOp ){
    addr = p->nOp - 1;
................................................................................
/*
** Replace the P3 field of the most recently coded instruction with
** comment text.
*/
void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
  va_list ap;
  assert( p->nOp>0 );
  assert( p->aOp==0 || p->aOp[p->nOp-1].p3==0 || sqlite3ThreadData()->mallocFailed );
  va_start(ap, zFormat);
  sqlite3VdbeChangeP3(p, -1, sqlite3VMPrintf(zFormat, ap), P3_DYNAMIC);
  va_end(ap);
}
#endif

/*
................................................................................
        nStack*sizeof(p->aStack[0])    /* aStack */
      + nArg*sizeof(Mem*)              /* apArg */
      + nVar*sizeof(Mem)               /* aVar */
      + nVar*sizeof(char*)             /* azVar */
      + nMem*sizeof(Mem)               /* aMem */
      + nCursor*sizeof(Cursor*)        /* apCsr */
    );
    if( !sqlite3ThreadData()->mallocFailed ){
      p->aMem = &p->aStack[nStack];
      p->nMem = nMem;
      p->aVar = &p->aMem[nMem];
      p->nVar = nVar;
      p->okVar = 0;
      p->apArg = (Mem**)&p->aVar[nVar];
      p->azVar = (char**)&p->apArg[nArg];
................................................................................
** the string is freed using sqliteFree() when the vdbe is finished with
** it. Otherwise, N bytes of zName are copied.
*/
int sqlite3VdbeSetColName(Vdbe *p, int idx, const char *zName, int N){
  int rc;
  Mem *pColName;
  assert( idx<(2*p->nResColumn) );
  if( sqlite3ThreadData()->mallocFailed ) return SQLITE_NOMEM;
  assert( p->aColName!=0 );
  pColName = &(p->aColName[idx]);
  if( N==P3_DYNAMIC || N==P3_STATIC ){
    rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
  }else{
    rc = sqlite3VdbeMemSetStr(pColName, zName, N, SQLITE_UTF8,SQLITE_TRANSIENT);
  }
................................................................................
** means the close did not happen and needs to be repeated.
*/
int sqlite3VdbeHalt(Vdbe *p){
  sqlite3 *db = p->db;
  int i;
  int (*xFunc)(Btree *pBt) = 0;  /* Function to call on each btree backend */

  if( sqlite3ThreadData()->mallocFailed ){
    p->rc = SQLITE_NOMEM;
  }

  if( p->magic!=VDBE_MAGIC_RUN ){
    /* Already halted.  Nothing to do. */
    assert( p->magic==VDBE_MAGIC_HALT );
    return SQLITE_OK;

Changes to src/vdbemem.c.

752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
    return 0;
  }
  if( pVal->flags&MEM_Str ){
    sqlite3VdbeChangeEncoding(pVal, enc);
  }else if( !(pVal->flags&MEM_Blob) ){
    sqlite3VdbeMemStringify(pVal, enc);
  }
  assert(pVal->enc==enc || sqlite3Tsd()->mallocFailed);
  return (const void *)(pVal->enc==enc ? (pVal->z) : 0);
}

/*
** Create a new sqlite3_value object.
*/
sqlite3_value* sqlite3ValueNew(void){







|







752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
    return 0;
  }
  if( pVal->flags&MEM_Str ){
    sqlite3VdbeChangeEncoding(pVal, enc);
  }else if( !(pVal->flags&MEM_Blob) ){
    sqlite3VdbeMemStringify(pVal, enc);
  }
  assert(pVal->enc==enc || sqlite3ThreadData()->mallocFailed);
  return (const void *)(pVal->enc==enc ? (pVal->z) : 0);
}

/*
** Create a new sqlite3_value object.
*/
sqlite3_value* sqlite3ValueNew(void){

Changes to src/where.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
....
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
....
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
** 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.191 2006/01/07 13:21:04 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
*/
#define BMS  (sizeof(Bitmask)*8)
................................................................................
  WhereTerm *pTerm = &pWC->a[idxTerm];
  Expr *pExpr = pTerm->pExpr;
  Bitmask prereqLeft;
  Bitmask prereqAll;
  int nPattern;
  int isComplete;

  if( sqlite3Tsd()->mallocFailed ) return;
  prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
  if( pExpr->op==TK_IN ){
    assert( pExpr->pRight==0 );
    pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->pList)
                          | exprSelectTableUsage(pMaskSet, pExpr->pSelect);
  }else{
    pTerm->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight);
................................................................................
  whereClauseInit(&wc, pParse);
  whereSplit(&wc, pWhere, TK_AND);
    
  /* Allocate and initialize the WhereInfo structure that will become the
  ** return value.
  */
  pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel));
  if( sqlite3Tsd()->mallocFailed ){
    goto whereBeginNoMem;
  }
  pWInfo->pParse = pParse;
  pWInfo->pTabList = pTabList;
  pWInfo->iBreak = sqlite3VdbeMakeLabel(v);

  /* Special case: a WHERE clause that is constant.  Evaluate the
................................................................................
  ** want to analyze these virtual terms, so start analyzing at the end
  ** and work forward so that the added virtual terms are never processed.
  */
  for(i=0; i<pTabList->nSrc; i++){
    createMask(&maskSet, pTabList->a[i].iCursor);
  }
  exprAnalyzeAll(pTabList, &maskSet, &wc);
  if( sqlite3Tsd()->mallocFailed ){
    goto whereBeginNoMem;
  }

  /* Chose the best index to use for each table in the FROM clause.
  **
  ** This loop fills in the following fields:
  **







|







 







|







 







|







 







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
....
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
....
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
** 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.192 2006/01/09 06:29:49 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
*/
#define BMS  (sizeof(Bitmask)*8)
................................................................................
  WhereTerm *pTerm = &pWC->a[idxTerm];
  Expr *pExpr = pTerm->pExpr;
  Bitmask prereqLeft;
  Bitmask prereqAll;
  int nPattern;
  int isComplete;

  if( sqlite3ThreadData()->mallocFailed ) return;
  prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
  if( pExpr->op==TK_IN ){
    assert( pExpr->pRight==0 );
    pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->pList)
                          | exprSelectTableUsage(pMaskSet, pExpr->pSelect);
  }else{
    pTerm->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight);
................................................................................
  whereClauseInit(&wc, pParse);
  whereSplit(&wc, pWhere, TK_AND);
    
  /* Allocate and initialize the WhereInfo structure that will become the
  ** return value.
  */
  pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel));
  if( sqlite3ThreadData()->mallocFailed ){
    goto whereBeginNoMem;
  }
  pWInfo->pParse = pParse;
  pWInfo->pTabList = pTabList;
  pWInfo->iBreak = sqlite3VdbeMakeLabel(v);

  /* Special case: a WHERE clause that is constant.  Evaluate the
................................................................................
  ** want to analyze these virtual terms, so start analyzing at the end
  ** and work forward so that the added virtual terms are never processed.
  */
  for(i=0; i<pTabList->nSrc; i++){
    createMask(&maskSet, pTabList->a[i].iCursor);
  }
  exprAnalyzeAll(pTabList, &maskSet, &wc);
  if( sqlite3ThreadData()->mallocFailed ){
    goto whereBeginNoMem;
  }

  /* Chose the best index to use for each table in the FROM clause.
  **
  ** This loop fills in the following fields:
  **

Changes to test/shared.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
31
32
33
34
35
36
37

38
39
40
41
42
43
44
...
459
460
461
462
463
464
465
466


467





































































468
469
470
#    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 the SELECT statement.
#
# $Id: shared.test,v 1.6 2006/01/07 13:21:04 danielk1977 Exp $

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

ifcapable !shared_cache {
  finish_test
................................................................................
#             write-transaction, including a simple test to ensure the 
#             external locking protocol is still working.
# shared-3.*: Simple test of read-uncommitted mode.
# shared-4.*: Check that the schema is locked and unlocked correctly.
# shared-5.*: Test that creating/dropping schema items works when databases
#             are attached in different orders to different handles.
# shared-6.*: Locking, UNION ALL queries and sub-queries.

#

do_test shared-1.1 {
  # Open a second database on the file test.db. It should use the same pager
  # cache and schema as the original connection. Verify that only 1 file is 
  # opened.
  sqlite3 db2 test.db
................................................................................
      lappend ret $d
    }
  }
  set ret
} {}

catch {db1 close}
catch {db2 close}








































































finish_test
sqlite3_enable_shared_cache $::enable_shared_cache








|







 







>







 








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



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
...
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
#    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 the SELECT statement.
#
# $Id: shared.test,v 1.7 2006/01/09 06:29:49 danielk1977 Exp $

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

ifcapable !shared_cache {
  finish_test
................................................................................
#             write-transaction, including a simple test to ensure the 
#             external locking protocol is still working.
# shared-3.*: Simple test of read-uncommitted mode.
# shared-4.*: Check that the schema is locked and unlocked correctly.
# shared-5.*: Test that creating/dropping schema items works when databases
#             are attached in different orders to different handles.
# shared-6.*: Locking, UNION ALL queries and sub-queries.
# shared-6.*: Autovacuum and shared-cache.
#

do_test shared-1.1 {
  # Open a second database on the file test.db. It should use the same pager
  # cache and schema as the original connection. Verify that only 1 file is 
  # opened.
  sqlite3 db2 test.db
................................................................................
      lappend ret $d
    }
  }
  set ret
} {}

catch {db1 close}
catch {db2 close}
foreach f [list test.db test2.db] {
  file delete -force $f ${f}-journal
}

#--------------------------------------------------------------------------
# Tests shared-7.* test auto-vacuum does not invalidate cursors from
# other shared-cache users when it reorganizes the database on 
# COMMIT.
#
do_test shared-7.1 {
  sqlite3 db test.db
  sqlite3 db2 test.db
  execsql {
    PRAGMA auto_vacuum = 1;
    BEGIN;
    CREATE TABLE t1(a PRIMARY KEY, b);
    CREATE TABLE t2(a PRIMARY KEY, b);
  }
  for {set i 0} {$i < 100} {incr i} {
    set a [string repeat "$i " 20]
    set b [string repeat "$i " 20]
    db eval {
      INSERT INTO t1 VALUES($a, $b);
    }
    lappend ::contents [list [expr $i+1] $a $b]
  }
  execsql {
    INSERT INTO t2 SELECT * FROM t1;
    COMMIT;
  }
  execsql {
    PRAGMA auto_vacuum;
  }
} {1}
do_test shared-7.2 {
  proc lockrow {db tbl oids body} {
    set ret [list]
    db eval "SELECT oid AS i, a, b FROM $tbl ORDER BY a" {
      if {$i==[lindex $oids 0]} {
        set noids [lrange $oids 1 end]
        if {[llength $noids]==0} {
          set subret [eval $body]
        } else {
          set subret [lockrow $db $tbl $noids $body]
        }
      }
      lappend ret [list $i $a $b]
    }
    return [linsert $subret 0 $ret]
  }
  proc locktblrows {db tbl body} {
    set oids [db eval "SELECT oid FROM $tbl"]
    lockrow $db $tbl $oids $body
  }

  set scans [locktblrows db t2 {
    execsql {
      DELETE FROM t1;
    } db2
  }]
  set error 0
  foreach s $scans {
    if {[lsort -integer -index 0 $s]!=$::contents} {
      set error 1
    }
  }
  set error
} {0}

catch {db close}
catch {db2 close}

finish_test
sqlite3_enable_shared_cache $::enable_shared_cache