/ Check-in [cce250ea]
Login

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

Overview
Comment:Backport of (1628) to version 2. (CVS 1631)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | version_2
Files: files | file ages | folders
SHA1: cce250eaee59eac2d15437b564f049c5b241317c
User & Date: danielk1977 2004-06-19 04:23:25
Context
2004-06-19
11:57
Fix a compiler warning in os.c. (CVS 1636) check-in: 28b737b5 user: drh tags: version_2
04:23
Backport of (1628) to version 2. (CVS 1631) check-in: cce250ea user: danielk1977 tags: version_2
2004-06-16
01:21
Update the publish.sh script so that it no longer generates documentation pages (that is handled by the version 3.0.0 publish.sh). Also insert version numbers in the filenames of all build products. (CVS 1601) check-in: f2b8d358 user: drh tags: version_2
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

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.164 2004/04/23 17:04:45 drh Exp $
           17  +** $Id: main.c,v 1.164.2.1 2004/06/19 04:23:25 danielk1977 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
................................................................................
   185    185   ** indicate success or failure.
   186    186   */
   187    187   static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
   188    188     int rc;
   189    189     BtCursor *curMain;
   190    190     int size;
   191    191     Table *pTab;
   192         -  char *azArg[6];
          192  +  char const *azArg[6];
   193    193     char zDbNum[30];
   194    194     int meta[SQLITE_N_BTREE_META];
   195    195     InitData initData;
          196  +  char const *zMasterSchema;
          197  +  char const *zMasterName;
          198  +  char *zSql = 0;
   196    199   
   197    200     /*
   198    201     ** The master database table has a structure like this
   199    202     */
   200    203     static char master_schema[] = 
   201    204        "CREATE TABLE sqlite_master(\n"
   202    205        "  type text,\n"
................................................................................
   212    215        "  name text,\n"
   213    216        "  tbl_name text,\n"
   214    217        "  rootpage integer,\n"
   215    218        "  sql text\n"
   216    219        ")"
   217    220     ;
   218    221   
   219         -  /* The following SQL will read the schema from the master tables.
   220         -  ** The first version works with SQLite file formats 2 or greater.
   221         -  ** The second version is for format 1 files.
   222         -  **
   223         -  ** Beginning with file format 2, the rowid for new table entries
   224         -  ** (including entries in sqlite_master) is an increasing integer.
   225         -  ** So for file format 2 and later, we can play back sqlite_master
   226         -  ** and all the CREATE statements will appear in the right order.
   227         -  ** But with file format 1, table entries were random and so we
   228         -  ** have to make sure the CREATE TABLEs occur before their corresponding
   229         -  ** CREATE INDEXs.  (We don't have to deal with CREATE VIEW or
   230         -  ** CREATE TRIGGER in file format 1 because those constructs did
   231         -  ** not exist then.) 
          222  +  assert( iDb>=0 && iDb<db->nDb );
          223  +
          224  +  /* zMasterSchema and zInitScript are set to point at the master schema
          225  +  ** and initialisation script appropriate for the database being
          226  +  ** initialised. zMasterName is the name of the master table.
   232    227     */
   233         -  static char init_script[] = 
   234         -     "SELECT type, name, rootpage, sql, 1 FROM sqlite_temp_master "
   235         -     "UNION ALL "
   236         -     "SELECT type, name, rootpage, sql, 0 FROM sqlite_master";
   237         -  static char older_init_script[] = 
   238         -     "SELECT type, name, rootpage, sql, 1 FROM sqlite_temp_master "
   239         -     "UNION ALL "
   240         -     "SELECT type, name, rootpage, sql, 0 FROM sqlite_master "
   241         -     "WHERE type='table' "
   242         -     "UNION ALL "
   243         -     "SELECT type, name, rootpage, sql, 0 FROM sqlite_master "
   244         -     "WHERE type='index'";
          228  +  if( iDb==1 ){
          229  +    zMasterSchema = temp_master_schema;
          230  +    zMasterName = TEMP_MASTER_NAME;
          231  +  }else{
          232  +    zMasterSchema = master_schema;
          233  +    zMasterName = MASTER_NAME;
          234  +  }
   245    235   
   246         -
   247         -  assert( iDb>=0 && iDb!=1 && iDb<db->nDb );
   248         -
   249         -  /* Construct the schema tables: sqlite_master and sqlite_temp_master
          236  +  /* Construct the schema table.
   250    237     */
   251    238     sqliteSafetyOff(db);
   252    239     azArg[0] = "table";
   253         -  azArg[1] = MASTER_NAME;
          240  +  azArg[1] = zMasterName;
   254    241     azArg[2] = "2";
   255         -  azArg[3] = master_schema;
          242  +  azArg[3] = zMasterSchema;
   256    243     sprintf(zDbNum, "%d", iDb);
   257    244     azArg[4] = zDbNum;
   258    245     azArg[5] = 0;
   259    246     initData.db = db;
   260    247     initData.pzErrMsg = pzErrMsg;
   261         -  sqliteInitCallback(&initData, 5, azArg, 0);
   262         -  pTab = sqliteFindTable(db, MASTER_NAME, "main");
          248  +  sqliteInitCallback(&initData, 5, (char **)azArg, 0);
          249  +  pTab = sqliteFindTable(db, zMasterName, db->aDb[iDb].zName);
   263    250     if( pTab ){
   264    251       pTab->readOnly = 1;
   265         -  }
   266         -  if( iDb==0 ){
   267         -    azArg[1] = TEMP_MASTER_NAME;
   268         -    azArg[3] = temp_master_schema;
   269         -    azArg[4] = "1";
   270         -    sqliteInitCallback(&initData, 5, azArg, 0);
   271         -    pTab = sqliteFindTable(db, TEMP_MASTER_NAME, "temp");
   272         -    if( pTab ){
   273         -      pTab->readOnly = 1;
   274         -    }
          252  +  }else{
          253  +    return SQLITE_NOMEM;
   275    254     }
   276    255     sqliteSafetyOn(db);
   277    256   
   278    257     /* Create a cursor to hold the database open
   279    258     */
   280    259     if( db->aDb[iDb].pBt==0 ) return SQLITE_OK;
   281    260     rc = sqliteBtreeCursor(db->aDb[iDb].pBt, 2, 0, &curMain);
................................................................................
   316    295         /* This happens if the database was initially empty */
   317    296         db->file_format = 4;
   318    297       }else if( db->file_format>4 ){
   319    298         sqliteBtreeCloseCursor(curMain);
   320    299         sqliteSetString(pzErrMsg, "unsupported file format", (char*)0);
   321    300         return SQLITE_ERROR;
   322    301       }
   323         -  }else if( db->file_format!=meta[2] || db->file_format<4 ){
          302  +  }else if( iDb!=1 && (db->file_format!=meta[2] || db->file_format<4) ){
   324    303       assert( db->file_format>=4 );
   325    304       if( meta[2]==0 ){
   326    305         sqliteSetString(pzErrMsg, "cannot attach empty database: ",
   327    306            db->aDb[iDb].zName, (char*)0);
   328    307       }else{
   329    308         sqliteSetString(pzErrMsg, "incompatible file format in auxiliary "
   330    309            "database: ", db->aDb[iDb].zName, (char*)0);
................................................................................
   336    315     sqliteBtreeSetCacheSize(db->aDb[iDb].pBt, db->cache_size);
   337    316     sqliteBtreeSetSafetyLevel(db->aDb[iDb].pBt, meta[4]==0 ? 2 : meta[4]);
   338    317   
   339    318     /* Read the schema information out of the schema tables
   340    319     */
   341    320     assert( db->init.busy );
   342    321     sqliteSafetyOff(db);
   343         -  if( iDb==0 ){
   344         -    rc = sqlite_exec(db, 
   345         -        db->file_format>=2 ? init_script : older_init_script,
   346         -        sqliteInitCallback, &initData, 0);
          322  +
          323  +  /* The following SQL will read the schema from the master tables.
          324  +  ** The first version works with SQLite file formats 2 or greater.
          325  +  ** The second version is for format 1 files.
          326  +  **
          327  +  ** Beginning with file format 2, the rowid for new table entries
          328  +  ** (including entries in sqlite_master) is an increasing integer.
          329  +  ** So for file format 2 and later, we can play back sqlite_master
          330  +  ** and all the CREATE statements will appear in the right order.
          331  +  ** But with file format 1, table entries were random and so we
          332  +  ** have to make sure the CREATE TABLEs occur before their corresponding
          333  +  ** CREATE INDEXs.  (We don't have to deal with CREATE VIEW or
          334  +  ** CREATE TRIGGER in file format 1 because those constructs did
          335  +  ** not exist then.) 
          336  +  */
          337  +  if( db->file_format>=2 ){
          338  +    sqliteSetString(&zSql, 
          339  +        "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
          340  +       db->aDb[iDb].zName, "\".", zMasterName, (char*)0);
   347    341     }else{
   348         -    char *zSql = 0;
   349    342       sqliteSetString(&zSql, 
   350         -       "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
   351         -       db->aDb[iDb].zName, "\".sqlite_master", (char*)0);
   352         -    rc = sqlite_exec(db, zSql, sqliteInitCallback, &initData, 0);
   353         -    sqliteFree(zSql);
          343  +        "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
          344  +       db->aDb[iDb].zName, "\".", zMasterName, 
          345  +       " WHERE type IN ('table', 'index')"
          346  +       " ORDER BY CASE type WHEN 'table' THEN 0 ELSE 1 END", (char*)0);
   354    347     }
          348  +  rc = sqlite_exec(db, zSql, sqliteInitCallback, &initData, 0);
          349  +
          350  +  sqliteFree(zSql);
   355    351     sqliteSafetyOn(db);
   356    352     sqliteBtreeCloseCursor(curMain);
   357    353     if( sqlite_malloc_failed ){
   358    354       sqliteSetString(pzErrMsg, "out of memory", (char*)0);
   359    355       rc = SQLITE_NOMEM;
   360    356       sqliteResetInternalSchema(db, 0);
   361    357     }
   362    358     if( rc==SQLITE_OK ){
   363    359       DbSetProperty(db, iDb, DB_SchemaLoaded);
   364         -    if( iDb==0 ){
   365         -      DbSetProperty(db, 1, DB_SchemaLoaded);
   366         -    }
   367    360     }else{
   368    361       sqliteResetInternalSchema(db, iDb);
   369    362     }
   370    363     return rc;
   371    364   }
   372    365   
   373    366   /*
................................................................................
   387    380     int i, rc;
   388    381     
   389    382     if( db->init.busy ) return SQLITE_OK;
   390    383     assert( (db->flags & SQLITE_Initialized)==0 );
   391    384     rc = SQLITE_OK;
   392    385     db->init.busy = 1;
   393    386     for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
   394         -    if( DbHasProperty(db, i, DB_SchemaLoaded) ) continue;
   395         -    assert( i!=1 );  /* Should have been initialized together with 0 */
          387  +    if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
   396    388       rc = sqliteInitOne(db, i, pzErrMsg);
   397    389       if( rc ){
   398    390         sqliteResetInternalSchema(db, i);
   399    391       }
   400    392     }
          393  +
          394  +  /* Once all the other databases have been initialised, load the schema
          395  +  ** for the TEMP database. This is loaded last, as the TEMP database
          396  +  ** schema may contain references to objects in other databases.
          397  +  */
          398  +  if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
          399  +    rc = sqliteInitOne(db, 1, pzErrMsg);
          400  +    if( rc ){
          401  +      sqliteResetInternalSchema(db, 1);
          402  +    }
          403  +  }
          404  +
   401    405     db->init.busy = 0;
   402    406     if( rc==SQLITE_OK ){
   403    407       db->flags |= SQLITE_Initialized;
   404    408       sqliteCommitInternalChanges(db);
   405    409     }
   406    410   
   407    411     /* If the database is in formats 1 or 2, then upgrade it to

Changes to test/trigger1.test.

   408    408   do_test trigger-9.2 {
   409    409     execsql {
   410    410       INSERT INTO t3 VALUES(1,3);
   411    411       SELECT * FROM t3 UNION ALL SELECT 99, 99 UNION ALL SELECT * FROM t4;
   412    412     }
   413    413   } {1 2 1 3 99 99 1 3}
   414    414   
          415  +execsql {
          416  +  DROP TABLE t2;
          417  +  DROP TABLE t3;
          418  +  DROP TABLE t4;
          419  +}
          420  +
          421  +# Ticket #764. At one stage TEMP triggers would fail to re-install when the
          422  +# schema was reloaded. The following tests ensure that TEMP triggers are
          423  +# correctly re-installed.
          424  +#
          425  +# Also verify that references within trigger programs are resolved at
          426  +# statement compile time, not trigger installation time. This means, for
          427  +# example, that you can drop and re-create tables referenced by triggers. 
          428  +do_test trigger-10.0 {
          429  +  file delete -force test2.db
          430  +  file delete -force test2.db-journal
          431  +  sqlite db2 test2.db
          432  +  execsql {CREATE TABLE t3(a, b, c);} db2
          433  +  db2 close
          434  +  execsql {
          435  +    ATTACH 'test2.db' AS aux;
          436  +  }
          437  +} {}
          438  +do_test trigger-10.1 {
          439  +  execsql {
          440  +    CREATE TABLE t1(a, b, c);
          441  +    CREATE temp TABLE t2(a, b, c);
          442  +    CREATE TABLE insert_log(db, a, b, c);
          443  +  }
          444  +} {}
          445  +do_test trigger-10.2 {
          446  +  execsql {
          447  +    CREATE TEMP TRIGGER trig1 AFTER INSERT ON t1 BEGIN 
          448  +      INSERT INTO insert_log VALUES('main', new.a, new.b, new.c);
          449  +    END;
          450  +    CREATE TEMP TRIGGER trig2 AFTER INSERT ON t2 BEGIN 
          451  +      INSERT INTO insert_log VALUES('temp', new.a, new.b, new.c);
          452  +    END;
          453  +    CREATE TEMP TRIGGER trig3 AFTER INSERT ON t3 BEGIN 
          454  +      INSERT INTO insert_log VALUES('aux', new.a, new.b, new.c);
          455  +    END;
          456  +  }
          457  +} {}
          458  +do_test trigger-10.3 {
          459  +  execsql {
          460  +    INSERT INTO t1 VALUES(1, 2, 3);
          461  +    INSERT INTO t2 VALUES(4, 5, 6);
          462  +    INSERT INTO t3  VALUES(7, 8, 9);
          463  +  }
          464  +} {}
          465  +do_test trigger-10.4 {
          466  +  execsql {
          467  +    SELECT * FROM insert_log;
          468  +  }
          469  +} {main 1 2 3 temp 4 5 6 aux 7 8 9}
          470  +do_test trigger-10.5 {
          471  +  execsql {
          472  +    BEGIN;
          473  +    INSERT INTO t1 VALUES(1, 2, 3);
          474  +    INSERT INTO t2 VALUES(4, 5, 6);
          475  +    INSERT INTO t3  VALUES(7, 8, 9);
          476  +    ROLLBACK;
          477  +  }
          478  +} {}
          479  +do_test trigger-10.6 {
          480  +  execsql {
          481  +    SELECT * FROM insert_log;
          482  +  }
          483  +} {main 1 2 3 temp 4 5 6 aux 7 8 9}
          484  +do_test trigger-10.7 {
          485  +  execsql {
          486  +    DELETE FROM insert_log;
          487  +    INSERT INTO t1 VALUES(11, 12, 13);
          488  +    INSERT INTO t2 VALUES(14, 15, 16);
          489  +    INSERT INTO t3 VALUES(17, 18, 19);
          490  +  }
          491  +} {}
          492  +do_test trigger-10.8 {
          493  +  execsql {
          494  +    SELECT * FROM insert_log;
          495  +  }
          496  +} {main 11 12 13 temp 14 15 16 aux 17 18 19}
          497  +do_test trigger-10.8 {
          498  +# Drop and re-create the insert_log table in a different database. Note
          499  +# that we can change the column names because the trigger programs don't
          500  +# use them explicitly.
          501  +  execsql {
          502  +    DROP TABLE insert_log;
          503  +    CREATE temp TABLE insert_log(db, d, e, f);
          504  +  }
          505  +} {}
          506  +do_test trigger-10.10 {
          507  +  execsql {
          508  +    INSERT INTO t1 VALUES(21, 22, 23);
          509  +    INSERT INTO t2 VALUES(24, 25, 26);
          510  +    INSERT INTO t3  VALUES(27, 28, 29);
          511  +  }
          512  +} {}
          513  +do_test trigger-10.11 {
          514  +  execsql {
          515  +    SELECT * FROM insert_log;
          516  +  }
          517  +} {main 21 22 23 temp 24 25 26 aux 27 28 29}
   415    518   
   416    519   finish_test