/ Check-in [8a593e9c]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Regression tests now work - except for some changes in error message text. The library is now safe to use for experimental work. (CVS 885)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8a593e9c2d57e758739a7ef54fa40ca6a0071a9a
User & Date: drh 2003-03-27 13:50:00
Context
2003-03-30
00:19
Fix a memory leak in triggers and update tests to show the latest error message text. (CVS 886) check-in: b90d9de3 user: drh tags: trunk
2003-03-27
13:50
Regression tests now work - except for some changes in error message text. The library is now safe to use for experimental work. (CVS 885) check-in: 8a593e9c user: drh tags: trunk
13:01
Fix a segfault in the trigger code. (CVS 884) check-in: 7672914b user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

    21     21   **     COPY
    22     22   **     VACUUM
    23     23   **     BEGIN TRANSACTION
    24     24   **     COMMIT
    25     25   **     ROLLBACK
    26     26   **     PRAGMA
    27     27   **
    28         -** $Id: build.c,v 1.134 2003/03/27 12:51:24 drh Exp $
           28  +** $Id: build.c,v 1.135 2003/03/27 13:50:00 drh Exp $
    29     29   */
    30     30   #include "sqliteInt.h"
    31     31   #include <ctype.h>
    32     32   
    33     33   /*
    34     34   ** This routine is called when a new SQL statement is beginning to
    35     35   ** be parsed.  Check to see if the schema for the database needs
................................................................................
   113    113   ** a particular database table given the name
   114    114   ** of that table.  Return NULL if not found.
   115    115   */
   116    116   Table *sqliteFindTable(sqlite *db, const char *zName, const char *zDatabase){
   117    117     Table *p = 0;
   118    118     int i;
   119    119     for(i=0; i<db->nDb; i++){
   120         -    if( zDatabase!=0 && sqliteStrICmp(zDatabase, db->aDb[i].zName) ) continue;
   121         -    p = sqliteHashFind(&db->aDb[i].tblHash, zName, strlen(zName)+1);
          120  +    int j = (i<2) ? i^1 : i;   /* Search TEMP before MAIN */
          121  +    if( zDatabase!=0 && sqliteStrICmp(zDatabase, db->aDb[j].zName) ) continue;
          122  +    p = sqliteHashFind(&db->aDb[j].tblHash, zName, strlen(zName)+1);
   122    123       if( p ) break;
   123    124     }
   124    125     return p;
   125    126   }
   126    127   
   127    128   /*
   128    129   ** Locate the in-memory structure that describes 
................................................................................
   129    130   ** a particular index given the name of that index.
   130    131   ** Return NULL if not found.
   131    132   */
   132    133   Index *sqliteFindIndex(sqlite *db, const char *zName, const char *zDb){
   133    134     Index *p = 0;
   134    135     int i;
   135    136     for(i=0; i<db->nDb; i++){
   136         -    if( zDb && sqliteStrICmp(zDb, db->aDb[i].zName) ) continue;
   137         -    p = sqliteHashFind(&db->aDb[i].idxHash, zName, strlen(zName)+1);
          137  +    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
          138  +    if( zDb && sqliteStrICmp(zDb, db->aDb[j].zName) ) continue;
          139  +    p = sqliteHashFind(&db->aDb[j].idxHash, zName, strlen(zName)+1);
   138    140       if( p ) break;
   139    141     }
   140    142     return p;
   141    143   }
   142    144   
   143    145   /*
   144    146   ** Remove the given index from the index hash table, and free
................................................................................
  1440   1442   
  1441   1443     /*
  1442   1444     ** Find the table that is to be indexed.  Return early if not found.
  1443   1445     */
  1444   1446     if( pTable!=0 ){
  1445   1447       assert( pName!=0 );
  1446   1448       assert( pTable->nSrc==1 );
  1447         -    pTab =  sqliteTableNameToTable(pParse, 
  1448         -                 pTable->a[0].zName, pTable->a[0].zDatabase);
         1449  +    pTab =  sqliteSrcListLookup(pParse, pTable);
  1449   1450     }else{
  1450   1451       assert( pName==0 );
  1451   1452       pTab =  pParse->pNewTable;
  1452   1453     }
  1453   1454     if( pTab==0 || pParse->nErr ) goto exit_create_index;
  1454   1455     if( !isTemp && (pTab->readOnly || pTab->iDb>=2) ){
  1455   1456       sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, 
................................................................................
  1981   1982     Index *pIdx;
  1982   1983     char *zFile = 0;
  1983   1984     sqlite *db = pParse->db;
  1984   1985   
  1985   1986   
  1986   1987     if( sqlite_malloc_failed  ) goto copy_cleanup;
  1987   1988     assert( pTableName->nSrc==1 );
  1988         -  pTab = sqliteTableNameToTable(pParse, pTableName->a[0].zName,
  1989         -                                pTableName->a[0].zDatabase);
  1990         -  if( pTab==0 ) goto copy_cleanup;
         1989  +  pTab = sqliteSrcListLookup(pParse, pTableName);
         1990  +  if( pTab==0 || sqliteIsReadOnly(pParse, pTab) ) goto copy_cleanup;
  1991   1991     zFile = sqliteStrNDup(pFilename->z, pFilename->n);
  1992   1992     sqliteDequote(zFile);
  1993   1993     if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, zFile)
  1994   1994         || sqliteAuthCheck(pParse, SQLITE_COPY, pTab->zName, zFile) ){
  1995   1995       goto copy_cleanup;
  1996   1996     }
  1997   1997     v = sqliteGetVdbe(pParse);

Changes to src/delete.c.

     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   ** This file contains C code routines that are called by the parser
    13     13   ** to handle DELETE FROM statements.
    14     14   **
    15         -** $Id: delete.c,v 1.48 2003/03/27 12:51:24 drh Exp $
           15  +** $Id: delete.c,v 1.49 2003/03/27 13:50:00 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19         -
    20     19   /*
    21         -** Given a table name, find the corresponding table and make sure the
    22         -** table is writeable.  Generate an error and return NULL if not.  If
    23         -** everything checks out, return a pointer to the Table structure.
           20  +** Look up every table that is named in pSrc.  If any table is not found,
           21  +** add an error message to pParse->zErrMsg and return NULL.  If all tables
           22  +** are found, return a pointer to the last table.
    24     23   */
    25         -Table *sqliteTableNameToTable(Parse *pParse, const char *zTab, const char *zDb){
    26         -  Table *pTab;
    27         -  pTab = sqliteFindTable(pParse->db, zTab, zDb);
    28         -  if( pTab==0 ){
    29         -    if( zDb==0 || zDb[0]==0 ){
    30         -      sqliteSetString(&pParse->zErrMsg, "no such table: ", zTab, 0);
    31         -    }else{
    32         -      sqliteSetString(&pParse->zErrMsg, "no such table: ", zDb, ".", zTab, 0);
           24  +Table *sqliteSrcListLookup(Parse *pParse, SrcList *pSrc){
           25  +  Table *pTab = 0;
           26  +  int i;
           27  +  for(i=0; i<pSrc->nSrc; i++){
           28  +    const char *zTab = pSrc->a[i].zName;
           29  +    const char *zDb = pSrc->a[i].zDatabase;
           30  +    pTab = sqliteFindTable(pParse->db, zTab, zDb);
           31  +    if( pTab==0 ){
           32  +      if( zDb==0 || zDb[0]==0 ){
           33  +        sqliteSetString(&pParse->zErrMsg, "no such table: ", zTab, 0);
           34  +      }else{
           35  +        sqliteSetString(&pParse->zErrMsg, "no such table: ", zDb, ".", zTab, 0);
           36  +      }
           37  +      pParse->nErr++;
           38  +      break;
    33     39       }
    34         -    pParse->nErr++;
    35         -    return 0;
    36         -  }
    37         -  if( pTab->readOnly || pTab->pSelect ){
    38         -    sqliteSetString(&pParse->zErrMsg, 
    39         -      pTab->pSelect ? "view " : "table ",
    40         -      zTab,
    41         -      " may not be modified", 0);
    42         -    pParse->nErr++;
    43         -    return 0;      
           40  +    pSrc->a[i].pTab = pTab;
    44     41     }
    45     42     return pTab;
    46     43   }
           44  +
           45  +/*
           46  +** Check to make sure the given table is writable.  If it is not
           47  +** writable, generate an error message and return 1.  If it is
           48  +** writable return 0;
           49  +*/
           50  +int sqliteIsReadOnly(Parse *pParse, Table *pTab){
           51  +  if( pTab->readOnly || pTab->pSelect ){
           52  +    sqliteSetString(&pParse->zErrMsg, 
           53  +      pTab->pSelect ? "view " : "table ", pTab->zName,
           54  +      " may not be modified", 0);
           55  +    pParse->nErr++;
           56  +    return 1;
           57  +  }
           58  +  return 0;
           59  +}
    47     60   
    48     61   /*
    49     62   ** Process a DELETE FROM statement.
    50     63   */
    51     64   void sqliteDeleteFrom(
    52     65     Parse *pParse,         /* The parser context */
    53     66     SrcList *pTabList,     /* The table from which we should delete things */
................................................................................
    97    110     }
    98    111   
    99    112     /* Locate the table which we want to delete.  This table has to be
   100    113     ** put in an SrcList structure because some of the subroutines we
   101    114     ** will be calling are designed to work with multiple tables and expect
   102    115     ** an SrcList* parameter instead of just a Table* parameter.
   103    116     */
   104         -  pTab = pTabList->a[0].pTab = sqliteTableNameToTable(pParse, zTab, zDb);
   105         -  if( pTab==0 ){
          117  +  pTab = sqliteSrcListLookup(pParse, pTabList);
          118  +  if( pTab==0 || sqliteIsReadOnly(pParse, pTab) ){
   106    119       goto delete_from_cleanup;
   107    120     }
   108    121     assert( pTab->pSelect==0 );  /* This table is not a view */
   109    122     if( sqliteAuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0) ){
   110    123       goto delete_from_cleanup;
   111    124     }
   112    125   

Changes to src/insert.c.

     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   ** This file contains C code routines that are called by the parser
    13     13   ** to handle INSERT statements in SQLite.
    14     14   **
    15         -** $Id: insert.c,v 1.75 2003/03/27 12:51:25 drh Exp $
           15  +** $Id: insert.c,v 1.76 2003/03/27 13:50:00 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   /*
    20     20   ** This routine is call to handle SQL of the following forms:
    21     21   **
    22     22   **    insert into TABLE (IDLIST) values(EXPRLIST)
................................................................................
    89     89     ExprList *pList,      /* List of values to be inserted */
    90     90     Select *pSelect,      /* A SELECT statement to use as the data source */
    91     91     IdList *pColumn,      /* Column names corresponding to IDLIST. */
    92     92     int onError           /* How to handle constraint errors */
    93     93   ){
    94     94     Table *pTab;          /* The table to insert into */
    95     95     char *zTab;           /* Name of the table into which we are inserting */
    96         -  char *zDb;            /* Name of the database holding zTab */
    97     96     int i, j, idx;        /* Loop counters */
    98     97     Vdbe *v;              /* Generate code into this virtual machine */
    99     98     Index *pIdx;          /* For looping over indices of the table */
   100     99     int nColumn;          /* Number of columns in the data */
   101    100     int base;             /* First available cursor */
   102    101     int iCont, iBreak;    /* Beginning and end of the loop over srcTab */
   103    102     sqlite *db;           /* The main database structure */
................................................................................
   117    116     db = pParse->db;
   118    117   
   119    118     /* Locate the table into which we will be inserting new information.
   120    119     */
   121    120     assert( pTabList->nSrc==1 );
   122    121     zTab = pTabList->a[0].zName;
   123    122     if( zTab==0 ) goto insert_cleanup;
   124         -  zDb = pTabList->a[0].zDatabase;
   125         -  pTab = sqliteTableNameToTable(pParse, zTab, zDb);
          123  +  pTab = sqliteSrcListLookup(pParse, pTabList);
   126    124     if( pTab==0 ){
   127    125       goto insert_cleanup;
   128    126     }
   129    127     if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0) ){
   130    128       goto insert_cleanup;
   131    129     }
   132    130   

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.165 2003/03/27 12:51:25 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.166 2003/03/27 13:50:00 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"
................................................................................
   249    249   #endif
   250    250   #ifndef SQLITE_OMIT_AUTHORIZATION
   251    251     int (*xAuth)(void*,int,const char*,const char*); /* Access Auth function */
   252    252     void *pAuthArg;               /* 1st argument to the access auth function */
   253    253   #endif
   254    254   };
   255    255   
          256  +/*
          257  +** The following are the indices of in sqlite.aDb[] of the main database
          258  +** file and the file used to store TEMP tables.
          259  +*/
          260  +#define DB_TMP     0
          261  +#define DB_MAIN    1
          262  +
   256    263   /*
   257    264   ** Possible values for the sqlite.flags.
   258    265   */
   259    266   #define SQLITE_VdbeTrace      0x00000001  /* True to trace VDBE execution */
   260    267   #define SQLITE_Initialized    0x00000002  /* True after initialization */
   261    268   #define SQLITE_Interrupt      0x00000004  /* Cancel current operation */
   262    269   #define SQLITE_InTrans        0x00000008  /* True if in a transaction */
................................................................................
   997   1004   void sqliteAddKeyType(Vdbe*, ExprList*);
   998   1005   void sqliteAddIdxKeyType(Vdbe*, Index*);
   999   1006   int sqliteSelect(Parse*, Select*, int, int, Select*, int, int*);
  1000   1007   Select *sqliteSelectNew(ExprList*,SrcList*,Expr*,ExprList*,Expr*,ExprList*,
  1001   1008                           int,int,int);
  1002   1009   void sqliteSelectDelete(Select*);
  1003   1010   void sqliteSelectUnbind(Select*);
  1004         -Table *sqliteTableNameToTable(Parse*, const char*, const char*);
         1011  +Table *sqliteSrcListLookup(Parse*, SrcList*);
         1012  +int sqliteIsReadOnly(Parse*, Table*);
  1005   1013   void sqliteDeleteFrom(Parse*, SrcList*, Expr*);
  1006   1014   void sqliteUpdate(Parse*, SrcList*, ExprList*, Expr*, int);
  1007   1015   WhereInfo *sqliteWhereBegin(Parse*, int, SrcList*, Expr*, int, ExprList**);
  1008   1016   void sqliteWhereEnd(WhereInfo*);
  1009   1017   void sqliteExprCode(Parse*, Expr*);
  1010   1018   void sqliteExprIfTrue(Parse*, Expr*, int, int);
  1011   1019   void sqliteExprIfFalse(Parse*, Expr*, int, int);

Changes to src/trigger.c.

    57     57     ** 2. the table (or view) does exist.
    58     58     ** 3. that we are not trying to create a trigger on the sqlite_master table
    59     59     ** 4. That we are not trying to create an INSTEAD OF trigger on a table.
    60     60     ** 5. That we are not trying to create a BEFORE or AFTER trigger on a view.
    61     61     */
    62     62     if( sqlite_malloc_failed ) goto trigger_cleanup;
    63     63     assert( pTableName->nSrc==1 );
    64         -  tab = sqliteTableNameToTable(pParse, pTableName->a[0].zName,
    65         -                                pTableName->a[0].zDatabase);
           64  +  tab = sqliteSrcListLookup(pParse, pTableName);
    66     65     if( !tab ){
    67     66       goto trigger_cleanup;
    68     67     }
    69     68     if( tab->iDb>=2 ){
    70     69       sqliteSetString(&pParse->zErrMsg, "triggers may not be added to "
    71     70          "auxiliary database \"", db->aDb[tab->iDb].zName, "\"", 0);
    72     71       pParse->nErr++;
................................................................................
   352    351   
   353    352     if( sqlite_malloc_failed ) goto drop_trigger_cleanup;
   354    353     assert( pName->nSrc==1 );
   355    354     zDb = pName->a[0].zDatabase;
   356    355     zName = pName->a[0].zName;
   357    356     nName = strlen(zName);
   358    357     for(i=0; i<db->nDb; i++){
   359         -    if( zDb && sqliteStrICmp(db->aDb[i].zName, zDb) ) continue;
   360         -    pTrigger = sqliteHashFind(&(db->aDb[i].trigHash), zName, nName+1);
          358  +    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
          359  +    if( zDb && sqliteStrICmp(db->aDb[j].zName, zDb) ) continue;
          360  +    pTrigger = sqliteHashFind(&(db->aDb[j].trigHash), zName, nName+1);
   361    361       if( pTrigger ) break;
   362    362     }
   363    363     if( !pTrigger ){
   364    364       sqliteSetString(&pParse->zErrMsg, "no such trigger: ", zName, 0);
   365    365       goto drop_trigger_cleanup;
   366    366     }
   367    367     assert( pTrigger->iDb>=0 && pTrigger->iDb<db->nDb );

Changes to src/update.c.

     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   ** This file contains C code routines that are called by the parser
    13     13   ** to handle UPDATE statements.
    14     14   **
    15         -** $Id: update.c,v 1.56 2003/03/27 12:51:25 drh Exp $
           15  +** $Id: update.c,v 1.57 2003/03/27 13:50:00 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   /*
    20     20   ** Process an UPDATE statement.
    21     21   */
    22     22   void sqliteUpdate(
................................................................................
    80     80     }
    81     81   
    82     82     /* Locate the table which we want to update.  This table has to be
    83     83     ** put in an SrcList structure because some of the subroutines we
    84     84     ** will be calling are designed to work with multiple tables and expect
    85     85     ** an SrcList* parameter instead of just a Table* parameter.
    86     86     */
    87         -  pTab = pTabList->a[0].pTab = sqliteTableNameToTable(pParse, zTab, zDb);
    88         -  if( pTab==0 ) goto update_cleanup;
           87  +  pTab = sqliteSrcListLookup(pParse, pTabList);
           88  +  if( pTab==0 || sqliteIsReadOnly(pParse, pTab) ) goto update_cleanup;
    89     89     assert( pTab->pSelect==0 );  /* This table is not a VIEW */
    90     90     aXRef = sqliteMalloc( sizeof(int) * pTab->nCol );
    91     91     if( aXRef==0 ) goto update_cleanup;
    92     92     for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
    93     93   
    94     94     /* If there are FOR EACH ROW triggers, allocate temp tables */
    95     95     if( row_triggers_exist ){