/ Check-in [af5c2be4]
Login

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

Overview
Comment:Eliminate the use of callbacks during schema initialization. (CVS 1242)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: af5c2be4aed1c50f69eb9634cf051a26263dcf51
User & Date: drh 2004-02-14 23:05:53
Context
2004-02-14
23:59
Eliminate obsolete code associated with the older callback functionality. (CVS 1243) check-in: 2dbc4593 user: drh tags: trunk
23:05
Eliminate the use of callbacks during schema initialization. (CVS 1242) check-in: af5c2be4 user: drh tags: trunk
17:35
Fix problems with malloc-failure handling. (CVS 1241) check-in: 398bc294 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

    19     19   **     DROP INDEX
    20     20   **     creating ID lists
    21     21   **     BEGIN TRANSACTION
    22     22   **     COMMIT
    23     23   **     ROLLBACK
    24     24   **     PRAGMA
    25     25   **
    26         -** $Id: build.c,v 1.168 2004/02/14 16:31:03 drh Exp $
           26  +** $Id: build.c,v 1.169 2004/02/14 23:05:53 drh Exp $
    27     27   */
    28     28   #include "sqliteInt.h"
    29     29   #include <ctype.h>
    30     30   
    31     31   /*
    32     32   ** This routine is called when a new SQL statement is beginning to
    33     33   ** be parsed.  Check to see if the schema for the database needs
................................................................................
    34     34   ** to be read from the SQLITE_MASTER and SQLITE_TEMP_MASTER tables.
    35     35   ** If it does, then read it.
    36     36   */
    37     37   void sqliteBeginParse(Parse *pParse, int explainFlag){
    38     38     sqlite *db = pParse->db;
    39     39     int i;
    40     40     pParse->explain = explainFlag;
    41         -  if((db->flags & SQLITE_Initialized)==0 && pParse->initFlag==0 ){
           41  +  if((db->flags & SQLITE_Initialized)==0 && db->init.busy==0 ){
    42     42       int rc = sqliteInit(db, &pParse->zErrMsg);
    43     43       if( rc!=SQLITE_OK ){
    44     44         pParse->rc = rc;
    45     45         pParse->nErr++;
    46     46       }
    47     47     }
    48     48     for(i=0; i<db->nDb; i++){
................................................................................
   467    467     sqlite *db = pParse->db;
   468    468     Vdbe *v;
   469    469     int iDb;
   470    470   
   471    471     pParse->sFirstToken = *pStart;
   472    472     zName = sqliteTableNameFromToken(pName);
   473    473     if( zName==0 ) return;
   474         -  if( pParse->iDb==1 ) isTemp = 1;
          474  +  if( db->init.iDb==1 ) isTemp = 1;
   475    475   #ifndef SQLITE_OMIT_AUTHORIZATION
   476    476     assert( (isTemp & 1)==isTemp );
   477    477     {
   478    478       int code;
   479    479       char *zDb = isTemp ? "temp" : "main";
   480    480       if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
   481    481         sqliteFree(zName);
................................................................................
   528    528     ** index or table name.  Issue an error message if it does.
   529    529     **
   530    530     ** If we are re-reading the sqlite_master table because of a schema
   531    531     ** change and a new permanent table is found whose name collides with
   532    532     ** an existing temporary table, that is not an error.
   533    533     */
   534    534     pTable = sqliteFindTable(db, zName, 0);
   535         -  iDb = isTemp ? 1 : pParse->iDb;
   536         -  if( pTable!=0 && (pTable->iDb==iDb || !pParse->initFlag) ){
          535  +  iDb = isTemp ? 1 : db->init.iDb;
          536  +  if( pTable!=0 && (pTable->iDb==iDb || !db->init.busy) ){
   537    537       sqliteSetNString(&pParse->zErrMsg, "table ", 0, pName->z, pName->n,
   538    538           " already exists", 0, 0);
   539    539       sqliteFree(zName);
   540    540       pParse->nErr++;
   541    541       return;
   542    542     }
   543    543     if( (pIdx = sqliteFindIndex(db, zName, 0))!=0 &&
   544         -          (pIdx->iDb==0 || !pParse->initFlag) ){
          544  +          (pIdx->iDb==0 || !db->init.busy) ){
   545    545       sqliteSetString(&pParse->zErrMsg, "there is already an index named ", 
   546    546          zName, (char*)0);
   547    547       sqliteFree(zName);
   548    548       pParse->nErr++;
   549    549       return;
   550    550     }
   551    551     pTable = sqliteMalloc( sizeof(Table) );
................................................................................
   566    566     ** the SQLITE_MASTER table.  Note in particular that we must go ahead
   567    567     ** and allocate the record number for the table entry now.  Before any
   568    568     ** PRIMARY KEY or UNIQUE keywords are parsed.  Those keywords will cause
   569    569     ** indices to be created and the table record must come before the 
   570    570     ** indices.  Hence, the record number for the table must be allocated
   571    571     ** now.
   572    572     */
   573         -  if( !pParse->initFlag && (v = sqliteGetVdbe(pParse))!=0 ){
          573  +  if( !db->init.busy && (v = sqliteGetVdbe(pParse))!=0 ){
   574    574       sqliteBeginWriteOperation(pParse, 0, isTemp);
   575    575       if( !isTemp ){
   576    576         sqliteVdbeAddOp(v, OP_Integer, db->file_format, 0);
   577    577         sqliteVdbeAddOp(v, OP_SetCookie, 0, 1);
   578    578       }
   579    579       sqliteOpenMasterTable(v, isTemp);
   580    580       sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
................................................................................
   923    923   ** This routine is called to report the final ")" that terminates
   924    924   ** a CREATE TABLE statement.
   925    925   **
   926    926   ** The table structure that other action routines have been building
   927    927   ** is added to the internal hash tables, assuming no errors have
   928    928   ** occurred.
   929    929   **
   930         -** An entry for the table is made in the master table on disk,
   931         -** unless this is a temporary table or initFlag==1.  When initFlag==1,
          930  +** An entry for the table is made in the master table on disk, unless
          931  +** this is a temporary table or db->init.busy==1.  When db->init.busy==1
   932    932   ** it means we are reading the sqlite_master table because we just
   933    933   ** connected to the database or because the sqlite_master table has
   934    934   ** recently changes, so the entry for this table already exists in
   935    935   ** the sqlite_master table.  We do not want to create it again.
   936    936   **
   937    937   ** If the pSelect argument is not NULL, it means that this routine
   938    938   ** was called to create a table generated from a 
................................................................................
   957    957       p->nCol = pSelTab->nCol;
   958    958       p->aCol = pSelTab->aCol;
   959    959       pSelTab->nCol = 0;
   960    960       pSelTab->aCol = 0;
   961    961       sqliteDeleteTable(0, pSelTab);
   962    962     }
   963    963   
   964         -  /* If the initFlag is 1 it means we are reading the SQL off the
          964  +  /* If the db->init.busy is 1 it means we are reading the SQL off the
   965    965     ** "sqlite_master" or "sqlite_temp_master" table on the disk.
   966    966     ** So do not write to the disk again.  Extract the root page number
   967         -  ** for the table from the pParse->newTnum field.  (The page number
          967  +  ** for the table from the db->init.newTnum field.  (The page number
   968    968     ** should have been put there by the sqliteOpenCb routine.)
   969    969     */
   970         -  if( pParse->initFlag ){
   971         -    p->tnum = pParse->newTnum;
          970  +  if( db->init.busy ){
          971  +    p->tnum = db->init.newTnum;
   972    972     }
   973    973   
   974    974     /* If not initializing, then create a record for the new table
   975    975     ** in the SQLITE_MASTER table of the database.  The record number
   976    976     ** for the new table entry should already be on the stack.
   977    977     **
   978    978     ** If this is a TEMPORARY table, write the entry into the auxiliary
   979    979     ** file instead of into the main database file.
   980    980     */
   981         -  if( !pParse->initFlag ){
          981  +  if( !db->init.busy ){
   982    982       int n;
   983    983       Vdbe *v;
   984    984   
   985    985       v = sqliteGetVdbe(pParse);
   986    986       if( v==0 ) return;
   987    987       if( p->pSelect==0 ){
   988    988         /* A regular table */
................................................................................
   997    997       sqliteVdbeAddOp(v, OP_String, 0, 0);
   998    998       if( p->pSelect==0 ){
   999    999         sqliteVdbeChangeP3(v, -1, "table", P3_STATIC);
  1000   1000       }else{
  1001   1001         sqliteVdbeChangeP3(v, -1, "view", P3_STATIC);
  1002   1002       }
  1003   1003       sqliteVdbeAddOp(v, OP_String, 0, 0);
  1004         -    sqliteVdbeChangeP3(v, -1, p->zName, P3_STATIC);
         1004  +    sqliteVdbeChangeP3(v, -1, p->zName, 0);
  1005   1005       sqliteVdbeAddOp(v, OP_String, 0, 0);
  1006         -    sqliteVdbeChangeP3(v, -1, p->zName, P3_STATIC);
         1006  +    sqliteVdbeChangeP3(v, -1, p->zName, 0);
  1007   1007       sqliteVdbeAddOp(v, OP_Dup, 4, 0);
  1008   1008       sqliteVdbeAddOp(v, OP_String, 0, 0);
  1009   1009       if( pSelect ){
  1010   1010         char *z = createTableStmt(p);
  1011   1011         n = z ? strlen(z) : 0;
  1012   1012         sqliteVdbeChangeP3(v, -1, z, n);
  1013   1013         sqliteFree(z);
................................................................................
  1085   1085     /* Make a copy of the entire SELECT statement that defines the view.
  1086   1086     ** This will force all the Expr.token.z values to be dynamically
  1087   1087     ** allocated rather than point to the input string - which means that
  1088   1088     ** they will persist after the current sqlite_exec() call returns.
  1089   1089     */
  1090   1090     p->pSelect = sqliteSelectDup(pSelect);
  1091   1091     sqliteSelectDelete(pSelect);
  1092         -  if( !pParse->initFlag ){
         1092  +  if( !pParse->db->init.busy ){
  1093   1093       sqliteViewGetColumnNames(pParse, p);
  1094   1094     }
  1095   1095   
  1096   1096     /* Locate the end of the CREATE VIEW statement.  Make sEnd point to
  1097   1097     ** the end.
  1098   1098     */
  1099   1099     sEnd = pParse->sLastToken;
................................................................................
  1563   1563     int i, j;
  1564   1564     Token nullId;    /* Fake token for an empty ID list */
  1565   1565     DbFixer sFix;    /* For assigning database names to pTable */
  1566   1566     int isTemp;      /* True for a temporary index */
  1567   1567     sqlite *db = pParse->db;
  1568   1568   
  1569   1569     if( pParse->nErr || sqlite_malloc_failed ) goto exit_create_index;
  1570         -  if( pParse->initFlag 
  1571         -     && sqliteFixInit(&sFix, pParse, pParse->iDb, "index", pName)
         1570  +  if( db->init.busy 
         1571  +     && sqliteFixInit(&sFix, pParse, db->init.iDb, "index", pName)
  1572   1572        && sqliteFixSrcList(&sFix, pTable)
  1573   1573     ){
  1574   1574       goto exit_create_index;
  1575   1575     }
  1576   1576   
  1577   1577     /*
  1578   1578     ** Find the table that is to be indexed.  Return early if not found.
................................................................................
  1588   1588     if( pTab==0 || pParse->nErr ) goto exit_create_index;
  1589   1589     if( pTab->readOnly ){
  1590   1590       sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName,
  1591   1591         " may not be indexed", (char*)0);
  1592   1592       pParse->nErr++;
  1593   1593       goto exit_create_index;
  1594   1594     }
  1595         -  if( pTab->iDb>=2 && pParse->initFlag==0 ){
         1595  +  if( pTab->iDb>=2 && db->init.busy==0 ){
  1596   1596       sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, 
  1597   1597         " may not have indices added", (char*)0);
  1598   1598       pParse->nErr++;
  1599   1599       goto exit_create_index;
  1600   1600     }
  1601   1601     if( pTab->pSelect ){
  1602   1602       sqliteSetString(&pParse->zErrMsg, "views may not be indexed", (char*)0);
................................................................................
  1614   1614     ** one of the index names collides with the name of a temporary table or
  1615   1615     ** index, then we will continue to process this index.
  1616   1616     **
  1617   1617     ** If pName==0 it means that we are
  1618   1618     ** dealing with a primary key or UNIQUE constraint.  We have to invent our
  1619   1619     ** own name.
  1620   1620     */
  1621         -  if( pName && !pParse->initFlag ){
         1621  +  if( pName && !db->init.busy ){
  1622   1622       Index *pISameName;    /* Another index with the same name */
  1623   1623       Table *pTSameName;    /* A table with same name as the index */
  1624   1624       zName = sqliteStrNDup(pName->z, pName->n);
  1625   1625       if( zName==0 ) goto exit_create_index;
  1626   1626       if( (pISameName = sqliteFindIndex(db, zName, 0))!=0 ){
  1627   1627         sqliteSetString(&pParse->zErrMsg, "index ", zName, 
  1628   1628            " already exists", (char*)0);
................................................................................
  1650   1650   
  1651   1651     /* Check for authorization to create an index.
  1652   1652     */
  1653   1653   #ifndef SQLITE_OMIT_AUTHORIZATION
  1654   1654     {
  1655   1655       const char *zDb = db->aDb[pTab->iDb].zName;
  1656   1656   
  1657         -    assert( pTab->iDb==pParse->iDb || isTemp );
         1657  +    assert( pTab->iDb==db->init.iDb || isTemp );
  1658   1658       if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
  1659   1659         goto exit_create_index;
  1660   1660       }
  1661   1661       i = SQLITE_CREATE_INDEX;
  1662   1662       if( isTemp ) i = SQLITE_CREATE_TEMP_INDEX;
  1663   1663       if( sqliteAuthCheck(pParse, i, zName, pTab->zName, zDb) ){
  1664   1664         goto exit_create_index;
................................................................................
  1686   1686     pIndex->aiColumn = (int*)&pIndex[1];
  1687   1687     pIndex->zName = (char*)&pIndex->aiColumn[pList->nId];
  1688   1688     strcpy(pIndex->zName, zName);
  1689   1689     pIndex->pTable = pTab;
  1690   1690     pIndex->nColumn = pList->nId;
  1691   1691     pIndex->onError = onError;
  1692   1692     pIndex->autoIndex = pName==0;
  1693         -  pIndex->iDb = isTemp ? 1 : pParse->iDb;
         1693  +  pIndex->iDb = isTemp ? 1 : db->init.iDb;
  1694   1694   
  1695   1695     /* Scan the names of the columns of the table to be indexed and
  1696   1696     ** load the column indices into the Index structure.  Report an error
  1697   1697     ** if any column is not found.
  1698   1698     */
  1699   1699     for(i=0; i<pList->nId; i++){
  1700   1700       for(j=0; j<pTab->nCol; j++){
................................................................................
  1739   1739       while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){
  1740   1740         pOther = pOther->pNext;
  1741   1741       }
  1742   1742       pIndex->pNext = pOther->pNext;
  1743   1743       pOther->pNext = pIndex;
  1744   1744     }
  1745   1745   
  1746         -  /* If the initFlag is 1 it means we are reading the SQL off the
         1746  +  /* If the db->init.busy is 1 it means we are reading the SQL off the
  1747   1747     ** "sqlite_master" table on the disk.  So do not write to the disk
  1748         -  ** again.  Extract the table number from the pParse->newTnum field.
         1748  +  ** again.  Extract the table number from the db->init.newTnum field.
  1749   1749     */
  1750         -  if( pParse->initFlag && pTable!=0 ){
  1751         -    pIndex->tnum = pParse->newTnum;
         1750  +  if( db->init.busy && pTable!=0 ){
         1751  +    pIndex->tnum = db->init.newTnum;
  1752   1752     }
  1753   1753   
  1754         -  /* If the initFlag is 0 then create the index on disk.  This
         1754  +  /* If the db->init.busy is 0 then create the index on disk.  This
  1755   1755     ** involves writing the index into the master table and filling in the
  1756   1756     ** index with the current table contents.
  1757   1757     **
  1758         -  ** The initFlag is 0 when the user first enters a CREATE INDEX 
  1759         -  ** command.  The initFlag is 1 when a database is opened and 
         1758  +  ** The db->init.busy is 0 when the user first enters a CREATE INDEX 
         1759  +  ** command.  db->init.busy is 1 when a database is opened and 
  1760   1760     ** CREATE INDEX statements are read out of the master table.  In
  1761   1761     ** the latter case the index already exists on disk, which is why
  1762   1762     ** we don't want to recreate it.
  1763   1763     **
  1764   1764     ** If pTable==0 it means this index is generated as a primary key
  1765   1765     ** or UNIQUE constraint of a CREATE TABLE statement.  Since the table
  1766   1766     ** has just been created, it contains no data and the index initialization
  1767   1767     ** step can be skipped.
  1768   1768     */
  1769         -  else if( pParse->initFlag==0 ){
         1769  +  else if( db->init.busy==0 ){
  1770   1770       int n;
  1771   1771       Vdbe *v;
  1772   1772       int lbl1, lbl2;
  1773   1773       int i;
  1774   1774       int addr;
  1775   1775   
  1776   1776       v = sqliteGetVdbe(pParse);
................................................................................
  1781   1781       }
  1782   1782       sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
  1783   1783       sqliteVdbeAddOp(v, OP_String, 0, 0);
  1784   1784       sqliteVdbeChangeP3(v, -1, "index", P3_STATIC);
  1785   1785       sqliteVdbeAddOp(v, OP_String, 0, 0);
  1786   1786       sqliteVdbeChangeP3(v, -1, pIndex->zName, strlen(pIndex->zName));
  1787   1787       sqliteVdbeAddOp(v, OP_String, 0, 0);
  1788         -    sqliteVdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
         1788  +    sqliteVdbeChangeP3(v, -1, pTab->zName, 0);
  1789   1789       addr = sqliteVdbeAddOp(v, OP_CreateIndex, 0, isTemp);
  1790   1790       sqliteVdbeChangeP3(v, addr, (char*)&pIndex->tnum, P3_POINTER);
  1791   1791       pIndex->tnum = 0;
  1792   1792       if( pTable ){
  1793   1793         sqliteVdbeAddOp(v, OP_Dup, 0, 0);
  1794   1794         sqliteVdbeAddOp(v, OP_Integer, isTemp, 0);
  1795   1795         sqliteVdbeAddOp(v, OP_OpenWrite, 1, 0);
................................................................................
  1800   1800         sqliteVdbeChangeP3(v, addr, pStart->z, n);
  1801   1801       }
  1802   1802       sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0);
  1803   1803       sqliteVdbeAddOp(v, OP_PutIntKey, 0, 0);
  1804   1804       if( pTable ){
  1805   1805         sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
  1806   1806         sqliteVdbeAddOp(v, OP_OpenRead, 2, pTab->tnum);
  1807         -      sqliteVdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
         1807  +      sqliteVdbeChangeP3(v, -1, pTab->zName, 0);
  1808   1808         lbl2 = sqliteVdbeMakeLabel(v);
  1809   1809         sqliteVdbeAddOp(v, OP_Rewind, 2, lbl2);
  1810   1810         lbl1 = sqliteVdbeAddOp(v, OP_Recno, 2, 0);
  1811   1811         for(i=0; i<pIndex->nColumn; i++){
  1812   1812           int iCol = pIndex->aiColumn[i];
  1813   1813           if( pTab->iPKey==iCol ){
  1814   1814             sqliteVdbeAddOp(v, OP_Dup, i, 0);

Changes to src/main.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** Main file for the SQLite library.  The routines in this file
    13     13   ** implement the programmer interface to the library.  Routines in
    14     14   ** other files are for internal use by SQLite and should not be
    15     15   ** accessed by users of the library.
    16     16   **
    17         -** $Id: main.c,v 1.153 2004/02/14 17:35:07 drh Exp $
           17  +** $Id: main.c,v 1.154 2004/02/14 23:05:53 drh Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include "os.h"
    21     21   #include <ctype.h>
    22     22   
    23     23   /*
    24     24   ** A pointer to this structure is used to communicate information
................................................................................
    29     29     char **pzErrMsg;    /* Error message stored here */
    30     30   } InitData;
    31     31   
    32     32   /*
    33     33   ** Fill the InitData structure with an error message that indicates
    34     34   ** that the database is corrupt.
    35     35   */
    36         -static void corruptSchema(InitData *pData){
    37         -  sqliteSetString(pData->pzErrMsg, "malformed database schema", (char*)0);
           36  +static void corruptSchema(InitData *pData, const char *zExtra){
           37  +  sqliteSetString(pData->pzErrMsg, "malformed database schema",
           38  +     zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0);
    38     39   }
    39     40   
    40     41   /*
    41     42   ** This is the callback routine for the code that initializes the
    42     43   ** database.  See sqliteInit() below for additional information.
    43     44   **
    44     45   ** Each callback contains the following information:
................................................................................
    50     51   **     argv[4] = "1" for temporary files, "0" for main database, "2" or more
    51     52   **               for auxiliary database files.
    52     53   **
    53     54   */
    54     55   static
    55     56   int sqliteInitCallback(void *pInit, int argc, char **argv, char **azColName){
    56     57     InitData *pData = (InitData*)pInit;
    57         -  Parse sParse;
    58     58     int nErr = 0;
    59     59   
    60     60     assert( argc==5 );
    61     61     if( argv==0 ) return 0;   /* Might happen if EMPTY_RESULT_CALLBACKS are on */
    62     62     if( argv[0]==0 ){
    63         -    corruptSchema(pData);
           63  +    corruptSchema(pData, 0);
    64     64       return 1;
    65     65     }
    66     66     switch( argv[0][0] ){
    67     67       case 'v':
    68     68       case 'i':
    69     69       case 't': {  /* CREATE TABLE, CREATE INDEX, or CREATE VIEW statements */
           70  +      sqlite *db = pData->db;
    70     71         if( argv[2]==0 || argv[4]==0 ){
    71         -        corruptSchema(pData);
           72  +        corruptSchema(pData, 0);
    72     73           return 1;
    73     74         }
    74     75         if( argv[3] && argv[3][0] ){
    75     76           /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
    76         -        ** But because sParse.initFlag is set to 1, no VDBE code is generated
           77  +        ** But because db->init.busy is set to 1, no VDBE code is generated
    77     78           ** or executed.  All the parser does is build the internal data
    78     79           ** structures that describe the table, index, or view.
    79     80           */
    80         -        memset(&sParse, 0, sizeof(sParse));
    81         -        sParse.db = pData->db;
    82         -        sParse.initFlag = 1;
    83         -        sParse.iDb = atoi(argv[4]);
    84         -        sParse.newTnum = atoi(argv[2]);
    85         -        sParse.useCallback = 1;
    86         -        sqliteRunParser(&sParse, argv[3], pData->pzErrMsg);
           81  +        char *zErr;
           82  +        assert( db->init.busy );
           83  +        db->init.iDb = atoi(argv[4]);
           84  +        assert( db->init.iDb>=0 && db->init.iDb<db->nDb );
           85  +        db->init.newTnum = atoi(argv[2]);
           86  +        if( sqlite_exec(db, argv[3], 0, 0, &zErr) ){
           87  +          corruptSchema(pData, zErr);
           88  +          sqlite_freemem(zErr);
           89  +        }
           90  +        db->init.iDb = 0;
    87     91         }else{
    88     92           /* If the SQL column is blank it means this is an index that
    89     93           ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
    90     94           ** constraint for a CREATE TABLE.  The index should have already
    91     95           ** been created when we processed the CREATE TABLE.  All we have
    92     96           ** to do here is record the root page number for that index.
    93     97           */
    94     98           int iDb;
    95     99           Index *pIndex;
    96    100   
    97    101           iDb = atoi(argv[4]);
    98         -        assert( iDb>=0 && iDb<pData->db->nDb );
    99         -        pIndex = sqliteFindIndex(pData->db, argv[1], pData->db->aDb[iDb].zName);
          102  +        assert( iDb>=0 && iDb<db->nDb );
          103  +        pIndex = sqliteFindIndex(db, argv[1], db->aDb[iDb].zName);
   100    104           if( pIndex==0 || pIndex->tnum!=0 ){
   101    105             /* This can occur if there exists an index on a TEMP table which
   102    106             ** has the same name as another index on a permanent index.  Since
   103    107             ** the permanent table is hidden by the TEMP table, we can also
   104    108             ** safely ignore the index on the permanent table.
   105    109             */
   106    110             /* Do Nothing */;
................................................................................
   184    188     int rc;
   185    189     BtCursor *curMain;
   186    190     int size;
   187    191     Table *pTab;
   188    192     char *azArg[6];
   189    193     char zDbNum[30];
   190    194     int meta[SQLITE_N_BTREE_META];
   191         -  Parse sParse;
   192    195     InitData initData;
   193    196   
   194    197     /*
   195    198     ** The master database table has a structure like this
   196    199     */
   197    200     static char master_schema[] = 
   198    201        "CREATE TABLE sqlite_master(\n"
................................................................................
   241    244        "WHERE type='index'";
   242    245   
   243    246   
   244    247     assert( iDb>=0 && iDb!=1 && iDb<db->nDb );
   245    248   
   246    249     /* Construct the schema tables: sqlite_master and sqlite_temp_master
   247    250     */
          251  +  sqliteSafetyOff(db);
   248    252     azArg[0] = "table";
   249    253     azArg[1] = MASTER_NAME;
   250    254     azArg[2] = "2";
   251    255     azArg[3] = master_schema;
   252    256     sprintf(zDbNum, "%d", iDb);
   253    257     azArg[4] = zDbNum;
   254    258     azArg[5] = 0;
................................................................................
   265    269       azArg[4] = "1";
   266    270       sqliteInitCallback(&initData, 5, azArg, 0);
   267    271       pTab = sqliteFindTable(db, TEMP_MASTER_NAME, "temp");
   268    272       if( pTab ){
   269    273         pTab->readOnly = 1;
   270    274       }
   271    275     }
          276  +  sqliteSafetyOn(db);
   272    277   
   273    278     /* Create a cursor to hold the database open
   274    279     */
   275    280     if( db->aDb[iDb].pBt==0 ) return SQLITE_OK;
   276    281     rc = sqliteBtreeCursor(db->aDb[iDb].pBt, 2, 0, &curMain);
   277    282     if( rc ){
   278    283       sqliteSetString(pzErrMsg, sqlite_error_string(rc), (char*)0);
................................................................................
   326    331       return SQLITE_FORMAT;
   327    332     }
   328    333     sqliteBtreeSetCacheSize(db->aDb[iDb].pBt, db->cache_size);
   329    334     sqliteBtreeSetSafetyLevel(db->aDb[iDb].pBt, meta[4]==0 ? 2 : meta[4]);
   330    335   
   331    336     /* Read the schema information out of the schema tables
   332    337     */
   333         -  memset(&sParse, 0, sizeof(sParse));
   334         -  sParse.db = db;
   335         -  sParse.xCallback = sqliteInitCallback;
   336         -  sParse.pArg = (void*)&initData;
   337         -  sParse.initFlag = 1;
   338         -  sParse.useCallback = 1;
          338  +  assert( db->init.busy );
          339  +  sqliteSafetyOff(db);
   339    340     if( iDb==0 ){
   340         -    sqliteRunParser(&sParse,
          341  +    rc = sqlite_exec(db, 
   341    342           db->file_format>=2 ? init_script : older_init_script,
   342         -        pzErrMsg);
          343  +        sqliteInitCallback, &initData, 0);
   343    344     }else{
   344    345       char *zSql = 0;
   345    346       sqliteSetString(&zSql, 
   346    347          "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
   347    348          db->aDb[iDb].zName, "\".sqlite_master", (char*)0);
   348         -    sqliteRunParser(&sParse, zSql, pzErrMsg);
          349  +    rc = sqlite_exec(db, zSql, sqliteInitCallback, &initData, 0);
   349    350       sqliteFree(zSql);
   350    351     }
          352  +  sqliteSafetyOn(db);
   351    353     sqliteBtreeCloseCursor(curMain);
   352    354     if( sqlite_malloc_failed ){
   353    355       sqliteSetString(pzErrMsg, "out of memory", (char*)0);
   354         -    sParse.rc = SQLITE_NOMEM;
          356  +    rc = SQLITE_NOMEM;
   355    357       sqliteResetInternalSchema(db, 0);
   356    358     }
   357         -  if( sParse.rc==SQLITE_OK ){
          359  +  if( rc==SQLITE_OK ){
   358    360       DbSetProperty(db, iDb, DB_SchemaLoaded);
   359    361       if( iDb==0 ){
   360    362         DbSetProperty(db, 1, DB_SchemaLoaded);
   361    363       }
   362    364     }else{
   363    365       sqliteResetInternalSchema(db, iDb);
   364    366     }
   365         -  return sParse.rc;
          367  +  return rc;
   366    368   }
   367    369   
   368    370   /*
   369    371   ** Initialize all database files - the main database file, the file
   370    372   ** used to store temporary tables, and any additional database files
   371    373   ** created using ATTACH statements.  Return a success code.  If an
   372    374   ** error occurs, write an error message into *pzErrMsg.
................................................................................
   377    379   ** is opened.  If that fails (perhaps because another process
   378    380   ** has the sqlite_master table locked) than another attempt
   379    381   ** is made the first time the database is accessed.
   380    382   */
   381    383   int sqliteInit(sqlite *db, char **pzErrMsg){
   382    384     int i, rc;
   383    385     
          386  +  if( db->init.busy ) return SQLITE_OK;
   384    387     assert( (db->flags & SQLITE_Initialized)==0 );
   385    388     rc = SQLITE_OK;
          389  +  db->init.busy = 1;
   386    390     for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
   387    391       if( DbHasProperty(db, i, DB_SchemaLoaded) ) continue;
   388    392       assert( i!=1 );  /* Should have been initialized together with 0 */
   389    393       rc = sqliteInitOne(db, i, pzErrMsg);
   390    394       if( rc ){
   391    395         sqliteResetInternalSchema(db, i);
   392    396       }
   393    397     }
          398  +  db->init.busy = 0;
   394    399     if( rc==SQLITE_OK ){
   395    400       db->flags |= SQLITE_Initialized;
   396    401       sqliteCommitInternalChanges(db);
   397    402     }
   398    403   
   399    404     /* If the database is in formats 1 or 2, then upgrade it to
   400    405     ** version 3.  This will reconstruct all indices.  If the
................................................................................
   665    670     sqlite_vm **ppVm,           /* OUT: The virtual machine */
   666    671     char **pzErrMsg             /* OUT: Write error messages here */
   667    672   ){
   668    673     Parse sParse;
   669    674   
   670    675     if( pzErrMsg ) *pzErrMsg = 0;
   671    676     if( sqliteSafetyOn(db) ) goto exec_misuse;
   672         -  if( (db->flags & SQLITE_Initialized)==0 ){
   673         -    int rc, cnt = 1;
   674         -    while( (rc = sqliteInit(db, pzErrMsg))==SQLITE_BUSY
   675         -       && db->xBusyCallback && db->xBusyCallback(db->pBusyArg, "", cnt++)!=0 ){}
   676         -    if( rc!=SQLITE_OK ){
   677         -      sqliteStrRealloc(pzErrMsg);
   678         -      sqliteSafetyOff(db);
   679         -      return rc;
          677  +  if( !db->init.busy ){
          678  +    if( (db->flags & SQLITE_Initialized)==0 ){
          679  +      int rc, cnt = 1;
          680  +      while( (rc = sqliteInit(db, pzErrMsg))==SQLITE_BUSY
          681  +         && db->xBusyCallback
          682  +         && db->xBusyCallback(db->pBusyArg, "", cnt++)!=0 ){}
          683  +      if( rc!=SQLITE_OK ){
          684  +        sqliteStrRealloc(pzErrMsg);
          685  +        sqliteSafetyOff(db);
          686  +        return rc;
          687  +      }
          688  +      if( pzErrMsg ){
          689  +        sqliteFree(*pzErrMsg);
          690  +        *pzErrMsg = 0;
          691  +      }
   680    692       }
   681         -    if( pzErrMsg ){
   682         -      sqliteFree(*pzErrMsg);
   683         -      *pzErrMsg = 0;
          693  +    if( db->file_format<3 ){
          694  +      sqliteSafetyOff(db);
          695  +      sqliteSetString(pzErrMsg, "obsolete database file format", (char*)0);
          696  +      return SQLITE_ERROR;
   684    697       }
   685    698     }
   686         -  if( db->file_format<3 ){
   687         -    sqliteSafetyOff(db);
   688         -    sqliteSetString(pzErrMsg, "obsolete database file format", (char*)0);
   689         -    return SQLITE_ERROR;
   690         -  }
          699  +  assert( (db->flags & SQLITE_Initialized)!=0 || db->init.busy );
   691    700     if( db->pVdbe==0 ){ db->nChange = 0; }
   692    701     memset(&sParse, 0, sizeof(sParse));
   693    702     sParse.db = db;
   694    703     sParse.useCallback = 0;
   695    704     if( db->xTrace ) db->xTrace(db->pTraceArg, zSql);
   696    705     sqliteRunParser(&sParse, zSql, pzErrMsg);
   697    706     if( sqlite_malloc_failed ){

Changes to src/sqliteInt.h.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.211 2004/02/12 18:46:39 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.212 2004/02/14 23:05:53 drh Exp $
    15     15   */
    16     16   #include "config.h"
    17     17   #include "sqlite.h"
    18     18   #include "hash.h"
    19     19   #include "vdbe.h"
    20     20   #include "parse.h"
    21     21   #include "btree.h"
................................................................................
   314    314     int nDb;                      /* Number of backends currently in use */
   315    315     Db *aDb;                      /* All backends */
   316    316     Db aDbStatic[2];              /* Static space for the 2 default backends */
   317    317     int flags;                    /* Miscellanous flags. See below */
   318    318     u8 file_format;               /* What file format version is this database? */
   319    319     u8 safety_level;              /* How aggressive at synching data to disk */
   320    320     u8 want_to_close;             /* Close after all VDBEs are deallocated */
          321  +  u8 temp_store;                /* 1=file, 2=memory, 0=compile-time default */
          322  +  u8 onError;                   /* Default conflict algorithm */
   321    323     int next_cookie;              /* Next value of aDb[0].schema_cookie */
   322    324     int cache_size;               /* Number of pages to use in the cache */
   323         -  int temp_store;               /* 1=file, 2=memory, 0=compile-time default */
   324    325     int nTable;                   /* Number of tables in the database */
   325    326     void *pBusyArg;               /* 1st Argument to the busy callback */
   326    327     int (*xBusyCallback)(void *,const char*,int);  /* The busy callback */
   327    328     void *pCommitArg;             /* Argument to xCommitCallback() */   
   328    329     int (*xCommitCallback)(void*);/* Invoked at every commit. */
   329    330     Hash aFunc;                   /* All functions that can be in SQL exprs */
   330    331     int lastRowid;                /* ROWID of most recent insert */
   331    332     int priorNewRowid;            /* Last randomly generated ROWID */
   332         -  int onError;                  /* Default conflict algorithm */
   333    333     int magic;                    /* Magic number for detect library misuse */
   334    334     int nChange;                  /* Number of rows changed */
          335  +  struct sqliteInitInfo {       /* Information used during initialization */
          336  +    int iDb;                       /* When back is being initialized */
          337  +    int newTnum;                   /* Rootpage of table being initialized */
          338  +    u8 busy;                       /* TRUE if currently initializing */
          339  +  } init;
   335    340     struct Vdbe *pVdbe;           /* List of active virtual machines */
   336    341     void (*xTrace)(void*,const char*);     /* Trace function */
   337    342     void *pTraceArg;                       /* Argument to the trace function */
   338    343   #ifndef SQLITE_OMIT_AUTHORIZATION
   339    344     int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
   340    345                                   /* Access authorization function */
   341    346     void *pAuthArg;               /* 1st argument to the access auth function */
................................................................................
   874    879     Token sFirstToken;   /* The first token parsed */
   875    880     Token sLastToken;    /* The last token parsed */
   876    881     const char *zTail;   /* All SQL text past the last semicolon parsed */
   877    882     Table *pNewTable;    /* A table being constructed by CREATE TABLE */
   878    883     Vdbe *pVdbe;         /* An engine for executing database bytecode */
   879    884     u8 colNamesSet;      /* TRUE after OP_ColumnName has been issued to pVdbe */
   880    885     u8 explain;          /* True if the EXPLAIN flag is found on the query */
   881         -  u8 initFlag;         /* True if reparsing CREATE TABLEs */
   882    886     u8 nameClash;        /* A permanent table name clashes with temp table name */
   883    887     u8 useAgg;           /* If true, extract field values from the aggregator
   884    888                          ** while generating expressions.  Normally false */
   885         -  u8 iDb;              /* Index of database whose schema is being parsed */
   886    889     u8 useCallback;      /* True if callbacks should be used to report results */
   887         -  int newTnum;         /* Table number to use when reparsing CREATE TABLEs */
   888    890     int nErr;            /* Number of errors seen */
   889    891     int nTab;            /* Number of previously allocated VDBE cursors */
   890    892     int nMem;            /* Number of memory cells used so far */
   891    893     int nSet;            /* Number of sets used so far */
   892    894     int nAgg;            /* Number of aggregate expressions */
   893    895     int nVar;            /* Number of '?' variables seen in the SQL so far */
   894    896     AggExpr *aAgg;       /* An array of aggregate expressions */

Changes to src/trigger.c.

    61     61     ** 2. the table (or view) does exist in the same database as the trigger.
    62     62     ** 3. that we are not trying to create a trigger on the sqlite_master table
    63     63     ** 4. That we are not trying to create an INSTEAD OF trigger on a table.
    64     64     ** 5. That we are not trying to create a BEFORE or AFTER trigger on a view.
    65     65     */
    66     66     if( sqlite_malloc_failed ) goto trigger_cleanup;
    67     67     assert( pTableName->nSrc==1 );
    68         -  if( pParse->initFlag 
    69         -   && sqliteFixInit(&sFix, pParse, pParse->iDb, "trigger", pName)
           68  +  if( db->init.busy
           69  +   && sqliteFixInit(&sFix, pParse, db->init.iDb, "trigger", pName)
    70     70      && sqliteFixSrcList(&sFix, pTableName)
    71     71     ){
    72     72       goto trigger_cleanup;
    73     73     }
    74     74     tab = sqliteSrcListLookup(pParse, pTableName);
    75     75     if( !tab ){
    76     76       goto trigger_cleanup;
    77     77     }
    78     78     iDb = isTemp ? 1 : tab->iDb;
    79         -  if( iDb>=2 && !pParse->initFlag ){
           79  +  if( iDb>=2 && !db->init.busy ){
    80     80       sqliteErrorMsg(pParse, "triggers may not be added to auxiliary "
    81     81          "database %s", db->aDb[tab->iDb].zName);
    82     82       goto trigger_cleanup;
    83     83     }
    84     84   
    85     85     zName = sqliteStrNDup(pName->z, pName->n);
    86     86     sqliteDequote(zName);
................................................................................
   177    177             && sqliteFixTriggerStep(&sFix, nt->step_list) ){
   178    178       goto triggerfinish_cleanup;
   179    179     }
   180    180   
   181    181     /* if we are not initializing, and this trigger is not on a TEMP table, 
   182    182     ** build the sqlite_master entry
   183    183     */
   184         -  if( !pParse->initFlag ){
          184  +  if( !db->init.busy ){
   185    185       static VdbeOp insertTrig[] = {
   186    186         { OP_NewRecno,   0, 0,  0          },
   187    187         { OP_String,     0, 0,  "trigger"  },
   188    188         { OP_String,     0, 0,  0          },  /* 2: trigger name */
   189    189         { OP_String,     0, 0,  0          },  /* 3: table name */
   190    190         { OP_Integer,    0, 0,  0          },
   191    191         { OP_String,     0, 0,  0          },  /* 5: SQL */