/ Check-in [e1bf96a4]
Login

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

Overview
Comment::-) (CVS 104)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: e1bf96a467b739373191bf75e6a097fc0f24bffc
User & Date: drh 2000-06-21 13:59:11
Context
2000-06-21
14:00
:-) (CVS 105) check-in: 516f0222 user: drh tags: trunk
13:59
:-) (CVS 104) check-in: e1bf96a4 user: drh tags: trunk
2000-06-19
19:10
:-) (CVS 103) check-in: af14a5b3 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

    29     29   **     DROP TABLE
    30     30   **     CREATE INDEX
    31     31   **     DROP INDEX
    32     32   **     creating expressions and ID lists
    33     33   **     COPY
    34     34   **     VACUUM
    35     35   **
    36         -** $Id: build.c,v 1.18 2000/06/17 13:12:39 drh Exp $
           36  +** $Id: build.c,v 1.19 2000/06/21 13:59:11 drh Exp $
    37     37   */
    38     38   #include "sqliteInt.h"
    39     39   
    40     40   /*
    41     41   ** This routine is called after a single SQL statement has been
    42     42   ** parsed and we want to execute the VDBE code to implement 
    43     43   ** that statement.  Prior action routines should have already
................................................................................
   147    147   }
   148    148   
   149    149   /*
   150    150   ** Remove the given index from the index hash table, and free
   151    151   ** its memory structures.
   152    152   **
   153    153   ** The index is removed from the database hash table, but it is
   154         -** not unlinked from the table that is being indexed.  Unlinking
   155         -** from the table must be done by the calling function.
          154  +** not unlinked from the Table that is being indexed.  Unlinking
          155  +** from the Table must be done by the calling function.
   156    156   */
   157    157   static void sqliteDeleteIndex(sqlite *db, Index *pIndex){
   158    158     int h;
   159    159     if( pIndex->zName ){
   160    160       h = sqliteHashNoCase(pIndex->zName, 0) % N_HASH;
   161    161       if( db->apIdxHash[h]==pIndex ){
   162    162         db->apIdxHash[h] = pIndex->pHash;
................................................................................
   169    169       }
   170    170     }
   171    171     sqliteFree(pIndex);
   172    172   }
   173    173   
   174    174   /*
   175    175   ** Remove the memory data structures associated with the given
   176         -** table.  No changes are made to disk by this routine.
          176  +** Table.  No changes are made to disk by this routine.
   177    177   **
   178    178   ** This routine just deletes the data structure.  It does not unlink
   179    179   ** the table data structure from the hash table.  But does it destroy
   180    180   ** memory structures of the indices associated with the table.
   181    181   */
   182    182   void sqliteDeleteTable(sqlite *db, Table *pTable){
   183    183     int i;
................................................................................
   508    508     pIndex = sqliteMalloc( sizeof(Index) + strlen(zName) + 1 +
   509    509                           sizeof(int)*pList->nId );
   510    510     if( pIndex==0 ){
   511    511       sqliteSetString(&pParse->zErrMsg, "out of memory", 0);
   512    512       pParse->nErr++;
   513    513       goto exit_create_index;
   514    514     }
   515         -  pIndex->aiField = (int*)&pIndex[1];
   516         -  pIndex->zName = (char*)&pIndex->aiField[pList->nId];
          515  +  pIndex->aiColumn = (int*)&pIndex[1];
          516  +  pIndex->zName = (char*)&pIndex->aiColumn[pList->nId];
   517    517     strcpy(pIndex->zName, zName);
   518    518     pIndex->pTable = pTab;
   519         -  pIndex->nField = pList->nId;
          519  +  pIndex->nColumn = pList->nId;
   520    520   
   521    521     /* Scan the names of the columns of the table to be indexed and
   522    522     ** load the column indices into the Index structure.  Report an error
   523    523     ** if any column is not found.
   524    524     */
   525    525     for(i=0; i<pList->nId; i++){
   526    526       for(j=0; j<pTab->nCol; j++){
................................................................................
   529    529       if( j>=pTab->nCol ){
   530    530         sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, 
   531    531           " has no column named ", pList->a[i].zName, 0);
   532    532         pParse->nErr++;
   533    533         sqliteFree(pIndex);
   534    534         goto exit_create_index;
   535    535       }
   536         -    pIndex->aiField[i] = j;
          536  +    pIndex->aiColumn[i] = j;
   537    537     }
   538    538   
   539    539     /* Link the new Index structure to its table and to the other
   540    540     ** in-memory database structures.
   541    541     */
   542    542     if( pParse->explain==0 ){
   543    543       h = sqliteHashNoCase(pIndex->zName, 0) % N_HASH;
................................................................................
   586    586         sqliteVdbeChangeP3(v, base+4, pTab->zName, 0);
   587    587         sqliteVdbeChangeP3(v, base+5, pStart->z, n);
   588    588       }
   589    589       lbl1 = sqliteVdbeMakeLabel(v);
   590    590       lbl2 = sqliteVdbeMakeLabel(v);
   591    591       sqliteVdbeAddOp(v, OP_Next, 0, lbl2, 0, lbl1);
   592    592       sqliteVdbeAddOp(v, OP_Key, 0, 0, 0, 0);
   593         -    for(i=0; i<pIndex->nField; i++){
   594         -      sqliteVdbeAddOp(v, OP_Field, 0, pIndex->aiField[i], 0, 0);
          593  +    for(i=0; i<pIndex->nColumn; i++){
          594  +      sqliteVdbeAddOp(v, OP_Field, 0, pIndex->aiColumn[i], 0, 0);
   595    595       }
   596         -    sqliteVdbeAddOp(v, OP_MakeKey, pIndex->nField, 0, 0, 0);
          596  +    sqliteVdbeAddOp(v, OP_MakeKey, pIndex->nColumn, 0, 0, 0);
   597    597       sqliteVdbeAddOp(v, OP_PutIdx, 1, 0, 0, 0);
   598    598       sqliteVdbeAddOp(v, OP_Goto, 0, lbl1, 0, 0);
   599    599       sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, lbl2);
   600    600       sqliteVdbeAddOp(v, OP_Close, 1, 0, 0, 0);
   601    601       sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0);
   602    602     }
   603    603   
................................................................................
   830    830       }
   831    831       sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0, 0, 0);
   832    832       sqliteVdbeAddOp(v, OP_Put, 0, 0, 0, 0);
   833    833       for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
   834    834         if( pIdx->pNext ){
   835    835           sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
   836    836         }
   837         -      for(j=0; j<pIdx->nField; j++){
   838         -        sqliteVdbeAddOp(v, OP_FileField, pIdx->aiField[j], 0, 0, 0);
          837  +      for(j=0; j<pIdx->nColumn; j++){
          838  +        sqliteVdbeAddOp(v, OP_FileField, pIdx->aiColumn[j], 0, 0, 0);
   839    839         }
   840         -      sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nField, 0, 0, 0);
          840  +      sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nColumn, 0, 0, 0);
   841    841         sqliteVdbeAddOp(v, OP_PutIdx, i, 0, 0, 0);
   842    842       }
   843    843       sqliteVdbeAddOp(v, OP_Goto, 0, addr, 0, 0);
   844    844       sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, end);
   845    845     }
   846    846     
   847    847   copy_cleanup:

Changes to src/dbbe.c.

    26     26   ** sqlite and the code that does the actually reading and writing
    27     27   ** of information to the disk.
    28     28   **
    29     29   ** This file uses GDBM as the database backend.  It should be
    30     30   ** relatively simple to convert to a different database such
    31     31   ** as NDBM, SDBM, or BerkeleyDB.
    32     32   **
    33         -** $Id: dbbe.c,v 1.14 2000/06/17 13:12:39 drh Exp $
           33  +** $Id: dbbe.c,v 1.15 2000/06/21 13:59:11 drh Exp $
    34     34   */
    35     35   #include "sqliteInt.h"
    36     36   #include <gdbm.h>
    37     37   #include <sys/stat.h>
    38     38   #include <unistd.h>
    39     39   #include <ctype.h>
    40     40   #include <time.h>
    41     41   
    42     42   /*
    43     43   ** Information about each open disk file is an instance of this 
    44     44   ** structure.  There will only be one such structure for each
    45     45   ** disk file.  If the VDBE opens the same file twice (as will happen
    46         -** for a self-join, for example) then two DbbeTable structures are
           46  +** for a self-join, for example) then two DbbeCursor structures are
    47     47   ** created but there is only a single BeFile structure with an
    48     48   ** nRef of 2.
    49     49   */
    50     50   typedef struct BeFile BeFile;
    51     51   struct BeFile {
    52     52     char *zName;            /* Name of the file */
    53     53     GDBM_FILE dbf;          /* The file itself */
................................................................................
    83     83     char **azTemp;     /* Names of the temporary files */
    84     84     struct rc4 rc4;    /* The random number generator */
    85     85   };
    86     86   
    87     87   /*
    88     88   ** An cursor into a database file is an instance of the following structure.
    89     89   ** There can only be a single BeFile structure for each disk file, but
    90         -** there can be multiple DbbeTable structures.  Each DbbeTable represents
           90  +** there can be multiple DbbeCursor structures.  Each DbbeCursor represents
    91     91   ** a cursor pointing to a particular part of the open BeFile.  The
    92         -** BeFile.nRef field hold a count of the number of DbbeTable structures
           92  +** BeFile.nRef field hold a count of the number of DbbeCursor structures
    93     93   ** associated with the same disk file.
    94     94   */
    95         -struct DbbeTable {
           95  +struct DbbeCursor {
    96     96     Dbbe *pBe;         /* The database of which this record is a part */
    97     97     BeFile *pFile;     /* The database file for this table */
    98     98     datum key;         /* Most recently used key */
    99     99     datum data;        /* Most recent data */
   100    100     int needRewind;    /* Next key should be the first */
   101    101     int readPending;   /* The fetch hasn't actually been done yet */
   102    102   };
................................................................................
   222    222     sqliteFree(pBe->azTemp);
   223    223     sqliteFree(pBe->apTemp);
   224    224     memset(pBe, 0, sizeof(*pBe));
   225    225     sqliteFree(pBe);
   226    226   }
   227    227   
   228    228   /*
   229         -** Translate the name of a table into the name of a file that holds
   230         -** that table.  Space to hold the filename is obtained from
          229  +** Translate the name of an SQL table (or index) into the name 
          230  +** of a file that holds the key/data pairs for that table or
          231  +** index.  Space to hold the filename is obtained from
   231    232   ** sqliteMalloc() and must be freed by the calling function.
   232    233   */
   233    234   static char *sqliteFileOfTable(Dbbe *pBe, const char *zTable){
   234    235     char *zFile = 0;
   235    236     int i;
   236    237     sqliteSetString(&zFile, pBe->zDir, "/", zTable, ".tbl", 0);
   237    238     if( zFile==0 ) return 0;
................................................................................
   265    266       zBuf[j++] = zRandomChars[c];
   266    267     }
   267    268     zBuf[j] = 0;
   268    269   }
   269    270   
   270    271   /*
   271    272   ** Open a new table cursor.  Write a pointer to the corresponding
   272         -** DbbeTable structure into *ppTable.  Return an integer success
          273  +** DbbeCursor structure into *ppCursr.  Return an integer success
   273    274   ** code:
   274    275   **
   275    276   **    SQLITE_OK          It worked!
   276    277   **
   277    278   **    SQLITE_NOMEM       sqliteMalloc() failed
   278    279   **
   279    280   **    SQLITE_PERM        Attempt to access a file for which file
................................................................................
   283    284   **                       the corresponding file and has that file locked.
   284    285   **
   285    286   **    SQLITE_READONLY    The current thread already has this file open
   286    287   **                       readonly but you are trying to open for writing.
   287    288   **                       (This can happen if a SELECT callback tries to
   288    289   **                       do an UPDATE or DELETE.)
   289    290   **
   290         -** If zTable is 0 or "", then a temporary table is created and opened.
   291         -** This table will be deleted from the disk when it is closed.
          291  +** If zTable is 0 or "", then a temporary database file is created and
          292  +** a cursor to that temporary file is opened.  The temporary file
          293  +** will be deleted from the disk when it is closed.
   292    294   */
   293         -int sqliteDbbeOpenTable(
          295  +int sqliteDbbeOpenCursor(
   294    296     Dbbe *pBe,              /* The database the table belongs to */
   295         -  const char *zTable,     /* The name of the table */
          297  +  const char *zTable,     /* The SQL name of the file to be opened */
   296    298     int writeable,          /* True to open for writing */
   297         -  DbbeTable **ppTable     /* Write the resulting table pointer here */
          299  +  DbbeCursor **ppCursr    /* Write the resulting table pointer here */
   298    300   ){
   299    301     char *zFile;            /* Name of the table file */
   300         -  DbbeTable *pTable;      /* The new table cursor */
          302  +  DbbeCursor *pCursr;     /* The new table cursor */
   301    303     BeFile *pFile;          /* The underlying data file for this table */
   302    304     int rc = SQLITE_OK;     /* Return value */
   303    305     int rw_mask;            /* Permissions mask for opening a table */
   304    306     int mode;               /* Mode for opening a table */
   305    307   
   306         -  *ppTable = 0;
   307         -  pTable = sqliteMalloc( sizeof(*pTable) );
   308         -  if( pTable==0 ) return SQLITE_NOMEM;
          308  +  *ppCursr = 0;
          309  +  pCursr = sqliteMalloc( sizeof(*pCursr) );
          310  +  if( pCursr==0 ) return SQLITE_NOMEM;
   309    311     if( zTable ){
   310    312       zFile = sqliteFileOfTable(pBe, zTable);
   311    313       for(pFile=pBe->pOpen; pFile; pFile=pFile->pNext){
   312    314         if( strcmp(pFile->zName,zFile)==0 ) break;
   313    315       }
   314    316     }else{
   315    317       pFile = 0;
................................................................................
   372    374     }else{
   373    375       sqliteFree(zFile);
   374    376       pFile->nRef++;
   375    377       if( writeable && !pFile->writeable ){
   376    378         rc = SQLITE_READONLY;
   377    379       }
   378    380     }
   379         -  pTable->pBe = pBe;
   380         -  pTable->pFile = pFile;
   381         -  pTable->readPending = 0;
   382         -  pTable->needRewind = 1;
   383         -  *ppTable = pTable;
          381  +  pCursr->pBe = pBe;
          382  +  pCursr->pFile = pFile;
          383  +  pCursr->readPending = 0;
          384  +  pCursr->needRewind = 1;
          385  +  *ppCursr = pCursr;
   384    386     return rc;
   385    387   }
   386    388   
   387    389   /*
   388    390   ** Drop a table from the database.  The file on the disk that corresponds
   389    391   ** to this table is deleted.
   390    392   */
................................................................................
   396    398     sqliteFree(zFile);
   397    399   }
   398    400   
   399    401   /*
   400    402   ** Reorganize a table to reduce search times and disk usage.
   401    403   */
   402    404   void sqliteDbbeReorganizeTable(Dbbe *pBe, const char *zTable){
   403         -  DbbeTable *pTab;
          405  +  DbbeCursor *pCrsr;
   404    406   
   405         -  if( sqliteDbbeOpenTable(pBe, zTable, 1, &pTab)!=SQLITE_OK ){
          407  +  if( sqliteDbbeOpenCursor(pBe, zTable, 1, &pCrsr)!=SQLITE_OK ){
   406    408       return;
   407    409     }
   408         -  if( pTab && pTab->pFile && pTab->pFile->dbf ){
   409         -    gdbm_reorganize(pTab->pFile->dbf);
          410  +  if( pCrsr && pCrsr->pFile && pCrsr->pFile->dbf ){
          411  +    gdbm_reorganize(pCrsr->pFile->dbf);
   410    412     }
   411         -  if( pTab ){
   412         -    sqliteDbbeCloseTable(pTab);
          413  +  if( pCrsr ){
          414  +    sqliteDbbeCloseCursor(pCrsr);
   413    415     }
   414    416   }
   415    417   
   416    418   /*
   417         -** Close a table previously opened by sqliteDbbeOpenTable().
          419  +** Close a cursor previously opened by sqliteDbbeOpenCursor().
          420  +**
          421  +** There can be multiple cursors pointing to the same open file.
          422  +** The underlying file is not closed until all cursors have been
          423  +** closed.  This routine decrements the BeFile.nref field of the
          424  +** underlying file and closes the file when nref reaches 0.
   418    425   */
   419         -void sqliteDbbeCloseTable(DbbeTable *pTable){
          426  +void sqliteDbbeCloseCursor(DbbeCursor *pCursr){
   420    427     BeFile *pFile;
   421    428     Dbbe *pBe;
   422         -  if( pTable==0 ) return;
   423         -  pFile = pTable->pFile;
   424         -  pBe = pTable->pBe;
          429  +  if( pCursr==0 ) return;
          430  +  pFile = pCursr->pFile;
          431  +  pBe = pCursr->pBe;
   425    432     pFile->nRef--;
   426    433     if( pFile->dbf!=NULL ){
   427    434       gdbm_sync(pFile->dbf);
   428    435     }
   429    436     if( pFile->nRef<=0 ){
   430    437       if( pFile->dbf!=NULL ){
   431    438         gdbm_close(pFile->dbf);
................................................................................
   441    448       if( pFile->delOnClose ){
   442    449         unlink(pFile->zName);
   443    450       }
   444    451       sqliteFree(pFile->zName);
   445    452       memset(pFile, 0, sizeof(*pFile));
   446    453       sqliteFree(pFile);
   447    454     }
   448         -  if( pTable->key.dptr ) free(pTable->key.dptr);
   449         -  if( pTable->data.dptr ) free(pTable->data.dptr);
   450         -  memset(pTable, 0, sizeof(*pTable));
   451         -  sqliteFree(pTable);
          455  +  if( pCursr->key.dptr ) free(pCursr->key.dptr);
          456  +  if( pCursr->data.dptr ) free(pCursr->data.dptr);
          457  +  memset(pCursr, 0, sizeof(*pCursr));
          458  +  sqliteFree(pCursr);
   452    459   }
   453    460   
   454    461   /*
   455    462   ** Clear the given datum
   456    463   */
   457    464   static void datumClear(datum *p){
   458    465     if( p->dptr ) free(p->dptr);
   459    466     p->dptr = 0;
   460    467     p->dsize = 0;
   461    468   }
   462    469   
   463    470   /*
   464         -** Fetch a single record from an open table.  Return 1 on success
          471  +** Fetch a single record from an open cursor.  Return 1 on success
   465    472   ** and 0 on failure.
   466    473   */
   467         -int sqliteDbbeFetch(DbbeTable *pTable, int nKey, char *pKey){
          474  +int sqliteDbbeFetch(DbbeCursor *pCursr, int nKey, char *pKey){
   468    475     datum key;
   469    476     key.dsize = nKey;
   470    477     key.dptr = pKey;
   471         -  datumClear(&pTable->key);
   472         -  datumClear(&pTable->data);
   473         -  if( pTable->pFile && pTable->pFile->dbf ){
   474         -    pTable->data = gdbm_fetch(pTable->pFile->dbf, key);
          478  +  datumClear(&pCursr->key);
          479  +  datumClear(&pCursr->data);
          480  +  if( pCursr->pFile && pCursr->pFile->dbf ){
          481  +    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, key);
   475    482     }
   476         -  return pTable->data.dptr!=0;
          483  +  return pCursr->data.dptr!=0;
   477    484   }
   478    485   
   479    486   /*
   480    487   ** Return 1 if the given key is already in the table.  Return 0
   481    488   ** if it is not.
   482    489   */
   483         -int sqliteDbbeTest(DbbeTable *pTable, int nKey, char *pKey){
          490  +int sqliteDbbeTest(DbbeCursor *pCursr, int nKey, char *pKey){
   484    491     datum key;
   485    492     int result = 0;
   486    493     key.dsize = nKey;
   487    494     key.dptr = pKey;
   488         -  if( pTable->pFile && pTable->pFile->dbf ){
   489         -    result = gdbm_exists(pTable->pFile->dbf, key);
          495  +  if( pCursr->pFile && pCursr->pFile->dbf ){
          496  +    result = gdbm_exists(pCursr->pFile->dbf, key);
   490    497     }
   491    498     return result;
   492    499   }
   493    500   
   494    501   /*
   495    502   ** Copy bytes from the current key or data into a buffer supplied by
   496    503   ** the calling function.  Return the number of bytes copied.
   497    504   */
   498         -int sqliteDbbeCopyKey(DbbeTable *pTable, int offset, int size, char *zBuf){
          505  +int sqliteDbbeCopyKey(DbbeCursor *pCursr, int offset, int size, char *zBuf){
   499    506     int n;
   500         -  if( offset>=pTable->key.dsize ) return 0;
   501         -  if( offset+size>pTable->key.dsize ){
   502         -    n = pTable->key.dsize - offset;
          507  +  if( offset>=pCursr->key.dsize ) return 0;
          508  +  if( offset+size>pCursr->key.dsize ){
          509  +    n = pCursr->key.dsize - offset;
   503    510     }else{
   504    511       n = size;
   505    512     }
   506         -  memcpy(zBuf, &pTable->key.dptr[offset], n);
          513  +  memcpy(zBuf, &pCursr->key.dptr[offset], n);
   507    514     return n;
   508    515   }
   509         -int sqliteDbbeCopyData(DbbeTable *pTable, int offset, int size, char *zBuf){
          516  +int sqliteDbbeCopyData(DbbeCursor *pCursr, int offset, int size, char *zBuf){
   510    517     int n;
   511         -  if( pTable->readPending && pTable->pFile && pTable->pFile->dbf ){
   512         -    pTable->data = gdbm_fetch(pTable->pFile->dbf, pTable->key);
   513         -    pTable->readPending = 0;
          518  +  if( pCursr->readPending && pCursr->pFile && pCursr->pFile->dbf ){
          519  +    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, pCursr->key);
          520  +    pCursr->readPending = 0;
   514    521     }
   515         -  if( offset>=pTable->data.dsize ) return 0;
   516         -  if( offset+size>pTable->data.dsize ){
   517         -    n = pTable->data.dsize - offset;
          522  +  if( offset>=pCursr->data.dsize ) return 0;
          523  +  if( offset+size>pCursr->data.dsize ){
          524  +    n = pCursr->data.dsize - offset;
   518    525     }else{
   519    526       n = size;
   520    527     }
   521         -  memcpy(zBuf, &pTable->data.dptr[offset], n);
          528  +  memcpy(zBuf, &pCursr->data.dptr[offset], n);
   522    529     return n;
   523    530   }
   524    531   
   525    532   /*
   526    533   ** Return a pointer to bytes from the key or data.  The data returned
   527    534   ** is ephemeral.
   528    535   */
   529         -char *sqliteDbbeReadKey(DbbeTable *pTable, int offset){
   530         -  if( offset<0 || offset>=pTable->key.dsize ) return "";
   531         -  return &pTable->key.dptr[offset];
          536  +char *sqliteDbbeReadKey(DbbeCursor *pCursr, int offset){
          537  +  if( offset<0 || offset>=pCursr->key.dsize ) return "";
          538  +  return &pCursr->key.dptr[offset];
   532    539   }
   533         -char *sqliteDbbeReadData(DbbeTable *pTable, int offset){
   534         -  if( pTable->readPending && pTable->pFile && pTable->pFile->dbf ){
   535         -    pTable->data = gdbm_fetch(pTable->pFile->dbf, pTable->key);
   536         -    pTable->readPending = 0;
          540  +char *sqliteDbbeReadData(DbbeCursor *pCursr, int offset){
          541  +  if( pCursr->readPending && pCursr->pFile && pCursr->pFile->dbf ){
          542  +    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, pCursr->key);
          543  +    pCursr->readPending = 0;
   537    544     }
   538         -  if( offset<0 || offset>=pTable->data.dsize ) return "";
   539         -  return &pTable->data.dptr[offset];
          545  +  if( offset<0 || offset>=pCursr->data.dsize ) return "";
          546  +  return &pCursr->data.dptr[offset];
   540    547   }
   541    548   
   542    549   /*
   543    550   ** Return the total number of bytes in either data or key.
   544    551   */
   545         -int sqliteDbbeKeyLength(DbbeTable *pTable){
   546         -  return pTable->key.dsize;
          552  +int sqliteDbbeKeyLength(DbbeCursor *pCursr){
          553  +  return pCursr->key.dsize;
   547    554   }
   548         -int sqliteDbbeDataLength(DbbeTable *pTable){
   549         -  if( pTable->readPending && pTable->pFile && pTable->pFile->dbf ){
   550         -    pTable->data = gdbm_fetch(pTable->pFile->dbf, pTable->key);
   551         -    pTable->readPending = 0;
          555  +int sqliteDbbeDataLength(DbbeCursor *pCursr){
          556  +  if( pCursr->readPending && pCursr->pFile && pCursr->pFile->dbf ){
          557  +    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, pCursr->key);
          558  +    pCursr->readPending = 0;
   552    559     }
   553         -  return pTable->data.dsize;
          560  +  return pCursr->data.dsize;
   554    561   }
   555    562   
   556    563   /*
   557    564   ** Make is so that the next call to sqliteNextKey() finds the first
   558    565   ** key of the table.
   559    566   */
   560         -int sqliteDbbeRewind(DbbeTable *pTable){
   561         -  pTable->needRewind = 1;
          567  +int sqliteDbbeRewind(DbbeCursor *pCursr){
          568  +  pCursr->needRewind = 1;
   562    569     return SQLITE_OK;
   563    570   }
   564    571   
   565    572   /*
   566    573   ** Read the next key from the table.  Return 1 on success.  Return
   567    574   ** 0 if there are no more keys.
   568    575   */
   569         -int sqliteDbbeNextKey(DbbeTable *pTable){
          576  +int sqliteDbbeNextKey(DbbeCursor *pCursr){
   570    577     datum nextkey;
   571    578     int rc;
   572         -  if( pTable==0 || pTable->pFile==0 || pTable->pFile->dbf==0 ){
   573         -    pTable->readPending = 0;
          579  +  if( pCursr==0 || pCursr->pFile==0 || pCursr->pFile->dbf==0 ){
          580  +    pCursr->readPending = 0;
   574    581       return 0;
   575    582     }
   576         -  if( pTable->needRewind ){
   577         -    nextkey = gdbm_firstkey(pTable->pFile->dbf);
   578         -    pTable->needRewind = 0;
          583  +  if( pCursr->needRewind ){
          584  +    nextkey = gdbm_firstkey(pCursr->pFile->dbf);
          585  +    pCursr->needRewind = 0;
   579    586     }else{
   580         -    nextkey = gdbm_nextkey(pTable->pFile->dbf, pTable->key);
          587  +    nextkey = gdbm_nextkey(pCursr->pFile->dbf, pCursr->key);
   581    588     }
   582         -  datumClear(&pTable->key);
   583         -  datumClear(&pTable->data);
   584         -  pTable->key = nextkey;
   585         -  if( pTable->key.dptr ){
   586         -    pTable->readPending = 1;
          589  +  datumClear(&pCursr->key);
          590  +  datumClear(&pCursr->data);
          591  +  pCursr->key = nextkey;
          592  +  if( pCursr->key.dptr ){
          593  +    pCursr->readPending = 1;
   587    594       rc = 1;
   588    595     }else{
   589         -    pTable->needRewind = 1;
   590         -    pTable->readPending = 0;
          596  +    pCursr->needRewind = 1;
          597  +    pCursr->readPending = 0;
   591    598       rc = 0;
   592    599     }
   593    600     return rc;
   594    601   }
   595    602   
   596    603   /*
   597    604   ** Get a new integer key.
   598    605   */
   599         -int sqliteDbbeNew(DbbeTable *pTable){
          606  +int sqliteDbbeNew(DbbeCursor *pCursr){
   600    607     int iKey;
   601    608     datum key;
   602    609     int go = 1;
   603    610     int i;
   604    611     struct rc4 *pRc4;
   605    612   
   606         -  if( pTable->pFile==0 || pTable->pFile->dbf==0 ) return 1;
   607         -  pRc4 = &pTable->pBe->rc4;
          613  +  if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return 1;
          614  +  pRc4 = &pCursr->pBe->rc4;
   608    615     while( go ){
   609    616       iKey = 0;
   610    617       for(i=0; i<4; i++){
   611    618         iKey = (iKey<<8) + rc4byte(pRc4);
   612    619       }
   613    620       key.dptr = (char*)&iKey;
   614    621       key.dsize = 4;
   615         -    go = gdbm_exists(pTable->pFile->dbf, key);
          622  +    go = gdbm_exists(pCursr->pFile->dbf, key);
   616    623     }
   617    624     return iKey;
   618    625   }   
   619    626   
   620    627   /*
   621    628   ** Write an entry into the table.  Overwrite any prior entry with the
   622    629   ** same key.
   623    630   */
   624         -int sqliteDbbePut(DbbeTable *pTable, int nKey,char *pKey,int nData,char *pData){
          631  +int sqliteDbbePut(DbbeCursor *pCursr, int nKey,char *pKey,int nData,char *pData){
   625    632     datum data, key;
   626    633     int rc;
   627         -  if( pTable->pFile==0 || pTable->pFile->dbf==0 ) return SQLITE_ERROR;
          634  +  if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return SQLITE_ERROR;
   628    635     data.dsize = nData;
   629    636     data.dptr = pData;
   630    637     key.dsize = nKey;
   631    638     key.dptr = pKey;
   632         -  rc = gdbm_store(pTable->pFile->dbf, key, data, GDBM_REPLACE);
          639  +  rc = gdbm_store(pCursr->pFile->dbf, key, data, GDBM_REPLACE);
   633    640     if( rc ) rc = SQLITE_ERROR;
   634         -  datumClear(&pTable->key);
   635         -  datumClear(&pTable->data);
          641  +  datumClear(&pCursr->key);
          642  +  datumClear(&pCursr->data);
   636    643     return rc;
   637    644   }
   638    645   
   639    646   /*
   640    647   ** Remove an entry from a table, if the entry exists.
   641    648   */
   642         -int sqliteDbbeDelete(DbbeTable *pTable, int nKey, char *pKey){
          649  +int sqliteDbbeDelete(DbbeCursor *pCursr, int nKey, char *pKey){
   643    650     datum key;
   644    651     int rc;
   645         -  datumClear(&pTable->key);
   646         -  datumClear(&pTable->data);
   647         -  if( pTable->pFile==0 || pTable->pFile->dbf==0 ) return SQLITE_ERROR;
          652  +  datumClear(&pCursr->key);
          653  +  datumClear(&pCursr->data);
          654  +  if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return SQLITE_ERROR;
   648    655     key.dsize = nKey;
   649    656     key.dptr = pKey;
   650         -  rc = gdbm_delete(pTable->pFile->dbf, key);
          657  +  rc = gdbm_delete(pCursr->pFile->dbf, key);
   651    658     if( rc ) rc = SQLITE_ERROR;
   652    659     return rc;
   653    660   }
   654    661   
   655    662   /*
   656    663   ** Open a temporary file.  The file should be deleted when closed.
   657    664   **

Changes to src/dbbe.h.

    24     24   ** This file defines the interface to the database backend (Dbbe).
    25     25   **
    26     26   ** The database backend is designed to be as general as possible
    27     27   ** so that it can easily be replaced by a different backend.
    28     28   ** This library was originally designed to support the following
    29     29   ** backends: GDBM, NDBM, SDBM, Berkeley DB.
    30     30   **
    31         -** $Id: dbbe.h,v 1.5 2000/06/17 13:12:39 drh Exp $
           31  +** $Id: dbbe.h,v 1.6 2000/06/21 13:59:11 drh Exp $
    32     32   */
    33     33   #ifndef _SQLITE_DBBE_H_
    34     34   #define _SQLITE_DBBE_H_
    35     35   #include <stdio.h>
    36     36   
    37     37   /*
    38     38   ** The database backend supports two opaque structures.  A Dbbe is
    39     39   ** a context for the entire set of tables forming a complete
    40         -** database.  A DbbeTable is a single table.
           40  +** database.  A DbbeCursor is a pointer into a single single table.
    41     41   **
    42     42   ** Note that at this level, the term "table" can mean either an
    43     43   ** SQL table or an SQL index.  In this module, a table stores a
    44     44   ** single arbitrary-length key and corresponding arbitrary-length
    45     45   ** data.  The differences between tables and indices, and the
    46     46   ** segregation of data into various fields or columns is handled
    47     47   ** by software at higher layers.
    48     48   **
    49         -** The DbbeTable structure holds some state information, such as
           49  +** The DbbeCursor structure holds some state information, such as
    50     50   ** the key and data from the last retrieval.  For this reason, 
    51     51   ** the backend must allow the creation of multiple independent
    52         -** DbbeTable structures for each table in the database.
           52  +** DbbeCursor structures for each table in the database.
    53     53   */
    54     54   typedef struct Dbbe Dbbe;
    55         -typedef struct DbbeTable DbbeTable;
           55  +typedef struct DbbeCursor DbbeCursor;
    56     56   
    57     57   /*
    58     58   ** The 18 interface routines.
    59     59   */
    60     60   
    61     61   /* Open a complete database */
    62     62   Dbbe *sqliteDbbeOpen(const char *zName, int write, int create, char **pzErr);
    63     63   
    64     64   /* Close the whole database. */
    65     65   void sqliteDbbeClose(Dbbe*);
    66     66   
    67         -/* Open a particular table of a previously opened database.
    68         -** Create the table if it doesn't already exist and writeable!=0.
           67  +/* Open a cursor into particular file of a previously opened database.
           68  +** Create the file if it doesn't already exist and writeable!=0.  zName
           69  +** is the base name of the file to be opened.  This routine will add
           70  +** an appropriate path and extension to the filename to locate the 
           71  +** actual file.
    69     72   **
    70         -** If zTableName is 0 or "", then a temporary table is created that
           73  +** If zName is 0 or "", then a temporary file is created that
    71     74   ** will be deleted when closed.
    72     75   */
    73         -int sqliteDbbeOpenTable(Dbbe*, const char *zName, int writeable, DbbeTable **);
           76  +int sqliteDbbeOpenCursor(Dbbe*, const char *zName, int writeable, DbbeCursor**);
    74     77   
    75     78   /* Delete a table from the database */
    76     79   void sqliteDbbeDropTable(Dbbe*, const char *zTableName);
    77     80   
    78     81   /* Reorganize a table to speed access or reduce its disk usage */
    79     82   void sqliteDbbeReorganizeTable(Dbbe*, const char *zTableName);
    80     83   
    81         -/* Close a table */
    82         -void sqliteDbbeCloseTable(DbbeTable*);
           84  +/* Close a cursor */
           85  +void sqliteDbbeCloseCursor(DbbeCursor*);
    83     86   
    84     87   /* Fetch an entry from a table with the given key.  Return 1 if
    85     88   ** successful and 0 if no such entry exists.
    86     89   */
    87         -int sqliteDbbeFetch(DbbeTable*, int nKey, char *pKey);
           90  +int sqliteDbbeFetch(DbbeCursor*, int nKey, char *pKey);
    88     91   
    89     92   /* Return 1 if the given key is already in the table.  Return 0
    90     93   ** if it is not.
    91     94   */
    92         -int sqliteDbbeTest(DbbeTable*, int nKey, char *pKey);
           95  +int sqliteDbbeTest(DbbeCursor*, int nKey, char *pKey);
    93     96   
    94     97   /* Retrieve the key or data used for the last fetch.  Only size
    95     98   ** bytes are read beginning with the offset-th byte.  The return
    96     99   ** value is the actual number of bytes read.
    97    100   */
    98         -int sqliteDbbeCopyKey(DbbeTable*, int offset, int size, char *zBuf);
    99         -int sqliteDbbeCopyData(DbbeTable*, int offset, int size, char *zBuf);
          101  +int sqliteDbbeCopyKey(DbbeCursor*, int offset, int size, char *zBuf);
          102  +int sqliteDbbeCopyData(DbbeCursor*, int offset, int size, char *zBuf);
   100    103   
   101    104   /* Retrieve the key or data.  The result is ephemeral.  In other words,
   102    105   ** the result is stored in a buffer that might be overwritten on the next
   103    106   ** call to any DBBE routine.  If the results are needed for longer than
   104    107   ** that, you must make a copy.
   105    108   */
   106         -char *sqliteDbbeReadKey(DbbeTable*, int offset);
   107         -char *sqliteDbbeReadData(DbbeTable*, int offset);
          109  +char *sqliteDbbeReadKey(DbbeCursor*, int offset);
          110  +char *sqliteDbbeReadData(DbbeCursor*, int offset);
   108    111   
   109    112   /* Return the length of the most recently fetched key or data. */
   110         -int sqliteDbbeKeyLength(DbbeTable*);
   111         -int sqliteDbbeDataLength(DbbeTable*);
          113  +int sqliteDbbeKeyLength(DbbeCursor*);
          114  +int sqliteDbbeDataLength(DbbeCursor*);
   112    115   
   113    116   /* Retrieve the next entry in the table.  The first key is retrieved
   114    117   ** the first time this routine is called, or after a call to
   115    118   ** sqliteDbbeRewind().  The return value is 1 if there is another
   116    119   ** entry, or 0 if there are no more entries. */
   117         -int sqliteDbbeNextKey(DbbeTable*);
          120  +int sqliteDbbeNextKey(DbbeCursor*);
   118    121   
   119    122   /* Make it so that the next call to sqliteDbbeNextKey() returns
   120    123   ** the first entry of the table. */
   121         -int sqliteDbbeRewind(DbbeTable*);
          124  +int sqliteDbbeRewind(DbbeCursor*);
   122    125   
   123    126   /* Get a new integer key for this table. */
   124         -int sqliteDbbeNew(DbbeTable*);
          127  +int sqliteDbbeNew(DbbeCursor*);
   125    128   
   126    129   /* Write an entry into a table.  If another entry already exists with
   127    130   ** the same key, the old entry is discarded first.
   128    131   */
   129         -int sqliteDbbePut(DbbeTable*, int nKey, char *pKey, int nData, char *pData);
          132  +int sqliteDbbePut(DbbeCursor*, int nKey, char *pKey, int nData, char *pData);
   130    133   
   131    134   /* Remove an entry from the table */
   132         -int sqliteDbbeDelete(DbbeTable*, int nKey, char *pKey);
          135  +int sqliteDbbeDelete(DbbeCursor*, int nKey, char *pKey);
   133    136   
   134    137   /* Open a file suitable for temporary storage */
   135    138   int sqliteDbbeOpenTempFile(Dbbe*, FILE**);
   136    139   
   137    140   /* Close a temporary file */
   138    141   void sqliteDbbeCloseTempFile(Dbbe *, FILE *);
   139    142   
   140    143   #endif /* defined(_SQLITE_DBBE_H_) */

Changes to src/delete.c.

    20     20   **   drh@hwaci.com
    21     21   **   http://www.hwaci.com/drh/
    22     22   **
    23     23   *************************************************************************
    24     24   ** This file contains C code routines that are called by the parser
    25     25   ** to handle DELETE FROM statements.
    26     26   **
    27         -** $Id: delete.c,v 1.5 2000/06/17 13:12:39 drh Exp $
           27  +** $Id: delete.c,v 1.6 2000/06/21 13:59:11 drh Exp $
    28     28   */
    29     29   #include "sqliteInt.h"
    30     30   
    31     31   /*
    32     32   ** Process a DELETE FROM statement.
    33     33   */
    34     34   void sqliteDeleteFrom(
................................................................................
    64     64           " may not be modified", 0);
    65     65         pParse->nErr++;
    66     66         goto delete_from_cleanup;
    67     67       }
    68     68     }
    69     69     pTab = pTabList->a[0].pTab;
    70     70   
    71         -  /* Resolve the field names in all the expressions.
           71  +  /* Resolve the column names in all the expressions.
    72     72     */
    73     73     if( pWhere ){
    74     74       sqliteExprResolveInSelect(pParse, pWhere);
    75     75       if( sqliteExprResolveIds(pParse, pTabList, pWhere) ){
    76     76         goto delete_from_cleanup;
    77     77       }
    78     78       if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
................................................................................
   113    113     addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end, 0, 0);
   114    114     if( pTab->pIndex ){
   115    115       sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
   116    116       sqliteVdbeAddOp(v, OP_Fetch, base, 0, 0, 0);
   117    117       for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
   118    118         int j;
   119    119         sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
   120         -      for(j=0; j<pIdx->nField; j++){
   121         -        sqliteVdbeAddOp(v, OP_Field, base, pIdx->aiField[j], 0, 0);
          120  +      for(j=0; j<pIdx->nColumn; j++){
          121  +        sqliteVdbeAddOp(v, OP_Field, base, pIdx->aiColumn[j], 0, 0);
   122    122         }
   123         -      sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nField, 0, 0, 0);
          123  +      sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nColumn, 0, 0, 0);
   124    124         sqliteVdbeAddOp(v, OP_DeleteIdx, base+i, 0, 0, 0);
   125    125       }
   126    126     }
   127    127     sqliteVdbeAddOp(v, OP_Delete, base, 0, 0, 0);
   128    128     sqliteVdbeAddOp(v, OP_Goto, 0, addr, 0, 0);
   129    129     sqliteVdbeAddOp(v, OP_ListClose, 0, 0, 0, end);
   130    130   
   131    131   delete_from_cleanup:
   132    132     sqliteIdListDelete(pTabList);
   133    133     sqliteExprDelete(pWhere);
   134    134     return;
   135    135   }

Changes to src/expr.c.

    20     20   **   drh@hwaci.com
    21     21   **   http://www.hwaci.com/drh/
    22     22   **
    23     23   *************************************************************************
    24     24   ** This file contains routines used for analyzing expressions and
    25     25   ** for generating VDBE code that evaluates expressions.
    26     26   **
    27         -** $Id: expr.c,v 1.17 2000/06/17 13:12:40 drh Exp $
           27  +** $Id: expr.c,v 1.18 2000/06/21 13:59:11 drh Exp $
    28     28   */
    29     29   #include "sqliteInt.h"
    30     30   
    31     31   /*
    32     32   ** Walk an expression tree.  Return 1 if the expression is constant
    33     33   ** and 0 if it involves variables.
    34     34   */
    35     35   static int isConstant(Expr *p){
    36     36     switch( p->op ){
    37     37       case TK_ID:
    38         -    case TK_FIELD:
           38  +    case TK_COLUMN:
    39     39       case TK_DOT:
    40     40         return 0;
    41     41       default: {
    42     42         if( p->pLeft && !isConstant(p->pLeft) ) return 0;
    43     43         if( p->pRight && !isConstant(p->pRight) ) return 0;
    44     44         if( p->pList ){
    45     45           int i;
................................................................................
    54     54   }
    55     55   
    56     56   /*
    57     57   ** Walk the expression tree and process operators of the form:
    58     58   **
    59     59   **       expr IN (SELECT ...)
    60     60   **
    61         -** These operators have to be processed before field names are
           61  +** These operators have to be processed before column names are
    62     62   ** resolved because each such operator increments pParse->nTab
    63     63   ** to reserve cursor numbers for its own use.  But pParse->nTab
    64         -** needs to be constant once we begin resolving field names.
           64  +** needs to be constant once we begin resolving column names.
    65     65   **
    66     66   ** Actually, the processing of IN-SELECT is only started by this
    67     67   ** routine.  This routine allocates a cursor number to the IN-SELECT
    68     68   ** and then moves on.  The code generation is done by 
    69     69   ** sqliteExprResolveIds() which must be called afterwards.
    70     70   */
    71     71   void sqliteExprResolveInSelect(Parse *pParse, Expr *pExpr){
................................................................................
    83     83         }
    84     84       }
    85     85     }
    86     86   }
    87     87   
    88     88   /*
    89     89   ** This routine walks an expression tree and resolves references to
    90         -** table fields.  Nodes of the form ID.ID or ID resolve into an
    91         -** index to the table in the table list and a field offset.  The opcode
    92         -** for such nodes is changed to TK_FIELD.  The iTable value is changed
           90  +** table columns.  Nodes of the form ID.ID or ID resolve into an
           91  +** index to the table in the table list and a column offset.  The opcode
           92  +** for such nodes is changed to TK_COLUMN.  The iTable value is changed
    93     93   ** to the index of the referenced table in pTabList plus the pParse->nTab
    94         -** value.  The iField value is changed to the index of the field of the 
           94  +** value.  The iColumn value is changed to the index of the column of the 
    95     95   ** referenced table.
    96     96   **
    97     97   ** We also check for instances of the IN operator.  IN comes in two
    98     98   ** forms:
    99     99   **
   100    100   **           expr IN (exprlist)
   101    101   ** and
................................................................................
   105    105   ** of allowed values.  The second form causes the SELECT to generate 
   106    106   ** a temporary table.
   107    107   **
   108    108   ** This routine also looks for scalar SELECTs that are part of an expression.
   109    109   ** If it finds any, it generates code to write the value of that select
   110    110   ** into a memory cell.
   111    111   **
   112         -** Unknown fields or tables provoke an error.  The function returns
          112  +** Unknown columns or tables provoke an error.  The function returns
   113    113   ** the number of errors seen and leaves an error message on pParse->zErrMsg.
   114    114   */
   115    115   int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){
   116    116     if( pExpr==0 ) return 0;
   117    117     switch( pExpr->op ){
   118    118       /* A lone identifier */
   119    119       case TK_ID: {
................................................................................
   124    124           int j;
   125    125           Table *pTab = pTabList->a[i].pTab;
   126    126           if( pTab==0 ) continue;
   127    127           for(j=0; j<pTab->nCol; j++){
   128    128             if( sqliteStrICmp(pTab->aCol[j].zName, z)==0 ){
   129    129               cnt++;
   130    130               pExpr->iTable = i + pParse->nTab;
   131         -            pExpr->iField = j;
          131  +            pExpr->iColumn = j;
   132    132             }
   133    133           }
   134    134         }
   135    135         sqliteFree(z);
   136    136         if( cnt==0 ){
   137         -        sqliteSetNString(&pParse->zErrMsg, "no such field: ", -1,  
          137  +        sqliteSetNString(&pParse->zErrMsg, "no such column: ", -1,  
   138    138             pExpr->token.z, pExpr->token.n, 0);
   139    139           pParse->nErr++;
   140    140           return 1;
   141    141         }else if( cnt>1 ){
   142         -        sqliteSetNString(&pParse->zErrMsg, "ambiguous field name: ", -1,  
          142  +        sqliteSetNString(&pParse->zErrMsg, "ambiguous column name: ", -1,  
   143    143             pExpr->token.z, pExpr->token.n, 0);
   144    144           pParse->nErr++;
   145    145           return 1;
   146    146         }
   147         -      pExpr->op = TK_FIELD;
          147  +      pExpr->op = TK_COLUMN;
   148    148         break; 
   149    149       }
   150    150     
   151         -    /* A table name and field name:  ID.ID */
          151  +    /* A table name and column name:  ID.ID */
   152    152       case TK_DOT: {
   153    153         int cnt = 0;             /* Number of matches */
   154    154         int i;                   /* Loop counter */
   155    155         Expr *pLeft, *pRight;    /* Left and right subbranches of the expr */
   156    156         char *zLeft, *zRight;    /* Text of an identifier */
   157    157   
   158    158         pLeft = pExpr->pLeft;
................................................................................
   172    172             zTab = pTab->zName;
   173    173           }
   174    174           if( sqliteStrICmp(zTab, zLeft)!=0 ) continue;
   175    175           for(j=0; j<pTab->nCol; j++){
   176    176             if( sqliteStrICmp(pTab->aCol[j].zName, zRight)==0 ){
   177    177               cnt++;
   178    178               pExpr->iTable = i + pParse->nTab;
   179         -            pExpr->iField = j;
          179  +            pExpr->iColumn = j;
   180    180             }
   181    181           }
   182    182         }
   183    183         sqliteFree(zLeft);
   184    184         sqliteFree(zRight);
   185    185         if( cnt==0 ){
   186         -        sqliteSetNString(&pParse->zErrMsg, "no such field: ", -1,  
          186  +        sqliteSetNString(&pParse->zErrMsg, "no such column: ", -1,  
   187    187             pLeft->token.z, pLeft->token.n, ".", 1, 
   188    188             pRight->token.z, pRight->token.n, 0);
   189    189           pParse->nErr++;
   190    190           return 1;
   191    191         }else if( cnt>1 ){
   192         -        sqliteSetNString(&pParse->zErrMsg, "ambiguous field name: ", -1,  
          192  +        sqliteSetNString(&pParse->zErrMsg, "ambiguous column name: ", -1,  
   193    193             pLeft->token.z, pLeft->token.n, ".", 1,
   194    194             pRight->token.z, pRight->token.n, 0);
   195    195           pParse->nErr++;
   196    196           return 1;
   197    197         }
   198    198         sqliteExprDelete(pLeft);
   199    199         pExpr->pLeft = 0;
   200    200         sqliteExprDelete(pRight);
   201    201         pExpr->pRight = 0;
   202         -      pExpr->op = TK_FIELD;
          202  +      pExpr->op = TK_COLUMN;
   203    203         break;
   204    204       }
   205    205   
   206    206       case TK_IN: {
   207    207         Vdbe *v = sqliteGetVdbe(pParse);
   208    208         if( v==0 ) return 1;
   209    209         if( sqliteExprResolveIds(pParse, pTabList, pExpr->pLeft) ){
................................................................................
   259    259         }
   260    260         break;
   261    261       }
   262    262   
   263    263       case TK_SELECT: {
   264    264         /* This has to be a scalar SELECT.  Generate code to put the
   265    265         ** value of this select in a memory cell and record the number
   266         -      ** of the memory cell in iField.
          266  +      ** of the memory cell in iColumn.
   267    267         */
   268         -      pExpr->iField = pParse->nMem++;
   269         -      if( sqliteSelect(pParse, pExpr->pSelect, SRT_Mem, pExpr->iField) ){
          268  +      pExpr->iColumn = pParse->nMem++;
          269  +      if( sqliteSelect(pParse, pExpr->pSelect, SRT_Mem, pExpr->iColumn) ){
   270    270           return 1;
   271    271         }
   272    272         break;
   273    273       }
   274    274   
   275    275       /* For all else, just recursively walk the tree */
   276    276       default: {
................................................................................
   351    351         int id = sqliteFuncId(&pExpr->token);
   352    352         int n = pExpr->pList ? pExpr->pList->nExpr : 0;
   353    353         int no_such_func = 0;
   354    354         int too_many_args = 0;
   355    355         int too_few_args = 0;
   356    356         int is_agg = 0;
   357    357         int i;
   358         -      pExpr->iField = id;
          358  +      pExpr->iColumn = id;
   359    359         switch( id ){
   360    360           case FN_Unknown: { 
   361    361             no_such_func = 1;
   362    362             break;
   363    363           }
   364    364           case FN_Count: { 
   365    365             no_such_func = !allowAgg;
................................................................................
   463    463       case TK_ISNULL:   op = OP_IsNull;   break;
   464    464       case TK_NOTNULL:  op = OP_NotNull;  break;
   465    465       case TK_NOT:      op = OP_Not;      break;
   466    466       case TK_UMINUS:   op = OP_Negative; break;
   467    467       default: break;
   468    468     }
   469    469     switch( pExpr->op ){
   470         -    case TK_FIELD: {
          470  +    case TK_COLUMN: {
   471    471         if( pParse->useAgg ){
   472    472           sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg, 0, 0);
   473    473         }else{
   474         -        sqliteVdbeAddOp(v, OP_Field, pExpr->iTable, pExpr->iField, 0, 0);
          474  +        sqliteVdbeAddOp(v, OP_Field, pExpr->iTable, pExpr->iColumn, 0, 0);
   475    475         }
   476    476         break;
   477    477       }
   478    478       case TK_INTEGER: {
   479    479         int i = atoi(pExpr->token.z);
   480    480         sqliteVdbeAddOp(v, OP_Integer, i, 0, 0, 0);
   481    481         break;
................................................................................
   558    558         dest = sqliteVdbeCurrentAddr(v) + 2;
   559    559         sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
   560    560         sqliteVdbeAddOp(v, OP_AddImm, -1, 0, 0, 0);
   561    561         break;
   562    562       }
   563    563       case TK_AGG_FUNCTION: {
   564    564         sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg, 0, 0);
   565         -      if( pExpr->iField==FN_Avg ){
          565  +      if( pExpr->iColumn==FN_Avg ){
   566    566           assert( pParse->iAggCount>=0 && pParse->iAggCount<pParse->nAgg );
   567    567           sqliteVdbeAddOp(v, OP_AggGet, 0, pParse->iAggCount, 0, 0);
   568    568           sqliteVdbeAddOp(v, OP_Divide, 0, 0, 0, 0);
   569    569         }
   570    570         break;
   571    571       }
   572    572       case TK_FUNCTION: {
   573         -      int id = pExpr->iField;
          573  +      int id = pExpr->iColumn;
   574    574         int op;
   575    575         int i;
   576    576         ExprList *pList = pExpr->pList;
   577    577         if( id==FN_Fcnt ){
   578    578           sqliteVdbeAddOp(v, OP_Fcnt, 0, 0, 0, 0);
   579    579           break;
   580    580         }
................................................................................
   584    584           if( i>0 ){
   585    585             sqliteVdbeAddOp(v, op, 0, 0, 0, 0);
   586    586           }
   587    587         }
   588    588         break;
   589    589       }
   590    590       case TK_SELECT: {
   591         -      sqliteVdbeAddOp(v, OP_MemLoad, pExpr->iField, 0, 0, 0);
          591  +      sqliteVdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0, 0, 0);
   592    592         break;
   593    593       }
   594    594       case TK_IN: {
   595    595         int addr;
   596    596         sqliteVdbeAddOp(v, OP_Integer, 1, 0, 0, 0);
   597    597         sqliteExprCode(pParse, pExpr->pLeft);
   598    598         addr = sqliteVdbeCurrentAddr(v);
................................................................................
   860    860   int sqliteExprAnalyzeAggregates(Parse *pParse, Expr *pExpr){
   861    861     int i;
   862    862     AggExpr *aAgg;
   863    863     int nErr = 0;
   864    864   
   865    865     if( pExpr==0 ) return 0;
   866    866     switch( pExpr->op ){
   867         -    case TK_FIELD: {
          867  +    case TK_COLUMN: {
   868    868         aAgg = pParse->aAgg;
   869    869         for(i=0; i<pParse->nAgg; i++){
   870    870           if( aAgg[i].isAgg ) continue;
   871    871           if( aAgg[i].pExpr->iTable==pExpr->iTable
   872         -         && aAgg[i].pExpr->iField==pExpr->iField ){
          872  +         && aAgg[i].pExpr->iColumn==pExpr->iColumn ){
   873    873             break;
   874    874           }
   875    875         }
   876    876         if( i>=pParse->nAgg ){
   877    877           i = appendAggInfo(pParse);
   878    878           if( i<0 ) return 1;
   879    879           pParse->aAgg[i].isAgg = 0;
   880    880           pParse->aAgg[i].pExpr = pExpr;
   881    881         }
   882    882         pExpr->iAgg = i;
   883    883         break;
   884    884       }
   885    885       case TK_AGG_FUNCTION: {
   886         -      if( pExpr->iField==FN_Count || pExpr->iField==FN_Avg ){
          886  +      if( pExpr->iColumn==FN_Count || pExpr->iColumn==FN_Avg ){
   887    887           if( pParse->iAggCount>=0 ){
   888    888             i = pParse->iAggCount;
   889    889           }else{
   890    890             i = appendAggInfo(pParse);
   891    891             if( i<0 ) return 1;
   892    892             pParse->aAgg[i].isAgg = 1;
   893    893             pParse->aAgg[i].pExpr = 0;
   894    894             pParse->iAggCount = i;
   895    895           }
   896         -        if( pExpr->iField==FN_Count ){
          896  +        if( pExpr->iColumn==FN_Count ){
   897    897             pExpr->iAgg = i;
   898    898             break;
   899    899           }
   900    900         }
   901    901         aAgg = pParse->aAgg;
   902    902         for(i=0; i<pParse->nAgg; i++){
   903    903           if( !aAgg[i].isAgg ) continue;

Changes to src/insert.c.

    20     20   **   drh@hwaci.com
    21     21   **   http://www.hwaci.com/drh/
    22     22   **
    23     23   *************************************************************************
    24     24   ** This file contains C code routines that are called by the parser
    25     25   ** to handle INSERT statements.
    26     26   **
    27         -** $Id: insert.c,v 1.10 2000/06/17 13:12:40 drh Exp $
           27  +** $Id: insert.c,v 1.11 2000/06/21 13:59:12 drh Exp $
    28     28   */
    29     29   #include "sqliteInt.h"
    30     30   
    31     31   /*
    32     32   ** This routine is call to handle SQL of the following forms:
    33     33   **
    34     34   **    insert into TABLE (IDLIST) values(EXPRLIST)
    35     35   **    insert into TABLE (IDLIST) select
    36     36   **
    37     37   ** The IDLIST following the table name is always optional.  If omitted,
    38     38   ** then a list of all columns for the table is substituted.  The IDLIST
    39         -** appears in the pField parameter.  pField is NULL if IDLIST is omitted.
           39  +** appears in the pColumn parameter.  pColumn is NULL if IDLIST is omitted.
    40     40   **
    41     41   ** The pList parameter holds EXPRLIST in the first form of the INSERT
    42     42   ** statement above, and pSelect is NULL.  For the second form, pList is
    43     43   ** NULL and pSelect is a pointer to the select statement used to generate
    44     44   ** data for the insert.
    45     45   */
    46     46   void sqliteInsert(
    47     47     Parse *pParse,        /* Parser context */
    48     48     Token *pTableName,    /* Name of table into which we are inserting */
    49     49     ExprList *pList,      /* List of values to be inserted */
    50     50     Select *pSelect,      /* A SELECT statement to use as the data source */
    51         -  IdList *pField        /* Field names corresponding to IDLIST. */
           51  +  IdList *pColumn       /* Column names corresponding to IDLIST. */
    52     52   ){
    53     53     Table *pTab;          /* The table to insert into */
    54     54     char *zTab;           /* Name of the table into which we are inserting */
    55     55     int i, j, idx;        /* Loop counters */
    56     56     Vdbe *v;              /* Generate code into this virtual machine */
    57     57     Index *pIdx;          /* For looping over indices of the table */
    58     58     int srcTab;           /* Date comes from this temporary cursor if >=0 */
    59         -  int nField;           /* Number of columns in the data */
           59  +  int nColumn;          /* Number of columns in the data */
    60     60     int base;             /* First available cursor */
    61     61     int iCont, iBreak;    /* Beginning and end of the loop over srcTab */
    62     62   
    63     63     /* Locate the table into which we will be inserting new information.
    64     64     */
    65     65     zTab = sqliteTableNameFromToken(pTableName);
    66     66     pTab = sqliteFindTable(pParse->db, zTab);
................................................................................
    92     92     if( pSelect ){
    93     93       int rc;
    94     94       srcTab = pParse->nTab++;
    95     95       sqliteVdbeAddOp(v, OP_Open, srcTab, 1, 0, 0);
    96     96       rc = sqliteSelect(pParse, pSelect, SRT_Table, srcTab);
    97     97       if( rc ) goto insert_cleanup;
    98     98       assert( pSelect->pEList );
    99         -    nField = pSelect->pEList->nExpr;
           99  +    nColumn = pSelect->pEList->nExpr;
   100    100     }else{
   101    101       srcTab = -1;
   102    102       assert( pList );
   103         -    nField = pList->nExpr;
          103  +    nColumn = pList->nExpr;
   104    104     }
   105    105   
   106    106     /* Make sure the number of columns in the source data matches the number
   107    107     ** of columns to be inserted into the table.
   108    108     */
   109         -  if( pField==0 && nField!=pTab->nCol ){
          109  +  if( pColumn==0 && nColumn!=pTab->nCol ){
   110    110       char zNum1[30];
   111    111       char zNum2[30];
   112         -    sprintf(zNum1,"%d", nField);
          112  +    sprintf(zNum1,"%d", nColumn);
   113    113       sprintf(zNum2,"%d", pTab->nCol);
   114    114       sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName,
   115    115          " has ", zNum2, " columns but ",
   116    116          zNum1, " values were supplied", 0);
   117    117       pParse->nErr++;
   118    118       goto insert_cleanup;
   119    119     }
   120         -  if( pField!=0 && nField!=pField->nId ){
          120  +  if( pColumn!=0 && nColumn!=pColumn->nId ){
   121    121       char zNum1[30];
   122    122       char zNum2[30];
   123         -    sprintf(zNum1,"%d", nField);
   124         -    sprintf(zNum2,"%d", pField->nId);
          123  +    sprintf(zNum1,"%d", nColumn);
          124  +    sprintf(zNum2,"%d", pColumn->nId);
   125    125       sqliteSetString(&pParse->zErrMsg, zNum1, " values for ",
   126    126          zNum2, " columns", 0);
   127    127       pParse->nErr++;
   128    128       goto insert_cleanup;
   129    129     }
   130    130   
   131    131     /* If the INSERT statement included an IDLIST term, then make sure
   132    132     ** all elements of the IDLIST really are columns of the table and 
   133    133     ** remember the column indices.
   134    134     */
   135         -  if( pField ){
   136         -    for(i=0; i<pField->nId; i++){
   137         -      pField->a[i].idx = -1;
          135  +  if( pColumn ){
          136  +    for(i=0; i<pColumn->nId; i++){
          137  +      pColumn->a[i].idx = -1;
   138    138       }
   139         -    for(i=0; i<pField->nId; i++){
          139  +    for(i=0; i<pColumn->nId; i++){
   140    140         for(j=0; j<pTab->nCol; j++){
   141         -        if( sqliteStrICmp(pField->a[i].zName, pTab->aCol[j].zName)==0 ){
   142         -          pField->a[i].idx = j;
          141  +        if( sqliteStrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
          142  +          pColumn->a[i].idx = j;
   143    143             break;
   144    144           }
   145    145         }
   146    146         if( j>=pTab->nCol ){
   147    147           sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName,
   148         -           " has no column named ", pField->a[i].zName, 0);
          148  +           " has no column named ", pColumn->a[i].zName, 0);
   149    149           pParse->nErr++;
   150    150           goto insert_cleanup;
   151    151         }
   152    152       }
   153    153     }
   154    154   
   155    155     /* Open cursors into the table that is received the new data and
................................................................................
   175    175     /* Create a new entry in the table and fill it with data.
   176    176     */
   177    177     sqliteVdbeAddOp(v, OP_New, 0, 0, 0, 0);
   178    178     if( pTab->pIndex ){
   179    179       sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
   180    180     }
   181    181     for(i=0; i<pTab->nCol; i++){
   182         -    if( pField==0 ){
          182  +    if( pColumn==0 ){
   183    183         j = i;
   184    184       }else{
   185         -      for(j=0; j<pField->nId; j++){
   186         -        if( pField->a[j].idx==i ) break;
          185  +      for(j=0; j<pColumn->nId; j++){
          186  +        if( pColumn->a[j].idx==i ) break;
   187    187         }
   188    188       }
   189         -    if( pField && j>=pField->nId ){
          189  +    if( pColumn && j>=pColumn->nId ){
   190    190         char *zDflt = pTab->aCol[i].zDflt;
   191    191         if( zDflt==0 ){
   192    192           sqliteVdbeAddOp(v, OP_Null, 0, 0, 0, 0);
   193    193         }else{
   194    194           sqliteVdbeAddOp(v, OP_String, 0, 0, zDflt, 0);
   195    195         }
   196    196       }else if( srcTab>=0 ){
................................................................................
   205    205     /* Create appropriate entries for the new data row in all indices
   206    206     ** of the table.
   207    207     */
   208    208     for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
   209    209       if( pIdx->pNext ){
   210    210         sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
   211    211       }
   212         -    for(i=0; i<pIdx->nField; i++){
   213         -      int idx = pIdx->aiField[i];
   214         -      if( pField==0 ){
          212  +    for(i=0; i<pIdx->nColumn; i++){
          213  +      int idx = pIdx->aiColumn[i];
          214  +      if( pColumn==0 ){
   215    215           j = idx;
   216    216         }else{
   217         -        for(j=0; j<pField->nId; j++){
   218         -          if( pField->a[j].idx==idx ) break;
          217  +        for(j=0; j<pColumn->nId; j++){
          218  +          if( pColumn->a[j].idx==idx ) break;
   219    219           }
   220    220         }
   221         -      if( pField && j>=pField->nId ){
          221  +      if( pColumn && j>=pColumn->nId ){
   222    222           char *zDflt = pTab->aCol[idx].zDflt;
   223    223           if( zDflt==0 ){
   224    224             sqliteVdbeAddOp(v, OP_Null, 0, 0, 0, 0);
   225    225           }else{
   226    226             sqliteVdbeAddOp(v, OP_String, 0, 0, zDflt, 0);
   227    227           }
   228    228         }else if( srcTab>=0 ){
   229    229           sqliteVdbeAddOp(v, OP_Field, srcTab, idx, 0, 0); 
   230    230         }else{
   231    231           sqliteExprCode(pParse, pList->a[j].pExpr);
   232    232         }
   233    233       }
   234         -    sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nField, 0, 0, 0);
          234  +    sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nColumn, 0, 0, 0);
   235    235       sqliteVdbeAddOp(v, OP_PutIdx, idx+base, 0, 0, 0);
   236    236     }
   237    237   
   238    238     /* The bottom of the loop, if the data source is a SELECT statement
   239    239     */
   240    240     if( srcTab>=0 ){
   241    241       sqliteVdbeAddOp(v, OP_Goto, 0, iCont, 0, 0);
   242    242       sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, iBreak);
   243    243     }
   244    244   
   245    245   insert_cleanup:
   246    246     if( pList ) sqliteExprListDelete(pList);
   247    247     if( pSelect ) sqliteSelectDelete(pSelect);
   248         -  sqliteIdListDelete(pField);
          248  +  sqliteIdListDelete(pColumn);
   249    249   }

Changes to src/main.c.

    22     22   **
    23     23   *************************************************************************
    24     24   ** Main file for the SQLite library.  The routines in this file
    25     25   ** implement the programmer interface to the library.  Routines in
    26     26   ** other files are for internal use by SQLite and should not be
    27     27   ** accessed by users of the library.
    28     28   **
    29         -** $Id: main.c,v 1.12 2000/06/07 23:51:50 drh Exp $
           29  +** $Id: main.c,v 1.13 2000/06/21 13:59:12 drh Exp $
    30     30   */
    31     31   #include "sqliteInt.h"
    32     32   
    33     33   /*
    34     34   ** This is the callback routine for the code that initializes the
    35     35   ** database.  Each callback contains text of a CREATE TABLE or
    36     36   ** CREATE INDEX statement that must be parsed to yield the internal
................................................................................
    86     86     **        type       text,    --  Either "table" or "index"
    87     87     **        name       text,    --  Name of table or index
    88     88     **        tbl_name   text,    --  Associated table 
    89     89     **        sql        text     --  The CREATE statement for this object
    90     90     **    );
    91     91     **
    92     92     ** The sqlite_master table contains a single entry for each table
    93         -  ** and each index.  The "type" field tells whether the entry is
    94         -  ** a table or index.  The "name" field is the name of the object.
           93  +  ** and each index.  The "type" column tells whether the entry is
           94  +  ** a table or index.  The "name" column is the name of the object.
    95     95     ** The "tbl_name" is the name of the associated table.  For tables,
    96         -  ** the tbl_name field is always the same as name.  For indices, the
    97         -  ** tbl_name field contains the name of the table that the index
    98         -  ** indexes.  Finally, the sql field contains the complete text of
           96  +  ** the tbl_name column is always the same as name.  For indices, the
           97  +  ** tbl_name column contains the name of the table that the index
           98  +  ** indexes.  Finally, the "sql" column contains the complete text of
    99     99     ** the CREATE TABLE or CREATE INDEX statement that originally created
   100    100     ** the table or index.
   101    101     **
   102    102     ** The following program invokes its callback on the SQL for each
   103    103     ** table then goes back and invokes the callback on the
   104    104     ** SQL for each index.  The callback will invoke the
   105    105     ** parser to build the internal representation of the

Changes to src/parse.y.

    22     22   **
    23     23   *************************************************************************
    24     24   ** This file contains SQLite's grammar for SQL.  Process this file
    25     25   ** using the lemon parser generator to generate C code that runs
    26     26   ** the parser.  Lemon will also generate a header file containing
    27     27   ** numeric codes for all of the tokens.
    28     28   **
    29         -** @(#) $Id: parse.y,v 1.22 2000/06/19 19:09:09 drh Exp $
           29  +** @(#) $Id: parse.y,v 1.23 2000/06/21 13:59:12 drh Exp $
    30     30   */
    31     31   %token_prefix TK_
    32     32   %token_type {Token}
    33     33   %extra_argument {Parse *pParse}
    34     34   %syntax_error {
    35     35     sqliteSetString(&pParse->zErrMsg,"syntax error",0);
    36     36     pParse->sErrToken = TOKEN;
................................................................................
    46     46   input ::= cmdlist.
    47     47   
    48     48   // These are extra tokens used by the lexer but never seen by the
    49     49   // parser.  We put them in a rule so that the parser generator will
    50     50   // add them to the parse.h output file.
    51     51   //
    52     52   input ::= END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION
    53         -          UMINUS FIELD AGG_FUNCTION.
           53  +          UMINUS COLUMN AGG_FUNCTION.
    54     54   
    55     55   // A list of commands is zero or more commands
    56     56   //
    57     57   cmdlist ::= ecmd.
    58     58   cmdlist ::= cmdlist SEMI ecmd.
    59     59   ecmd ::= explain cmd.  {sqliteExec(pParse);}
    60     60   ecmd ::= cmd.          {sqliteExec(pParse);}
................................................................................
   246    246   cmd ::= UPDATE id(X) SET setlist(Y) where_opt(Z).
   247    247       {sqliteUpdate(pParse,&X,Y,Z);}
   248    248   
   249    249   setlist(A) ::= id(X) EQ expr(Y) COMMA setlist(Z).
   250    250       {A = sqliteExprListAppend(Z,Y,&X);}
   251    251   setlist(A) ::= id(X) EQ expr(Y).   {A = sqliteExprListAppend(0,Y,&X);}
   252    252   
   253         -cmd ::= INSERT INTO id(X) fieldlist_opt(F) VALUES LP itemlist(Y) RP.
          253  +cmd ::= INSERT INTO id(X) inscollist_opt(F) VALUES LP itemlist(Y) RP.
   254    254                  {sqliteInsert(pParse, &X, Y, 0, F);}
   255         -cmd ::= INSERT INTO id(X) fieldlist_opt(F) select(S).
          255  +cmd ::= INSERT INTO id(X) inscollist_opt(F) select(S).
   256    256                  {sqliteInsert(pParse, &X, 0, S, F);}
   257    257   
   258    258   
   259    259   %type itemlist {ExprList*}
   260    260   %destructor itemlist {sqliteExprListDelete($$);}
   261    261   %type item {Expr*}
   262    262   %destructor item {sqliteExprDelete($$);}
................................................................................
   274    274   item(A) ::= MINUS FLOAT(X).  {
   275    275     A = sqliteExpr(TK_UMINUS, 0, 0, 0);
   276    276     A->pLeft = sqliteExpr(TK_FLOAT, 0, 0, &X);
   277    277   }
   278    278   item(A) ::= STRING(X).       {A = sqliteExpr(TK_STRING, 0, 0, &X);}
   279    279   item(A) ::= NULL.            {A = sqliteExpr(TK_NULL, 0, 0, 0);}
   280    280   
   281         -%type fieldlist_opt {IdList*}
   282         -%destructor fieldlist_opt {sqliteIdListDelete($$);}
   283         -%type fieldlist {IdList*}
   284         -%destructor fieldlist {sqliteIdListDelete($$);}
          281  +%type inscollist_opt {IdList*}
          282  +%destructor inscollist_opt {sqliteIdListDelete($$);}
          283  +%type inscollist {IdList*}
          284  +%destructor inscollist {sqliteIdListDelete($$);}
   285    285   
   286         -fieldlist_opt(A) ::= .                    {A = 0;}
   287         -fieldlist_opt(A) ::= LP fieldlist(X) RP.  {A = X;}
   288         -fieldlist(A) ::= fieldlist(X) COMMA id(Y). {A = sqliteIdListAppend(X,&Y);}
   289         -fieldlist(A) ::= id(Y).                    {A = sqliteIdListAppend(0,&Y);}
          286  +inscollist_opt(A) ::= .                      {A = 0;}
          287  +inscollist_opt(A) ::= LP inscollist(X) RP.   {A = X;}
          288  +inscollist(A) ::= inscollist(X) COMMA id(Y). {A = sqliteIdListAppend(X,&Y);}
          289  +inscollist(A) ::= id(Y).                     {A = sqliteIdListAppend(0,&Y);}
   290    290   
   291    291   %left OR.
   292    292   %left AND.
   293    293   %right NOT.
   294    294   %left EQ NE ISNULL NOTNULL IS LIKE GLOB BETWEEN IN.
   295    295   %left GT GE LT LE.
   296    296   %left PLUS MINUS.

Changes to src/select.c.

    20     20   **   drh@hwaci.com
    21     21   **   http://www.hwaci.com/drh/
    22     22   **
    23     23   *************************************************************************
    24     24   ** This file contains C code routines that are called by the parser
    25     25   ** to handle SELECT statements.
    26     26   **
    27         -** $Id: select.c,v 1.24 2000/06/19 19:09:09 drh Exp $
           27  +** $Id: select.c,v 1.25 2000/06/21 13:59:12 drh Exp $
    28     28   */
    29     29   #include "sqliteInt.h"
    30     30   
    31     31   /*
    32     32   ** Allocate a new Select structure and return a pointer to that
    33     33   ** structure.
    34     34   */
................................................................................
    82     82   }
    83     83   
    84     84   /*
    85     85   ** This routine generates the code for the inside of the inner loop
    86     86   ** of a SELECT.
    87     87   **
    88     88   ** The pEList is used to determine the values for each column in the
    89         -** result row.  Except  if pEList==NULL, then we just read nField
           89  +** result row.  Except  if pEList==NULL, then we just read nColumn
    90     90   ** elements from the srcTab table.
    91     91   */
    92     92   static int selectInnerLoop(
    93     93     Parse *pParse,          /* The parser context */
    94     94     ExprList *pEList,       /* List of values being extracted */
    95     95     int srcTab,             /* Pull data from this table */
    96         -  int nField,             /* Number of fields in the source table */
           96  +  int nColumn,            /* Number of columns in the source table */
    97     97     ExprList *pOrderBy,     /* If not NULL, sort results using this key */
    98     98     int distinct,           /* If >=0, make sure results are distinct */
    99     99     int eDest,              /* How to dispose of the results */
   100    100     int iParm,              /* An argument to the disposal method */
   101    101     int iContinue,          /* Jump here to continue with next row */
   102    102     int iBreak              /* Jump here to break out of the inner loop */
   103    103   ){
   104    104     Vdbe *v = pParse->pVdbe;
   105    105     int i;
   106    106   
   107         -  /* Pull the requested fields.
          107  +  /* Pull the requested columns.
   108    108     */
   109    109     if( pEList ){
   110    110       for(i=0; i<pEList->nExpr; i++){
   111    111         sqliteExprCode(pParse, pEList->a[i].pExpr);
   112    112       }
   113         -    nField = pEList->nExpr;
          113  +    nColumn = pEList->nExpr;
   114    114     }else{
   115         -    for(i=0; i<nField; i++){
          115  +    for(i=0; i<nColumn; i++){
   116    116         sqliteVdbeAddOp(v, OP_Field, srcTab, i, 0, 0);
   117    117       }
   118    118     }
   119    119   
   120    120     /* If the current result is not distinct, skip the rest
   121    121     ** of the processing for the current row.
   122    122     */
................................................................................
   131    131     }
   132    132   
   133    133     /* If there is an ORDER BY clause, then store the results
   134    134     ** in a sorter.
   135    135     */
   136    136     if( pOrderBy ){
   137    137       char *zSortOrder;
   138         -    sqliteVdbeAddOp(v, OP_SortMakeRec, nField, 0, 0, 0);
          138  +    sqliteVdbeAddOp(v, OP_SortMakeRec, nColumn, 0, 0, 0);
   139    139       zSortOrder = sqliteMalloc( pOrderBy->nExpr + 1 );
   140    140       if( zSortOrder==0 ) return 1;
   141    141       for(i=0; i<pOrderBy->nExpr; i++){
   142    142         zSortOrder[i] = pOrderBy->a[i].sortOrder ? '-' : '+';
   143    143         sqliteExprCode(pParse, pOrderBy->a[i].pExpr);
   144    144       }
   145    145       zSortOrder[pOrderBy->nExpr] = 0;
................................................................................
   148    148       sqliteVdbeAddOp(v, OP_SortPut, 0, 0, 0, 0);
   149    149     }else 
   150    150   
   151    151     /* In this mode, write each query result to the key of the temporary
   152    152     ** table iParm.
   153    153     */
   154    154     if( eDest==SRT_Union ){
   155         -    sqliteVdbeAddOp(v, OP_MakeRecord, nField, 0, 0, 0);
          155  +    sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0, 0, 0);
   156    156       sqliteVdbeAddOp(v, OP_String, iParm, 0, "", 0);
   157    157       sqliteVdbeAddOp(v, OP_Put, iParm, 0, 0, 0);
   158    158     }else 
   159    159   
   160    160     /* Store the result as data using a unique key.
   161    161     */
   162    162     if( eDest==SRT_Table ){
   163         -    sqliteVdbeAddOp(v, OP_MakeRecord, nField, 0, 0, 0);
          163  +    sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0, 0, 0);
   164    164       sqliteVdbeAddOp(v, OP_New, iParm, 0, 0, 0);
   165    165       sqliteVdbeAddOp(v, OP_Pull, 1, 0, 0, 0);
   166    166       sqliteVdbeAddOp(v, OP_Put, iParm, 0, 0, 0);
   167    167     }else 
   168    168   
   169    169     /* Construct a record from the query result, but instead of
   170    170     ** saving that record, use it as a key to delete elements from
   171    171     ** the temporary table iParm.
   172    172     */
   173    173     if( eDest==SRT_Except ){
   174         -    sqliteVdbeAddOp(v, OP_MakeRecord, nField, 0, 0, 0);
          174  +    sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0, 0, 0);
   175    175       sqliteVdbeAddOp(v, OP_Delete, iParm, 0, 0, 0);
   176    176     }else 
   177    177   
   178    178     /* If we are creating a set for an "expr IN (SELECT ...)" construct,
   179    179     ** then there should be a single item on the stack.  Write this
   180    180     ** item into the set table with bogus data.
   181    181     */
   182    182     if( eDest==SRT_Set ){
   183         -    assert( nField==1 );
          183  +    assert( nColumn==1 );
   184    184       sqliteVdbeAddOp(v, OP_String, 0, 0, "", 0);
   185    185       sqliteVdbeAddOp(v, OP_Put, iParm, 0, 0, 0);
   186    186     }else 
   187    187   
   188    188   
   189    189     /* If this is a scalar select that is part of an expression, then
   190    190     ** store the results in the appropriate memory cell and break out
   191    191     ** of the scan loop.
   192    192     */
   193    193     if( eDest==SRT_Mem ){
   194         -    assert( nField==1 );
          194  +    assert( nColumn==1 );
   195    195       sqliteVdbeAddOp(v, OP_MemStore, iParm, 0, 0, 0);
   196    196       sqliteVdbeAddOp(v, OP_Goto, 0, iBreak, 0, 0);
   197    197     }else
   198    198   
   199    199     /* If none of the above, send the data to the callback function.
   200    200     */
   201    201     {
   202         -    sqliteVdbeAddOp(v, OP_Callback, nField, 0, 0, 0);
          202  +    sqliteVdbeAddOp(v, OP_Callback, nColumn, 0, 0, 0);
   203    203     }
   204    204     return 0;
   205    205   }
   206    206   
   207    207   /*
   208    208   ** If the inner loop was generated using a non-null pOrderBy argument,
   209    209   ** then the results were placed in a sorter.  After the loop is terminated
   210    210   ** we need to run the sorter and output the results.  The following
   211    211   ** routine generates the code needed to do that.
   212    212   */
   213         -static void generateSortTail(Vdbe *v, int nField){
          213  +static void generateSortTail(Vdbe *v, int nColumn){
   214    214     int end = sqliteVdbeMakeLabel(v);
   215    215     int addr;
   216    216     sqliteVdbeAddOp(v, OP_Sort, 0, 0, 0, 0);
   217    217     addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end, 0, 0);
   218         -  sqliteVdbeAddOp(v, OP_SortCallback, nField, 0, 0, 0);
          218  +  sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0, 0, 0);
   219    219     sqliteVdbeAddOp(v, OP_Goto, 0, addr, 0, 0);
   220    220     sqliteVdbeAddOp(v, OP_SortClose, 0, 0, 0, end);
   221    221   }
   222    222   
   223    223   /*
   224    224   ** Generate code that will tell the VDBE how many columns there
   225    225   ** are in the result and the name for each column.  This information
................................................................................
   236    236       Expr *p;
   237    237       if( pEList->a[i].zName ){
   238    238         char *zName = pEList->a[i].zName;
   239    239         sqliteVdbeAddOp(v, OP_ColumnName, i, 0, zName, 0);
   240    240         continue;
   241    241       }
   242    242       p = pEList->a[i].pExpr;
   243         -    if( p->op!=TK_FIELD || pTabList==0 ){
          243  +    if( p->op!=TK_COLUMN || pTabList==0 ){
   244    244         char zName[30];
   245    245         sprintf(zName, "column%d", i+1);
   246    246         sqliteVdbeAddOp(v, OP_ColumnName, i, 0, zName, 0);
   247    247       }else{
   248    248         if( pTabList->nId>1 ){
   249    249           char *zName = 0;
   250    250           Table *pTab = pTabList->a[p->iTable].pTab;
   251    251           char *zTab;
   252    252    
   253    253           zTab = pTabList->a[p->iTable].zAlias;
   254    254           if( zTab==0 ) zTab = pTab->zName;
   255         -        sqliteSetString(&zName, zTab, ".", pTab->aCol[p->iField].zName, 0);
          255  +        sqliteSetString(&zName, zTab, ".", pTab->aCol[p->iColumn].zName, 0);
   256    256           sqliteVdbeAddOp(v, OP_ColumnName, i, 0, zName, 0);
   257    257           sqliteFree(zName);
   258    258         }else{
   259    259           Table *pTab = pTabList->a[0].pTab;
   260         -        char *zName = pTab->aCol[p->iField].zName;
          260  +        char *zName = pTab->aCol[p->iColumn].zName;
   261    261           sqliteVdbeAddOp(v, OP_ColumnName, i, 0, zName, 0);
   262    262         }
   263    263       }
   264    264     }
   265    265   }
   266    266   
   267    267   /*
................................................................................
   277    277     }
   278    278     return z;
   279    279   }
   280    280   
   281    281   /*
   282    282   ** For the given SELECT statement, do two things.
   283    283   **
   284         -**    (1)  Fill in the pTab fields of the IdList that defines the set
   285         -**         of tables we are scanning.
          284  +**    (1)  Fill in the pTabList->a[].pTab fields in the IdList that 
          285  +**         defines the set of tables that should be scanned.
   286    286   **
   287    287   **    (2)  If the columns to be extracted variable (pEList) is NULL
   288    288   **         (meaning that a "*" was used in the SQL statement) then
   289    289   **         create a fake pEList containing the names of all columns
   290    290   **         of all tables.
   291    291   **
   292    292   ** Return 0 on success.  If there are problems, leave an error message
................................................................................
   334    334     }
   335    335     return 0;
   336    336   }
   337    337   
   338    338   /*
   339    339   ** This routine associates entries in an ORDER BY expression list with
   340    340   ** columns in a result.  For each ORDER BY expression, the opcode of
   341         -** the top-level node is changed to TK_FIELD and the iField value of
          341  +** the top-level node is changed to TK_COLUMN and the iColumn value of
   342    342   ** the top-level node is filled in with column number and the iTable
   343    343   ** value of the top-level node is filled with iTable parameter.
   344    344   **
   345    345   ** If there are prior SELECT clauses, they are processed first.  A match
   346    346   ** in an earlier SELECT takes precedence over a later SELECT.
   347    347   **
   348    348   ** Any entry that does not match is flagged as an error.  The number
................................................................................
   386    386           }
   387    387           sqliteFree(zLabel);
   388    388         }
   389    389         if( match==0 && sqliteExprCompare(pE, pEList->a[j].pExpr) ){
   390    390           match = 1;
   391    391         }
   392    392         if( match ){
   393         -        pE->op = TK_FIELD;
   394         -        pE->iField = j;
          393  +        pE->op = TK_COLUMN;
          394  +        pE->iColumn = j;
   395    395           pE->iTable = iTable;
   396    396           pOrderBy->a[i].done = 1;
   397    397           break;
   398    398         }
   399    399       }
   400    400       if( !match && mustComplete ){
   401    401         char zBuf[30];
................................................................................
   626    626     int eDest,             /* One of: SRT_Callback Mem Set Union Except */
   627    627     int iParm              /* Save result in this memory location, if >=0 */
   628    628   ){
   629    629     int i;
   630    630     WhereInfo *pWInfo;
   631    631     Vdbe *v;
   632    632     int isAgg = 0;         /* True for select lists like "count(*)" */
   633         -  ExprList *pEList;      /* List of fields to extract.  NULL means "*" */
          633  +  ExprList *pEList;      /* List of columns to extract.  NULL means "*" */
   634    634     IdList *pTabList;      /* List of tables to select from */
   635    635     Expr *pWhere;          /* The WHERE clause.  May be NULL */
   636    636     ExprList *pOrderBy;    /* The ORDER BY clause.  May be NULL */
   637    637     ExprList *pGroupBy;    /* The GROUP BY clause.  May be NULL */
   638    638     Expr *pHaving;         /* The HAVING clause.  May be NULL */
   639    639     int isDistinct;        /* True if the DISTINCT keyword is present */
   640    640     int distinct;          /* Table to use for the distinct set */
................................................................................
   665    665     ** errors before this routine starts.
   666    666     */
   667    667     if( pParse->nErr>0 ) return 1;
   668    668     sqliteParseInfoReset(pParse);
   669    669   
   670    670     /* Look up every table in the table list and create an appropriate
   671    671     ** columnlist in pEList if there isn't one already.  (The parser leaves
   672         -  ** a NULL in the pEList field if the SQL said "SELECT * FROM ...")
          672  +  ** a NULL in the p->pEList if the SQL said "SELECT * FROM ...")
   673    673     */
   674    674     if( fillInColumnList(pParse, p) ){
   675    675       return 1;
   676    676     }
   677    677     pEList = p->pEList;
   678    678   
   679    679     /* Allocate a temporary table to use for the DISTINCT set, if
................................................................................
   720    720     }
   721    721     if( pHaving ) sqliteExprResolveInSelect(pParse, pHaving);
   722    722   
   723    723     /* At this point, we should have allocated all the cursors that we
   724    724     ** need to handle subquerys and temporary tables.  From here on we
   725    725     ** are committed to keeping the same value for pParse->nTab.
   726    726     **
   727         -  ** Resolve the field names and do a semantics check on all the expressions.
          727  +  ** Resolve the column names and do a semantics check on all the expressions.
   728    728     */
   729    729     for(i=0; i<pEList->nExpr; i++){
   730    730       if( sqliteExprResolveIds(pParse, pTabList, pEList->a[i].pExpr) ){
   731    731         return 1;
   732    732       }
   733    733       if( sqliteExprCheck(pParse, pEList->a[i].pExpr, 1, &isAgg) ){
   734    734         return 1;
................................................................................
   902    902           sqliteVdbeAddOp(v, OP_AggIncr, 1, i, 0, 0);
   903    903           continue;
   904    904         }
   905    905         assert( pE->op==TK_AGG_FUNCTION );
   906    906         assert( pE->pList!=0 && pE->pList->nExpr==1 );
   907    907         sqliteExprCode(pParse, pE->pList->a[0].pExpr);
   908    908         sqliteVdbeAddOp(v, OP_AggGet, 0, i, 0, 0);
   909         -      switch( pE->iField ){
          909  +      switch( pE->iColumn ){
   910    910           case FN_Min:  op = OP_Min;   break;
   911    911           case FN_Max:  op = OP_Max;   break;
   912    912           case FN_Avg:  op = OP_Add;   break;
   913    913           case FN_Sum:  op = OP_Add;   break;
   914    914         }
   915    915         sqliteVdbeAddOp(v, op, 0, 0, 0, 0);
   916    916         sqliteVdbeAddOp(v, OP_AggSet, 0, i, 0, 0);

Changes to src/shell.c.

    20     20   **   drh@hwaci.com
    21     21   **   http://www.hwaci.com/drh/
    22     22   **
    23     23   *************************************************************************
    24     24   ** This file contains code to implement the "sqlite" command line
    25     25   ** utility for accessing SQLite databases.
    26     26   **
    27         -** $Id: shell.c,v 1.14 2000/06/15 16:49:49 drh Exp $
           27  +** $Id: shell.c,v 1.15 2000/06/21 13:59:12 drh Exp $
    28     28   */
    29     29   #include <stdlib.h>
    30     30   #include <string.h>
    31     31   #include <stdio.h>
    32     32   #include "sqlite.h"
    33     33   #include <unistd.h>
    34     34   #include <ctype.h>
................................................................................
   132    132     char separator[20];    /* Separator character for MODE_List */
   133    133     int colWidth[30];      /* Width of each column when in column mode */
   134    134   };
   135    135   
   136    136   /*
   137    137   ** These are the allowed modes.
   138    138   */
   139         -#define MODE_Line     0  /* One field per line.  Blank line between records */
          139  +#define MODE_Line     0  /* One column per line.  Blank line between records */
   140    140   #define MODE_Column   1  /* One record per line in neat columns */
   141    141   #define MODE_List     2  /* One record per line with a separator */
   142    142   #define MODE_Html     3  /* Generate an XHTML table */
   143    143   #define MODE_Insert   4  /* Generate SQL "insert" statements */
   144    144   
   145    145   /*
   146    146   ** Number of elements in an array

Changes to src/sqliteInt.h.

    19     19   ** Author contact information:
    20     20   **   drh@hwaci.com
    21     21   **   http://www.hwaci.com/drh/
    22     22   **
    23     23   *************************************************************************
    24     24   ** Internal interface definitions for SQLite.
    25     25   **
    26         -** @(#) $Id: sqliteInt.h,v 1.24 2000/06/11 23:50:13 drh Exp $
           26  +** @(#) $Id: sqliteInt.h,v 1.25 2000/06/21 13:59:12 drh Exp $
    27     27   */
    28     28   #include "sqlite.h"
    29     29   #include "dbbe.h"
    30     30   #include "vdbe.h"
    31     31   #include "parse.h"
    32     32   #include <gdbm.h>
    33     33   #include <stdio.h>
    34     34   #include <stdlib.h>
    35     35   #include <string.h>
    36     36   #include <assert.h>
    37     37   
    38         -/* #define MEMORY_DEBUG 1 */
           38  +/*
           39  +** If memory allocation problems are found, recompile with
           40  +**
           41  +**      -DMEMORY_DEBUG=1
           42  +**
           43  +** to enable some sanity checking on malloc() and free().  To
           44  +** check for memory leaks, recompile with
           45  +**
           46  +**      -DMEMORY_DEBUG=2
           47  +**
           48  +** and a line of text will be written to standard error for
           49  +** each malloc() and free().  This output can be analyzed
           50  +** by an AWK script to determine if there are any leaks.
           51  +*/
    39     52   #ifdef MEMORY_DEBUG
    40     53   # define sqliteMalloc(X)    sqliteMalloc_(X,__FILE__,__LINE__)
    41     54   # define sqliteFree(X)      sqliteFree_(X,__FILE__,__LINE__)
    42     55   # define sqliteRealloc(X,Y) sqliteRealloc_(X,Y,__FILE__,__LINE__)
    43     56   # define sqliteStrDup(X)    sqliteStrDup_(X,__FILE__,__LINE__)
    44     57   # define sqliteStrNDup(X,Y) sqliteStrNDup_(X,Y,__FILE__,__LINE__)
    45     58     void sqliteStrRealloc(char**);
................................................................................
    54     67   #ifdef MEMORY_DEBUG
    55     68   int sqlite_nMalloc;         /* Number of sqliteMalloc() calls */
    56     69   int sqlite_nFree;           /* Number of sqliteFree() calls */
    57     70   int sqlite_iMallocFail;     /* Fail sqliteMalloc() after this many calls */
    58     71   #endif
    59     72   
    60     73   /*
    61         -** The number of entries in the in-memory hash table holding the
    62         -** schema.
           74  +** The number of entries in the in-memory hash array holding the
           75  +** database schema.
    63     76   */
    64     77   #define N_HASH        51
    65     78   
    66     79   /*
    67     80   ** Name of the master database table.  The master database table
    68     81   ** is a special table that holds the names and attributes of all
    69     82   ** user tables and indices.
................................................................................
    73     86   /*
    74     87   ** A convenience macro that returns the number of elements in
    75     88   ** an array.
    76     89   */
    77     90   #define ArraySize(X)    (sizeof(X)/sizeof(X[0]))
    78     91   
    79     92   /*
    80         -** Integer identifiers for functions.
           93  +** Integer identifiers for built-in SQL functions.
    81     94   */
    82     95   #define FN_Unknown    0
    83     96   #define FN_Count      1
    84     97   #define FN_Min        2
    85     98   #define FN_Max        3
    86     99   #define FN_Sum        4
    87    100   #define FN_Avg        5
................................................................................
   110    123     Dbbe *pBe;                 /* The backend driver */
   111    124     int flags;                 /* Miscellanous flags */
   112    125     Table *apTblHash[N_HASH];  /* All tables of the database */
   113    126     Index *apIdxHash[N_HASH];  /* All indices of the database */
   114    127   };
   115    128   
   116    129   /*
   117         -** Possible values for the flags field of sqlite
          130  +** Possible values for the sqlite.flags.
   118    131   */
   119    132   #define SQLITE_VdbeTrace    0x00000001
   120    133   #define SQLITE_Initialized  0x00000002
   121    134   
   122    135   /*
   123         -** information about each column of a table is held in an instance
          136  +** information about each column of an SQL table is held in an instance
   124    137   ** of this structure.
   125    138   */
   126    139   struct Column {
   127         -  char *zName;        /* Name of this column */
   128         -  char *zDflt;        /* Default value of this column */
   129         -  int notNull;        /* True if there is a NOT NULL constraing */
          140  +  char *zName;     /* Name of this column */
          141  +  char *zDflt;     /* Default value of this column */
          142  +  int notNull;     /* True if there is a NOT NULL constraint */
   130    143   };
   131    144   
   132    145   /*
   133         -** Each table is represented in memory by
   134         -** an instance of the following structure
          146  +** Each SQL table is represented in memory by
          147  +** an instance of the following structure.
   135    148   */
   136    149   struct Table {
   137         -  char *zName;        /* Name of the table */
   138         -  Table *pHash;       /* Next table with same hash on zName */
   139         -  int nCol;           /* Number of columns in this table */
   140         -  Column *aCol;       /* Information about each column */
   141         -  int readOnly;       /* True if this table should not be written by the user */
   142         -  Index *pIndex;      /* List of indices on this table. */
          150  +  char *zName;     /* Name of the table */
          151  +  Table *pHash;    /* Next table with same hash on zName */
          152  +  int nCol;        /* Number of columns in this table */
          153  +  Column *aCol;    /* Information about each column */
          154  +  int readOnly;    /* True if this table should not be written by the user */
          155  +  Index *pIndex;   /* List of SQL indexes on this table. */
   143    156   };
   144    157   
   145    158   /*
   146         -** Each index is represented in memory by and
          159  +** Each SQL index is represented in memory by and
   147    160   ** instance of the following structure.
          161  +**
          162  +** The columns of the table that are to be indexed are described
          163  +** by the aiColumn[] field of this structure.  For example, suppose
          164  +** we have the following table and index:
          165  +**
          166  +**     CREATE TABLE Ex1(c1 int, c2 int, c3 text);
          167  +**     CREATE INDEX Ex2 ON Ex1(c3,c1);
          168  +**
          169  +** In the Table structure describing Ex1, nCol==3 because there are
          170  +** three columns in the table.  In the Index structure describing
          171  +** Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed.
          172  +** The value of aiColumn is {2, 0}.  aiColumn[0]==2 because the 
          173  +** first column to be indexed (c3) has an index of 2 in Ex1.aCol[].
          174  +** The second column to be indexed (c1) has an index of 0 in
          175  +** Ex1.aCol[], hence Ex2.aiColumn[1]==0.
   148    176   */
   149    177   struct Index {
   150         -  char *zName;        /* Name of this index */
   151         -  Index *pHash;       /* Next index with the same hash on zName */
   152         -  int nField;         /* Number of fields in the table indexed by this index */
   153         -  int *aiField;       /* Indices of fields used by this index.  1st is 0 */
   154         -  Table *pTable;      /* The table being indexed */
   155         -  int isUnique;       /* True if keys must all be unique */
   156         -  Index *pNext;       /* The next index associated with the same table */
          178  +  char *zName;     /* Name of this index */
          179  +  Index *pHash;    /* Next index with the same hash on zName */
          180  +  int nColumn;     /* Number of columns in the table used by this index */
          181  +  int *aiColumn;   /* Which columns are used by this index.  1st is 0 */
          182  +  Table *pTable;   /* The SQL table being indexed */
          183  +  int isUnique;    /* True if keys must all be unique */
          184  +  Index *pNext;    /* The next index associated with the same table */
   157    185   };
   158    186   
   159    187   /*
   160    188   ** Each token coming out of the lexer is an instance of
   161    189   ** this structure.
   162    190   */
   163    191   struct Token {
................................................................................
   170    198   ** of this structure
   171    199   */
   172    200   struct Expr {
   173    201     int op;                /* Operation performed by this node */
   174    202     Expr *pLeft, *pRight;  /* Left and right subnodes */
   175    203     ExprList *pList;       /* A list of expressions used as a function argument */
   176    204     Token token;           /* An operand token */
   177         -  int iTable, iField;    /* When op==TK_FIELD, then this node means the
   178         -                         ** iField-th field of the iTable-th table.  When
   179         -                         ** op==TK_FUNCTION, iField holds the function id */
   180         -  int iAgg;              /* When op==TK_FIELD and pParse->useAgg==TRUE, pull
   181         -                         ** value from these element of the aggregator */
          205  +  int iTable, iColumn;   /* When op==TK_COLUMN, then this expr node means the
          206  +                         ** iColumn-th field of the iTable-th table.  When
          207  +                         ** op==TK_FUNCTION, iColumn holds the function id */
          208  +  int iAgg;              /* When op==TK_COLUMN and pParse->useAgg==TRUE, pull
          209  +                         ** result from the iAgg-th element of the aggregator */
   182    210     Select *pSelect;       /* When the expression is a sub-select */
   183    211   };
   184    212   
   185    213   /*
   186    214   ** A list of expressions.  Each expression may optionally have a
   187    215   ** name.  An expr/name combination can be used in several ways, such
   188    216   ** as the list of "expr AS ID" fields following a "SELECT" or in the
................................................................................
   205    233   ** A list of identifiers.
   206    234   */
   207    235   struct IdList {
   208    236     int nId;         /* Number of identifiers on the list */
   209    237     struct {
   210    238       char *zName;      /* Text of the identifier. */
   211    239       char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
   212         -    Table *pTab;      /* Table corresponding to zName */
   213         -    int idx;          /* Index of a field named zName in a table */
          240  +    Table *pTab;      /* An SQL table corresponding to zName */
          241  +    int idx;          /* Index in some Table.aCol[] of a column named zName */
   214    242     } *a;            /* One entry for each identifier on the list */
   215    243   };
   216    244   
   217    245   /*
   218    246   ** The WHERE clause processing routine has two halves.  The
   219    247   ** first part does the start of the WHERE loop and the second
   220    248   ** half does the tail of the WHERE loop.  An instance of
................................................................................
   239    267     ExprList *pEList;      /* The fields of the result */
   240    268     IdList *pSrc;          /* The FROM clause */
   241    269     Expr *pWhere;          /* The WHERE clause */
   242    270     ExprList *pGroupBy;    /* The GROUP BY clause */
   243    271     Expr *pHaving;         /* The HAVING clause */
   244    272     ExprList *pOrderBy;    /* The ORDER BY clause */
   245    273     int op;                /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
   246         -  Select *pPrior;        /* Prior select to which this one joins */
          274  +  Select *pPrior;        /* Prior select in a compound select statement */
   247    275   };
   248    276   
   249    277   /*
   250    278   ** The results of a select can be distributed in several ways.
   251    279   */
   252    280   #define SRT_Callback     1  /* Invoke a callback with each row of result */
   253    281   #define SRT_Mem          2  /* Store result in a memory cell */

Changes to src/update.c.

    20     20   **   drh@hwaci.com
    21     21   **   http://www.hwaci.com/drh/
    22     22   **
    23     23   *************************************************************************
    24     24   ** This file contains C code routines that are called by the parser
    25     25   ** to handle UPDATE statements.
    26     26   **
    27         -** $Id: update.c,v 1.7 2000/06/19 19:09:09 drh Exp $
           27  +** $Id: update.c,v 1.8 2000/06/21 13:59:12 drh Exp $
    28     28   */
    29     29   #include "sqliteInt.h"
    30     30   
    31     31   /*
    32     32   ** Process an UPDATE statement.
    33     33   */
    34     34   void sqliteUpdate(
................................................................................
    44     44     WhereInfo *pWInfo;     /* Information about the WHERE clause */
    45     45     Vdbe *v;               /* The virtual database engine */
    46     46     Index *pIdx;           /* For looping over indices */
    47     47     int nIdx;              /* Number of indices that need updating */
    48     48     int base;              /* Index of first available table cursor */
    49     49     Index **apIdx = 0;     /* An array of indices that need updating too */
    50     50     int *aXRef = 0;        /* aXRef[i] is the index in pChanges->a[] of the
    51         -                         ** an expression for the i-th field of the table.
    52         -                         ** aXRef[i]==-1 if the i-th field is not changed. */
           51  +                         ** an expression for the i-th column of the table.
           52  +                         ** aXRef[i]==-1 if the i-th column is not changed. */
    53     53   
    54     54     /* Locate the table which we want to update.  This table has to be
    55     55     ** put in an IdList structure because some of the subroutines we
    56     56     ** will be calling are designed to work with multiple tables and expect
    57     57     ** an IdList* parameter instead of just a Table* parameger.
    58     58     */
    59     59     pTabList = sqliteIdListAppend(0, pTableName);
................................................................................
    73     73       }
    74     74     }
    75     75     pTab = pTabList->a[0].pTab;
    76     76     aXRef = sqliteMalloc( sizeof(int) * pTab->nCol );
    77     77     if( aXRef==0 ) goto update_cleanup;
    78     78     for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
    79     79   
    80         -  /* Resolve the field names in all the expressions in both the
    81         -  ** WHERE clause and in the new values.  Also find the field index
    82         -  ** for each field to be updated in the pChanges array.
           80  +  /* Resolve the column names in all the expressions in both the
           81  +  ** WHERE clause and in the new values.  Also find the column index
           82  +  ** for each column to be updated in the pChanges array.
    83     83     */
    84     84     if( pWhere ){
    85     85       sqliteExprResolveInSelect(pParse, pWhere);
    86     86     }
    87     87     for(i=0; i<pChanges->nExpr; i++){
    88     88       sqliteExprResolveInSelect(pParse, pChanges->a[i].pExpr);
    89     89     }
................................................................................
   105    105       for(j=0; j<pTab->nCol; j++){
   106    106         if( sqliteStrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
   107    107           aXRef[j] = i;
   108    108           break;
   109    109         }
   110    110       }
   111    111       if( j>=pTab->nCol ){
   112         -      sqliteSetString(&pParse->zErrMsg, "no such field: ", 
          112  +      sqliteSetString(&pParse->zErrMsg, "no such column: ", 
   113    113            pChanges->a[i].zName, 0);
   114    114         pParse->nErr++;
   115    115         goto update_cleanup;
   116    116       }
   117    117     }
   118    118   
   119    119     /* Allocate memory for the array apIdx[] and fill it pointers to every
   120    120     ** index that needs to be updated.  Indices only need updating if their
   121         -  ** key includes one of the fields named in pChanges.
          121  +  ** key includes one of the columns named in pChanges.
   122    122     */
   123    123     for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
   124         -    for(i=0; i<pIdx->nField; i++){
   125         -      if( aXRef[pIdx->aiField[i]]>=0 ) break;
          124  +    for(i=0; i<pIdx->nColumn; i++){
          125  +      if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
   126    126       }
   127         -    if( i<pIdx->nField ) nIdx++;
          127  +    if( i<pIdx->nColumn ) nIdx++;
   128    128     }
   129    129     apIdx = sqliteMalloc( sizeof(Index*) * nIdx );
   130    130     if( apIdx==0 ) goto update_cleanup;
   131    131     for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
   132         -    for(i=0; i<pIdx->nField; i++){
   133         -      if( aXRef[pIdx->aiField[i]]>=0 ) break;
          132  +    for(i=0; i<pIdx->nColumn; i++){
          133  +      if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
   134    134       }
   135         -    if( i<pIdx->nField ) apIdx[nIdx++] = pIdx;
          135  +    if( i<pIdx->nColumn ) apIdx[nIdx++] = pIdx;
   136    136     }
   137    137   
   138    138     /* Begin generating code.
   139    139     */
   140    140     v = sqliteGetVdbe(pParse);
   141    141     if( v==0 ) goto update_cleanup;
   142    142   
................................................................................
   161    161     base = pParse->nTab;
   162    162     sqliteVdbeAddOp(v, OP_Open, base, 1, pTab->zName, 0);
   163    163     for(i=0; i<nIdx; i++){
   164    164       sqliteVdbeAddOp(v, OP_Open, base+i+1, 1, apIdx[i]->zName, 0);
   165    165     }
   166    166   
   167    167     /* Loop over every record that needs updating.  We have to load
   168         -  ** the old data for each record to be updated because some fields
          168  +  ** the old data for each record to be updated because some columns
   169    169     ** might not change and we will need to copy the old value.
   170    170     ** Also, the old data is needed to delete the old index entires.
   171    171     */
   172    172     end = sqliteVdbeMakeLabel(v);
   173    173     addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end, 0, 0);
   174    174     sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
   175    175     sqliteVdbeAddOp(v, OP_Fetch, base, 0, 0, 0);
   176    176   
   177    177     /* Delete the old indices for the current record.
   178    178     */
   179    179     for(i=0; i<nIdx; i++){
   180    180       sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
   181    181       pIdx = apIdx[i];
   182         -    for(j=0; j<pIdx->nField; j++){
   183         -      sqliteVdbeAddOp(v, OP_Field, base, pIdx->aiField[j], 0, 0);
          182  +    for(j=0; j<pIdx->nColumn; j++){
          183  +      sqliteVdbeAddOp(v, OP_Field, base, pIdx->aiColumn[j], 0, 0);
   184    184       }
   185         -    sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nField, 0, 0, 0);
          185  +    sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nColumn, 0, 0, 0);
   186    186       sqliteVdbeAddOp(v, OP_DeleteIdx, base+i+1, 0, 0, 0);
   187    187     }
   188    188   
   189    189     /* Compute a completely new data for this record.  
   190    190     */
   191    191     for(i=0; i<pTab->nCol; i++){
   192    192       j = aXRef[i];
................................................................................
   198    198     }
   199    199   
   200    200     /* Insert new index entries that correspond to the new data
   201    201     */
   202    202     for(i=0; i<nIdx; i++){
   203    203       sqliteVdbeAddOp(v, OP_Dup, pTab->nCol, 0, 0, 0); /* The KEY */
   204    204       pIdx = apIdx[i];
   205         -    for(j=0; j<pIdx->nField; j++){
   206         -      sqliteVdbeAddOp(v, OP_Dup, j+pTab->nCol-pIdx->aiField[j], 0, 0, 0);
          205  +    for(j=0; j<pIdx->nColumn; j++){
          206  +      sqliteVdbeAddOp(v, OP_Dup, j+pTab->nCol-pIdx->aiColumn[j], 0, 0, 0);
   207    207       }
   208         -    sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nField, 0, 0, 0);
          208  +    sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nColumn, 0, 0, 0);
   209    209       sqliteVdbeAddOp(v, OP_PutIdx, base+i+1, 0, 0, 0);
   210    210     }
   211    211   
   212    212     /* Write the new data back into the database.
   213    213     */
   214    214     sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0, 0, 0);
   215    215     sqliteVdbeAddOp(v, OP_Put, base, 0, 0, 0);

Changes to src/util.c.

    22     22   **
    23     23   *************************************************************************
    24     24   ** Utility functions used throughout sqlite.
    25     25   **
    26     26   ** This file contains functions for allocating memory, comparing
    27     27   ** strings, and stuff like that.
    28     28   **
    29         -** $Id: util.c,v 1.12 2000/06/08 13:36:41 drh Exp $
           29  +** $Id: util.c,v 1.13 2000/06/21 13:59:12 drh Exp $
    30     30   */
    31     31   #include "sqliteInt.h"
    32     32   #include <stdarg.h>
    33     33   #include <ctype.h>
    34     34   
    35     35   #ifdef MEMORY_DEBUG
    36     36   
................................................................................
   356    356       h = h<<3 ^ h ^ UpperToLower[c];
   357    357     }
   358    358     if( h<0 ) h = -h;
   359    359     return h;
   360    360   }
   361    361   
   362    362   /*
   363         -** Some system shave stricmp().  Others have strcasecmp().  Because
          363  +** Some systems have stricmp().  Others have strcasecmp().  Because
   364    364   ** there is no consistency, we will define our own.
   365    365   */
   366    366   int sqliteStrICmp(const char *zLeft, const char *zRight){
   367    367     register unsigned char *a, *b;
   368    368     a = (unsigned char *)zLeft;
   369    369     b = (unsigned char *)zRight;
   370    370     while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }

Changes to src/vdbe.c.

    37     37   ** inplicit conversion from one type to the other occurs as necessary.
    38     38   ** 
    39     39   ** Most of the code in this file is taken up by the sqliteVdbeExec()
    40     40   ** function which does the work of interpreting a VDBE program.
    41     41   ** But other routines are also provided to help in building up
    42     42   ** a program instruction by instruction.
    43     43   **
    44         -** $Id: vdbe.c,v 1.33 2000/06/11 23:50:13 drh Exp $
           44  +** $Id: vdbe.c,v 1.34 2000/06/21 13:59:13 drh Exp $
    45     45   */
    46     46   #include "sqliteInt.h"
    47     47   #include <unistd.h>
    48     48   
    49     49   /*
    50     50   ** SQL is translated into a sequence of instructions to be
    51     51   ** executed by a virtual machine.  Each instruction is an instance
    52     52   ** of the following structure.
    53     53   */
    54     54   typedef struct VdbeOp Op;
    55     55   
    56     56   /*
    57         -** Every table that the virtual machine has open is represented by an
           57  +** A cursor is a pointer into a database file.  The database file
           58  +** can represent either an SQL table or an SQL index.  Each file is
           59  +** a bag of key/data pairs.  The cursor can loop over all key/data
           60  +** pairs (in an arbitrary order) or it can retrieve a particular
           61  +** key/data pair given a copy of the key.
           62  +** 
           63  +** Every cursor that the virtual machine has open is represented by an
    58     64   ** instance of the following structure.
    59     65   */
    60         -struct VdbeTable {
    61         -  DbbeTable *pTable;    /* The table structure of the backend */
           66  +struct Cursor {
           67  +  DbbeCursor *pCursor;  /* The cursor structure of the backend */
    62     68     int index;            /* The next index to extract */
    63     69     int keyAsData;        /* The OP_Field command works on key instead of data */
    64     70   };
    65         -typedef struct VdbeTable VdbeTable;
           71  +typedef struct Cursor Cursor;
    66     72   
    67     73   /*
    68     74   ** A sorter builds a list of elements to be sorted.  Each element of
    69     75   ** the list is an instance of the following structure.
    70     76   */
    71     77   typedef struct Sorter Sorter;
    72     78   struct Sorter {
................................................................................
   113    119   #define STK_Null      0x0001   /* Value is NULL */
   114    120   #define STK_Str       0x0002   /* Value is a string */
   115    121   #define STK_Int       0x0004   /* Value is an integer */
   116    122   #define STK_Real      0x0008   /* Value is a real number */
   117    123   #define STK_Dyn       0x0010   /* Need to call sqliteFree() on zStack[*] */
   118    124   
   119    125   /*
   120         -** An Agg structure describes and Aggregator.  Each Agg consists of
          126  +** An Agg structure describes an Aggregator.  Each Agg consists of
   121    127   ** zero or more Aggregator elements (AggElem).  Each AggElem contains
   122    128   ** a key and one or more values.  The values are used in processing
   123    129   ** aggregate functions in a SELECT.  The key is used to implement
   124    130   ** the GROUP BY clause of a select.
   125    131   */
   126    132   typedef struct Agg Agg;
   127    133   typedef struct AggElem AggElem;
   128    134   struct Agg {
   129    135     int nMem;              /* Number of values stored in each AggElem */
   130    136     AggElem *pCurrent;     /* The AggElem currently in focus */
   131    137     int nElem;             /* The number of AggElems */
   132    138     int nHash;             /* Number of slots in apHash[] */
   133         -  AggElem **apHash;      /* A hash table for looking up AggElems by zKey */
          139  +  AggElem **apHash;      /* A hash array for looking up AggElems by zKey */
   134    140     AggElem *pFirst;       /* A list of all AggElems */
   135    141   };
   136    142   struct AggElem {
   137    143     char *zKey;            /* The key to this AggElem */
   138    144     AggElem *pHash;        /* Next AggElem with the same hash on zKey */
   139    145     AggElem *pNext;        /* Next AggElem in a list of them all */
   140    146     Mem aMem[1];           /* The values for this AggElem */
................................................................................
   146    152   ** this:
   147    153   **            x.y IN ('hi','hoo','hum')
   148    154   */
   149    155   typedef struct Set Set;
   150    156   typedef struct SetElem SetElem;
   151    157   struct Set {
   152    158     SetElem *pAll;         /* All elements of this set */
   153         -  SetElem *apHash[41];   /* A hash table for all elements in this set */
          159  +  SetElem *apHash[41];   /* A hash array for all elements in this set */
   154    160   };
   155    161   struct SetElem {
   156    162     SetElem *pHash;        /* Next element with the same hash on zKey */
   157    163     SetElem *pNext;        /* Next element in a list of them all */
   158    164     char zKey[1];          /* Value of this key */
   159    165   };
   160    166   
................................................................................
   171    177     int nLabelAlloc;    /* Number of slots allocated in aLabel[] */
   172    178     int *aLabel;        /* Space to hold the labels */
   173    179     int tos;            /* Index of top of stack */
   174    180     int nStackAlloc;    /* Size of the stack */
   175    181     Stack *aStack;      /* The operand stack, except string values */
   176    182     char **zStack;      /* Text or binary values of the stack */
   177    183     char **azColName;   /* Becomes the 4th parameter to callbacks */
   178         -  int nTable;         /* Number of slots in aTab[] */
   179         -  VdbeTable *aTab;    /* On element of this array for each open table */
          184  +  int nCursor;        /* Number of slots in aCsr[] */
          185  +  Cursor *aCsr;       /* On element of this array for each open cursor */
   180    186     int nList;          /* Number of slots in apList[] */
   181    187     FILE **apList;      /* An open file for each list */
   182    188     int nSort;          /* Number of slots in apSort[] */
   183    189     Sorter **apSort;    /* An open sorter list */
   184    190     FILE *pFile;        /* At most one open file handler */
   185    191     int nField;         /* Number of file fields */
   186    192     char **azField;     /* Data for each file field */
................................................................................
   390    396       sqliteFree(pElem);
   391    397     }
   392    398     sqliteFree(p->apHash);
   393    399     memset(p, 0, sizeof(*p));
   394    400   }
   395    401   
   396    402   /*
   397         -** Add the given AggElem to the hash table
          403  +** Add the given AggElem to the hash array
   398    404   */
   399    405   static void AggEnhash(Agg *p, AggElem *pElem){
   400    406     int h = sqliteHashNoCase(pElem->zKey, 0) % p->nHash;
   401    407     pElem->pHash = p->apHash[h];
   402    408     p->apHash[h] = pElem;
   403    409   }
   404    410   
   405    411   /*
   406         -** Change the size of the hash table to the amount given.
          412  +** Change the size of the hash array to the amount given.
   407    413   */
   408    414   static void AggRehash(Agg *p, int nHash){
   409    415     int size;
   410    416     AggElem *pElem;
   411    417     if( p->nHash==nHash ) return;
   412    418     size = nHash * sizeof(AggElem*);
   413    419     p->apHash = sqliteRealloc(p->apHash, size );
................................................................................
   630    636     }
   631    637     return 0;
   632    638   }
   633    639   
   634    640   /*
   635    641   ** Clean up the VM after execution.
   636    642   **
   637         -** This routine will automatically close any tables, list, and/or
          643  +** This routine will automatically close any cursors, list, and/or
   638    644   ** sorters that were left open.
   639    645   */
   640    646   static void Cleanup(Vdbe *p){
   641    647     int i;
   642    648     PopStack(p, p->tos+1);
   643    649     sqliteFree(p->azColName);
   644    650     p->azColName = 0;
   645         -  for(i=0; i<p->nTable; i++){
   646         -    if( p->aTab[i].pTable ){
   647         -      sqliteDbbeCloseTable(p->aTab[i].pTable);
   648         -      p->aTab[i].pTable = 0;
          651  +  for(i=0; i<p->nCursor; i++){
          652  +    if( p->aCsr[i].pCursor ){
          653  +      sqliteDbbeCloseCursor(p->aCsr[i].pCursor);
          654  +      p->aCsr[i].pCursor = 0;
   649    655       }
   650    656     }
   651         -  sqliteFree(p->aTab);
   652         -  p->aTab = 0;
   653         -  p->nTable = 0;
          657  +  sqliteFree(p->aCsr);
          658  +  p->aCsr = 0;
          659  +  p->nCursor = 0;
   654    660     for(i=0; i<p->nMem; i++){
   655    661       if( p->aMem[i].s.flags & STK_Dyn ){
   656    662         sqliteFree(p->aMem[i].z);
   657    663       }
   658    664     }
   659    665     sqliteFree(p->aMem);
   660    666     p->aMem = 0;
................................................................................
   782    788   int sqliteVdbeList(
   783    789     Vdbe *p,                   /* The VDBE */
   784    790     sqlite_callback xCallback, /* The callback */
   785    791     void *pArg,                /* 1st argument to callback */
   786    792     char **pzErrMsg            /* Error msg written here */
   787    793   ){
   788    794     int i, rc;
   789         -  char *azField[6];
          795  +  char *azValue[6];
   790    796     char zAddr[20];
   791    797     char zP1[20];
   792    798     char zP2[20];
   793    799     static char *azColumnNames[] = {
   794    800        "addr", "opcode", "p1", "p2", "p3", 0
   795    801     };
   796    802   
   797    803     if( xCallback==0 ) return 0;
   798         -  azField[0] = zAddr;
   799         -  azField[2] = zP1;
   800         -  azField[3] = zP2;
   801         -  azField[5] = 0;
          804  +  azValue[0] = zAddr;
          805  +  azValue[2] = zP1;
          806  +  azValue[3] = zP2;
          807  +  azValue[5] = 0;
   802    808     rc = SQLITE_OK;
   803    809     /* if( pzErrMsg ){ *pzErrMsg = 0; } */
   804    810     for(i=0; rc==SQLITE_OK && i<p->nOp; i++){
   805    811       sprintf(zAddr,"%d",i);
   806    812       sprintf(zP1,"%d", p->aOp[i].p1);
   807    813       sprintf(zP2,"%d", p->aOp[i].p2);
   808         -    azField[4] = p->aOp[i].p3;
   809         -    azField[1] = zOpName[p->aOp[i].opcode];
   810         -    if( xCallback(pArg, 5, azField, azColumnNames) ){
          814  +    azValue[4] = p->aOp[i].p3;
          815  +    azValue[1] = zOpName[p->aOp[i].opcode];
          816  +    if( xCallback(pArg, 5, azValue, azColumnNames) ){
   811    817         rc = SQLITE_ABORT;
   812    818       }
   813    819     }
   814    820     return rc;
   815    821   }
   816    822   
   817    823   /*
................................................................................
  1488   1494             p->aStack[tos].flags = STK_Real;
  1489   1495           }
  1490   1496           break;
  1491   1497         }
  1492   1498   
  1493   1499         /* Opcode: Not * * *
  1494   1500         **
  1495         -      ** Treat the top of the stack as a boolean value.  Replace it
         1501  +      ** Interpret the top of the stack as a boolean value.  Replace it
  1496   1502         ** with its complement.
  1497   1503         */
  1498   1504         case OP_Not: {
  1499   1505           int tos = p->tos;
  1500   1506           if( p->tos<0 ) goto not_enough_stack;
  1501   1507           Integerify(p, tos);
  1502   1508           Release(p, tos);
................................................................................
  1672   1678           p->aStack[p->tos].flags = STK_Str|STK_Dyn;
  1673   1679           p->zStack[p->tos] = zNewKey;
  1674   1680           break;
  1675   1681         }
  1676   1682   
  1677   1683         /* Opcode: Open P1 P2 P3
  1678   1684         **
  1679         -      ** Open a new cursor for the database table named P3.  Give the
  1680         -      ** cursor an identifier P1.
  1681         -      ** Open readonly if P2==0 and for reading and writing if P2!=0.
  1682         -      ** The table is created if it does not already exist and P2!=0.
  1683         -      ** If there is already another cursor opened with identifier P1,
  1684         -      ** then the old cursor is closed first.
  1685         -      ** All cursors are automatically closed when
  1686         -      ** the VDBE finishes execution.  The P1 values need not be
         1685  +      ** Open a new cursor for the database file named P3.  Give the
         1686  +      ** cursor an identifier P1.  The P1 values need not be
  1687   1687         ** contiguous but all P1 values should be small integers.  It is
  1688   1688         ** an error for P1 to be negative.
  1689   1689         **
  1690         -      ** If P3 is null or an empty string, a temporary table created.
  1691         -      ** This table is automatically deleted when the cursor is closed.
         1690  +      ** Open readonly if P2==0 and for reading and writing if P2!=0.
         1691  +      ** The file is created if it does not already exist and P2!=0.
         1692  +      ** If there is already another cursor opened with identifier P1,
         1693  +      ** then the old cursor is closed first.  All cursors are
         1694  +      ** automatically closed when the VDBE finishes execution.
         1695  +      **
         1696  +      ** If P3 is null or an empty string, a temporary database file
         1697  +      ** is created.  This temporary database file is automatically 
         1698  +      ** deleted when the cursor is closed.
  1692   1699         */
  1693   1700         case OP_Open: {
  1694   1701           int i = pOp->p1;
  1695   1702           if( i<0 ) goto bad_instruction;
  1696         -        if( i>=p->nTable ){
         1703  +        if( i>=p->nCursor ){
  1697   1704             int j;
  1698         -          p->aTab = sqliteRealloc( p->aTab, (i+1)*sizeof(VdbeTable) );
  1699         -          if( p->aTab==0 ){ p->nTable = 0; goto no_mem; }
  1700         -          for(j=p->nTable; j<=i; j++) p->aTab[j].pTable = 0;
  1701         -          p->nTable = i+1;
  1702         -        }else if( p->aTab[i].pTable ){
  1703         -          sqliteDbbeCloseTable(p->aTab[i].pTable);
         1705  +          p->aCsr = sqliteRealloc( p->aCsr, (i+1)*sizeof(Cursor) );
         1706  +          if( p->aCsr==0 ){ p->nCursor = 0; goto no_mem; }
         1707  +          for(j=p->nCursor; j<=i; j++) p->aCsr[j].pCursor = 0;
         1708  +          p->nCursor = i+1;
         1709  +        }else if( p->aCsr[i].pCursor ){
         1710  +          sqliteDbbeCloseCursor(p->aCsr[i].pCursor);
  1704   1711           }
  1705         -        rc = sqliteDbbeOpenTable(p->pBe, pOp->p3, pOp->p2, &p->aTab[i].pTable);
         1712  +        rc = sqliteDbbeOpenCursor(p->pBe, pOp->p3, pOp->p2,&p->aCsr[i].pCursor);
  1706   1713           switch( rc ){
  1707   1714             case SQLITE_BUSY: {
  1708   1715               sqliteSetString(pzErrMsg,"table ", pOp->p3, " is locked", 0);
  1709   1716               break;
  1710   1717             }
  1711   1718             case SQLITE_PERM: {
  1712   1719               sqliteSetString(pzErrMsg, pOp->p2 ? "write" : "read",
................................................................................
  1718   1725                  " is readonly", 0);
  1719   1726               break;
  1720   1727             }
  1721   1728             case SQLITE_NOMEM: {
  1722   1729               goto no_mem;
  1723   1730             }
  1724   1731           }
  1725         -        p->aTab[i].index = 0;
  1726         -        p->aTab[i].keyAsData = 0;
         1732  +        p->aCsr[i].index = 0;
         1733  +        p->aCsr[i].keyAsData = 0;
  1727   1734           break;
  1728   1735         }
  1729   1736   
  1730   1737         /* Opcode: Close P1 * *
  1731   1738         **
  1732         -      ** Close a database table previously opened as P1.  If P1 is not
         1739  +      ** Close a cursor previously opened as P1.  If P1 is not
  1733   1740         ** currently open, this instruction is a no-op.
  1734   1741         */
  1735   1742         case OP_Close: {
  1736   1743           int i = pOp->p1;
  1737         -        if( i>=0 && i<p->nTable && p->aTab[i].pTable ){
  1738         -          sqliteDbbeCloseTable(p->aTab[i].pTable);
  1739         -          p->aTab[i].pTable = 0;
         1744  +        if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor ){
         1745  +          sqliteDbbeCloseCursor(p->aCsr[i].pCursor);
         1746  +          p->aCsr[i].pCursor = 0;
  1740   1747           }
  1741   1748           break;
  1742   1749         }
  1743   1750   
  1744   1751         /* Opcode: Fetch P1 * *
  1745   1752         **
  1746   1753         ** Pop the top of the stack and use its value as a key to fetch
  1747         -      ** a record from database table or index P1.  The data is held
  1748         -      ** in the P1 cursor until needed.  The data is not pushed onto the
  1749         -      ** stack.
         1754  +      ** a record from cursor P1.  The key/data pair is held
         1755  +      ** in the P1 cursor until needed.
  1750   1756         */
  1751   1757         case OP_Fetch: {
  1752   1758           int i = pOp->p1;
  1753   1759           int tos = p->tos;
  1754   1760           if( tos<0 ) goto not_enough_stack;
  1755         -        if( i>=0 && i<p->nTable && p->aTab[i].pTable ){
         1761  +        if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor ){
  1756   1762             if( p->aStack[tos].flags & STK_Int ){
  1757         -            sqliteDbbeFetch(p->aTab[i].pTable, sizeof(int), 
         1763  +            sqliteDbbeFetch(p->aCsr[i].pCursor, sizeof(int), 
  1758   1764                              (char*)&p->aStack[tos].i);
  1759   1765             }else{
  1760   1766               if( Stringify(p, tos) ) goto no_mem;
  1761         -            sqliteDbbeFetch(p->aTab[i].pTable, p->aStack[tos].n, 
         1767  +            sqliteDbbeFetch(p->aCsr[i].pCursor, p->aStack[tos].n, 
  1762   1768                              p->zStack[tos]);
  1763   1769             }
  1764   1770             p->nFetch++;
  1765   1771           }
  1766   1772           PopStack(p, 1);
  1767   1773           break;
  1768   1774         }
................................................................................
  1783   1789           p->aStack[i].flags = STK_Int;
  1784   1790           break;
  1785   1791         }
  1786   1792   
  1787   1793         /* Opcode: Distinct P1 P2 *
  1788   1794         **
  1789   1795         ** Use the top of the stack as a key.  If a record with that key
  1790         -      ** does not exist in table P1, then jump to P2.  If the record
         1796  +      ** does not exist in file P1, then jump to P2.  If the record
  1791   1797         ** does already exist, then fall thru.  The record is not retrieved.
  1792   1798         ** The key is not popped from the stack.
  1793   1799         **
  1794   1800         ** This operation is similar to NotFound except that this operation
  1795   1801         ** does not pop the key from the stack.
  1796   1802         */
  1797   1803         /* Opcode: Found P1 P2 *
  1798   1804         **
  1799   1805         ** Use the top of the stack as a key.  If a record with that key
  1800         -      ** does exist in table P1, then jump to P2.  If the record
         1806  +      ** does exist in file P1, then jump to P2.  If the record
  1801   1807         ** does not exist, then fall thru.  The record is not retrieved.
  1802   1808         ** The key is popped from the stack.
  1803   1809         */
  1804   1810         /* Opcode: NotFound P1 P2 *
  1805   1811         **
  1806   1812         ** Use the top of the stack as a key.  If a record with that key
  1807         -      ** does not exist in table P1, then jump to P2.  If the record
         1813  +      ** does not exist in file P1, then jump to P2.  If the record
  1808   1814         ** does exist, then fall thru.  The record is not retrieved.
  1809   1815         ** The key is popped from the stack.
  1810   1816         **
  1811   1817         ** The difference between this operation and Distinct is that
  1812   1818         ** Distinct does not pop the key from the stack.
  1813   1819         */
  1814   1820         case OP_Distinct:
  1815   1821         case OP_NotFound:
  1816   1822         case OP_Found: {
  1817   1823           int i = pOp->p1;
  1818   1824           int tos = p->tos;
  1819   1825           int alreadyExists = 0;
  1820   1826           if( tos<0 ) goto not_enough_stack;
  1821         -        if( i>=0 && i<p->nTable && p->aTab[i].pTable ){
         1827  +        if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor ){
  1822   1828             if( p->aStack[tos].flags & STK_Int ){
  1823         -            alreadyExists = sqliteDbbeTest(p->aTab[i].pTable, sizeof(int), 
         1829  +            alreadyExists = sqliteDbbeTest(p->aCsr[i].pCursor, sizeof(int), 
  1824   1830                                             (char*)&p->aStack[tos].i);
  1825   1831             }else{
  1826   1832               if( Stringify(p, tos) ) goto no_mem;
  1827         -            alreadyExists = sqliteDbbeTest(p->aTab[i].pTable, p->aStack[tos].n, 
         1833  +            alreadyExists = sqliteDbbeTest(p->aCsr[i].pCursor,p->aStack[tos].n, 
  1828   1834                                              p->zStack[tos]);
  1829   1835             }
  1830   1836           }
  1831   1837           if( pOp->opcode==OP_Found ){
  1832   1838             if( alreadyExists ) pc = pOp->p2 - 1;
  1833   1839           }else{
  1834   1840             if( !alreadyExists ) pc = pOp->p2 - 1;
................................................................................
  1837   1843             PopStack(p, 1);
  1838   1844           }
  1839   1845           break;
  1840   1846         }
  1841   1847   
  1842   1848         /* Opcode: New P1 * *
  1843   1849         **
  1844         -      ** Get a new integer key not previous used by table P1 and
  1845         -      ** push it onto the stack.
         1850  +      ** Get a new integer key not previous used by the database file
         1851  +      ** associated with cursor P1 and push it onto the stack.
  1846   1852         */
  1847   1853         case OP_New: {
  1848   1854           int i = pOp->p1;
  1849   1855           int v;
  1850         -        if( i<0 || i>=p->nTable || p->aTab[i].pTable==0 ){
         1856  +        if( i<0 || i>=p->nCursor || p->aCsr[i].pCursor==0 ){
  1851   1857             v = 0;
  1852   1858           }else{
  1853         -          v = sqliteDbbeNew(p->aTab[i].pTable);
         1859  +          v = sqliteDbbeNew(p->aCsr[i].pCursor);
  1854   1860           }
  1855   1861           NeedStack(p, p->tos+1);
  1856   1862           p->tos++;
  1857   1863           p->aStack[p->tos].i = v;
  1858   1864           p->aStack[p->tos].flags = STK_Int;
  1859   1865           break;
  1860   1866         }
  1861   1867   
  1862   1868         /* Opcode: Put P1 * *
  1863   1869         **
  1864         -      ** Write an entry into the database table P1.  A new entry is
         1870  +      ** Write an entry into the database file P1.  A new entry is
  1865   1871         ** created if it doesn't already exist, or the data for an existing
  1866   1872         ** entry is overwritten.  The data is the value on the top of the
  1867   1873         ** stack.  The key is the next value down on the stack.  The stack
  1868   1874         ** is popped twice by this instruction.
  1869   1875         */
  1870   1876         case OP_Put: {
  1871   1877           int tos = p->tos;
  1872   1878           int nos = p->tos-1;
  1873   1879           int i = pOp->p1;
  1874   1880           if( nos<0 ) goto not_enough_stack;
  1875         -        if( i>=0 && i<p->nTable && p->aTab[i].pTable!=0 ){
         1881  +        if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor!=0 ){
  1876   1882             char *zKey;
  1877   1883             int nKey;
  1878   1884             if( (p->aStack[nos].flags & STK_Int)==0 ){
  1879   1885               if( Stringify(p, nos) ) goto no_mem;
  1880   1886               nKey = p->aStack[nos].n;
  1881   1887               zKey = p->zStack[nos];
  1882   1888             }else{
  1883   1889               nKey = sizeof(int);
  1884   1890               zKey = (char*)&p->aStack[nos].i;
  1885   1891             }
  1886         -          sqliteDbbePut(p->aTab[i].pTable, nKey, zKey,
         1892  +          sqliteDbbePut(p->aCsr[i].pCursor, nKey, zKey,
  1887   1893                           p->aStack[tos].n, p->zStack[tos]);
  1888   1894           }
  1889   1895           PopStack(p, 2);
  1890   1896           break;
  1891   1897         }
  1892   1898   
  1893   1899         /* Opcode: Delete P1 * *
  1894   1900         **
  1895   1901         ** The top of the stack is a key.  Remove this key and its data
  1896         -      ** from database table P1.  Then pop the stack to discard the key.
         1902  +      ** from database file P1.  Then pop the stack to discard the key.
  1897   1903         */
  1898   1904         case OP_Delete: {
  1899   1905           int tos = p->tos;
  1900   1906           int i = pOp->p1;
  1901   1907           if( tos<0 ) goto not_enough_stack;
  1902         -        if( i>=0 && i<p->nTable && p->aTab[i].pTable!=0 ){
         1908  +        if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor!=0 ){
  1903   1909             char *zKey;
  1904   1910             int nKey;
  1905   1911             if( p->aStack[tos].flags & STK_Int ){
  1906   1912               nKey = sizeof(int);
  1907   1913               zKey = (char*)&p->aStack[tos].i;
  1908   1914             }else{
  1909   1915               if( Stringify(p, tos) ) goto no_mem;
  1910   1916               nKey = p->aStack[tos].n;
  1911   1917               zKey = p->zStack[tos];
  1912   1918             }
  1913         -          sqliteDbbeDelete(p->aTab[i].pTable, nKey, zKey);
         1919  +          sqliteDbbeDelete(p->aCsr[i].pCursor, nKey, zKey);
  1914   1920           }
  1915   1921           PopStack(p, 1);
  1916   1922           break;
  1917   1923         }
  1918   1924   
  1919   1925         /* Opcode: KeyAsData P1 P2 *
  1920   1926         **
................................................................................
  1921   1927         ** Turn the key-as-data mode for cursor P1 either on (if P2==1) or
  1922   1928         ** off (if P2==0).  In key-as-data mode, the OP_Fetch opcode pulls
  1923   1929         ** data off of the key rather than the data.  This is useful for
  1924   1930         ** processing compound selects.
  1925   1931         */
  1926   1932         case OP_KeyAsData: {
  1927   1933           int i = pOp->p1;
  1928         -        if( i>=0 && i<p->nTable && p->aTab[i].pTable!=0 ){
  1929         -          p->aTab[i].keyAsData = pOp->p2;
         1934  +        if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor!=0 ){
         1935  +          p->aCsr[i].keyAsData = pOp->p2;
  1930   1936           }
  1931   1937           break;
  1932   1938         }
  1933   1939   
  1934   1940         /* Opcode: Field P1 P2 *
  1935   1941         **
  1936         -      ** Push onto the stack the value of the P2-th field from the
  1937         -      ** most recent Fetch from table P1.
         1942  +      ** Interpret the data in the most recent fetch from cursor P1
         1943  +      ** is a structure built using the MakeRecord instruction.
         1944  +      ** Push onto the stack the value of the P2-th field of that
         1945  +      ** structure.
  1938   1946         ** 
  1939   1947         ** The value pushed is just a pointer to the data in the cursor.
  1940   1948         ** The value will go away the next time a record is fetched from P1,
  1941   1949         ** or when P1 is closed.  Make a copy of the string (using
  1942   1950         ** "Concat 1 0 0") if it needs to persist longer than that.
  1943   1951         **
  1944   1952         ** If the KeyAsData opcode has previously executed on this cursor,
  1945   1953         ** then the field might be extracted from the key rather than the
  1946   1954         ** data.
         1955  +      **
         1956  +      ** Viewed from a higher level, this instruction retrieves the
         1957  +      ** data from a single column in a particular row of an SQL table
         1958  +      ** file.  Perhaps the name of this instruction should be
         1959  +      ** "Column" instead of "Field"...
  1947   1960         */
  1948   1961         case OP_Field: {
  1949   1962           int *pAddr;
  1950   1963           int amt;
  1951   1964           int i = pOp->p1;
  1952   1965           int p2 = pOp->p2;
  1953   1966           int tos = ++p->tos;
  1954         -        DbbeTable *pTab;
         1967  +        DbbeCursor *pCrsr;
  1955   1968           char *z;
  1956   1969   
  1957   1970           if( NeedStack(p, tos) ) goto no_mem;
  1958         -        if( i>=0 && i<p->nTable && (pTab = p->aTab[i].pTable)!=0 ){
  1959         -          if( p->aTab[i].keyAsData ){
  1960         -            amt = sqliteDbbeKeyLength(pTab);
         1971  +        if( i>=0 && i<p->nCursor && (pCrsr = p->aCsr[i].pCursor)!=0 ){
         1972  +          if( p->aCsr[i].keyAsData ){
         1973  +            amt = sqliteDbbeKeyLength(pCrsr);
  1961   1974               if( amt<=sizeof(int)*(p2+1) ){
  1962   1975                 p->aStack[tos].flags = STK_Null;
  1963   1976                 break;
  1964   1977               }
  1965         -            pAddr = (int*)sqliteDbbeReadKey(pTab, sizeof(int)*p2);
         1978  +            pAddr = (int*)sqliteDbbeReadKey(pCrsr, sizeof(int)*p2);
  1966   1979               if( *pAddr==0 ){
  1967   1980                 p->aStack[tos].flags = STK_Null;
  1968   1981                 break;
  1969   1982               }
  1970         -            z = sqliteDbbeReadKey(pTab, *pAddr);
         1983  +            z = sqliteDbbeReadKey(pCrsr, *pAddr);
  1971   1984             }else{
  1972         -            amt = sqliteDbbeDataLength(pTab);
         1985  +            amt = sqliteDbbeDataLength(pCrsr);
  1973   1986               if( amt<=sizeof(int)*(p2+1) ){
  1974   1987                 p->aStack[tos].flags = STK_Null;
  1975   1988                 break;
  1976   1989               }
  1977         -            pAddr = (int*)sqliteDbbeReadData(pTab, sizeof(int)*p2);
         1990  +            pAddr = (int*)sqliteDbbeReadData(pCrsr, sizeof(int)*p2);
  1978   1991               if( *pAddr==0 ){
  1979   1992                 p->aStack[tos].flags = STK_Null;
  1980   1993                 break;
  1981   1994               }
  1982         -            z = sqliteDbbeReadData(pTab, *pAddr);
         1995  +            z = sqliteDbbeReadData(pCrsr, *pAddr);
  1983   1996             }
  1984   1997             p->zStack[tos] = z;
  1985   1998             p->aStack[tos].n = strlen(z) + 1;
  1986   1999             p->aStack[tos].flags = STK_Str;
  1987   2000           }
  1988   2001           break;
  1989   2002         }
  1990   2003   
  1991   2004         /* Opcode: Key P1 * *
  1992   2005         **
  1993   2006         ** Push onto the stack an integer which is the first 4 bytes of the
  1994         -      ** the key to the current entry in a sequential scan of the table P1.
  1995         -      ** A sequential scan is started using the Next opcode.
         2007  +      ** the key to the current entry in a sequential scan of the database
         2008  +      ** file P1.  The sequential scan should have been started using the 
         2009  +      ** Next opcode.
  1996   2010         */
  1997   2011         case OP_Key: {
  1998   2012           int i = pOp->p1;
  1999   2013           int tos = ++p->tos;
  2000         -        DbbeTable *pTab;
         2014  +        DbbeCursor *pCrsr;
  2001   2015   
  2002   2016           if( NeedStack(p, p->tos) ) goto no_mem;
  2003         -        if( i>=0 && i<p->nTable && (pTab = p->aTab[i].pTable)!=0 ){
  2004         -          char *z = sqliteDbbeReadKey(pTab, 0);
  2005         -          if( p->aTab[i].keyAsData ){
         2017  +        if( i>=0 && i<p->nCursor && (pCrsr = p->aCsr[i].pCursor)!=0 ){
         2018  +          char *z = sqliteDbbeReadKey(pCrsr, 0);
         2019  +          if( p->aCsr[i].keyAsData ){
  2006   2020               p->zStack[tos] = z;
  2007   2021               p->aStack[tos].flags = STK_Str;
  2008         -            p->aStack[tos].n = sqliteDbbeKeyLength(pTab);
         2022  +            p->aStack[tos].n = sqliteDbbeKeyLength(pCrsr);
  2009   2023             }else{
  2010   2024               memcpy(&p->aStack[tos].i, z, sizeof(int));
  2011   2025               p->aStack[tos].flags = STK_Int;
  2012   2026             }
  2013   2027           }
  2014   2028           break;
  2015   2029         }
  2016   2030   
  2017   2031         /* Opcode: Rewind P1 * *
  2018   2032         **
  2019   2033         ** The next use of the Key or Field or Next instruction for P1 
  2020         -      ** will refer to the first entry in the table.
         2034  +      ** will refer to the first entry in the database file.
  2021   2035         */
  2022   2036         case OP_Rewind: {
  2023   2037           int i = pOp->p1;
  2024         -        if( i>=0 && i<p->nTable && p->aTab[i].pTable!=0 ){
  2025         -          sqliteDbbeRewind(p->aTab[i].pTable);
         2038  +        if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor!=0 ){
         2039  +          sqliteDbbeRewind(p->aCsr[i].pCursor);
  2026   2040           }
  2027   2041           break;
  2028   2042         }
  2029   2043   
  2030   2044         /* Opcode: Next P1 P2 *
  2031   2045         **
  2032         -      ** Advance P1 to the next entry in the table.  Or, if there are no
  2033         -      ** more entries, rewind P1 and jump to location P2.
         2046  +      ** Advance P1 to the next key/data pair in the file.  Or, if there are no
         2047  +      ** more key/data pairs, rewind P1 and jump to location P2.
  2034   2048         */
  2035   2049         case OP_Next: {
  2036   2050           int i = pOp->p1;
  2037         -        if( i>=0 && i<p->nTable && p->aTab[i].pTable!=0 ){
  2038         -          if( sqliteDbbeNextKey(p->aTab[i].pTable)==0 ){
         2051  +        if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor!=0 ){
         2052  +          if( sqliteDbbeNextKey(p->aCsr[i].pCursor)==0 ){
  2039   2053               pc = pOp->p2 - 1;
  2040   2054             }else{
  2041   2055               p->nFetch++;
  2042   2056             }
  2043   2057           }
  2044   2058           break;
  2045   2059         }
  2046   2060   
  2047   2061         /* Opcode: ResetIdx P1 * *
  2048   2062         **
  2049         -      ** Begin treating the current row of table P1 as an index.  The next
  2050         -      ** NextIdx instruction will refer to the first index in the table.
         2063  +      ** Begin treating the current data in cursor P1 as a bunch of integer
         2064  +      ** keys to records of a (separate) SQL table file.  This instruction
         2065  +      ** causes the new NextIdx instruction push the first integer table
         2066  +      ** key in the data.
  2051   2067         */
  2052   2068         case OP_ResetIdx: {
  2053   2069           int i = pOp->p1;
  2054         -        if( i>=0 && i<p->nTable ){
  2055         -          p->aTab[i].index = 0;
         2070  +        if( i>=0 && i<p->nCursor ){
         2071  +          p->aCsr[i].index = 0;
  2056   2072           }
  2057   2073           break;
  2058   2074         }
  2059   2075   
  2060   2076         /* Opcode: NextIdx P1 P2 *
  2061   2077         **
  2062         -      ** Push the next index from the current entry of table P1 onto the
  2063         -      ** stack and advance the pointer.  If there are no more indices, then
  2064         -      ** reset the table entry and jump to P2
         2078  +      ** The P1 cursor points to an SQL index.  The data from the most
         2079  +      ** recent fetch on that cursor consists of a bunch of integers where
         2080  +      ** each integer is the key to a record in an SQL table file.
         2081  +      ** This instruction grabs the next integer table key from the data
         2082  +      ** of P1 and pushes that integer onto the stack.  The first time
         2083  +      ** this instruction is executed after a fetch, the first integer 
         2084  +      ** table key is pushed.  Subsequent integer table keys are pushed 
         2085  +      ** in each subsequent execution of this instruction.
         2086  +      **
         2087  +      ** If there are no more integer table keys in the data of P1
         2088  +      ** when this instruction is executed, then nothing gets pushed and
         2089  +      ** there is an immediate jump to instruction P2.
  2065   2090         */
  2066   2091         case OP_NextIdx: {
  2067   2092           int i = pOp->p1;
  2068   2093           int tos = ++p->tos;
  2069         -        DbbeTable *pTab;
         2094  +        DbbeCursor *pCrsr;
  2070   2095   
  2071   2096           if( NeedStack(p, p->tos) ) goto no_mem;
  2072   2097           p->zStack[tos] = 0;
  2073         -        if( i>=0 && i<p->nTable && (pTab = p->aTab[i].pTable)!=0 ){
         2098  +        if( i>=0 && i<p->nCursor && (pCrsr = p->aCsr[i].pCursor)!=0 ){
  2074   2099             int *aIdx;
  2075   2100             int nIdx;
  2076   2101             int j;
  2077         -          nIdx = sqliteDbbeDataLength(pTab)/sizeof(int);
  2078         -          aIdx = (int*)sqliteDbbeReadData(pTab, 0);
  2079         -          for(j=p->aTab[i].index; j<nIdx; j++){
         2102  +          nIdx = sqliteDbbeDataLength(pCrsr)/sizeof(int);
         2103  +          aIdx = (int*)sqliteDbbeReadData(pCrsr, 0);
         2104  +          for(j=p->aCsr[i].index; j<nIdx; j++){
  2080   2105               if( aIdx[j]!=0 ){
  2081   2106                 p->aStack[tos].i = aIdx[j];
  2082   2107                 p->aStack[tos].flags = STK_Int;
  2083   2108                 break;
  2084   2109               }
  2085   2110             }
  2086   2111             if( j>=nIdx ){
  2087   2112               j = -1;
  2088   2113               pc = pOp->p2 - 1;
  2089   2114               PopStack(p, 1);
  2090   2115             }
  2091         -          p->aTab[i].index = j+1;
         2116  +          p->aCsr[i].index = j+1;
  2092   2117           }
  2093   2118           break;
  2094   2119         }
  2095   2120   
  2096   2121         /* Opcode: PutIdx P1 * *
  2097   2122         **
  2098         -      ** The top of the stack hold an index key (probably made using the
  2099         -      ** MakeKey instruction) and next on stack holds an index value for
  2100         -      ** a table.  Locate the record in the index P1 that has the key 
  2101         -      ** and insert the index value into its
  2102         -      ** data.  Write the results back to the index.
  2103         -      ** If the key doesn't exist it is created.
         2123  +      ** The top of the stack hold an SQL index key (probably made using the
         2124  +      ** MakeKey instruction) and next on stack holds an integer which
         2125  +      ** the key to an SQL table entry.  Locate the record in cursor P1
         2126  +      ** that has the same key as on the TOS.  Create a new record if
         2127  +      ** necessary.  Then append the integer table key to the data for that
         2128  +      ** record and write it back to the P1 file.
  2104   2129         */
  2105   2130         case OP_PutIdx: {
  2106   2131           int i = pOp->p1;
  2107   2132           int tos = p->tos;
  2108   2133           int nos = tos - 1;
  2109         -        DbbeTable *pTab;
         2134  +        DbbeCursor *pCrsr;
  2110   2135           if( nos<0 ) goto not_enough_stack;
  2111         -        if( i>=0 && i<p->nTable && (pTab = p->aTab[i].pTable)!=0 ){
         2136  +        if( i>=0 && i<p->nCursor && (pCrsr = p->aCsr[i].pCursor)!=0 ){
  2112   2137             int r;
  2113   2138             int newVal;
  2114   2139             Integerify(p, nos);
  2115   2140             newVal = p->aStack[nos].i;
  2116   2141             if( Stringify(p, tos) ) goto no_mem;
  2117         -          r = sqliteDbbeFetch(pTab, p->aStack[tos].n, p->zStack[tos]);
         2142  +          r = sqliteDbbeFetch(pCrsr, p->aStack[tos].n, p->zStack[tos]);
  2118   2143             if( r==0 ){
  2119   2144               /* Create a new record for this index */
  2120         -            sqliteDbbePut(pTab, p->aStack[tos].n, p->zStack[tos],
         2145  +            sqliteDbbePut(pCrsr, p->aStack[tos].n, p->zStack[tos],
  2121   2146                             sizeof(int), (char*)&newVal);
  2122   2147             }else{
  2123   2148               /* Extend the existing record */
  2124   2149               int nIdx;
  2125   2150               int *aIdx;
  2126         -            nIdx = sqliteDbbeDataLength(pTab)/sizeof(int);
         2151  +            nIdx = sqliteDbbeDataLength(pCrsr)/sizeof(int);
  2127   2152               aIdx = sqliteMalloc( sizeof(int)*(nIdx+1) );
  2128   2153               if( aIdx==0 ) goto no_mem;
  2129         -            sqliteDbbeCopyData(pTab, 0, nIdx*sizeof(int), (char*)aIdx);
         2154  +            sqliteDbbeCopyData(pCrsr, 0, nIdx*sizeof(int), (char*)aIdx);
  2130   2155               aIdx[nIdx] = newVal;
  2131         -            sqliteDbbePut(pTab, p->aStack[tos].n, p->zStack[tos],
         2156  +            sqliteDbbePut(pCrsr, p->aStack[tos].n, p->zStack[tos],
  2132   2157                             sizeof(int)*(nIdx+1), (char*)aIdx);
  2133   2158               sqliteFree(aIdx);
  2134   2159             }
  2135   2160           }
  2136   2161           PopStack(p, 2);
  2137   2162           break;
  2138   2163         }
  2139   2164   
  2140   2165         /* Opcode: DeleteIdx P1 * *
  2141   2166         **
  2142         -      ** The top of the stack is a key and next on stack is an index value.
  2143         -      ** Locate the record
  2144         -      ** in index P1 that has the key and remove the index value from its
  2145         -      ** data.  Write the results back to the table.  If after removing
  2146         -      ** the index value no more indices remain in the record, then the
  2147         -      ** record is removed from the table.
         2167  +      ** The top of the stack is a key and next on stack is integer
         2168  +      ** which is the key to a record in an SQL table.
         2169  +      ** Locate the record in the cursor P1 (P1 represents an SQL index)
         2170  +      ** that has the same key as the top of stack.  Then look through
         2171  +      ** the integer table-keys contained in the data of the P1 record.
         2172  +      ** Remove the integer table-key that matches the NOS and write the
         2173  +      ** revised data back to P1 with the same key.
         2174  +      **
         2175  +      ** If this routine removes the very last integer table-key from
         2176  +      ** the P1 data, then the corresponding P1 record is deleted.
  2148   2177         */
  2149   2178         case OP_DeleteIdx: {
  2150   2179           int i = pOp->p1;
  2151   2180           int tos = p->tos;
  2152   2181           int nos = tos - 1;
  2153         -        DbbeTable *pTab;
         2182  +        DbbeCursor *pCrsr;
  2154   2183           if( nos<0 ) goto not_enough_stack;
  2155         -        if( i>=0 && i<p->nTable && (pTab = p->aTab[i].pTable)!=0 ){
         2184  +        if( i>=0 && i<p->nCursor && (pCrsr = p->aCsr[i].pCursor)!=0 ){
  2156   2185             int *aIdx;
  2157   2186             int nIdx;
  2158   2187             int j;
  2159   2188             int r;
  2160   2189             int oldVal;
  2161   2190             Integerify(p, nos);
  2162   2191             oldVal = p->aStack[nos].i;
  2163   2192             if( Stringify(p, tos) ) goto no_mem;
  2164         -          r = sqliteDbbeFetch(pTab, p->aStack[tos].n, p->zStack[tos]);
         2193  +          r = sqliteDbbeFetch(pCrsr, p->aStack[tos].n, p->zStack[tos]);
  2165   2194             if( r==0 ) break;
  2166         -          nIdx = sqliteDbbeDataLength(pTab)/sizeof(int);
  2167         -          aIdx = (int*)sqliteDbbeReadData(pTab, 0);
         2195  +          nIdx = sqliteDbbeDataLength(pCrsr)/sizeof(int);
         2196  +          aIdx = (int*)sqliteDbbeReadData(pCrsr, 0);
  2168   2197             for(j=0; j<nIdx && aIdx[j]!=oldVal; j++){}
  2169   2198             if( j>=nIdx ) break;
  2170   2199             aIdx[j] = aIdx[nIdx-1];
  2171   2200             if( nIdx==1 ){
  2172         -            sqliteDbbeDelete(pTab, p->aStack[tos].n, p->zStack[tos]);
         2201  +            sqliteDbbeDelete(pCrsr, p->aStack[tos].n, p->zStack[tos]);
  2173   2202             }else{
  2174         -            sqliteDbbePut(pTab, p->aStack[tos].n, p->zStack[tos], 
         2203  +            sqliteDbbePut(pCrsr, p->aStack[tos].n, p->zStack[tos], 
  2175   2204                             sizeof(int)*(nIdx-1), (char*)aIdx);
  2176   2205             }
  2177   2206           }
  2178   2207           PopStack(p, 2);
  2179   2208           break;
  2180   2209         }
  2181   2210   
  2182   2211         /* Opcode: Destroy * * P3
  2183   2212         **
  2184         -      ** Drop the table whose name is P3.  The file that holds this table
  2185         -      ** is removed from the disk drive.
         2213  +      ** Drop the disk file whose name is P3.  All key/data pairs in
         2214  +      ** the file are deleted and the file itself is removed
         2215  +      ** from the disk.
  2186   2216         */
  2187   2217         case OP_Destroy: {
  2188   2218           sqliteDbbeDropTable(p->pBe, pOp->p3);
  2189   2219           break;
  2190   2220         }
  2191   2221   
  2192   2222         /* Opcode: Reorganize * * P3
................................................................................
  2196   2226         case OP_Reorganize: {
  2197   2227           sqliteDbbeReorganizeTable(p->pBe, pOp->p3);
  2198   2228           break;
  2199   2229         }
  2200   2230   
  2201   2231         /* Opcode: ListOpen P1 * *
  2202   2232         **
  2203         -      ** Open a file used for temporary storage of index numbers.  P1
         2233  +      ** Open a file used for temporary storage of integer table keys.  P1
  2204   2234         ** will server as a handle to this temporary file for future
  2205   2235         ** interactions.  If another temporary file with the P1 handle is
  2206   2236         ** already opened, the prior file is closed and a new one opened
  2207   2237         ** in its place.
  2208   2238         */
  2209   2239         case OP_ListOpen: {
  2210   2240           int i = pOp->p1;
................................................................................
  2256   2286           }
  2257   2287           break;
  2258   2288         }
  2259   2289   
  2260   2290         /* Opcode: ListRead P1 P2 *
  2261   2291         **
  2262   2292         ** Attempt to read an integer from temporary storage buffer P1
  2263         -      ** and push it onto the stack.  If the storage buffer is empty
         2293  +      ** and push it onto the stack.  If the storage buffer is empty, 
  2264   2294         ** push nothing but instead jump to P2.
  2265   2295         */
  2266   2296         case OP_ListRead: {
  2267   2297           int i = pOp->p1;
  2268   2298           int val, amt;
  2269   2299           if( i<0 || i>=p->nList || p->apList[i]==0 ) goto bad_instruction;
  2270   2300           amt = fread(&val, sizeof(int), 1, p->apList[i]);
................................................................................
  2689   2719           pc = pOp->p2 - 1;
  2690   2720           break;
  2691   2721         }
  2692   2722   
  2693   2723         /* Opcode: FileField P1 * *
  2694   2724         **
  2695   2725         ** Push onto the stack the P1-th field of the most recently read line
  2696         -      ** from the file.
         2726  +      ** from the input file.
  2697   2727         */
  2698   2728         case OP_FileField: {
  2699   2729           int i = pOp->p1;
  2700   2730           char *z;
  2701   2731           if( NeedStack(p, p->tos+1) ) goto no_mem;
  2702   2732           if( i>=0 && i<p->nField && p->azField ){
  2703   2733             z = p->azField[i];
................................................................................
  2824   2854           }
  2825   2855           PopStack(p, 1);
  2826   2856           break; 
  2827   2857         }
  2828   2858   
  2829   2859         /* Opcode: AggIncr P1 P2 *
  2830   2860         **
  2831         -      ** Increment the P2-th field of the aggregate element current
  2832         -      ** in focus by an amount P1.
         2861  +      ** Increase the integer value in the P2-th field of the aggregate
         2862  +      ** element current in focus by an amount P1.
  2833   2863         */
  2834   2864         case OP_AggIncr: {
  2835   2865           AggElem *pFocus = AggInFocus(p->agg);
  2836   2866           int i = pOp->p2;
  2837   2867           if( pFocus==0 ) goto no_mem;
  2838   2868           if( i>=0 && i<p->agg.nMem ){
  2839   2869             Mem *pMem = &pFocus->aMem[i];

Changes to src/where.c.

    21     21   **   http://www.hwaci.com/drh/
    22     22   **
    23     23   *************************************************************************
    24     24   ** This module contains C code that generates VDBE code used to process
    25     25   ** the WHERE clause of SQL statements.  Also found here are subroutines
    26     26   ** to generate VDBE code to evaluate expressions.
    27     27   **
    28         -** $Id: where.c,v 1.7 2000/06/06 13:54:16 drh Exp $
           28  +** $Id: where.c,v 1.8 2000/06/21 13:59:13 drh Exp $
    29     29   */
    30     30   #include "sqliteInt.h"
    31     31   
    32     32   /*
    33     33   ** The query generator uses an array of instances of this structure to
    34     34   ** help it analyze the subexpressions of the WHERE clause.  Each WHERE
    35     35   ** clause subexpression is separated from the others by an AND operator.
    36     36   */
    37     37   typedef struct ExprInfo ExprInfo;
    38     38   struct ExprInfo {
    39     39     Expr *p;                /* Pointer to the subexpression */
    40     40     int indexable;          /* True if this subexprssion is usable by an index */
    41         -  int idxLeft;            /* p->pLeft is a field in this table number. -1 if
    42         -                          ** p->pLeft is not the field of any table */
    43         -  int idxRight;           /* p->pRight is a field in this table number. -1 if
    44         -                          ** p->pRight is not the field of any table */
           41  +  int idxLeft;            /* p->pLeft is a column in this table number. -1 if
           42  +                          ** p->pLeft is not the column of any table */
           43  +  int idxRight;           /* p->pRight is a column in this table number. -1 if
           44  +                          ** p->pRight is not the column of any table */
    45     45     unsigned prereqLeft;    /* Tables referenced by p->pLeft */
    46     46     unsigned prereqRight;   /* Tables referenced by p->pRight */
    47     47   };
    48     48   
    49     49   /*
    50     50   ** Determine the number of elements in an array.
    51     51   */
................................................................................
    90     90   ** "base" is the cursor number (the value of the iTable field) that
    91     91   ** corresponds to the first entry in the table list.  This is the
    92     92   ** same as pParse->nTab.
    93     93   */
    94     94   static int exprTableUsage(int base, Expr *p){
    95     95     unsigned int mask = 0;
    96     96     if( p==0 ) return 0;
    97         -  if( p->op==TK_FIELD ){
           97  +  if( p->op==TK_COLUMN ){
    98     98       return 1<< (p->iTable - base);
    99     99     }
   100    100     if( p->pRight ){
   101    101       mask = exprTableUsage(base, p->pRight);
   102    102     }
   103    103     if( p->pLeft ){
   104    104       mask |= exprTableUsage(base, p->pLeft);
................................................................................
   120    120     Expr *pExpr = pInfo->p;
   121    121     pInfo->prereqLeft = exprTableUsage(base, pExpr->pLeft);
   122    122     pInfo->prereqRight = exprTableUsage(base, pExpr->pRight);
   123    123     pInfo->indexable = 0;
   124    124     pInfo->idxLeft = -1;
   125    125     pInfo->idxRight = -1;
   126    126     if( pExpr->op==TK_EQ && (pInfo->prereqRight & pInfo->prereqLeft)==0 ){
   127         -    if( pExpr->pRight->op==TK_FIELD ){
          127  +    if( pExpr->pRight->op==TK_COLUMN ){
   128    128         pInfo->idxRight = pExpr->pRight->iTable - base;
   129    129         pInfo->indexable = 1;
   130    130       }
   131         -    if( pExpr->pLeft->op==TK_FIELD ){
          131  +    if( pExpr->pLeft->op==TK_COLUMN ){
   132    132         pInfo->idxLeft = pExpr->pLeft->iTable - base;
   133    133         pInfo->indexable = 1;
   134    134       }
   135    135     }
   136    136   }
   137    137   
   138    138   /*
................................................................................
   221    221       Index *pIdx;
   222    222       Index *pBestIdx = 0;
   223    223   
   224    224       /* Do a search for usable indices.  Leave pBestIdx pointing to
   225    225       ** the most specific usable index.
   226    226       **
   227    227       ** "Most specific" means that pBestIdx is the usable index that
   228         -    ** has the largest value for nField.  A usable index is one for
   229         -    ** which there are subexpressions to compute every field of the
          228  +    ** has the largest value for nColumn.  A usable index is one for
          229  +    ** which there are subexpressions to compute every column of the
   230    230       ** index.
   231    231       */
   232    232       for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
   233    233         int j;
   234         -      int fieldMask = 0;
          234  +      int columnMask = 0;
   235    235   
   236         -      if( pIdx->nField>32 ) continue;
          236  +      if( pIdx->nColumn>32 ) continue;
   237    237         for(j=0; j<nExpr; j++){
   238    238           if( aExpr[j].idxLeft==idx 
   239    239                && (aExpr[j].prereqRight & loopMask)==aExpr[j].prereqRight ){
   240         -          int iField = aExpr[j].p->pLeft->iField;
          240  +          int iColumn = aExpr[j].p->pLeft->iColumn;
   241    241             int k;
   242         -          for(k=0; k<pIdx->nField; k++){
   243         -            if( pIdx->aiField[k]==iField ){
   244         -              fieldMask |= 1<<k;
          242  +          for(k=0; k<pIdx->nColumn; k++){
          243  +            if( pIdx->aiColumn[k]==iColumn ){
          244  +              columnMask |= 1<<k;
   245    245                 break;
   246    246               }
   247    247             }
   248    248           }
   249    249           if( aExpr[j].idxRight==idx 
   250    250                && (aExpr[j].prereqLeft & loopMask)==aExpr[j].prereqLeft ){
   251         -          int iField = aExpr[j].p->pRight->iField;
          251  +          int iColumn = aExpr[j].p->pRight->iColumn;
   252    252             int k;
   253         -          for(k=0; k<pIdx->nField; k++){
   254         -            if( pIdx->aiField[k]==iField ){
   255         -              fieldMask |= 1<<k;
          253  +          for(k=0; k<pIdx->nColumn; k++){
          254  +            if( pIdx->aiColumn[k]==iColumn ){
          255  +              columnMask |= 1<<k;
   256    256                 break;
   257    257               }
   258    258             }
   259    259           }
   260    260         }
   261         -      if( fieldMask + 1 == (1<<pIdx->nField) ){
   262         -        if( pBestIdx==0 || pBestIdx->nField<pIdx->nField ){
          261  +      if( columnMask + 1 == (1<<pIdx->nColumn) ){
          262  +        if( pBestIdx==0 || pBestIdx->nColumn<pIdx->nColumn ){
   263    263             pBestIdx = pIdx;
   264    264           }
   265    265         }
   266    266       }
   267    267       aIdx[i] = pBestIdx;
   268    268       loopMask |= 1<<idx;
   269    269     }
................................................................................
   293    293         ** scan of the table.
   294    294         */
   295    295         sqliteVdbeAddOp(v, OP_Next, base+idx, brk, 0, cont);
   296    296         haveKey = 0;
   297    297       }else{
   298    298         /* Case 2:  We do have a usable index in pIdx.
   299    299         */
   300         -      for(j=0; j<pIdx->nField; j++){
          300  +      for(j=0; j<pIdx->nColumn; j++){
   301    301           for(k=0; k<nExpr; k++){
   302    302             if( aExpr[k].p==0 ) continue;
   303    303             if( aExpr[k].idxLeft==idx 
   304    304                && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight 
   305         -             && aExpr[k].p->pLeft->iField==pIdx->aiField[j]
          305  +             && aExpr[k].p->pLeft->iColumn==pIdx->aiColumn[j]
   306    306             ){
   307    307               sqliteExprCode(pParse, aExpr[k].p->pRight);
   308    308               aExpr[k].p = 0;
   309    309               break;
   310    310             }
   311    311             if( aExpr[k].idxRight==idx 
   312    312                && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft
   313         -             && aExpr[k].p->pRight->iField==pIdx->aiField[j]
          313  +             && aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
   314    314             ){
   315    315               sqliteExprCode(pParse, aExpr[k].p->pLeft);
   316    316               aExpr[k].p = 0;
   317    317               break;
   318    318             }
   319    319           }
   320    320         }
   321         -      sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nField, 0, 0, 0);
          321  +      sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nColumn, 0, 0, 0);
   322    322         sqliteVdbeAddOp(v, OP_Fetch, base+pTabList->nId+i, 0, 0, 0);
   323    323         sqliteVdbeAddOp(v, OP_NextIdx, base+pTabList->nId+i, brk, 0, cont);
   324    324         if( i==pTabList->nId-1 && pushKey ){
   325    325           haveKey = 1;
   326    326         }else{
   327    327           sqliteVdbeAddOp(v, OP_Fetch, idx, 0, 0, 0);
   328    328           haveKey = 0;

Changes to test/delete.test.

    19     19   #   drh@hwaci.com
    20     20   #   http://www.hwaci.com/drh/
    21     21   #
    22     22   #***********************************************************************
    23     23   # This file implements regression tests for SQLite library.  The
    24     24   # focus of this file is testing the DELETE FROM statement.
    25     25   #
    26         -# $Id: delete.test,v 1.5 2000/06/08 15:10:48 drh Exp $
           26  +# $Id: delete.test,v 1.6 2000/06/21 13:59:13 drh Exp $
    27     27   
    28     28   set testdir [file dirname $argv0]
    29     29   source $testdir/tester.tcl
    30     30   
    31     31   # Try to delete from a non-existant table.
    32     32   #
    33     33   do_test delete-1.1 {
................................................................................
    68     68   
    69     69   # Semantic errors in the WHERE clause
    70     70   #
    71     71   do_test delete-4.1 {
    72     72     execsql {CREATE TABLE table2(f1 int, f2 int)}
    73     73     set v [catch {execsql {DELETE FROM table2 WHERE f3=5}} msg]
    74     74     lappend v $msg
    75         -} {1 {no such field: f3}}
           75  +} {1 {no such column: f3}}
    76     76   
    77     77   do_test delete-4.2 {
    78     78     set v [catch {execsql {DELETE FROM table2 WHERE xyzzy(f1+4)}} msg]
    79     79     lappend v $msg
    80     80   } {1 {no such function: xyzzy}}
    81     81   
    82     82   finish_test

Changes to test/in.test.

    19     19   #   drh@hwaci.com
    20     20   #   http://www.hwaci.com/drh/
    21     21   #
    22     22   #***********************************************************************
    23     23   # This file implements regression tests for SQLite library.  The
    24     24   # focus of this file is testing the IN and BETWEEN operator.
    25     25   #
    26         -# $Id: in.test,v 1.2 2000/06/07 23:51:51 drh Exp $
           26  +# $Id: in.test,v 1.3 2000/06/21 13:59:13 drh Exp $
    27     27   
    28     28   set testdir [file dirname $argv0]
    29     29   source $testdir/tester.tcl
    30     30   
    31     31   # Generate the test data we will need for the first squences of tests.
    32     32   #
    33     33   do_test in-1.0 {
................................................................................
   102    102   do_test in-2.10 {
   103    103     set v [catch {execsql {SELECT a FROM t1 WHERE min(0,b IN (a,30))}} msg]
   104    104     lappend v $msg
   105    105   } {1 {right-hand side of IN operator must be constant}}
   106    106   do_test in-2.11 {
   107    107     set v [catch {execsql {SELECT a FROM t1 WHERE c IN (10,20)}} msg]
   108    108     lappend v $msg
   109         -} {1 {no such field: c}}
          109  +} {1 {no such column: c}}
   110    110   
   111    111   # Testing the IN operator where the right-hand side is a SELECT
   112    112   #
   113    113   do_test in-3.1 {
   114    114     execsql {
   115    115       SELECT a FROM t1
   116    116       WHERE b IN (SELECT b FROM t1 WHERE a<5)

Changes to test/select1.test.

    19     19   #   drh@hwaci.com
    20     20   #   http://www.hwaci.com/drh/
    21     21   #
    22     22   #***********************************************************************
    23     23   # This file implements regression tests for SQLite library.  The
    24     24   # focus of this file is testing the SELECT statement.
    25     25   #
    26         -# $Id: select1.test,v 1.5 2000/06/07 15:11:27 drh Exp $
           26  +# $Id: select1.test,v 1.6 2000/06/21 13:59:13 drh Exp $
    27     27   
    28     28   set testdir [file dirname $argv0]
    29     29   source $testdir/tester.tcl
    30     30   
    31     31   # Try to select on a non-existant table.
    32     32   #
    33     33   do_test select1-1.1 {
................................................................................
    45     45     set v [catch {execsql {SELECT * FROM test2, test1}} msg]
    46     46     lappend v $msg
    47     47   } {1 {no such table: test2}}
    48     48   
    49     49   execsql {INSERT INTO test1(f1,f2) VALUES(11,22)}
    50     50   
    51     51   
    52         -# Make sure the fields are extracted correctly.
           52  +# Make sure the columns are extracted correctly.
    53     53   #
    54     54   do_test select1-1.4 {
    55     55     execsql {SELECT f1 FROM test1}
    56     56   } {11}
    57     57   do_test select1-1.5 {
    58     58     execsql {SELECT f2 FROM test1}
    59     59   } {22}
................................................................................
   240    240     set v [catch {execsql {SELECT max(f1) FROM test1 ORDER BY f2}} msg]
   241    241     lappend v $msg
   242    242   } {0 33}
   243    243   
   244    244   execsql {CREATE TABLE test2(t1 test, t2 text)}
   245    245   execsql {INSERT INTO test2 VALUES('abc','xyz')}
   246    246   
   247         -# Check for field naming
          247  +# Check for column naming
   248    248   #
   249    249   do_test select1-6.1 {
   250    250     set v [catch {execsql2 {SELECT f1 FROM test1 ORDER BY f2}} msg]
   251    251     lappend v $msg
   252    252   } {0 {f1 11 f1 33}}
   253    253   do_test select1-6.2 {
   254    254     set v [catch {execsql2 {SELECT f1 as xyzzy FROM test1 ORDER BY f2}} msg]
................................................................................
   276    276            ORDER BY f2}} msg]
   277    277     lappend v $msg
   278    278   } {0 {A.f1 11 test2.t1 abc A.f1 33 test2.t1 abc}}
   279    279   do_test select1-6.8 {
   280    280     set v [catch {execsql2 {SELECT A.f1, f1 FROM test1 as A, test1 as B 
   281    281            ORDER BY f2}} msg]
   282    282     lappend v $msg
   283         -} {1 {ambiguous field name: f1}}
          283  +} {1 {ambiguous column name: f1}}
   284    284   do_test select1-6.8b {
   285    285     set v [catch {execsql2 {SELECT A.f1, B.f1 FROM test1 as A, test1 as B 
   286    286            ORDER BY f2}} msg]
   287    287     lappend v $msg
   288         -} {1 {ambiguous field name: f2}}
          288  +} {1 {ambiguous column name: f2}}
   289    289   do_test select1-6.8c {
   290    290     set v [catch {execsql2 {SELECT A.f1, f1 FROM test1 as A, test1 as A 
   291    291            ORDER BY f2}} msg]
   292    292     lappend v $msg
   293         -} {1 {ambiguous field name: A.f1}}
          293  +} {1 {ambiguous column name: A.f1}}
   294    294   do_test select1-6.9 {
   295    295     set v [catch {execsql2 {SELECT A.f1, B.f1 FROM test1 as A, test1 as B 
   296    296            ORDER BY A.f1, B.f1}} msg]
   297    297     lappend v $msg
   298    298   } {0 {A.f1 11 B.f1 11 A.f1 11 B.f1 33 A.f1 33 B.f1 11 A.f1 33 B.f1 33}}
   299    299   
   300    300   finish_test

Changes to test/select2.test.

    19     19   #   drh@hwaci.com
    20     20   #   http://www.hwaci.com/drh/
    21     21   #
    22     22   #***********************************************************************
    23     23   # This file implements regression tests for SQLite library.  The
    24     24   # focus of this file is testing the SELECT statement.
    25     25   #
    26         -# $Id: select2.test,v 1.6 2000/06/08 16:54:40 drh Exp $
           26  +# $Id: select2.test,v 1.7 2000/06/21 13:59:13 drh Exp $
    27     27   
    28     28   set testdir [file dirname $argv0]
    29     29   source $testdir/tester.tcl
    30     30   
    31     31   # Create a table with some data
    32     32   #
    33     33   execsql {CREATE TABLE tbl1(f1 int, f2 int)}
................................................................................
   102    102   } {500}
   103    103   do_test select2-3.2c {
   104    104     execsql {SELECT f1 FROM tbl2 WHERE f2=1000}
   105    105   } {500}
   106    106   do_test select2-3.2d {
   107    107     set t1 [lindex [time {execsql {SELECT f1 FROM tbl2 WHERE 1000=f2}} 1] 0]
   108    108     set t2 [lindex [time {execsql {SELECT f1 FROM tbl2 WHERE f2=1000}} 1] 0]
   109         -  expr {$t1*0.9<$t2 && $t2*0.9<$t1}
          109  +  expr {$t1*0.8<$t2 && $t2*0.8<$t1}
   110    110   } {1}
   111    111   
   112    112   # Make sure queries run faster with an index than without
   113    113   #
   114    114   do_test select2-3.3 {
   115    115     set t1 [lindex [time {execsql {SELECT f1 from tbl2 WHERE f2==2000}} 1] 0]
   116    116     execsql {DROP INDEX idx1}
   117    117     set t2 [lindex [time {execsql {SELECT f1 FROM tbl2 WHERE f2==2000}} 1] 0]
   118    118     expr {$t1*25 < $t2}
   119    119   } {1}
   120    120   
   121    121   finish_test

Changes to test/select5.test.

    20     20   #   http://www.hwaci.com/drh/
    21     21   #
    22     22   #***********************************************************************
    23     23   # This file implements regression tests for SQLite library.  The
    24     24   # focus of this file is testing aggregate functions and the
    25     25   # GROUP BY and HAVING clauses of SELECT statements.
    26     26   #
    27         -# $Id: select5.test,v 1.3 2000/06/08 16:26:25 drh Exp $
           27  +# $Id: select5.test,v 1.4 2000/06/21 13:59:13 drh Exp $
    28     28   
    29     29   set testdir [file dirname $argv0]
    30     30   source $testdir/tester.tcl
    31     31   
    32     32   # Build some test data
    33     33   #
    34     34   set fd [open data1.txt w]
................................................................................
    62     62   # Some error messages associated with aggregates and GROUP BY
    63     63   #
    64     64   do_test select5-2.1 {
    65     65     set v [catch {execsql {
    66     66       SELECT y, count(*) FROM t1 GROUP BY z ORDER BY y
    67     67     }} msg]
    68     68     lappend v $msg
    69         -} {1 {no such field: z}}
           69  +} {1 {no such column: z}}
    70     70   do_test select5-2.2 {
    71     71     set v [catch {execsql {
    72     72       SELECT y, count(*) FROM t1 GROUP BY z(y) ORDER BY y
    73     73     }} msg]
    74     74     lappend v $msg
    75     75   } {1 {no such function: z}}
    76     76   do_test select5-2.3 {
................................................................................
    86     86     lappend v $msg
    87     87   } {1 {no such function: z}}
    88     88   do_test select5-2.5 {
    89     89     set v [catch {execsql {
    90     90       SELECT y, count(*) FROM t1 GROUP BY y HAVING count(*)<z ORDER BY y
    91     91     }} msg]
    92     92     lappend v $msg
    93         -} {1 {no such field: z}}
           93  +} {1 {no such column: z}}
    94     94   
    95     95   # Get the Agg function to rehash in vdbe.c
    96     96   #
    97     97   do_test select5-3.1 {
    98     98     execsql {
    99     99       SELECT x, count(*), avg(y) FROM t1 GROUP BY x HAVING x<4 ORDER BY x
   100    100     }

Changes to test/update.test.

    19     19   #   drh@hwaci.com
    20     20   #   http://www.hwaci.com/drh/
    21     21   #
    22     22   #***********************************************************************
    23     23   # This file implements regression tests for SQLite library.  The
    24     24   # focus of this file is testing the UPDATE statement.
    25     25   #
    26         -# $Id: update.test,v 1.3 2000/06/19 19:09:09 drh Exp $
           26  +# $Id: update.test,v 1.4 2000/06/21 13:59:14 drh Exp $
    27     27   
    28     28   set testdir [file dirname $argv0]
    29     29   source $testdir/tester.tcl
    30     30   
    31     31   # Try to update an non-existent table
    32     32   #
    33     33   do_test update-1.1 {
................................................................................
    50     50     for {set i 1} {$i<=10} {incr i} {
    51     51       set sql "INSERT INTO test1 VALUES($i,[expr {int(pow(2,$i))}])"
    52     52       execsql $sql
    53     53     }
    54     54     execsql {SELECT * FROM test1 ORDER BY f1}
    55     55   } {1 2 2 4 3 8 4 16 5 32 6 64 7 128 8 256 9 512 10 1024}
    56     56   
    57         -# Unknown field name in an expression
           57  +# Unknown column name in an expression
    58     58   #
    59     59   do_test update-3.2 {
    60     60     set v [catch {execsql {UPDATE test1 SET f1=f3*2 WHERE f2==32}} msg]
    61     61     lappend v $msg
    62         -} {1 {no such field: f3}}
           62  +} {1 {no such column: f3}}
    63     63   do_test update-3.3 {
    64     64     set v [catch {execsql {UPDATE test1 SET f1=test2.f1*2 WHERE f2==32}} msg]
    65     65     lappend v $msg
    66         -} {1 {no such field: test2.f1}}
           66  +} {1 {no such column: test2.f1}}
    67     67   do_test update-3.4 {
    68     68     set v [catch {execsql {UPDATE test1 SET f3=f1*2 WHERE f2==32}} msg]
    69     69     lappend v $msg
    70         -} {1 {no such field: f3}}
           70  +} {1 {no such column: f3}}
    71     71   
    72     72   # Actually do some updates
    73     73   #
    74     74   do_test update-3.5 {
    75     75     execsql {UPDATE test1 SET f2=f2*3}
    76     76     execsql {SELECT * FROM test1 ORDER BY f1}
    77     77   } {1 6 2 12 3 24 4 48 5 96 6 192 7 384 8 768 9 1536 10 3072}
................................................................................
   113    113   # Error messages
   114    114   #
   115    115   do_test update-4.1 {
   116    116     set v [catch {execsql {
   117    117       UPDATE test1 SET x=11 WHERE f1=1025
   118    118     }} msg]
   119    119     lappend v $msg
   120         -} {1 {no such field: x}}
          120  +} {1 {no such column: x}}
   121    121   do_test update-4.2 {
   122    122     set v [catch {execsql {
   123    123       UPDATE test1 SET f1=x(11) WHERE f1=1025
   124    124     }} msg]
   125    125     lappend v $msg
   126    126   } {1 {no such function: x}}
   127    127   do_test update-4.3 {
   128    128     set v [catch {execsql {
   129    129       UPDATE test1 SET f1=11 WHERE x=1025
   130    130     }} msg]
   131    131     lappend v $msg
   132         -} {1 {no such field: x}}
          132  +} {1 {no such column: x}}
   133    133   do_test update-4.4 {
   134    134     set v [catch {execsql {
   135    135       UPDATE test1 SET f1=11 WHERE x(f1)=1025
   136    136     }} msg]
   137    137     lappend v $msg
   138    138   } {1 {no such function: x}}
   139    139   
   140    140   
   141    141   
   142    142   
   143    143   
   144    144   
   145    145   finish_test

Changes to www/c_interface.tcl.

     1      1   #
     2      2   # Run this Tcl script to generate the sqlite.html file.
     3      3   #
     4         -set rcsid {$Id: c_interface.tcl,v 1.4 2000/06/06 18:24:42 drh Exp $}
            4  +set rcsid {$Id: c_interface.tcl,v 1.5 2000/06/21 13:59:14 drh Exp $}
     5      5   
     6      6   puts {<html>
     7      7   <head>
     8      8     <title>The C language interface to the SQLite library</title>
     9      9   </head>
    10     10   <body bgcolor=white>
    11     11   <h1 align=center>
................................................................................
    84     84   pointer to an opaque <b>sqlite</b> structure.  This pointer will
    85     85   be the first argument to all subsequent SQLite function calls that
    86     86   deal with the same database.  NULL is returned if the open fails
    87     87   for any reason.</p>
    88     88   
    89     89   <h2>Closing the database</h2>
    90     90   
    91         -<p>To close an SQLite database, just call the <b>sqlite_close()</b>
           91  +<p>To close an SQLite database, call the <b>sqlite_close()</b>
    92     92   function passing it the sqlite structure pointer that was obtained
    93     93   from a prior call to <b>sqlite_open</b>.
    94     94   
    95     95   <h2>Executing SQL statements</h2>
    96     96   
    97     97   <p>The <b>sqlite_exec()</b> function is used to process SQL statements
    98     98   and queries.  This function requires 5 parameters as follows:</p>
................................................................................
   142    142   argv[i] == 0
   143    143   </pre></blockquote>
   144    144   <p>The names of the columns are contained in the fourth argument.</p>
   145    145   
   146    146   <p>The callback function should normally return 0.  If the callback
   147    147   function returns non-zero, the query is immediately aborted and 
   148    148   <b>sqlite_exec()</b> will return SQLITE_ABORT.</p>
          149  +
          150  +<p>The <b>sqlite_exec()</b> function returns an integer to indicate
          151  +success or failure of the operation.  The following are possible
          152  +return values:</p>
          153  +
          154  +<blockquote>
          155  +<dl>
          156  +<dt>SQLITE_OK</dt>
          157  +<dd><p>This value is returned if everything worked and there were no errors.
          158  +</p></dd>
          159  +<dt>SQLITE_INTERNAL</dt>
          160  +<dd><p>This value indicates that an internal consistency check within
          161  +the SQLite library failed.  This can only happen if there is a bug in
          162  +the SQLite library.  If you ever get an SQLITE_INTERNAL reply from
          163  +an <b>sqlite_exec()</b> call, please report the problem on the SQLite
          164  +mailing list.
          165  +</p></dd>
          166  +<dt>SQLITE_ERROR</dt>
          167  +<dd><p>This return value indicates that there was an error in the SQL
          168  +that was passed into the <b>sqlite_exec()</b>.
          169  +</p></dd>
          170  +<dt>SQLITE_PERM</dt>
          171  +<dd><p>This return value says that the access permissions on one of the
          172  +GDBM files is such that the file cannot be opened.
          173  +</p></dd>
          174  +<dt>SQLITE_ABORT</dt>
          175  +<dd><p>This value is returned if the callback function returns non-zero.
          176  +</p></dd>
          177  +<dt>SQLITE_BUSY</dt>
          178  +<dd><p>This return code indicates that one of the underlying GDBM files
          179  +is locked because it is currently being accessed by another thread or
          180  +process.  GDBM allows mutiple readers of the same file, but only one
          181  +writer.  So multiple processes can query an SQLite database at once.
          182  +But only a single process can write to an SQLite database at one time.
          183  +If an attempt is made to write to an SQLite database that another
          184  +process is currently reading, the write is not performed and 
          185  +<b>sqlite_exec()</b> returns SQLITE_BUSY.  Similarly, an attempt to read
          186  +an SQLite database that is currently being written by another process
          187  +will return SQLITE_BUSY.  In both cases, the write or query attempt
          188  +can be retried after the other process finishes.</p>
          189  +<p>Note that locking is done at the file level.  One process can
          190  +write to table ABC (for example) while another process simultaneously
          191  +reads from a different table XYZ.  But you cannot have two processes reading
          192  +and writing table ABC at the same time.
          193  +</p></dd>
          194  +<dt>SQLITE_NOMEM</dt>
          195  +<dd><p>This value is returned if a call to <b>malloc()</b> fails.
          196  +</p></dd>
          197  +<dt>SQLITE_READONLY</dt>
          198  +<dd><p>This return code indicates that an attempt was made to write to
          199  +a database file that was originally opened for reading only.  This can
          200  +happen if the callback from a query attempts to update the table
          201  +being queried.
          202  +</p></dd>
          203  +</dl>
          204  +</blockquote>
   149    205   
   150    206   <h2>Testing for a complete SQL statement</h2>
   151    207   
   152    208   <p>The last interface routine to SQLite is a convenience function used
   153    209   to test whether or not a string forms a complete SQL statement.
   154    210   If the <b>sqlite_complete()</b> function returns true when its input
   155    211   is a string, then the argument forms a complete SQL statement.

Changes to www/sqlite.tcl.

     1      1   #
     2      2   # Run this Tcl script to generate the sqlite.html file.
     3      3   #
     4         -set rcsid {$Id: sqlite.tcl,v 1.8 2000/06/08 19:43:40 drh Exp $}
            4  +set rcsid {$Id: sqlite.tcl,v 1.9 2000/06/21 13:59:14 drh Exp $}
     5      5   
     6      6   puts {<html>
     7      7   <head>
     8      8     <title>sqlite: A program of interacting with SQLite databases</title>
     9      9   </head>
    10     10   <body bgcolor=white>
    11     11   <h1 align=center>
................................................................................
   146    146   .dump                  Dump database in a text format
   147    147   .exit                  Exit this program
   148    148   .explain               Set output mode suitable for EXPLAIN
   149    149   .header ON|OFF         Turn display of headers on or off
   150    150   .help                  Show this message
   151    151   .indices TABLE         Show names of all indices on TABLE
   152    152   .mode MODE             Set mode to one of "line", "column", "list", or "html"
          153  +.mode insert TABLE     Generate SQL insert statements for TABLE
   153    154   .output FILENAME       Send output to FILENAME
   154    155   .output stdout         Send output to the screen
   155    156   .schema ?TABLE?        Show the CREATE statements
   156    157   .separator STRING      Change separator string for "list" mode
   157    158   .tables                List names all tables in the database
   158    159   .width NUM NUM ...     Set column widths for "column" mode
   159    160   sqlite> 
   160    161   }
   161    162   
   162    163   puts {
   163    164   <h2>Changing Output Formats</h2>
   164    165   
   165    166   <p>The sqlite program is able to show the results of a query
   166         -in four different formats: "line", "column", "list", and "html".
          167  +in five different formats: "line", "column", "list", "html", and "insert".
   167    168   You can use the ".mode" dot command to switch between these three output
   168    169   formats.</p>
   169    170   
   170    171   <p>The default output mode is "list".  In
   171    172   list mode, each record of a query result is written on one line of
   172         -output and each field within that record is separated by a specific
          173  +output and each column within that record is separated by a specific
   173    174   separator string.  The default separator is a pipe symbol ("|").
   174    175   List mode is especially useful when you are going to send the output
   175    176   of a query to another program (such as AWK) for additional processing.</p>}
   176    177   
   177    178   Code {
   178    179   sqlite> (((.mode list)))
   179    180   sqlite> (((select * from tbl1;)))
................................................................................
   192    193   sqlite> (((select * from tbl1;)))
   193    194   hello, 10
   194    195   goodbye, 20
   195    196   sqlite>
   196    197   }
   197    198   
   198    199   puts {
   199         -<p>In "line" mode, each field in a record of the database
   200         -is shown on a line by itself.  Each line consists of the field
   201         -name, an equal sign and the field data.  Successive records are
          200  +<p>In "line" mode, each column in a row of the database
          201  +is shown on a line by itself.  Each line consists of the column
          202  +name, an equal sign and the column data.  Successive records are
   202    203   separated by a blank line.  Here is an example of line mode
   203    204   output:</p>}
   204    205   
   205    206   Code {
   206    207   sqlite> (((.mode line)))
   207    208   sqlite> (((select * from tbl1;)))
   208    209   one = hello
................................................................................
   259    260   sqlite> (((select * from tbl1;)))
   260    261   hello         10    
   261    262   goodbye       20    
   262    263   sqlite>
   263    264   }
   264    265   
   265    266   puts {
          267  +<p>Another useful output mode is "insert".  In insert mode, the output
          268  +is formatted to look like SQL INSERT statements.  You can use insert
          269  +mode to generate text that can later be used to input data into a 
          270  +different database.</p>
          271  +
   266    272   <p>The last output mode is "html".  In this mode, sqlite writes
   267    273   the results of the query as an XHTML table.  The beginning
   268    274   &lt;TABLE&gt; and the ending &lt;/TABLE&gt; are not written, but
   269    275   all of the intervening &lt;TR&gt;s, &lt;TH&gt;s, and &lt;TD&gt;s
   270    276   are.  The html output mode is envisioned as being useful for
   271    277   CGI.</p>
   272    278   }