]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
:-) (CVS 104)
authordrh <drh@noemail.net>
Wed, 21 Jun 2000 13:59:10 +0000 (13:59 +0000)
committerdrh <drh@noemail.net>
Wed, 21 Jun 2000 13:59:10 +0000 (13:59 +0000)
FossilOrigin-Name: e1bf96a467b739373191bf75e6a097fc0f24bffc

25 files changed:
manifest
manifest.uuid
src/build.c
src/dbbe.c
src/dbbe.h
src/delete.c
src/expr.c
src/insert.c
src/main.c
src/parse.y
src/select.c
src/shell.c
src/sqliteInt.h
src/update.c
src/util.c
src/vdbe.c
src/where.c
test/delete.test
test/in.test
test/select1.test
test/select2.test
test/select5.test
test/update.test
www/c_interface.tcl
www/sqlite.tcl

index 2ec09d6d89c432ecc7426ac793c4d8ef0222c82f..91411719ac85db5139b170e7ec335e8a72bc872a 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,50 +1,50 @@
-C :-)\s(CVS\s103)
-D 2000-06-19T19:10:29
+C :-)\s(CVS\s104)
+D 2000-06-21T13:59:11
 F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
 F Makefile.in 4dc16840f68e3b599915e1ec8463d365474dd286
 F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
 F configure c366a0402bce79ef11fe1bf703ad6ce4ff6afbb0 x
 F configure.in 1085ff994a334b131325de906ed318e926673588
 F doc/lemon.html e233a3e97a779c7a87e1bc4528c664a58e49dd47
-F src/build.c 9ce11eafbab395b7d19bc5722d1a8955961889b0
-F src/dbbe.c ae5e77f010ba1b68a65aa3cd55c8578eda523dd2
-F src/dbbe.h 9a678ae524c2daad22e959111edd4494e6144dbc
-F src/delete.c 2d5758055ff546453385524d856feb1b51ea7b8a
-F src/expr.c 88ff9ea12a23a3f0dfaf117670524bdc160af597
-F src/insert.c b1434c7c7c387c69e467d993e9d05460f1047bcc
-F src/main.c e3297835b8e38ca726ac73f2c2bdb7cf08103197
-F src/parse.y 974ed07702bda4f04171ef22776eccbb5dae81ca
-F src/select.c 2a91f683d64de0362834248cb291bc601cd2950b
-F src/shell.c 78a35607a88b3d557e1666ae9d0c2c03cbb3553e
+F src/build.c 55edb404bbf4476c73c81604ddb9738281a689a4
+F src/dbbe.c 99aa6daca9a039eebb284dd459bef712ea3843f9
+F src/dbbe.h 8718b718b36d37584e9bbdfccec10588fa91271f
+F src/delete.c 4d491eaf61b515516749c7ed68fa3b2ee8a09065
+F src/expr.c 2fa63f086707176d09092e71832f9bbdc6a8ac85
+F src/insert.c f146f149ad2422a1dc3bfa7a1651a25940f98958
+F src/main.c 30b33b6e0cdd5ae1c0af9f626e78a1dc7b835e26
+F src/parse.y 86e268c29a0f00ffc062bbe934d95ea0d6308b0a
+F src/select.c aaf23d4a6ef44e4378840ec94b6aa64641c01b5c
+F src/shell.c 8387580e44878022c88c02b189bf23bff1862bda
 F src/sqlite.h 58da0a8590133777b741f9836beaef3d58f40268
-F src/sqliteInt.h 19954bd2f75632849b265b9d7163a67391ec5148
+F src/sqliteInt.h ddc6f8081ef469ede272cf6a382773dac5758dfc
 F src/tclsqlite.c 9f358618ae803bedf4fb96da5154fd45023bc1f7
 F src/tokenize.c 77ff8164a8751994bc9926ce282847f653ac0c16
-F src/update.c 162fc0b86dcd61d164dedc77081a5e7daf6b8fb0
-F src/util.c 38e4bb5edf6fa92e677698c45785bf73c69b9e9f
-F src/vdbe.c 00b2ab7e0c0df2ac6eb4bf659656afc30e76c66b
+F src/update.c 51b9ef7434b15e31096155da920302e9db0d27fc
+F src/util.c fcd7ac9d2be8353f746e52f665e6c4f5d6b3b805
+F src/vdbe.c 38cec3e88db70b7689018377c1594ac18f746b19
 F src/vdbe.h 5f58611b19799de2dbcdefa4eef33a255cfa8d0d
-F src/where.c c9b90e7672f4662a83ef9a27a193020d69fe034c
+F src/where.c 420f666a38b405cd58bd7af832ed99f1dbc7d336
 F test/all.test 0950c135cab7e60c07bd745ccfad1476211e5bd7
 F test/copy.test b77a1214bd7756f2849d5c4fa6e715c0ff0c34eb
 F test/dbbe.test 0a8e4293cf816e590dcbb01be4cd4e8f7f95bdc8
-F test/delete.test 30edd2c7484274fb2e7dbc4a1ac769bb330b322e
+F test/delete.test 402ee3ccb6e544582d24c573ef70b34d09583ae7
 F test/expr.test 09b55ccf81cb8cc2f9cd83d592a2ba187ee48ba8
-F test/in.test 962a605b6a3a619214f84d1950dfc44fcf0d8b8f
+F test/in.test 2c560c0f55fb777029fd9bb5378f2997582aa603
 F test/index.test 620ceab7165dd078d1266bdc2cac6147f04534ac
 F test/insert.test 66f4c3bd600fec8eb1e733b928cbe6fa885eff0c
 F test/insert2.test 732405e30331635af8d159fccabe835eea5cd0c6
 F test/main.test b7366cc6f3690915a11834bc1090deeff08acaf9
-F test/select1.test 64703852af34c85bb31b0a74bd73b340e8267f42
-F test/select2.test 5e2783a48360b83956366ea24b2c5f0293015a84
+F test/select1.test 4e57b0b5eae0c991d9cc51d1288be0476110e6f6
+F test/select2.test ed6e7fc3437079686d7ae4390a00347bbd5f7bf8
 F test/select3.test a9234b8424b6c6d71de534f43b91ade9be68e9cc
 F test/select4.test cb5374d7c87680e294ac749307459a5cc547609d
-F test/select5.test 80ea257ce35e736c559bc6cd342361974e60a979
+F test/select5.test e2b9d51d88cbd6c307c2c05b0ef55fe7ba811ac2
 F test/sort.test d582086c4bb7df3fbf50aa72e69d7e235e9f8e31
 F test/subselect.test bf8b251a92fb091973c1c469ce499dc9648a41d5
 F test/table.test d3e01e4916a99ade7d8f1d534ee1b36d57c00490
 F test/tester.tcl 95b286791e6256bb6db0165f9342c70fff549a62
-F test/update.test 0f763adc3d84e85224e1dadff72237bcabab1938
+F test/update.test 62f6ce99ff31756aab0ca832ff6d34c5a87b6250
 F test/vacuum.test 8becf5cfeb897108b35cdd996793e7f1df2f28fd
 F test/where.test bbab5a308055fb6087dc23d600b4ad2b72797397
 F tool/gdbmdump.c 529e67c78d920606ba196326ea55b57b75fcc82b
@@ -57,14 +57,14 @@ F tool/renumberOps.awk 6d067177ad5f8d711b79577b462da9b3634bd0a9
 F www/arch.fig 4e26e9dca3c49724fc8f554c695ddea9f2413156
 F www/arch.png c4d908b79065a72e7dcf19317f36d1324c550e87
 F www/arch.tcl 4f6a9afecc099a27bba17b4f8cc9561abc15dc40
-F www/c_interface.tcl 9ac800854272db5fe439e07b7435b243a5422293
+F www/c_interface.tcl 8eb800f67e6896b1894d666b81c0b418cea09fc7
 F www/changes.tcl 160f7522145efaf49961f6cf3671c66c02f2207b
 F www/fileformat.tcl b11435fcd2cf2238a1c5e6d16fe5e83bcd14d434
 F www/index.tcl 4116afce6a8c63d68882d2b00aa10b079e0129cd
 F www/lang.tcl 1645e9107d75709be4c6099b643db235bbe0a151
 F www/opcode.tcl 3cdc4bb2515fcfcbe853e3f0c91cd9199e82dadd
-F www/sqlite.tcl 5420eab24b539928f80ea9b3088e2549d34f438d
-P 8cce4d279de00da45c5970c8f0946f49e03e6846
-R 24ae8084d8386391fc8e3403683f09be
+F www/sqlite.tcl 9fdcfd48fe9e5669116d02f29b2608903f295740
+P af14a5b3ba4a13665142b700e8864bf63d591d95
+R 4b875fc1d381ebbdab00fc05e8ad8c74
 U drh
-Z 34d7058e222643fe967104d6dc2aa522
+Z e8d8e8697e4d556ecd0e3a4c2a206a66
index 842ff3b58645034defdc686559d22e21ac95cc1a..75bd74aa2411872668288d94a29b41786b94cf91 100644 (file)
@@ -1 +1 @@
-af14a5b3ba4a13665142b700e8864bf63d591d95
\ No newline at end of file
+e1bf96a467b739373191bf75e6a097fc0f24bffc
\ No newline at end of file
index 4d0e1c78deb94b1a806c773fa413c74dc7806527..a49072e080c697c47adb4f4b5edc4ad535242728 100644 (file)
@@ -33,7 +33,7 @@
 **     COPY
 **     VACUUM
 **
-** $Id: build.c,v 1.18 2000/06/17 13:12:39 drh Exp $
+** $Id: build.c,v 1.19 2000/06/21 13:59:11 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -151,8 +151,8 @@ Index *sqliteFindIndex(sqlite *db, char *zName){
 ** its memory structures.
 **
 ** The index is removed from the database hash table, but it is
-** not unlinked from the table that is being indexed.  Unlinking
-** from the table must be done by the calling function.
+** not unlinked from the Table that is being indexed.  Unlinking
+** from the Table must be done by the calling function.
 */
 static void sqliteDeleteIndex(sqlite *db, Index *pIndex){
   int h;
@@ -173,7 +173,7 @@ static void sqliteDeleteIndex(sqlite *db, Index *pIndex){
 
 /*
 ** Remove the memory data structures associated with the given
-** table.  No changes are made to disk by this routine.
+** Table.  No changes are made to disk by this routine.
 **
 ** This routine just deletes the data structure.  It does not unlink
 ** the table data structure from the hash table.  But does it destroy
@@ -512,11 +512,11 @@ void sqliteCreateIndex(
     pParse->nErr++;
     goto exit_create_index;
   }
-  pIndex->aiField = (int*)&pIndex[1];
-  pIndex->zName = (char*)&pIndex->aiField[pList->nId];
+  pIndex->aiColumn = (int*)&pIndex[1];
+  pIndex->zName = (char*)&pIndex->aiColumn[pList->nId];
   strcpy(pIndex->zName, zName);
   pIndex->pTable = pTab;
-  pIndex->nField = pList->nId;
+  pIndex->nColumn = pList->nId;
 
   /* Scan the names of the columns of the table to be indexed and
   ** load the column indices into the Index structure.  Report an error
@@ -533,7 +533,7 @@ void sqliteCreateIndex(
       sqliteFree(pIndex);
       goto exit_create_index;
     }
-    pIndex->aiField[i] = j;
+    pIndex->aiColumn[i] = j;
   }
 
   /* Link the new Index structure to its table and to the other
@@ -590,10 +590,10 @@ void sqliteCreateIndex(
     lbl2 = sqliteVdbeMakeLabel(v);
     sqliteVdbeAddOp(v, OP_Next, 0, lbl2, 0, lbl1);
     sqliteVdbeAddOp(v, OP_Key, 0, 0, 0, 0);
-    for(i=0; i<pIndex->nField; i++){
-      sqliteVdbeAddOp(v, OP_Field, 0, pIndex->aiField[i], 0, 0);
+    for(i=0; i<pIndex->nColumn; i++){
+      sqliteVdbeAddOp(v, OP_Field, 0, pIndex->aiColumn[i], 0, 0);
     }
-    sqliteVdbeAddOp(v, OP_MakeKey, pIndex->nField, 0, 0, 0);
+    sqliteVdbeAddOp(v, OP_MakeKey, pIndex->nColumn, 0, 0, 0);
     sqliteVdbeAddOp(v, OP_PutIdx, 1, 0, 0, 0);
     sqliteVdbeAddOp(v, OP_Goto, 0, lbl1, 0, 0);
     sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, lbl2);
@@ -834,10 +834,10 @@ void sqliteCopy(
       if( pIdx->pNext ){
         sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
       }
-      for(j=0; j<pIdx->nField; j++){
-        sqliteVdbeAddOp(v, OP_FileField, pIdx->aiField[j], 0, 0, 0);
+      for(j=0; j<pIdx->nColumn; j++){
+        sqliteVdbeAddOp(v, OP_FileField, pIdx->aiColumn[j], 0, 0, 0);
       }
-      sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nField, 0, 0, 0);
+      sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nColumn, 0, 0, 0);
       sqliteVdbeAddOp(v, OP_PutIdx, i, 0, 0, 0);
     }
     sqliteVdbeAddOp(v, OP_Goto, 0, addr, 0, 0);
index c8b0beb280c218e0ca588f3556e0c5c9482091e0..d690329beb336cdbc0fdc418cb187f81d845846b 100644 (file)
@@ -30,7 +30,7 @@
 ** relatively simple to convert to a different database such
 ** as NDBM, SDBM, or BerkeleyDB.
 **
-** $Id: dbbe.c,v 1.14 2000/06/17 13:12:39 drh Exp $
+** $Id: dbbe.c,v 1.15 2000/06/21 13:59:11 drh Exp $
 */
 #include "sqliteInt.h"
 #include <gdbm.h>
@@ -43,7 +43,7 @@
 ** Information about each open disk file is an instance of this 
 ** structure.  There will only be one such structure for each
 ** disk file.  If the VDBE opens the same file twice (as will happen
-** for a self-join, for example) then two DbbeTable structures are
+** for a self-join, for example) then two DbbeCursor structures are
 ** created but there is only a single BeFile structure with an
 ** nRef of 2.
 */
@@ -87,12 +87,12 @@ struct Dbbe {
 /*
 ** An cursor into a database file is an instance of the following structure.
 ** There can only be a single BeFile structure for each disk file, but
-** there can be multiple DbbeTable structures.  Each DbbeTable represents
+** there can be multiple DbbeCursor structures.  Each DbbeCursor represents
 ** a cursor pointing to a particular part of the open BeFile.  The
-** BeFile.nRef field hold a count of the number of DbbeTable structures
+** BeFile.nRef field hold a count of the number of DbbeCursor structures
 ** associated with the same disk file.
 */
-struct DbbeTable {
+struct DbbeCursor {
   Dbbe *pBe;         /* The database of which this record is a part */
   BeFile *pFile;     /* The database file for this table */
   datum key;         /* Most recently used key */
@@ -226,8 +226,9 @@ void sqliteDbbeClose(Dbbe *pBe){
 }
 
 /*
-** Translate the name of a table into the name of a file that holds
-** that table.  Space to hold the filename is obtained from
+** Translate the name of an SQL table (or index) into the name 
+** of a file that holds the key/data pairs for that table or
+** index.  Space to hold the filename is obtained from
 ** sqliteMalloc() and must be freed by the calling function.
 */
 static char *sqliteFileOfTable(Dbbe *pBe, const char *zTable){
@@ -269,7 +270,7 @@ static void randomName(struct rc4 *pRc4, char *zBuf, char *zPrefix){
 
 /*
 ** Open a new table cursor.  Write a pointer to the corresponding
-** DbbeTable structure into *ppTable.  Return an integer success
+** DbbeCursor structure into *ppCursr.  Return an integer success
 ** code:
 **
 **    SQLITE_OK          It worked!
@@ -287,25 +288,26 @@ static void randomName(struct rc4 *pRc4, char *zBuf, char *zPrefix){
 **                       (This can happen if a SELECT callback tries to
 **                       do an UPDATE or DELETE.)
 **
-** If zTable is 0 or "", then a temporary table is created and opened.
-** This table will be deleted from the disk when it is closed.
+** If zTable is 0 or "", then a temporary database file is created and
+** a cursor to that temporary file is opened.  The temporary file
+** will be deleted from the disk when it is closed.
 */
-int sqliteDbbeOpenTable(
+int sqliteDbbeOpenCursor(
   Dbbe *pBe,              /* The database the table belongs to */
-  const char *zTable,     /* The name of the table */
+  const char *zTable,     /* The SQL name of the file to be opened */
   int writeable,          /* True to open for writing */
-  DbbeTable **ppTable     /* Write the resulting table pointer here */
+  DbbeCursor **ppCursr    /* Write the resulting table pointer here */
 ){
   char *zFile;            /* Name of the table file */
-  DbbeTable *pTable;      /* The new table cursor */
+  DbbeCursor *pCursr;     /* The new table cursor */
   BeFile *pFile;          /* The underlying data file for this table */
   int rc = SQLITE_OK;     /* Return value */
   int rw_mask;            /* Permissions mask for opening a table */
   int mode;               /* Mode for opening a table */
 
-  *ppTable = 0;
-  pTable = sqliteMalloc( sizeof(*pTable) );
-  if( pTable==0 ) return SQLITE_NOMEM;
+  *ppCursr = 0;
+  pCursr = sqliteMalloc( sizeof(*pCursr) );
+  if( pCursr==0 ) return SQLITE_NOMEM;
   if( zTable ){
     zFile = sqliteFileOfTable(pBe, zTable);
     for(pFile=pBe->pOpen; pFile; pFile=pFile->pNext){
@@ -376,11 +378,11 @@ int sqliteDbbeOpenTable(
       rc = SQLITE_READONLY;
     }
   }
-  pTable->pBe = pBe;
-  pTable->pFile = pFile;
-  pTable->readPending = 0;
-  pTable->needRewind = 1;
-  *ppTable = pTable;
+  pCursr->pBe = pBe;
+  pCursr->pFile = pFile;
+  pCursr->readPending = 0;
+  pCursr->needRewind = 1;
+  *ppCursr = pCursr;
   return rc;
 }
 
@@ -400,28 +402,33 @@ void sqliteDbbeDropTable(Dbbe *pBe, const char *zTable){
 ** Reorganize a table to reduce search times and disk usage.
 */
 void sqliteDbbeReorganizeTable(Dbbe *pBe, const char *zTable){
-  DbbeTable *pTab;
+  DbbeCursor *pCrsr;
 
-  if( sqliteDbbeOpenTable(pBe, zTable, 1, &pTab)!=SQLITE_OK ){
+  if( sqliteDbbeOpenCursor(pBe, zTable, 1, &pCrsr)!=SQLITE_OK ){
     return;
   }
-  if( pTab && pTab->pFile && pTab->pFile->dbf ){
-    gdbm_reorganize(pTab->pFile->dbf);
+  if( pCrsr && pCrsr->pFile && pCrsr->pFile->dbf ){
+    gdbm_reorganize(pCrsr->pFile->dbf);
   }
-  if( pTab ){
-    sqliteDbbeCloseTable(pTab);
+  if( pCrsr ){
+    sqliteDbbeCloseCursor(pCrsr);
   }
 }
 
 /*
-** Close a table previously opened by sqliteDbbeOpenTable().
+** Close a cursor previously opened by sqliteDbbeOpenCursor().
+**
+** There can be multiple cursors pointing to the same open file.
+** The underlying file is not closed until all cursors have been
+** closed.  This routine decrements the BeFile.nref field of the
+** underlying file and closes the file when nref reaches 0.
 */
-void sqliteDbbeCloseTable(DbbeTable *pTable){
+void sqliteDbbeCloseCursor(DbbeCursor *pCursr){
   BeFile *pFile;
   Dbbe *pBe;
-  if( pTable==0 ) return;
-  pFile = pTable->pFile;
-  pBe = pTable->pBe;
+  if( pCursr==0 ) return;
+  pFile = pCursr->pFile;
+  pBe = pCursr->pBe;
   pFile->nRef--;
   if( pFile->dbf!=NULL ){
     gdbm_sync(pFile->dbf);
@@ -445,10 +452,10 @@ void sqliteDbbeCloseTable(DbbeTable *pTable){
     memset(pFile, 0, sizeof(*pFile));
     sqliteFree(pFile);
   }
-  if( pTable->key.dptr ) free(pTable->key.dptr);
-  if( pTable->data.dptr ) free(pTable->data.dptr);
-  memset(pTable, 0, sizeof(*pTable));
-  sqliteFree(pTable);
+  if( pCursr->key.dptr ) free(pCursr->key.dptr);
+  if( pCursr->data.dptr ) free(pCursr->data.dptr);
+  memset(pCursr, 0, sizeof(*pCursr));
+  sqliteFree(pCursr);
 }
 
 /*
@@ -461,32 +468,32 @@ static void datumClear(datum *p){
 }
 
 /*
-** Fetch a single record from an open table.  Return 1 on success
+** Fetch a single record from an open cursor.  Return 1 on success
 ** and 0 on failure.
 */
-int sqliteDbbeFetch(DbbeTable *pTable, int nKey, char *pKey){
+int sqliteDbbeFetch(DbbeCursor *pCursr, int nKey, char *pKey){
   datum key;
   key.dsize = nKey;
   key.dptr = pKey;
-  datumClear(&pTable->key);
-  datumClear(&pTable->data);
-  if( pTable->pFile && pTable->pFile->dbf ){
-    pTable->data = gdbm_fetch(pTable->pFile->dbf, key);
+  datumClear(&pCursr->key);
+  datumClear(&pCursr->data);
+  if( pCursr->pFile && pCursr->pFile->dbf ){
+    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, key);
   }
-  return pTable->data.dptr!=0;
+  return pCursr->data.dptr!=0;
 }
 
 /*
 ** Return 1 if the given key is already in the table.  Return 0
 ** if it is not.
 */
-int sqliteDbbeTest(DbbeTable *pTable, int nKey, char *pKey){
+int sqliteDbbeTest(DbbeCursor *pCursr, int nKey, char *pKey){
   datum key;
   int result = 0;
   key.dsize = nKey;
   key.dptr = pKey;
-  if( pTable->pFile && pTable->pFile->dbf ){
-    result = gdbm_exists(pTable->pFile->dbf, key);
+  if( pCursr->pFile && pCursr->pFile->dbf ){
+    result = gdbm_exists(pCursr->pFile->dbf, key);
   }
   return result;
 }
@@ -495,30 +502,30 @@ int sqliteDbbeTest(DbbeTable *pTable, int nKey, char *pKey){
 ** Copy bytes from the current key or data into a buffer supplied by
 ** the calling function.  Return the number of bytes copied.
 */
-int sqliteDbbeCopyKey(DbbeTable *pTable, int offset, int size, char *zBuf){
+int sqliteDbbeCopyKey(DbbeCursor *pCursr, int offset, int size, char *zBuf){
   int n;
-  if( offset>=pTable->key.dsize ) return 0;
-  if( offset+size>pTable->key.dsize ){
-    n = pTable->key.dsize - offset;
+  if( offset>=pCursr->key.dsize ) return 0;
+  if( offset+size>pCursr->key.dsize ){
+    n = pCursr->key.dsize - offset;
   }else{
     n = size;
   }
-  memcpy(zBuf, &pTable->key.dptr[offset], n);
+  memcpy(zBuf, &pCursr->key.dptr[offset], n);
   return n;
 }
-int sqliteDbbeCopyData(DbbeTable *pTable, int offset, int size, char *zBuf){
+int sqliteDbbeCopyData(DbbeCursor *pCursr, int offset, int size, char *zBuf){
   int n;
-  if( pTable->readPending && pTable->pFile && pTable->pFile->dbf ){
-    pTable->data = gdbm_fetch(pTable->pFile->dbf, pTable->key);
-    pTable->readPending = 0;
+  if( pCursr->readPending && pCursr->pFile && pCursr->pFile->dbf ){
+    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, pCursr->key);
+    pCursr->readPending = 0;
   }
-  if( offset>=pTable->data.dsize ) return 0;
-  if( offset+size>pTable->data.dsize ){
-    n = pTable->data.dsize - offset;
+  if( offset>=pCursr->data.dsize ) return 0;
+  if( offset+size>pCursr->data.dsize ){
+    n = pCursr->data.dsize - offset;
   }else{
     n = size;
   }
-  memcpy(zBuf, &pTable->data.dptr[offset], n);
+  memcpy(zBuf, &pCursr->data.dptr[offset], n);
   return n;
 }
 
@@ -526,39 +533,39 @@ int sqliteDbbeCopyData(DbbeTable *pTable, int offset, int size, char *zBuf){
 ** Return a pointer to bytes from the key or data.  The data returned
 ** is ephemeral.
 */
-char *sqliteDbbeReadKey(DbbeTable *pTable, int offset){
-  if( offset<0 || offset>=pTable->key.dsize ) return "";
-  return &pTable->key.dptr[offset];
+char *sqliteDbbeReadKey(DbbeCursor *pCursr, int offset){
+  if( offset<0 || offset>=pCursr->key.dsize ) return "";
+  return &pCursr->key.dptr[offset];
 }
-char *sqliteDbbeReadData(DbbeTable *pTable, int offset){
-  if( pTable->readPending && pTable->pFile && pTable->pFile->dbf ){
-    pTable->data = gdbm_fetch(pTable->pFile->dbf, pTable->key);
-    pTable->readPending = 0;
+char *sqliteDbbeReadData(DbbeCursor *pCursr, int offset){
+  if( pCursr->readPending && pCursr->pFile && pCursr->pFile->dbf ){
+    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, pCursr->key);
+    pCursr->readPending = 0;
   }
-  if( offset<0 || offset>=pTable->data.dsize ) return "";
-  return &pTable->data.dptr[offset];
+  if( offset<0 || offset>=pCursr->data.dsize ) return "";
+  return &pCursr->data.dptr[offset];
 }
 
 /*
 ** Return the total number of bytes in either data or key.
 */
-int sqliteDbbeKeyLength(DbbeTable *pTable){
-  return pTable->key.dsize;
+int sqliteDbbeKeyLength(DbbeCursor *pCursr){
+  return pCursr->key.dsize;
 }
-int sqliteDbbeDataLength(DbbeTable *pTable){
-  if( pTable->readPending && pTable->pFile && pTable->pFile->dbf ){
-    pTable->data = gdbm_fetch(pTable->pFile->dbf, pTable->key);
-    pTable->readPending = 0;
+int sqliteDbbeDataLength(DbbeCursor *pCursr){
+  if( pCursr->readPending && pCursr->pFile && pCursr->pFile->dbf ){
+    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, pCursr->key);
+    pCursr->readPending = 0;
   }
-  return pTable->data.dsize;
+  return pCursr->data.dsize;
 }
 
 /*
 ** Make is so that the next call to sqliteNextKey() finds the first
 ** key of the table.
 */
-int sqliteDbbeRewind(DbbeTable *pTable){
-  pTable->needRewind = 1;
+int sqliteDbbeRewind(DbbeCursor *pCursr){
+  pCursr->needRewind = 1;
   return SQLITE_OK;
 }
 
@@ -566,28 +573,28 @@ int sqliteDbbeRewind(DbbeTable *pTable){
 ** Read the next key from the table.  Return 1 on success.  Return
 ** 0 if there are no more keys.
 */
-int sqliteDbbeNextKey(DbbeTable *pTable){
+int sqliteDbbeNextKey(DbbeCursor *pCursr){
   datum nextkey;
   int rc;
-  if( pTable==0 || pTable->pFile==0 || pTable->pFile->dbf==0 ){
-    pTable->readPending = 0;
+  if( pCursr==0 || pCursr->pFile==0 || pCursr->pFile->dbf==0 ){
+    pCursr->readPending = 0;
     return 0;
   }
-  if( pTable->needRewind ){
-    nextkey = gdbm_firstkey(pTable->pFile->dbf);
-    pTable->needRewind = 0;
+  if( pCursr->needRewind ){
+    nextkey = gdbm_firstkey(pCursr->pFile->dbf);
+    pCursr->needRewind = 0;
   }else{
-    nextkey = gdbm_nextkey(pTable->pFile->dbf, pTable->key);
+    nextkey = gdbm_nextkey(pCursr->pFile->dbf, pCursr->key);
   }
-  datumClear(&pTable->key);
-  datumClear(&pTable->data);
-  pTable->key = nextkey;
-  if( pTable->key.dptr ){
-    pTable->readPending = 1;
+  datumClear(&pCursr->key);
+  datumClear(&pCursr->data);
+  pCursr->key = nextkey;
+  if( pCursr->key.dptr ){
+    pCursr->readPending = 1;
     rc = 1;
   }else{
-    pTable->needRewind = 1;
-    pTable->readPending = 0;
+    pCursr->needRewind = 1;
+    pCursr->readPending = 0;
     rc = 0;
   }
   return rc;
@@ -596,15 +603,15 @@ int sqliteDbbeNextKey(DbbeTable *pTable){
 /*
 ** Get a new integer key.
 */
-int sqliteDbbeNew(DbbeTable *pTable){
+int sqliteDbbeNew(DbbeCursor *pCursr){
   int iKey;
   datum key;
   int go = 1;
   int i;
   struct rc4 *pRc4;
 
-  if( pTable->pFile==0 || pTable->pFile->dbf==0 ) return 1;
-  pRc4 = &pTable->pBe->rc4;
+  if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return 1;
+  pRc4 = &pCursr->pBe->rc4;
   while( go ){
     iKey = 0;
     for(i=0; i<4; i++){
@@ -612,7 +619,7 @@ int sqliteDbbeNew(DbbeTable *pTable){
     }
     key.dptr = (char*)&iKey;
     key.dsize = 4;
-    go = gdbm_exists(pTable->pFile->dbf, key);
+    go = gdbm_exists(pCursr->pFile->dbf, key);
   }
   return iKey;
 }   
@@ -621,33 +628,33 @@ int sqliteDbbeNew(DbbeTable *pTable){
 ** Write an entry into the table.  Overwrite any prior entry with the
 ** same key.
 */
-int sqliteDbbePut(DbbeTable *pTable, int nKey,char *pKey,int nData,char *pData){
+int sqliteDbbePut(DbbeCursor *pCursr, int nKey,char *pKey,int nData,char *pData){
   datum data, key;
   int rc;
-  if( pTable->pFile==0 || pTable->pFile->dbf==0 ) return SQLITE_ERROR;
+  if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return SQLITE_ERROR;
   data.dsize = nData;
   data.dptr = pData;
   key.dsize = nKey;
   key.dptr = pKey;
-  rc = gdbm_store(pTable->pFile->dbf, key, data, GDBM_REPLACE);
+  rc = gdbm_store(pCursr->pFile->dbf, key, data, GDBM_REPLACE);
   if( rc ) rc = SQLITE_ERROR;
-  datumClear(&pTable->key);
-  datumClear(&pTable->data);
+  datumClear(&pCursr->key);
+  datumClear(&pCursr->data);
   return rc;
 }
 
 /*
 ** Remove an entry from a table, if the entry exists.
 */
-int sqliteDbbeDelete(DbbeTable *pTable, int nKey, char *pKey){
+int sqliteDbbeDelete(DbbeCursor *pCursr, int nKey, char *pKey){
   datum key;
   int rc;
-  datumClear(&pTable->key);
-  datumClear(&pTable->data);
-  if( pTable->pFile==0 || pTable->pFile->dbf==0 ) return SQLITE_ERROR;
+  datumClear(&pCursr->key);
+  datumClear(&pCursr->data);
+  if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return SQLITE_ERROR;
   key.dsize = nKey;
   key.dptr = pKey;
-  rc = gdbm_delete(pTable->pFile->dbf, key);
+  rc = gdbm_delete(pCursr->pFile->dbf, key);
   if( rc ) rc = SQLITE_ERROR;
   return rc;
 }
index 0edab794a4cbdf8300c77014bf1e8ee08611e4ee..8ccb53f18f9c7e1f402d30c57cbbb35af58d8029 100644 (file)
@@ -28,7 +28,7 @@
 ** This library was originally designed to support the following
 ** backends: GDBM, NDBM, SDBM, Berkeley DB.
 **
-** $Id: dbbe.h,v 1.5 2000/06/17 13:12:39 drh Exp $
+** $Id: dbbe.h,v 1.6 2000/06/21 13:59:11 drh Exp $
 */
 #ifndef _SQLITE_DBBE_H_
 #define _SQLITE_DBBE_H_
@@ -37,7 +37,7 @@
 /*
 ** The database backend supports two opaque structures.  A Dbbe is
 ** a context for the entire set of tables forming a complete
-** database.  A DbbeTable is a single table.
+** database.  A DbbeCursor is a pointer into a single single table.
 **
 ** Note that at this level, the term "table" can mean either an
 ** SQL table or an SQL index.  In this module, a table stores a
 ** segregation of data into various fields or columns is handled
 ** by software at higher layers.
 **
-** The DbbeTable structure holds some state information, such as
+** The DbbeCursor structure holds some state information, such as
 ** the key and data from the last retrieval.  For this reason, 
 ** the backend must allow the creation of multiple independent
-** DbbeTable structures for each table in the database.
+** DbbeCursor structures for each table in the database.
 */
 typedef struct Dbbe Dbbe;
-typedef struct DbbeTable DbbeTable;
+typedef struct DbbeCursor DbbeCursor;
 
 /*
 ** The 18 interface routines.
@@ -64,13 +64,16 @@ Dbbe *sqliteDbbeOpen(const char *zName, int write, int create, char **pzErr);
 /* Close the whole database. */
 void sqliteDbbeClose(Dbbe*);
 
-/* Open a particular table of a previously opened database.
-** Create the table if it doesn't already exist and writeable!=0.
+/* Open a cursor into particular file of a previously opened database.
+** Create the file if it doesn't already exist and writeable!=0.  zName
+** is the base name of the file to be opened.  This routine will add
+** an appropriate path and extension to the filename to locate the 
+** actual file.
 **
-** If zTableName is 0 or "", then a temporary table is created that
+** If zName is 0 or "", then a temporary file is created that
 ** will be deleted when closed.
 */
-int sqliteDbbeOpenTable(Dbbe*, const char *zName, int writeable, DbbeTable **);
+int sqliteDbbeOpenCursor(Dbbe*, const char *zName, int writeable, DbbeCursor**);
 
 /* Delete a table from the database */
 void sqliteDbbeDropTable(Dbbe*, const char *zTableName);
@@ -78,58 +81,58 @@ void sqliteDbbeDropTable(Dbbe*, const char *zTableName);
 /* Reorganize a table to speed access or reduce its disk usage */
 void sqliteDbbeReorganizeTable(Dbbe*, const char *zTableName);
 
-/* Close a table */
-void sqliteDbbeCloseTable(DbbeTable*);
+/* Close a cursor */
+void sqliteDbbeCloseCursor(DbbeCursor*);
 
 /* Fetch an entry from a table with the given key.  Return 1 if
 ** successful and 0 if no such entry exists.
 */
-int sqliteDbbeFetch(DbbeTable*, int nKey, char *pKey);
+int sqliteDbbeFetch(DbbeCursor*, int nKey, char *pKey);
 
 /* Return 1 if the given key is already in the table.  Return 0
 ** if it is not.
 */
-int sqliteDbbeTest(DbbeTable*, int nKey, char *pKey);
+int sqliteDbbeTest(DbbeCursor*, int nKey, char *pKey);
 
 /* Retrieve the key or data used for the last fetch.  Only size
 ** bytes are read beginning with the offset-th byte.  The return
 ** value is the actual number of bytes read.
 */
-int sqliteDbbeCopyKey(DbbeTable*, int offset, int size, char *zBuf);
-int sqliteDbbeCopyData(DbbeTable*, int offset, int size, char *zBuf);
+int sqliteDbbeCopyKey(DbbeCursor*, int offset, int size, char *zBuf);
+int sqliteDbbeCopyData(DbbeCursor*, int offset, int size, char *zBuf);
 
 /* Retrieve the key or data.  The result is ephemeral.  In other words,
 ** the result is stored in a buffer that might be overwritten on the next
 ** call to any DBBE routine.  If the results are needed for longer than
 ** that, you must make a copy.
 */
-char *sqliteDbbeReadKey(DbbeTable*, int offset);
-char *sqliteDbbeReadData(DbbeTable*, int offset);
+char *sqliteDbbeReadKey(DbbeCursor*, int offset);
+char *sqliteDbbeReadData(DbbeCursor*, int offset);
 
 /* Return the length of the most recently fetched key or data. */
-int sqliteDbbeKeyLength(DbbeTable*);
-int sqliteDbbeDataLength(DbbeTable*);
+int sqliteDbbeKeyLength(DbbeCursor*);
+int sqliteDbbeDataLength(DbbeCursor*);
 
 /* Retrieve the next entry in the table.  The first key is retrieved
 ** the first time this routine is called, or after a call to
 ** sqliteDbbeRewind().  The return value is 1 if there is another
 ** entry, or 0 if there are no more entries. */
-int sqliteDbbeNextKey(DbbeTable*);
+int sqliteDbbeNextKey(DbbeCursor*);
 
 /* Make it so that the next call to sqliteDbbeNextKey() returns
 ** the first entry of the table. */
-int sqliteDbbeRewind(DbbeTable*);
+int sqliteDbbeRewind(DbbeCursor*);
 
 /* Get a new integer key for this table. */
-int sqliteDbbeNew(DbbeTable*);
+int sqliteDbbeNew(DbbeCursor*);
 
 /* Write an entry into a table.  If another entry already exists with
 ** the same key, the old entry is discarded first.
 */
-int sqliteDbbePut(DbbeTable*, int nKey, char *pKey, int nData, char *pData);
+int sqliteDbbePut(DbbeCursor*, int nKey, char *pKey, int nData, char *pData);
 
 /* Remove an entry from the table */
-int sqliteDbbeDelete(DbbeTable*, int nKey, char *pKey);
+int sqliteDbbeDelete(DbbeCursor*, int nKey, char *pKey);
 
 /* Open a file suitable for temporary storage */
 int sqliteDbbeOpenTempFile(Dbbe*, FILE**);
index e81272f735218ac5871a5e48177eb365ece4625d..f6822f9ab5806f49a05f6a2a5192d04b6afb226d 100644 (file)
@@ -24,7 +24,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle DELETE FROM statements.
 **
-** $Id: delete.c,v 1.5 2000/06/17 13:12:39 drh Exp $
+** $Id: delete.c,v 1.6 2000/06/21 13:59:11 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -68,7 +68,7 @@ void sqliteDeleteFrom(
   }
   pTab = pTabList->a[0].pTab;
 
-  /* Resolve the field names in all the expressions.
+  /* Resolve the column names in all the expressions.
   */
   if( pWhere ){
     sqliteExprResolveInSelect(pParse, pWhere);
@@ -117,10 +117,10 @@ void sqliteDeleteFrom(
     for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
       int j;
       sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
-      for(j=0; j<pIdx->nField; j++){
-        sqliteVdbeAddOp(v, OP_Field, base, pIdx->aiField[j], 0, 0);
+      for(j=0; j<pIdx->nColumn; j++){
+        sqliteVdbeAddOp(v, OP_Field, base, pIdx->aiColumn[j], 0, 0);
       }
-      sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nField, 0, 0, 0);
+      sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nColumn, 0, 0, 0);
       sqliteVdbeAddOp(v, OP_DeleteIdx, base+i, 0, 0, 0);
     }
   }
index 74873bc1e2246eb30291046b6f23fd6815461e07..c94fd247a4666b4fc6203e7e6207ae1c3924738e 100644 (file)
@@ -24,7 +24,7 @@
 ** This file contains routines used for analyzing expressions and
 ** for generating VDBE code that evaluates expressions.
 **
-** $Id: expr.c,v 1.17 2000/06/17 13:12:40 drh Exp $
+** $Id: expr.c,v 1.18 2000/06/21 13:59:11 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -35,7 +35,7 @@
 static int isConstant(Expr *p){
   switch( p->op ){
     case TK_ID:
-    case TK_FIELD:
+    case TK_COLUMN:
     case TK_DOT:
       return 0;
     default: {
@@ -58,10 +58,10 @@ static int isConstant(Expr *p){
 **
 **       expr IN (SELECT ...)
 **
-** These operators have to be processed before field names are
+** These operators have to be processed before column names are
 ** resolved because each such operator increments pParse->nTab
 ** to reserve cursor numbers for its own use.  But pParse->nTab
-** needs to be constant once we begin resolving field names.
+** needs to be constant once we begin resolving column names.
 **
 ** Actually, the processing of IN-SELECT is only started by this
 ** routine.  This routine allocates a cursor number to the IN-SELECT
@@ -87,11 +87,11 @@ void sqliteExprResolveInSelect(Parse *pParse, Expr *pExpr){
 
 /*
 ** This routine walks an expression tree and resolves references to
-** table fields.  Nodes of the form ID.ID or ID resolve into an
-** index to the table in the table list and a field offset.  The opcode
-** for such nodes is changed to TK_FIELD.  The iTable value is changed
+** table columns.  Nodes of the form ID.ID or ID resolve into an
+** index to the table in the table list and a column offset.  The opcode
+** for such nodes is changed to TK_COLUMN.  The iTable value is changed
 ** to the index of the referenced table in pTabList plus the pParse->nTab
-** value.  The iField value is changed to the index of the field of the 
+** value.  The iColumn value is changed to the index of the column of the 
 ** referenced table.
 **
 ** We also check for instances of the IN operator.  IN comes in two
@@ -109,7 +109,7 @@ void sqliteExprResolveInSelect(Parse *pParse, Expr *pExpr){
 ** If it finds any, it generates code to write the value of that select
 ** into a memory cell.
 **
-** Unknown fields or tables provoke an error.  The function returns
+** Unknown columns or tables provoke an error.  The function returns
 ** the number of errors seen and leaves an error message on pParse->zErrMsg.
 */
 int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){
@@ -128,27 +128,27 @@ int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){
           if( sqliteStrICmp(pTab->aCol[j].zName, z)==0 ){
             cnt++;
             pExpr->iTable = i + pParse->nTab;
-            pExpr->iField = j;
+            pExpr->iColumn = j;
           }
         }
       }
       sqliteFree(z);
       if( cnt==0 ){
-        sqliteSetNString(&pParse->zErrMsg, "no such field: ", -1,  
+        sqliteSetNString(&pParse->zErrMsg, "no such column: ", -1,  
           pExpr->token.z, pExpr->token.n, 0);
         pParse->nErr++;
         return 1;
       }else if( cnt>1 ){
-        sqliteSetNString(&pParse->zErrMsg, "ambiguous field name: ", -1,  
+        sqliteSetNString(&pParse->zErrMsg, "ambiguous column name: ", -1,  
           pExpr->token.z, pExpr->token.n, 0);
         pParse->nErr++;
         return 1;
       }
-      pExpr->op = TK_FIELD;
+      pExpr->op = TK_COLUMN;
       break; 
     }
   
-    /* A table name and field name:  ID.ID */
+    /* A table name and column name:  ID.ID */
     case TK_DOT: {
       int cnt = 0;             /* Number of matches */
       int i;                   /* Loop counter */
@@ -176,20 +176,20 @@ int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){
           if( sqliteStrICmp(pTab->aCol[j].zName, zRight)==0 ){
             cnt++;
             pExpr->iTable = i + pParse->nTab;
-            pExpr->iField = j;
+            pExpr->iColumn = j;
           }
         }
       }
       sqliteFree(zLeft);
       sqliteFree(zRight);
       if( cnt==0 ){
-        sqliteSetNString(&pParse->zErrMsg, "no such field: ", -1,  
+        sqliteSetNString(&pParse->zErrMsg, "no such column: ", -1,  
           pLeft->token.z, pLeft->token.n, ".", 1, 
           pRight->token.z, pRight->token.n, 0);
         pParse->nErr++;
         return 1;
       }else if( cnt>1 ){
-        sqliteSetNString(&pParse->zErrMsg, "ambiguous field name: ", -1,  
+        sqliteSetNString(&pParse->zErrMsg, "ambiguous column name: ", -1,  
           pLeft->token.z, pLeft->token.n, ".", 1,
           pRight->token.z, pRight->token.n, 0);
         pParse->nErr++;
@@ -199,7 +199,7 @@ int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){
       pExpr->pLeft = 0;
       sqliteExprDelete(pRight);
       pExpr->pRight = 0;
-      pExpr->op = TK_FIELD;
+      pExpr->op = TK_COLUMN;
       break;
     }
 
@@ -263,10 +263,10 @@ int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){
     case TK_SELECT: {
       /* This has to be a scalar SELECT.  Generate code to put the
       ** value of this select in a memory cell and record the number
-      ** of the memory cell in iField.
+      ** of the memory cell in iColumn.
       */
-      pExpr->iField = pParse->nMem++;
-      if( sqliteSelect(pParse, pExpr->pSelect, SRT_Mem, pExpr->iField) ){
+      pExpr->iColumn = pParse->nMem++;
+      if( sqliteSelect(pParse, pExpr->pSelect, SRT_Mem, pExpr->iColumn) ){
         return 1;
       }
       break;
@@ -355,7 +355,7 @@ int sqliteExprCheck(Parse *pParse, Expr *pExpr, int allowAgg, int *pIsAgg){
       int too_few_args = 0;
       int is_agg = 0;
       int i;
-      pExpr->iField = id;
+      pExpr->iColumn = id;
       switch( id ){
         case FN_Unknown: { 
           no_such_func = 1;
@@ -467,11 +467,11 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
     default: break;
   }
   switch( pExpr->op ){
-    case TK_FIELD: {
+    case TK_COLUMN: {
       if( pParse->useAgg ){
         sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg, 0, 0);
       }else{
-        sqliteVdbeAddOp(v, OP_Field, pExpr->iTable, pExpr->iField, 0, 0);
+        sqliteVdbeAddOp(v, OP_Field, pExpr->iTable, pExpr->iColumn, 0, 0);
       }
       break;
     }
@@ -562,7 +562,7 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
     }
     case TK_AGG_FUNCTION: {
       sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg, 0, 0);
-      if( pExpr->iField==FN_Avg ){
+      if( pExpr->iColumn==FN_Avg ){
         assert( pParse->iAggCount>=0 && pParse->iAggCount<pParse->nAgg );
         sqliteVdbeAddOp(v, OP_AggGet, 0, pParse->iAggCount, 0, 0);
         sqliteVdbeAddOp(v, OP_Divide, 0, 0, 0, 0);
@@ -570,7 +570,7 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
       break;
     }
     case TK_FUNCTION: {
-      int id = pExpr->iField;
+      int id = pExpr->iColumn;
       int op;
       int i;
       ExprList *pList = pExpr->pList;
@@ -588,7 +588,7 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
       break;
     }
     case TK_SELECT: {
-      sqliteVdbeAddOp(v, OP_MemLoad, pExpr->iField, 0, 0, 0);
+      sqliteVdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0, 0, 0);
       break;
     }
     case TK_IN: {
@@ -864,12 +864,12 @@ int sqliteExprAnalyzeAggregates(Parse *pParse, Expr *pExpr){
 
   if( pExpr==0 ) return 0;
   switch( pExpr->op ){
-    case TK_FIELD: {
+    case TK_COLUMN: {
       aAgg = pParse->aAgg;
       for(i=0; i<pParse->nAgg; i++){
         if( aAgg[i].isAgg ) continue;
         if( aAgg[i].pExpr->iTable==pExpr->iTable
-         && aAgg[i].pExpr->iField==pExpr->iField ){
+         && aAgg[i].pExpr->iColumn==pExpr->iColumn ){
           break;
         }
       }
@@ -883,7 +883,7 @@ int sqliteExprAnalyzeAggregates(Parse *pParse, Expr *pExpr){
       break;
     }
     case TK_AGG_FUNCTION: {
-      if( pExpr->iField==FN_Count || pExpr->iField==FN_Avg ){
+      if( pExpr->iColumn==FN_Count || pExpr->iColumn==FN_Avg ){
         if( pParse->iAggCount>=0 ){
           i = pParse->iAggCount;
         }else{
@@ -893,7 +893,7 @@ int sqliteExprAnalyzeAggregates(Parse *pParse, Expr *pExpr){
           pParse->aAgg[i].pExpr = 0;
           pParse->iAggCount = i;
         }
-        if( pExpr->iField==FN_Count ){
+        if( pExpr->iColumn==FN_Count ){
           pExpr->iAgg = i;
           break;
         }
index a40ea91c1c2dfa4f27bffe09a3798f79d886641b..a044bc144894148090df156a40fb8cd3d0d8af0c 100644 (file)
@@ -24,7 +24,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle INSERT statements.
 **
-** $Id: insert.c,v 1.10 2000/06/17 13:12:40 drh Exp $
+** $Id: insert.c,v 1.11 2000/06/21 13:59:12 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -36,7 +36,7 @@
 **
 ** The IDLIST following the table name is always optional.  If omitted,
 ** then a list of all columns for the table is substituted.  The IDLIST
-** appears in the pField parameter.  pField is NULL if IDLIST is omitted.
+** appears in the pColumn parameter.  pColumn is NULL if IDLIST is omitted.
 **
 ** The pList parameter holds EXPRLIST in the first form of the INSERT
 ** statement above, and pSelect is NULL.  For the second form, pList is
@@ -48,7 +48,7 @@ void sqliteInsert(
   Token *pTableName,    /* Name of table into which we are inserting */
   ExprList *pList,      /* List of values to be inserted */
   Select *pSelect,      /* A SELECT statement to use as the data source */
-  IdList *pField        /* Field names corresponding to IDLIST. */
+  IdList *pColumn       /* Column names corresponding to IDLIST. */
 ){
   Table *pTab;          /* The table to insert into */
   char *zTab;           /* Name of the table into which we are inserting */
@@ -56,7 +56,7 @@ void sqliteInsert(
   Vdbe *v;              /* Generate code into this virtual machine */
   Index *pIdx;          /* For looping over indices of the table */
   int srcTab;           /* Date comes from this temporary cursor if >=0 */
-  int nField;           /* Number of columns in the data */
+  int nColumn;          /* Number of columns in the data */
   int base;             /* First available cursor */
   int iCont, iBreak;    /* Beginning and end of the loop over srcTab */
 
@@ -96,20 +96,20 @@ void sqliteInsert(
     rc = sqliteSelect(pParse, pSelect, SRT_Table, srcTab);
     if( rc ) goto insert_cleanup;
     assert( pSelect->pEList );
-    nField = pSelect->pEList->nExpr;
+    nColumn = pSelect->pEList->nExpr;
   }else{
     srcTab = -1;
     assert( pList );
-    nField = pList->nExpr;
+    nColumn = pList->nExpr;
   }
 
   /* Make sure the number of columns in the source data matches the number
   ** of columns to be inserted into the table.
   */
-  if( pField==0 && nField!=pTab->nCol ){
+  if( pColumn==0 && nColumn!=pTab->nCol ){
     char zNum1[30];
     char zNum2[30];
-    sprintf(zNum1,"%d", nField);
+    sprintf(zNum1,"%d", nColumn);
     sprintf(zNum2,"%d", pTab->nCol);
     sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName,
        " has ", zNum2, " columns but ",
@@ -117,11 +117,11 @@ void sqliteInsert(
     pParse->nErr++;
     goto insert_cleanup;
   }
-  if( pField!=0 && nField!=pField->nId ){
+  if( pColumn!=0 && nColumn!=pColumn->nId ){
     char zNum1[30];
     char zNum2[30];
-    sprintf(zNum1,"%d", nField);
-    sprintf(zNum2,"%d", pField->nId);
+    sprintf(zNum1,"%d", nColumn);
+    sprintf(zNum2,"%d", pColumn->nId);
     sqliteSetString(&pParse->zErrMsg, zNum1, " values for ",
        zNum2, " columns", 0);
     pParse->nErr++;
@@ -132,20 +132,20 @@ void sqliteInsert(
   ** all elements of the IDLIST really are columns of the table and 
   ** remember the column indices.
   */
-  if( pField ){
-    for(i=0; i<pField->nId; i++){
-      pField->a[i].idx = -1;
+  if( pColumn ){
+    for(i=0; i<pColumn->nId; i++){
+      pColumn->a[i].idx = -1;
     }
-    for(i=0; i<pField->nId; i++){
+    for(i=0; i<pColumn->nId; i++){
       for(j=0; j<pTab->nCol; j++){
-        if( sqliteStrICmp(pField->a[i].zName, pTab->aCol[j].zName)==0 ){
-          pField->a[i].idx = j;
+        if( sqliteStrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
+          pColumn->a[i].idx = j;
           break;
         }
       }
       if( j>=pTab->nCol ){
         sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName,
-           " has no column named ", pField->a[i].zName, 0);
+           " has no column named ", pColumn->a[i].zName, 0);
         pParse->nErr++;
         goto insert_cleanup;
       }
@@ -179,14 +179,14 @@ void sqliteInsert(
     sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
   }
   for(i=0; i<pTab->nCol; i++){
-    if( pField==0 ){
+    if( pColumn==0 ){
       j = i;
     }else{
-      for(j=0; j<pField->nId; j++){
-        if( pField->a[j].idx==i ) break;
+      for(j=0; j<pColumn->nId; j++){
+        if( pColumn->a[j].idx==i ) break;
       }
     }
-    if( pField && j>=pField->nId ){
+    if( pColumn && j>=pColumn->nId ){
       char *zDflt = pTab->aCol[i].zDflt;
       if( zDflt==0 ){
         sqliteVdbeAddOp(v, OP_Null, 0, 0, 0, 0);
@@ -209,16 +209,16 @@ void sqliteInsert(
     if( pIdx->pNext ){
       sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
     }
-    for(i=0; i<pIdx->nField; i++){
-      int idx = pIdx->aiField[i];
-      if( pField==0 ){
+    for(i=0; i<pIdx->nColumn; i++){
+      int idx = pIdx->aiColumn[i];
+      if( pColumn==0 ){
         j = idx;
       }else{
-        for(j=0; j<pField->nId; j++){
-          if( pField->a[j].idx==idx ) break;
+        for(j=0; j<pColumn->nId; j++){
+          if( pColumn->a[j].idx==idx ) break;
         }
       }
-      if( pField && j>=pField->nId ){
+      if( pColumn && j>=pColumn->nId ){
         char *zDflt = pTab->aCol[idx].zDflt;
         if( zDflt==0 ){
           sqliteVdbeAddOp(v, OP_Null, 0, 0, 0, 0);
@@ -231,7 +231,7 @@ void sqliteInsert(
         sqliteExprCode(pParse, pList->a[j].pExpr);
       }
     }
-    sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nField, 0, 0, 0);
+    sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nColumn, 0, 0, 0);
     sqliteVdbeAddOp(v, OP_PutIdx, idx+base, 0, 0, 0);
   }
 
@@ -245,5 +245,5 @@ void sqliteInsert(
 insert_cleanup:
   if( pList ) sqliteExprListDelete(pList);
   if( pSelect ) sqliteSelectDelete(pSelect);
-  sqliteIdListDelete(pField);
+  sqliteIdListDelete(pColumn);
 }
index 3c81beca33052932a72d5ee3c4f0d3e82295a473..06423b54539732ae8f23c9086d5b08814726f2d4 100644 (file)
@@ -26,7 +26,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.12 2000/06/07 23:51:50 drh Exp $
+** $Id: main.c,v 1.13 2000/06/21 13:59:12 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -90,12 +90,12 @@ static int sqliteInit(sqlite *db, char **pzErrMsg){
   **    );
   **
   ** The sqlite_master table contains a single entry for each table
-  ** and each index.  The "type" field tells whether the entry is
-  ** a table or index.  The "name" field is the name of the object.
+  ** and each index.  The "type" column tells whether the entry is
+  ** a table or index.  The "name" column is the name of the object.
   ** The "tbl_name" is the name of the associated table.  For tables,
-  ** the tbl_name field is always the same as name.  For indices, the
-  ** tbl_name field contains the name of the table that the index
-  ** indexes.  Finally, the sql field contains the complete text of
+  ** the tbl_name column is always the same as name.  For indices, the
+  ** tbl_name column contains the name of the table that the index
+  ** indexes.  Finally, the "sql" column contains the complete text of
   ** the CREATE TABLE or CREATE INDEX statement that originally created
   ** the table or index.
   **
index 862e1d6309c45d5b82c8c18e949cced65dedfd2f..f59b662b643d4d596781a51c1de4a15a73bcf548 100644 (file)
@@ -26,7 +26,7 @@
 ** the parser.  Lemon will also generate a header file containing
 ** numeric codes for all of the tokens.
 **
-** @(#) $Id: parse.y,v 1.22 2000/06/19 19:09:09 drh Exp $
+** @(#) $Id: parse.y,v 1.23 2000/06/21 13:59:12 drh Exp $
 */
 %token_prefix TK_
 %token_type {Token}
@@ -50,7 +50,7 @@ input ::= cmdlist.
 // add them to the parse.h output file.
 //
 input ::= END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION
-          UMINUS FIELD AGG_FUNCTION.
+          UMINUS COLUMN AGG_FUNCTION.
 
 // A list of commands is zero or more commands
 //
@@ -250,9 +250,9 @@ setlist(A) ::= id(X) EQ expr(Y) COMMA setlist(Z).
     {A = sqliteExprListAppend(Z,Y,&X);}
 setlist(A) ::= id(X) EQ expr(Y).   {A = sqliteExprListAppend(0,Y,&X);}
 
-cmd ::= INSERT INTO id(X) fieldlist_opt(F) VALUES LP itemlist(Y) RP.
+cmd ::= INSERT INTO id(X) inscollist_opt(F) VALUES LP itemlist(Y) RP.
                {sqliteInsert(pParse, &X, Y, 0, F);}
-cmd ::= INSERT INTO id(X) fieldlist_opt(F) select(S).
+cmd ::= INSERT INTO id(X) inscollist_opt(F) select(S).
                {sqliteInsert(pParse, &X, 0, S, F);}
 
 
@@ -278,15 +278,15 @@ item(A) ::= MINUS FLOAT(X).  {
 item(A) ::= STRING(X).       {A = sqliteExpr(TK_STRING, 0, 0, &X);}
 item(A) ::= NULL.            {A = sqliteExpr(TK_NULL, 0, 0, 0);}
 
-%type fieldlist_opt {IdList*}
-%destructor fieldlist_opt {sqliteIdListDelete($$);}
-%type fieldlist {IdList*}
-%destructor fieldlist {sqliteIdListDelete($$);}
+%type inscollist_opt {IdList*}
+%destructor inscollist_opt {sqliteIdListDelete($$);}
+%type inscollist {IdList*}
+%destructor inscollist {sqliteIdListDelete($$);}
 
-fieldlist_opt(A) ::= .                    {A = 0;}
-fieldlist_opt(A) ::= LP fieldlist(X) RP.  {A = X;}
-fieldlist(A) ::= fieldlist(X) COMMA id(Y). {A = sqliteIdListAppend(X,&Y);}
-fieldlist(A) ::= id(Y).                    {A = sqliteIdListAppend(0,&Y);}
+inscollist_opt(A) ::= .                      {A = 0;}
+inscollist_opt(A) ::= LP inscollist(X) RP.   {A = X;}
+inscollist(A) ::= inscollist(X) COMMA id(Y). {A = sqliteIdListAppend(X,&Y);}
+inscollist(A) ::= id(Y).                     {A = sqliteIdListAppend(0,&Y);}
 
 %left OR.
 %left AND.
index e39e415a4c7c08534148b6b840aa62da02aa3122..d9d21c76a3f1e512c71761dae8e330518bbf5404 100644 (file)
@@ -24,7 +24,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle SELECT statements.
 **
-** $Id: select.c,v 1.24 2000/06/19 19:09:09 drh Exp $
+** $Id: select.c,v 1.25 2000/06/21 13:59:12 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -86,14 +86,14 @@ void sqliteParseInfoReset(Parse *pParse){
 ** of a SELECT.
 **
 ** The pEList is used to determine the values for each column in the
-** result row.  Except  if pEList==NULL, then we just read nField
+** result row.  Except  if pEList==NULL, then we just read nColumn
 ** elements from the srcTab table.
 */
 static int selectInnerLoop(
   Parse *pParse,          /* The parser context */
   ExprList *pEList,       /* List of values being extracted */
   int srcTab,             /* Pull data from this table */
-  int nField,             /* Number of fields in the source table */
+  int nColumn,            /* Number of columns in the source table */
   ExprList *pOrderBy,     /* If not NULL, sort results using this key */
   int distinct,           /* If >=0, make sure results are distinct */
   int eDest,              /* How to dispose of the results */
@@ -104,15 +104,15 @@ static int selectInnerLoop(
   Vdbe *v = pParse->pVdbe;
   int i;
 
-  /* Pull the requested fields.
+  /* Pull the requested columns.
   */
   if( pEList ){
     for(i=0; i<pEList->nExpr; i++){
       sqliteExprCode(pParse, pEList->a[i].pExpr);
     }
-    nField = pEList->nExpr;
+    nColumn = pEList->nExpr;
   }else{
-    for(i=0; i<nField; i++){
+    for(i=0; i<nColumn; i++){
       sqliteVdbeAddOp(v, OP_Field, srcTab, i, 0, 0);
     }
   }
@@ -135,7 +135,7 @@ static int selectInnerLoop(
   */
   if( pOrderBy ){
     char *zSortOrder;
-    sqliteVdbeAddOp(v, OP_SortMakeRec, nField, 0, 0, 0);
+    sqliteVdbeAddOp(v, OP_SortMakeRec, nColumn, 0, 0, 0);
     zSortOrder = sqliteMalloc( pOrderBy->nExpr + 1 );
     if( zSortOrder==0 ) return 1;
     for(i=0; i<pOrderBy->nExpr; i++){
@@ -152,7 +152,7 @@ static int selectInnerLoop(
   ** table iParm.
   */
   if( eDest==SRT_Union ){
-    sqliteVdbeAddOp(v, OP_MakeRecord, nField, 0, 0, 0);
+    sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0, 0, 0);
     sqliteVdbeAddOp(v, OP_String, iParm, 0, "", 0);
     sqliteVdbeAddOp(v, OP_Put, iParm, 0, 0, 0);
   }else 
@@ -160,7 +160,7 @@ static int selectInnerLoop(
   /* Store the result as data using a unique key.
   */
   if( eDest==SRT_Table ){
-    sqliteVdbeAddOp(v, OP_MakeRecord, nField, 0, 0, 0);
+    sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0, 0, 0);
     sqliteVdbeAddOp(v, OP_New, iParm, 0, 0, 0);
     sqliteVdbeAddOp(v, OP_Pull, 1, 0, 0, 0);
     sqliteVdbeAddOp(v, OP_Put, iParm, 0, 0, 0);
@@ -171,7 +171,7 @@ static int selectInnerLoop(
   ** the temporary table iParm.
   */
   if( eDest==SRT_Except ){
-    sqliteVdbeAddOp(v, OP_MakeRecord, nField, 0, 0, 0);
+    sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0, 0, 0);
     sqliteVdbeAddOp(v, OP_Delete, iParm, 0, 0, 0);
   }else 
 
@@ -180,7 +180,7 @@ static int selectInnerLoop(
   ** item into the set table with bogus data.
   */
   if( eDest==SRT_Set ){
-    assert( nField==1 );
+    assert( nColumn==1 );
     sqliteVdbeAddOp(v, OP_String, 0, 0, "", 0);
     sqliteVdbeAddOp(v, OP_Put, iParm, 0, 0, 0);
   }else 
@@ -191,7 +191,7 @@ static int selectInnerLoop(
   ** of the scan loop.
   */
   if( eDest==SRT_Mem ){
-    assert( nField==1 );
+    assert( nColumn==1 );
     sqliteVdbeAddOp(v, OP_MemStore, iParm, 0, 0, 0);
     sqliteVdbeAddOp(v, OP_Goto, 0, iBreak, 0, 0);
   }else
@@ -199,7 +199,7 @@ static int selectInnerLoop(
   /* If none of the above, send the data to the callback function.
   */
   {
-    sqliteVdbeAddOp(v, OP_Callback, nField, 0, 0, 0);
+    sqliteVdbeAddOp(v, OP_Callback, nColumn, 0, 0, 0);
   }
   return 0;
 }
@@ -210,12 +210,12 @@ static int selectInnerLoop(
 ** we need to run the sorter and output the results.  The following
 ** routine generates the code needed to do that.
 */
-static void generateSortTail(Vdbe *v, int nField){
+static void generateSortTail(Vdbe *v, int nColumn){
   int end = sqliteVdbeMakeLabel(v);
   int addr;
   sqliteVdbeAddOp(v, OP_Sort, 0, 0, 0, 0);
   addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end, 0, 0);
-  sqliteVdbeAddOp(v, OP_SortCallback, nField, 0, 0, 0);
+  sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0, 0, 0);
   sqliteVdbeAddOp(v, OP_Goto, 0, addr, 0, 0);
   sqliteVdbeAddOp(v, OP_SortClose, 0, 0, 0, end);
 }
@@ -240,7 +240,7 @@ void generateColumnNames(Parse *pParse, IdList *pTabList, ExprList *pEList){
       continue;
     }
     p = pEList->a[i].pExpr;
-    if( p->op!=TK_FIELD || pTabList==0 ){
+    if( p->op!=TK_COLUMN || pTabList==0 ){
       char zName[30];
       sprintf(zName, "column%d", i+1);
       sqliteVdbeAddOp(v, OP_ColumnName, i, 0, zName, 0);
@@ -252,12 +252,12 @@ void generateColumnNames(Parse *pParse, IdList *pTabList, ExprList *pEList){
  
         zTab = pTabList->a[p->iTable].zAlias;
         if( zTab==0 ) zTab = pTab->zName;
-        sqliteSetString(&zName, zTab, ".", pTab->aCol[p->iField].zName, 0);
+        sqliteSetString(&zName, zTab, ".", pTab->aCol[p->iColumn].zName, 0);
         sqliteVdbeAddOp(v, OP_ColumnName, i, 0, zName, 0);
         sqliteFree(zName);
       }else{
         Table *pTab = pTabList->a[0].pTab;
-        char *zName = pTab->aCol[p->iField].zName;
+        char *zName = pTab->aCol[p->iColumn].zName;
         sqliteVdbeAddOp(v, OP_ColumnName, i, 0, zName, 0);
       }
     }
@@ -281,8 +281,8 @@ static const char *selectOpName(int id){
 /*
 ** For the given SELECT statement, do two things.
 **
-**    (1)  Fill in the pTab fields of the IdList that defines the set
-**         of tables we are scanning.
+**    (1)  Fill in the pTabList->a[].pTab fields in the IdList that 
+**         defines the set of tables that should be scanned.
 **
 **    (2)  If the columns to be extracted variable (pEList) is NULL
 **         (meaning that a "*" was used in the SQL statement) then
@@ -338,7 +338,7 @@ static int fillInColumnList(Parse *pParse, Select *p){
 /*
 ** This routine associates entries in an ORDER BY expression list with
 ** columns in a result.  For each ORDER BY expression, the opcode of
-** the top-level node is changed to TK_FIELD and the iField value of
+** the top-level node is changed to TK_COLUMN and the iColumn value of
 ** the top-level node is filled in with column number and the iTable
 ** value of the top-level node is filled with iTable parameter.
 **
@@ -390,8 +390,8 @@ static int matchOrderbyToColumn(
         match = 1;
       }
       if( match ){
-        pE->op = TK_FIELD;
-        pE->iField = j;
+        pE->op = TK_COLUMN;
+        pE->iColumn = j;
         pE->iTable = iTable;
         pOrderBy->a[i].done = 1;
         break;
@@ -630,7 +630,7 @@ int sqliteSelect(
   WhereInfo *pWInfo;
   Vdbe *v;
   int isAgg = 0;         /* True for select lists like "count(*)" */
-  ExprList *pEList;      /* List of fields to extract.  NULL means "*" */
+  ExprList *pEList;      /* List of columns to extract.  NULL means "*" */
   IdList *pTabList;      /* List of tables to select from */
   Expr *pWhere;          /* The WHERE clause.  May be NULL */
   ExprList *pOrderBy;    /* The ORDER BY clause.  May be NULL */
@@ -669,7 +669,7 @@ int sqliteSelect(
 
   /* Look up every table in the table list and create an appropriate
   ** columnlist in pEList if there isn't one already.  (The parser leaves
-  ** a NULL in the pEList field if the SQL said "SELECT * FROM ...")
+  ** a NULL in the p->pEList if the SQL said "SELECT * FROM ...")
   */
   if( fillInColumnList(pParse, p) ){
     return 1;
@@ -724,7 +724,7 @@ int sqliteSelect(
   ** need to handle subquerys and temporary tables.  From here on we
   ** are committed to keeping the same value for pParse->nTab.
   **
-  ** Resolve the field names and do a semantics check on all the expressions.
+  ** Resolve the column names and do a semantics check on all the expressions.
   */
   for(i=0; i<pEList->nExpr; i++){
     if( sqliteExprResolveIds(pParse, pTabList, pEList->a[i].pExpr) ){
@@ -906,7 +906,7 @@ int sqliteSelect(
       assert( pE->pList!=0 && pE->pList->nExpr==1 );
       sqliteExprCode(pParse, pE->pList->a[0].pExpr);
       sqliteVdbeAddOp(v, OP_AggGet, 0, i, 0, 0);
-      switch( pE->iField ){
+      switch( pE->iColumn ){
         case FN_Min:  op = OP_Min;   break;
         case FN_Max:  op = OP_Max;   break;
         case FN_Avg:  op = OP_Add;   break;
index e3bf5e96458821109ba3b54d3d108fd8eebb2150..b34557dd3b8036e3810b3ced66835ae6218730d3 100644 (file)
@@ -24,7 +24,7 @@
 ** This file contains code to implement the "sqlite" command line
 ** utility for accessing SQLite databases.
 **
-** $Id: shell.c,v 1.14 2000/06/15 16:49:49 drh Exp $
+** $Id: shell.c,v 1.15 2000/06/21 13:59:12 drh Exp $
 */
 #include <stdlib.h>
 #include <string.h>
@@ -136,7 +136,7 @@ struct callback_data {
 /*
 ** These are the allowed modes.
 */
-#define MODE_Line     0  /* One field per line.  Blank line between records */
+#define MODE_Line     0  /* One column per line.  Blank line between records */
 #define MODE_Column   1  /* One record per line in neat columns */
 #define MODE_List     2  /* One record per line with a separator */
 #define MODE_Html     3  /* Generate an XHTML table */
index d4069eac8623adb1a0fb4ee80a7cff860312c5b9..9eef275306b09ffbaea855056ba2ec3fa55a041f 100644 (file)
@@ -23,7 +23,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.24 2000/06/11 23:50:13 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.25 2000/06/21 13:59:12 drh Exp $
 */
 #include "sqlite.h"
 #include "dbbe.h"
 #include <string.h>
 #include <assert.h>
 
-/* #define MEMORY_DEBUG 1 */
+/*
+** If memory allocation problems are found, recompile with
+**
+**      -DMEMORY_DEBUG=1
+**
+** to enable some sanity checking on malloc() and free().  To
+** check for memory leaks, recompile with
+**
+**      -DMEMORY_DEBUG=2
+**
+** and a line of text will be written to standard error for
+** each malloc() and free().  This output can be analyzed
+** by an AWK script to determine if there are any leaks.
+*/
 #ifdef MEMORY_DEBUG
 # define sqliteMalloc(X)    sqliteMalloc_(X,__FILE__,__LINE__)
 # define sqliteFree(X)      sqliteFree_(X,__FILE__,__LINE__)
@@ -58,8 +71,8 @@ int sqlite_iMallocFail;     /* Fail sqliteMalloc() after this many calls */
 #endif
 
 /*
-** The number of entries in the in-memory hash table holding the
-** schema.
+** The number of entries in the in-memory hash array holding the
+** database schema.
 */
 #define N_HASH        51
 
@@ -77,7 +90,7 @@ int sqlite_iMallocFail;     /* Fail sqliteMalloc() after this many calls */
 #define ArraySize(X)    (sizeof(X)/sizeof(X[0]))
 
 /*
-** Integer identifiers for functions.
+** Integer identifiers for built-in SQL functions.
 */
 #define FN_Unknown    0
 #define FN_Count      1
@@ -114,46 +127,61 @@ struct sqlite {
 };
 
 /*
-** Possible values for the flags field of sqlite
+** Possible values for the sqlite.flags.
 */
 #define SQLITE_VdbeTrace    0x00000001
 #define SQLITE_Initialized  0x00000002
 
 /*
-** information about each column of a table is held in an instance
+** information about each column of an SQL table is held in an instance
 ** of this structure.
 */
 struct Column {
-  char *zName;        /* Name of this column */
-  char *zDflt;        /* Default value of this column */
-  int notNull;        /* True if there is a NOT NULL constraing */
+  char *zName;     /* Name of this column */
+  char *zDflt;     /* Default value of this column */
+  int notNull;     /* True if there is a NOT NULL constraint */
 };
 
 /*
-** Each table is represented in memory by
-** an instance of the following structure
+** Each SQL table is represented in memory by
+** an instance of the following structure.
 */
 struct Table {
-  char *zName;        /* Name of the table */
-  Table *pHash;       /* Next table with same hash on zName */
-  int nCol;           /* Number of columns in this table */
-  Column *aCol;       /* Information about each column */
-  int readOnly;       /* True if this table should not be written by the user */
-  Index *pIndex;      /* List of indices on this table. */
+  char *zName;     /* Name of the table */
+  Table *pHash;    /* Next table with same hash on zName */
+  int nCol;        /* Number of columns in this table */
+  Column *aCol;    /* Information about each column */
+  int readOnly;    /* True if this table should not be written by the user */
+  Index *pIndex;   /* List of SQL indexes on this table. */
 };
 
 /*
-** Each index is represented in memory by and
+** Each SQL index is represented in memory by and
 ** instance of the following structure.
+**
+** The columns of the table that are to be indexed are described
+** by the aiColumn[] field of this structure.  For example, suppose
+** we have the following table and index:
+**
+**     CREATE TABLE Ex1(c1 int, c2 int, c3 text);
+**     CREATE INDEX Ex2 ON Ex1(c3,c1);
+**
+** In the Table structure describing Ex1, nCol==3 because there are
+** three columns in the table.  In the Index structure describing
+** Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed.
+** The value of aiColumn is {2, 0}.  aiColumn[0]==2 because the 
+** first column to be indexed (c3) has an index of 2 in Ex1.aCol[].
+** The second column to be indexed (c1) has an index of 0 in
+** Ex1.aCol[], hence Ex2.aiColumn[1]==0.
 */
 struct Index {
-  char *zName;        /* Name of this index */
-  Index *pHash;       /* Next index with the same hash on zName */
-  int nField;         /* Number of fields in the table indexed by this index */
-  int *aiField;       /* Indices of fields used by this index.  1st is 0 */
-  Table *pTable;      /* The table being indexed */
-  int isUnique;       /* True if keys must all be unique */
-  Index *pNext;       /* The next index associated with the same table */
+  char *zName;     /* Name of this index */
+  Index *pHash;    /* Next index with the same hash on zName */
+  int nColumn;     /* Number of columns in the table used by this index */
+  int *aiColumn;   /* Which columns are used by this index.  1st is 0 */
+  Table *pTable;   /* The SQL table being indexed */
+  int isUnique;    /* True if keys must all be unique */
+  Index *pNext;    /* The next index associated with the same table */
 };
 
 /*
@@ -174,11 +202,11 @@ struct Expr {
   Expr *pLeft, *pRight;  /* Left and right subnodes */
   ExprList *pList;       /* A list of expressions used as a function argument */
   Token token;           /* An operand token */
-  int iTable, iField;    /* When op==TK_FIELD, then this node means the
-                         ** iField-th field of the iTable-th table.  When
-                         ** op==TK_FUNCTION, iField holds the function id */
-  int iAgg;              /* When op==TK_FIELD and pParse->useAgg==TRUE, pull
-                         ** value from these element of the aggregator */
+  int iTable, iColumn;   /* When op==TK_COLUMN, then this expr node means the
+                         ** iColumn-th field of the iTable-th table.  When
+                         ** op==TK_FUNCTION, iColumn holds the function id */
+  int iAgg;              /* When op==TK_COLUMN and pParse->useAgg==TRUE, pull
+                         ** result from the iAgg-th element of the aggregator */
   Select *pSelect;       /* When the expression is a sub-select */
 };
 
@@ -209,8 +237,8 @@ struct IdList {
   struct {
     char *zName;      /* Text of the identifier. */
     char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
-    Table *pTab;      /* Table corresponding to zName */
-    int idx;          /* Index of a field named zName in a table */
+    Table *pTab;      /* An SQL table corresponding to zName */
+    int idx;          /* Index in some Table.aCol[] of a column named zName */
   } *a;            /* One entry for each identifier on the list */
 };
 
@@ -243,7 +271,7 @@ struct Select {
   Expr *pHaving;         /* The HAVING clause */
   ExprList *pOrderBy;    /* The ORDER BY clause */
   int op;                /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
-  Select *pPrior;        /* Prior select to which this one joins */
+  Select *pPrior;        /* Prior select in a compound select statement */
 };
 
 /*
index 982d125893558e616e383cc56af735171417671c..6902a94e3cc163e041852c76060cbeffae97d0c1 100644 (file)
@@ -24,7 +24,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle UPDATE statements.
 **
-** $Id: update.c,v 1.7 2000/06/19 19:09:09 drh Exp $
+** $Id: update.c,v 1.8 2000/06/21 13:59:12 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -48,8 +48,8 @@ void sqliteUpdate(
   int base;              /* Index of first available table cursor */
   Index **apIdx = 0;     /* An array of indices that need updating too */
   int *aXRef = 0;        /* aXRef[i] is the index in pChanges->a[] of the
-                         ** an expression for the i-th field of the table.
-                         ** aXRef[i]==-1 if the i-th field is not changed. */
+                         ** an expression for the i-th column of the table.
+                         ** aXRef[i]==-1 if the i-th column is not changed. */
 
   /* Locate the table which we want to update.  This table has to be
   ** put in an IdList structure because some of the subroutines we
@@ -77,9 +77,9 @@ void sqliteUpdate(
   if( aXRef==0 ) goto update_cleanup;
   for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
 
-  /* Resolve the field names in all the expressions in both the
-  ** WHERE clause and in the new values.  Also find the field index
-  ** for each field to be updated in the pChanges array.
+  /* Resolve the column names in all the expressions in both the
+  ** WHERE clause and in the new values.  Also find the column index
+  ** for each column to be updated in the pChanges array.
   */
   if( pWhere ){
     sqliteExprResolveInSelect(pParse, pWhere);
@@ -109,7 +109,7 @@ void sqliteUpdate(
       }
     }
     if( j>=pTab->nCol ){
-      sqliteSetString(&pParse->zErrMsg, "no such field: ", 
+      sqliteSetString(&pParse->zErrMsg, "no such column: ", 
          pChanges->a[i].zName, 0);
       pParse->nErr++;
       goto update_cleanup;
@@ -118,21 +118,21 @@ void sqliteUpdate(
 
   /* Allocate memory for the array apIdx[] and fill it pointers to every
   ** index that needs to be updated.  Indices only need updating if their
-  ** key includes one of the fields named in pChanges.
+  ** key includes one of the columns named in pChanges.
   */
   for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
-    for(i=0; i<pIdx->nField; i++){
-      if( aXRef[pIdx->aiField[i]]>=0 ) break;
+    for(i=0; i<pIdx->nColumn; i++){
+      if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
     }
-    if( i<pIdx->nField ) nIdx++;
+    if( i<pIdx->nColumn ) nIdx++;
   }
   apIdx = sqliteMalloc( sizeof(Index*) * nIdx );
   if( apIdx==0 ) goto update_cleanup;
   for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
-    for(i=0; i<pIdx->nField; i++){
-      if( aXRef[pIdx->aiField[i]]>=0 ) break;
+    for(i=0; i<pIdx->nColumn; i++){
+      if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
     }
-    if( i<pIdx->nField ) apIdx[nIdx++] = pIdx;
+    if( i<pIdx->nColumn ) apIdx[nIdx++] = pIdx;
   }
 
   /* Begin generating code.
@@ -165,7 +165,7 @@ void sqliteUpdate(
   }
 
   /* Loop over every record that needs updating.  We have to load
-  ** the old data for each record to be updated because some fields
+  ** the old data for each record to be updated because some columns
   ** might not change and we will need to copy the old value.
   ** Also, the old data is needed to delete the old index entires.
   */
@@ -179,10 +179,10 @@ void sqliteUpdate(
   for(i=0; i<nIdx; i++){
     sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
     pIdx = apIdx[i];
-    for(j=0; j<pIdx->nField; j++){
-      sqliteVdbeAddOp(v, OP_Field, base, pIdx->aiField[j], 0, 0);
+    for(j=0; j<pIdx->nColumn; j++){
+      sqliteVdbeAddOp(v, OP_Field, base, pIdx->aiColumn[j], 0, 0);
     }
-    sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nField, 0, 0, 0);
+    sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nColumn, 0, 0, 0);
     sqliteVdbeAddOp(v, OP_DeleteIdx, base+i+1, 0, 0, 0);
   }
 
@@ -202,10 +202,10 @@ void sqliteUpdate(
   for(i=0; i<nIdx; i++){
     sqliteVdbeAddOp(v, OP_Dup, pTab->nCol, 0, 0, 0); /* The KEY */
     pIdx = apIdx[i];
-    for(j=0; j<pIdx->nField; j++){
-      sqliteVdbeAddOp(v, OP_Dup, j+pTab->nCol-pIdx->aiField[j], 0, 0, 0);
+    for(j=0; j<pIdx->nColumn; j++){
+      sqliteVdbeAddOp(v, OP_Dup, j+pTab->nCol-pIdx->aiColumn[j], 0, 0, 0);
     }
-    sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nField, 0, 0, 0);
+    sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nColumn, 0, 0, 0);
     sqliteVdbeAddOp(v, OP_PutIdx, base+i+1, 0, 0, 0);
   }
 
index 5d53beb98da1d2ccb72880fc047a7b6dcae8241a..0d96bcdd5dc8c4062e29bb0d2ff8ecc940a5c685 100644 (file)
@@ -26,7 +26,7 @@
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
-** $Id: util.c,v 1.12 2000/06/08 13:36:41 drh Exp $
+** $Id: util.c,v 1.13 2000/06/21 13:59:12 drh Exp $
 */
 #include "sqliteInt.h"
 #include <stdarg.h>
@@ -360,7 +360,7 @@ int sqliteHashNoCase(const char *z, int n){
 }
 
 /*
-** Some system shave stricmp().  Others have strcasecmp().  Because
+** Some systemhave stricmp().  Others have strcasecmp().  Because
 ** there is no consistency, we will define our own.
 */
 int sqliteStrICmp(const char *zLeft, const char *zRight){
index 6dc03010ccf8db712bc73c1cc4d0dad38857f42a..eb2b821e6b89def30b8564d75ba7561a4ae66bcd 100644 (file)
@@ -41,7 +41,7 @@
 ** But other routines are also provided to help in building up
 ** a program instruction by instruction.
 **
-** $Id: vdbe.c,v 1.33 2000/06/11 23:50:13 drh Exp $
+** $Id: vdbe.c,v 1.34 2000/06/21 13:59:13 drh Exp $
 */
 #include "sqliteInt.h"
 #include <unistd.h>
 typedef struct VdbeOp Op;
 
 /*
-** Every table that the virtual machine has open is represented by an
+** A cursor is a pointer into a database file.  The database file
+** can represent either an SQL table or an SQL index.  Each file is
+** a bag of key/data pairs.  The cursor can loop over all key/data
+** pairs (in an arbitrary order) or it can retrieve a particular
+** key/data pair given a copy of the key.
+** 
+** Every cursor that the virtual machine has open is represented by an
 ** instance of the following structure.
 */
-struct VdbeTable {
-  DbbeTable *pTable;    /* The table structure of the backend */
+struct Cursor {
+  DbbeCursor *pCursor;  /* The cursor structure of the backend */
   int index;            /* The next index to extract */
   int keyAsData;        /* The OP_Field command works on key instead of data */
 };
-typedef struct VdbeTable VdbeTable;
+typedef struct Cursor Cursor;
 
 /*
 ** A sorter builds a list of elements to be sorted.  Each element of
@@ -117,7 +123,7 @@ typedef struct Mem Mem;
 #define STK_Dyn       0x0010   /* Need to call sqliteFree() on zStack[*] */
 
 /*
-** An Agg structure describes and Aggregator.  Each Agg consists of
+** An Agg structure describes an Aggregator.  Each Agg consists of
 ** zero or more Aggregator elements (AggElem).  Each AggElem contains
 ** a key and one or more values.  The values are used in processing
 ** aggregate functions in a SELECT.  The key is used to implement
@@ -130,7 +136,7 @@ struct Agg {
   AggElem *pCurrent;     /* The AggElem currently in focus */
   int nElem;             /* The number of AggElems */
   int nHash;             /* Number of slots in apHash[] */
-  AggElem **apHash;      /* A hash table for looking up AggElems by zKey */
+  AggElem **apHash;      /* A hash array for looking up AggElems by zKey */
   AggElem *pFirst;       /* A list of all AggElems */
 };
 struct AggElem {
@@ -150,7 +156,7 @@ typedef struct Set Set;
 typedef struct SetElem SetElem;
 struct Set {
   SetElem *pAll;         /* All elements of this set */
-  SetElem *apHash[41];   /* A hash table for all elements in this set */
+  SetElem *apHash[41];   /* A hash array for all elements in this set */
 };
 struct SetElem {
   SetElem *pHash;        /* Next element with the same hash on zKey */
@@ -175,8 +181,8 @@ struct Vdbe {
   Stack *aStack;      /* The operand stack, except string values */
   char **zStack;      /* Text or binary values of the stack */
   char **azColName;   /* Becomes the 4th parameter to callbacks */
-  int nTable;         /* Number of slots in aTab[] */
-  VdbeTable *aTab;    /* On element of this array for each open table */
+  int nCursor;        /* Number of slots in aCsr[] */
+  Cursor *aCsr;       /* On element of this array for each open cursor */
   int nList;          /* Number of slots in apList[] */
   FILE **apList;      /* An open file for each list */
   int nSort;          /* Number of slots in apSort[] */
@@ -394,7 +400,7 @@ static void AggReset(Agg *p){
 }
 
 /*
-** Add the given AggElem to the hash table
+** Add the given AggElem to the hash array
 */
 static void AggEnhash(Agg *p, AggElem *pElem){
   int h = sqliteHashNoCase(pElem->zKey, 0) % p->nHash;
@@ -403,7 +409,7 @@ static void AggEnhash(Agg *p, AggElem *pElem){
 }
 
 /*
-** Change the size of the hash table to the amount given.
+** Change the size of the hash array to the amount given.
 */
 static void AggRehash(Agg *p, int nHash){
   int size;
@@ -634,7 +640,7 @@ static int hardNeedStack(Vdbe *p, int N){
 /*
 ** Clean up the VM after execution.
 **
-** This routine will automatically close any tables, list, and/or
+** This routine will automatically close any cursors, list, and/or
 ** sorters that were left open.
 */
 static void Cleanup(Vdbe *p){
@@ -642,15 +648,15 @@ static void Cleanup(Vdbe *p){
   PopStack(p, p->tos+1);
   sqliteFree(p->azColName);
   p->azColName = 0;
-  for(i=0; i<p->nTable; i++){
-    if( p->aTab[i].pTable ){
-      sqliteDbbeCloseTable(p->aTab[i].pTable);
-      p->aTab[i].pTable = 0;
+  for(i=0; i<p->nCursor; i++){
+    if( p->aCsr[i].pCursor ){
+      sqliteDbbeCloseCursor(p->aCsr[i].pCursor);
+      p->aCsr[i].pCursor = 0;
     }
   }
-  sqliteFree(p->aTab);
-  p->aTab = 0;
-  p->nTable = 0;
+  sqliteFree(p->aCsr);
+  p->aCsr = 0;
+  p->nCursor = 0;
   for(i=0; i<p->nMem; i++){
     if( p->aMem[i].s.flags & STK_Dyn ){
       sqliteFree(p->aMem[i].z);
@@ -786,7 +792,7 @@ int sqliteVdbeList(
   char **pzErrMsg            /* Error msg written here */
 ){
   int i, rc;
-  char *azField[6];
+  char *azValue[6];
   char zAddr[20];
   char zP1[20];
   char zP2[20];
@@ -795,19 +801,19 @@ int sqliteVdbeList(
   };
 
   if( xCallback==0 ) return 0;
-  azField[0] = zAddr;
-  azField[2] = zP1;
-  azField[3] = zP2;
-  azField[5] = 0;
+  azValue[0] = zAddr;
+  azValue[2] = zP1;
+  azValue[3] = zP2;
+  azValue[5] = 0;
   rc = SQLITE_OK;
   /* if( pzErrMsg ){ *pzErrMsg = 0; } */
   for(i=0; rc==SQLITE_OK && i<p->nOp; i++){
     sprintf(zAddr,"%d",i);
     sprintf(zP1,"%d", p->aOp[i].p1);
     sprintf(zP2,"%d", p->aOp[i].p2);
-    azField[4] = p->aOp[i].p3;
-    azField[1] = zOpName[p->aOp[i].opcode];
-    if( xCallback(pArg, 5, azField, azColumnNames) ){
+    azValue[4] = p->aOp[i].p3;
+    azValue[1] = zOpName[p->aOp[i].opcode];
+    if( xCallback(pArg, 5, azValue, azColumnNames) ){
       rc = SQLITE_ABORT;
     }
   }
@@ -1492,7 +1498,7 @@ int sqliteVdbeExec(
 
       /* Opcode: Not * * *
       **
-      ** Treat the top of the stack as a boolean value.  Replace it
+      ** Interpret the top of the stack as a boolean value.  Replace it
       ** with its complement.
       */
       case OP_Not: {
@@ -1676,33 +1682,34 @@ int sqliteVdbeExec(
 
       /* Opcode: Open P1 P2 P3
       **
-      ** Open a new cursor for the database table named P3.  Give the
-      ** cursor an identifier P1.
-      ** Open readonly if P2==0 and for reading and writing if P2!=0.
-      ** The table is created if it does not already exist and P2!=0.
-      ** If there is already another cursor opened with identifier P1,
-      ** then the old cursor is closed first.
-      ** All cursors are automatically closed when
-      ** the VDBE finishes execution.  The P1 values need not be
+      ** Open a new cursor for the database file named P3.  Give the
+      ** cursor an identifier P1.  The P1 values need not be
       ** contiguous but all P1 values should be small integers.  It is
       ** an error for P1 to be negative.
       **
-      ** If P3 is null or an empty string, a temporary table created.
-      ** This table is automatically deleted when the cursor is closed.
+      ** Open readonly if P2==0 and for reading and writing if P2!=0.
+      ** The file is created if it does not already exist and P2!=0.
+      ** If there is already another cursor opened with identifier P1,
+      ** then the old cursor is closed first.  All cursors are
+      ** automatically closed when the VDBE finishes execution.
+      **
+      ** If P3 is null or an empty string, a temporary database file
+      ** is created.  This temporary database file is automatically 
+      ** deleted when the cursor is closed.
       */
       case OP_Open: {
         int i = pOp->p1;
         if( i<0 ) goto bad_instruction;
-        if( i>=p->nTable ){
+        if( i>=p->nCursor ){
           int j;
-          p->aTab = sqliteRealloc( p->aTab, (i+1)*sizeof(VdbeTable) );
-          if( p->aTab==0 ){ p->nTable = 0; goto no_mem; }
-          for(j=p->nTable; j<=i; j++) p->aTab[j].pTable = 0;
-          p->nTable = i+1;
-        }else if( p->aTab[i].pTable ){
-          sqliteDbbeCloseTable(p->aTab[i].pTable);
-        }
-        rc = sqliteDbbeOpenTable(p->pBe, pOp->p3, pOp->p2, &p->aTab[i].pTable);
+          p->aCsr = sqliteRealloc( p->aCsr, (i+1)*sizeof(Cursor) );
+          if( p->aCsr==0 ){ p->nCursor = 0; goto no_mem; }
+          for(j=p->nCursor; j<=i; j++) p->aCsr[j].pCursor = 0;
+          p->nCursor = i+1;
+        }else if( p->aCsr[i].pCursor ){
+          sqliteDbbeCloseCursor(p->aCsr[i].pCursor);
+        }
+        rc = sqliteDbbeOpenCursor(p->pBe, pOp->p3, pOp->p2,&p->aCsr[i].pCursor);
         switch( rc ){
           case SQLITE_BUSY: {
             sqliteSetString(pzErrMsg,"table ", pOp->p3, " is locked", 0);
@@ -1722,21 +1729,21 @@ int sqliteVdbeExec(
             goto no_mem;
           }
         }
-        p->aTab[i].index = 0;
-        p->aTab[i].keyAsData = 0;
+        p->aCsr[i].index = 0;
+        p->aCsr[i].keyAsData = 0;
         break;
       }
 
       /* Opcode: Close P1 * *
       **
-      ** Close a database table previously opened as P1.  If P1 is not
+      ** Close a cursor previously opened as P1.  If P1 is not
       ** currently open, this instruction is a no-op.
       */
       case OP_Close: {
         int i = pOp->p1;
-        if( i>=0 && i<p->nTable && p->aTab[i].pTable ){
-          sqliteDbbeCloseTable(p->aTab[i].pTable);
-          p->aTab[i].pTable = 0;
+        if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor ){
+          sqliteDbbeCloseCursor(p->aCsr[i].pCursor);
+          p->aCsr[i].pCursor = 0;
         }
         break;
       }
@@ -1744,21 +1751,20 @@ int sqliteVdbeExec(
       /* Opcode: Fetch P1 * *
       **
       ** Pop the top of the stack and use its value as a key to fetch
-      ** a record from database table or index P1.  The data is held
-      ** in the P1 cursor until needed.  The data is not pushed onto the
-      ** stack.
+      ** a record from cursor P1.  The key/data pair is held
+      ** in the P1 cursor until needed.
       */
       case OP_Fetch: {
         int i = pOp->p1;
         int tos = p->tos;
         if( tos<0 ) goto not_enough_stack;
-        if( i>=0 && i<p->nTable && p->aTab[i].pTable ){
+        if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor ){
           if( p->aStack[tos].flags & STK_Int ){
-            sqliteDbbeFetch(p->aTab[i].pTable, sizeof(int), 
+            sqliteDbbeFetch(p->aCsr[i].pCursor, sizeof(int), 
                            (char*)&p->aStack[tos].i);
           }else{
             if( Stringify(p, tos) ) goto no_mem;
-            sqliteDbbeFetch(p->aTab[i].pTable, p->aStack[tos].n, 
+            sqliteDbbeFetch(p->aCsr[i].pCursor, p->aStack[tos].n, 
                            p->zStack[tos]);
           }
           p->nFetch++;
@@ -1787,7 +1793,7 @@ int sqliteVdbeExec(
       /* Opcode: Distinct P1 P2 *
       **
       ** Use the top of the stack as a key.  If a record with that key
-      ** does not exist in table P1, then jump to P2.  If the record
+      ** does not exist in file P1, then jump to P2.  If the record
       ** does already exist, then fall thru.  The record is not retrieved.
       ** The key is not popped from the stack.
       **
@@ -1797,14 +1803,14 @@ int sqliteVdbeExec(
       /* Opcode: Found P1 P2 *
       **
       ** Use the top of the stack as a key.  If a record with that key
-      ** does exist in table P1, then jump to P2.  If the record
+      ** does exist in file P1, then jump to P2.  If the record
       ** does not exist, then fall thru.  The record is not retrieved.
       ** The key is popped from the stack.
       */
       /* Opcode: NotFound P1 P2 *
       **
       ** Use the top of the stack as a key.  If a record with that key
-      ** does not exist in table P1, then jump to P2.  If the record
+      ** does not exist in file P1, then jump to P2.  If the record
       ** does exist, then fall thru.  The record is not retrieved.
       ** The key is popped from the stack.
       **
@@ -1818,13 +1824,13 @@ int sqliteVdbeExec(
         int tos = p->tos;
         int alreadyExists = 0;
         if( tos<0 ) goto not_enough_stack;
-        if( i>=0 && i<p->nTable && p->aTab[i].pTable ){
+        if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor ){
           if( p->aStack[tos].flags & STK_Int ){
-            alreadyExists = sqliteDbbeTest(p->aTab[i].pTable, sizeof(int), 
+            alreadyExists = sqliteDbbeTest(p->aCsr[i].pCursor, sizeof(int), 
                                           (char*)&p->aStack[tos].i);
           }else{
             if( Stringify(p, tos) ) goto no_mem;
-            alreadyExists = sqliteDbbeTest(p->aTab[i].pTable, p->aStack[tos].n, 
+            alreadyExists = sqliteDbbeTest(p->aCsr[i].pCursor,p->aStack[tos].n, 
                                            p->zStack[tos]);
           }
         }
@@ -1841,16 +1847,16 @@ int sqliteVdbeExec(
 
       /* Opcode: New P1 * *
       **
-      ** Get a new integer key not previous used by table P1 and
-      ** push it onto the stack.
+      ** Get a new integer key not previous used by the database file
+      ** associated with cursor P1 and push it onto the stack.
       */
       case OP_New: {
         int i = pOp->p1;
         int v;
-        if( i<0 || i>=p->nTable || p->aTab[i].pTable==0 ){
+        if( i<0 || i>=p->nCursor || p->aCsr[i].pCursor==0 ){
           v = 0;
         }else{
-          v = sqliteDbbeNew(p->aTab[i].pTable);
+          v = sqliteDbbeNew(p->aCsr[i].pCursor);
         }
         NeedStack(p, p->tos+1);
         p->tos++;
@@ -1861,7 +1867,7 @@ int sqliteVdbeExec(
 
       /* Opcode: Put P1 * *
       **
-      ** Write an entry into the database table P1.  A new entry is
+      ** Write an entry into the database file P1.  A new entry is
       ** created if it doesn't already exist, or the data for an existing
       ** entry is overwritten.  The data is the value on the top of the
       ** stack.  The key is the next value down on the stack.  The stack
@@ -1872,7 +1878,7 @@ int sqliteVdbeExec(
         int nos = p->tos-1;
         int i = pOp->p1;
         if( nos<0 ) goto not_enough_stack;
-        if( i>=0 && i<p->nTable && p->aTab[i].pTable!=0 ){
+        if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor!=0 ){
           char *zKey;
           int nKey;
           if( (p->aStack[nos].flags & STK_Int)==0 ){
@@ -1883,7 +1889,7 @@ int sqliteVdbeExec(
             nKey = sizeof(int);
             zKey = (char*)&p->aStack[nos].i;
           }
-          sqliteDbbePut(p->aTab[i].pTable, nKey, zKey,
+          sqliteDbbePut(p->aCsr[i].pCursor, nKey, zKey,
                         p->aStack[tos].n, p->zStack[tos]);
         }
         PopStack(p, 2);
@@ -1893,13 +1899,13 @@ int sqliteVdbeExec(
       /* Opcode: Delete P1 * *
       **
       ** The top of the stack is a key.  Remove this key and its data
-      ** from database table P1.  Then pop the stack to discard the key.
+      ** from database file P1.  Then pop the stack to discard the key.
       */
       case OP_Delete: {
         int tos = p->tos;
         int i = pOp->p1;
         if( tos<0 ) goto not_enough_stack;
-        if( i>=0 && i<p->nTable && p->aTab[i].pTable!=0 ){
+        if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor!=0 ){
           char *zKey;
           int nKey;
           if( p->aStack[tos].flags & STK_Int ){
@@ -1910,7 +1916,7 @@ int sqliteVdbeExec(
             nKey = p->aStack[tos].n;
             zKey = p->zStack[tos];
           }
-          sqliteDbbeDelete(p->aTab[i].pTable, nKey, zKey);
+          sqliteDbbeDelete(p->aCsr[i].pCursor, nKey, zKey);
         }
         PopStack(p, 1);
         break;
@@ -1925,16 +1931,18 @@ int sqliteVdbeExec(
       */
       case OP_KeyAsData: {
         int i = pOp->p1;
-        if( i>=0 && i<p->nTable && p->aTab[i].pTable!=0 ){
-          p->aTab[i].keyAsData = pOp->p2;
+        if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor!=0 ){
+          p->aCsr[i].keyAsData = pOp->p2;
         }
         break;
       }
 
       /* Opcode: Field P1 P2 *
       **
-      ** Push onto the stack the value of the P2-th field from the
-      ** most recent Fetch from table P1.
+      ** Interpret the data in the most recent fetch from cursor P1
+      ** is a structure built using the MakeRecord instruction.
+      ** Push onto the stack the value of the P2-th field of that
+      ** structure.
       ** 
       ** The value pushed is just a pointer to the data in the cursor.
       ** The value will go away the next time a record is fetched from P1,
@@ -1944,6 +1952,11 @@ int sqliteVdbeExec(
       ** If the KeyAsData opcode has previously executed on this cursor,
       ** then the field might be extracted from the key rather than the
       ** data.
+      **
+      ** Viewed from a higher level, this instruction retrieves the
+      ** data from a single column in a particular row of an SQL table
+      ** file.  Perhaps the name of this instruction should be
+      ** "Column" instead of "Field"...
       */
       case OP_Field: {
         int *pAddr;
@@ -1951,35 +1964,35 @@ int sqliteVdbeExec(
         int i = pOp->p1;
         int p2 = pOp->p2;
         int tos = ++p->tos;
-        DbbeTable *pTab;
+        DbbeCursor *pCrsr;
         char *z;
 
         if( NeedStack(p, tos) ) goto no_mem;
-        if( i>=0 && i<p->nTable && (pTab = p->aTab[i].pTable)!=0 ){
-          if( p->aTab[i].keyAsData ){
-            amt = sqliteDbbeKeyLength(pTab);
+        if( i>=0 && i<p->nCursor && (pCrsr = p->aCsr[i].pCursor)!=0 ){
+          if( p->aCsr[i].keyAsData ){
+            amt = sqliteDbbeKeyLength(pCrsr);
             if( amt<=sizeof(int)*(p2+1) ){
               p->aStack[tos].flags = STK_Null;
               break;
             }
-            pAddr = (int*)sqliteDbbeReadKey(pTab, sizeof(int)*p2);
+            pAddr = (int*)sqliteDbbeReadKey(pCrsr, sizeof(int)*p2);
             if( *pAddr==0 ){
               p->aStack[tos].flags = STK_Null;
               break;
             }
-            z = sqliteDbbeReadKey(pTab, *pAddr);
+            z = sqliteDbbeReadKey(pCrsr, *pAddr);
           }else{
-            amt = sqliteDbbeDataLength(pTab);
+            amt = sqliteDbbeDataLength(pCrsr);
             if( amt<=sizeof(int)*(p2+1) ){
               p->aStack[tos].flags = STK_Null;
               break;
             }
-            pAddr = (int*)sqliteDbbeReadData(pTab, sizeof(int)*p2);
+            pAddr = (int*)sqliteDbbeReadData(pCrsr, sizeof(int)*p2);
             if( *pAddr==0 ){
               p->aStack[tos].flags = STK_Null;
               break;
             }
-            z = sqliteDbbeReadData(pTab, *pAddr);
+            z = sqliteDbbeReadData(pCrsr, *pAddr);
           }
           p->zStack[tos] = z;
           p->aStack[tos].n = strlen(z) + 1;
@@ -1991,21 +2004,22 @@ int sqliteVdbeExec(
       /* Opcode: Key P1 * *
       **
       ** Push onto the stack an integer which is the first 4 bytes of the
-      ** the key to the current entry in a sequential scan of the table P1.
-      ** A sequential scan is started using the Next opcode.
+      ** the key to the current entry in a sequential scan of the database
+      ** file P1.  The sequential scan should have been started using the 
+      ** Next opcode.
       */
       case OP_Key: {
         int i = pOp->p1;
         int tos = ++p->tos;
-        DbbeTable *pTab;
+        DbbeCursor *pCrsr;
 
         if( NeedStack(p, p->tos) ) goto no_mem;
-        if( i>=0 && i<p->nTable && (pTab = p->aTab[i].pTable)!=0 ){
-          char *z = sqliteDbbeReadKey(pTab, 0);
-          if( p->aTab[i].keyAsData ){
+        if( i>=0 && i<p->nCursor && (pCrsr = p->aCsr[i].pCursor)!=0 ){
+          char *z = sqliteDbbeReadKey(pCrsr, 0);
+          if( p->aCsr[i].keyAsData ){
             p->zStack[tos] = z;
             p->aStack[tos].flags = STK_Str;
-            p->aStack[tos].n = sqliteDbbeKeyLength(pTab);
+            p->aStack[tos].n = sqliteDbbeKeyLength(pCrsr);
           }else{
             memcpy(&p->aStack[tos].i, z, sizeof(int));
             p->aStack[tos].flags = STK_Int;
@@ -2017,25 +2031,25 @@ int sqliteVdbeExec(
       /* Opcode: Rewind P1 * *
       **
       ** The next use of the Key or Field or Next instruction for P1 
-      ** will refer to the first entry in the table.
+      ** will refer to the first entry in the database file.
       */
       case OP_Rewind: {
         int i = pOp->p1;
-        if( i>=0 && i<p->nTable && p->aTab[i].pTable!=0 ){
-          sqliteDbbeRewind(p->aTab[i].pTable);
+        if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor!=0 ){
+          sqliteDbbeRewind(p->aCsr[i].pCursor);
         }
         break;
       }
 
       /* Opcode: Next P1 P2 *
       **
-      ** Advance P1 to the next entry in the table.  Or, if there are no
-      ** more entries, rewind P1 and jump to location P2.
+      ** Advance P1 to the next key/data pair in the file.  Or, if there are no
+      ** more key/data pairs, rewind P1 and jump to location P2.
       */
       case OP_Next: {
         int i = pOp->p1;
-        if( i>=0 && i<p->nTable && p->aTab[i].pTable!=0 ){
-          if( sqliteDbbeNextKey(p->aTab[i].pTable)==0 ){
+        if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor!=0 ){
+          if( sqliteDbbeNextKey(p->aCsr[i].pCursor)==0 ){
             pc = pOp->p2 - 1;
           }else{
             p->nFetch++;
@@ -2046,37 +2060,48 @@ int sqliteVdbeExec(
 
       /* Opcode: ResetIdx P1 * *
       **
-      ** Begin treating the current row of table P1 as an index.  The next
-      ** NextIdx instruction will refer to the first index in the table.
+      ** Begin treating the current data in cursor P1 as a bunch of integer
+      ** keys to records of a (separate) SQL table file.  This instruction
+      ** causes the new NextIdx instruction push the first integer table
+      ** key in the data.
       */
       case OP_ResetIdx: {
         int i = pOp->p1;
-        if( i>=0 && i<p->nTable ){
-          p->aTab[i].index = 0;
+        if( i>=0 && i<p->nCursor ){
+          p->aCsr[i].index = 0;
         }
         break;
       }
 
       /* Opcode: NextIdx P1 P2 *
       **
-      ** Push the next index from the current entry of table P1 onto the
-      ** stack and advance the pointer.  If there are no more indices, then
-      ** reset the table entry and jump to P2
+      ** The P1 cursor points to an SQL index.  The data from the most
+      ** recent fetch on that cursor consists of a bunch of integers where
+      ** each integer is the key to a record in an SQL table file.
+      ** This instruction grabs the next integer table key from the data
+      ** of P1 and pushes that integer onto the stack.  The first time
+      ** this instruction is executed after a fetch, the first integer 
+      ** table key is pushed.  Subsequent integer table keys are pushed 
+      ** in each subsequent execution of this instruction.
+      **
+      ** If there are no more integer table keys in the data of P1
+      ** when this instruction is executed, then nothing gets pushed and
+      ** there is an immediate jump to instruction P2.
       */
       case OP_NextIdx: {
         int i = pOp->p1;
         int tos = ++p->tos;
-        DbbeTable *pTab;
+        DbbeCursor *pCrsr;
 
         if( NeedStack(p, p->tos) ) goto no_mem;
         p->zStack[tos] = 0;
-        if( i>=0 && i<p->nTable && (pTab = p->aTab[i].pTable)!=0 ){
+        if( i>=0 && i<p->nCursor && (pCrsr = p->aCsr[i].pCursor)!=0 ){
           int *aIdx;
           int nIdx;
           int j;
-          nIdx = sqliteDbbeDataLength(pTab)/sizeof(int);
-          aIdx = (int*)sqliteDbbeReadData(pTab, 0);
-          for(j=p->aTab[i].index; j<nIdx; j++){
+          nIdx = sqliteDbbeDataLength(pCrsr)/sizeof(int);
+          aIdx = (int*)sqliteDbbeReadData(pCrsr, 0);
+          for(j=p->aCsr[i].index; j<nIdx; j++){
             if( aIdx[j]!=0 ){
               p->aStack[tos].i = aIdx[j];
               p->aStack[tos].flags = STK_Int;
@@ -2088,47 +2113,47 @@ int sqliteVdbeExec(
             pc = pOp->p2 - 1;
             PopStack(p, 1);
           }
-          p->aTab[i].index = j+1;
+          p->aCsr[i].index = j+1;
         }
         break;
       }
 
       /* Opcode: PutIdx P1 * *
       **
-      ** The top of the stack hold an index key (probably made using the
-      ** MakeKey instruction) and next on stack holds an index value for
-      ** a table.  Locate the record in the index P1 that has the key 
-      ** and insert the index value into its
-      ** data.  Write the results back to the index.
-      ** If the key doesn't exist it is created.
+      ** The top of the stack hold an SQL index key (probably made using the
+      ** MakeKey instruction) and next on stack holds an integer which
+      ** the key to an SQL table entry.  Locate the record in cursor P1
+      ** that has the same key as on the TOS.  Create a new record if
+      ** necessary.  Then append the integer table key to the data for that
+      ** record and write it back to the P1 file.
       */
       case OP_PutIdx: {
         int i = pOp->p1;
         int tos = p->tos;
         int nos = tos - 1;
-        DbbeTable *pTab;
+        DbbeCursor *pCrsr;
         if( nos<0 ) goto not_enough_stack;
-        if( i>=0 && i<p->nTable && (pTab = p->aTab[i].pTable)!=0 ){
+        if( i>=0 && i<p->nCursor && (pCrsr = p->aCsr[i].pCursor)!=0 ){
           int r;
           int newVal;
           Integerify(p, nos);
           newVal = p->aStack[nos].i;
           if( Stringify(p, tos) ) goto no_mem;
-          r = sqliteDbbeFetch(pTab, p->aStack[tos].n, p->zStack[tos]);
+          r = sqliteDbbeFetch(pCrsr, p->aStack[tos].n, p->zStack[tos]);
           if( r==0 ){
             /* Create a new record for this index */
-            sqliteDbbePut(pTab, p->aStack[tos].n, p->zStack[tos],
+            sqliteDbbePut(pCrsr, p->aStack[tos].n, p->zStack[tos],
                           sizeof(int), (char*)&newVal);
           }else{
             /* Extend the existing record */
             int nIdx;
             int *aIdx;
-            nIdx = sqliteDbbeDataLength(pTab)/sizeof(int);
+            nIdx = sqliteDbbeDataLength(pCrsr)/sizeof(int);
             aIdx = sqliteMalloc( sizeof(int)*(nIdx+1) );
             if( aIdx==0 ) goto no_mem;
-            sqliteDbbeCopyData(pTab, 0, nIdx*sizeof(int), (char*)aIdx);
+            sqliteDbbeCopyData(pCrsr, 0, nIdx*sizeof(int), (char*)aIdx);
             aIdx[nIdx] = newVal;
-            sqliteDbbePut(pTab, p->aStack[tos].n, p->zStack[tos],
+            sqliteDbbePut(pCrsr, p->aStack[tos].n, p->zStack[tos],
                           sizeof(int)*(nIdx+1), (char*)aIdx);
             sqliteFree(aIdx);
           }
@@ -2139,20 +2164,24 @@ int sqliteVdbeExec(
 
       /* Opcode: DeleteIdx P1 * *
       **
-      ** The top of the stack is a key and next on stack is an index value.
-      ** Locate the record
-      ** in index P1 that has the key and remove the index value from its
-      ** data.  Write the results back to the table.  If after removing
-      ** the index value no more indices remain in the record, then the
-      ** record is removed from the table.
+      ** The top of the stack is a key and next on stack is integer
+      ** which is the key to a record in an SQL table.
+      ** Locate the record in the cursor P1 (P1 represents an SQL index)
+      ** that has the same key as the top of stack.  Then look through
+      ** the integer table-keys contained in the data of the P1 record.
+      ** Remove the integer table-key that matches the NOS and write the
+      ** revised data back to P1 with the same key.
+      **
+      ** If this routine removes the very last integer table-key from
+      ** the P1 data, then the corresponding P1 record is deleted.
       */
       case OP_DeleteIdx: {
         int i = pOp->p1;
         int tos = p->tos;
         int nos = tos - 1;
-        DbbeTable *pTab;
+        DbbeCursor *pCrsr;
         if( nos<0 ) goto not_enough_stack;
-        if( i>=0 && i<p->nTable && (pTab = p->aTab[i].pTable)!=0 ){
+        if( i>=0 && i<p->nCursor && (pCrsr = p->aCsr[i].pCursor)!=0 ){
           int *aIdx;
           int nIdx;
           int j;
@@ -2161,17 +2190,17 @@ int sqliteVdbeExec(
           Integerify(p, nos);
           oldVal = p->aStack[nos].i;
           if( Stringify(p, tos) ) goto no_mem;
-          r = sqliteDbbeFetch(pTab, p->aStack[tos].n, p->zStack[tos]);
+          r = sqliteDbbeFetch(pCrsr, p->aStack[tos].n, p->zStack[tos]);
           if( r==0 ) break;
-          nIdx = sqliteDbbeDataLength(pTab)/sizeof(int);
-          aIdx = (int*)sqliteDbbeReadData(pTab, 0);
+          nIdx = sqliteDbbeDataLength(pCrsr)/sizeof(int);
+          aIdx = (int*)sqliteDbbeReadData(pCrsr, 0);
           for(j=0; j<nIdx && aIdx[j]!=oldVal; j++){}
           if( j>=nIdx ) break;
           aIdx[j] = aIdx[nIdx-1];
           if( nIdx==1 ){
-            sqliteDbbeDelete(pTab, p->aStack[tos].n, p->zStack[tos]);
+            sqliteDbbeDelete(pCrsr, p->aStack[tos].n, p->zStack[tos]);
           }else{
-            sqliteDbbePut(pTab, p->aStack[tos].n, p->zStack[tos], 
+            sqliteDbbePut(pCrsr, p->aStack[tos].n, p->zStack[tos], 
                           sizeof(int)*(nIdx-1), (char*)aIdx);
           }
         }
@@ -2181,8 +2210,9 @@ int sqliteVdbeExec(
 
       /* Opcode: Destroy * * P3
       **
-      ** Drop the table whose name is P3.  The file that holds this table
-      ** is removed from the disk drive.
+      ** Drop the disk file whose name is P3.  All key/data pairs in
+      ** the file are deleted and the file itself is removed
+      ** from the disk.
       */
       case OP_Destroy: {
         sqliteDbbeDropTable(p->pBe, pOp->p3);
@@ -2200,7 +2230,7 @@ int sqliteVdbeExec(
 
       /* Opcode: ListOpen P1 * *
       **
-      ** Open a file used for temporary storage of index numbers.  P1
+      ** Open a file used for temporary storage of integer table keys.  P1
       ** will server as a handle to this temporary file for future
       ** interactions.  If another temporary file with the P1 handle is
       ** already opened, the prior file is closed and a new one opened
@@ -2260,7 +2290,7 @@ int sqliteVdbeExec(
       /* Opcode: ListRead P1 P2 *
       **
       ** Attempt to read an integer from temporary storage buffer P1
-      ** and push it onto the stack.  If the storage buffer is empty
+      ** and push it onto the stack.  If the storage buffer is empty
       ** push nothing but instead jump to P2.
       */
       case OP_ListRead: {
@@ -2693,7 +2723,7 @@ int sqliteVdbeExec(
       /* Opcode: FileField P1 * *
       **
       ** Push onto the stack the P1-th field of the most recently read line
-      ** from the file.
+      ** from the input file.
       */
       case OP_FileField: {
         int i = pOp->p1;
@@ -2828,8 +2858,8 @@ int sqliteVdbeExec(
 
       /* Opcode: AggIncr P1 P2 *
       **
-      ** Increment the P2-th field of the aggregate element current
-      ** in focus by an amount P1.
+      ** Increase the integer value in the P2-th field of the aggregate
+      ** element current in focus by an amount P1.
       */
       case OP_AggIncr: {
         AggElem *pFocus = AggInFocus(p->agg);
index bfdd2a78293ad7b39db0326d071e88e173310517..5cf7d7a3af58b6fd455ec68262c3b8174bd50a3c 100644 (file)
@@ -25,7 +25,7 @@
 ** the WHERE clause of SQL statements.  Also found here are subroutines
 ** to generate VDBE code to evaluate expressions.
 **
-** $Id: where.c,v 1.7 2000/06/06 13:54:16 drh Exp $
+** $Id: where.c,v 1.8 2000/06/21 13:59:13 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -38,10 +38,10 @@ typedef struct ExprInfo ExprInfo;
 struct ExprInfo {
   Expr *p;                /* Pointer to the subexpression */
   int indexable;          /* True if this subexprssion is usable by an index */
-  int idxLeft;            /* p->pLeft is a field in this table number. -1 if
-                          ** p->pLeft is not the field of any table */
-  int idxRight;           /* p->pRight is a field in this table number. -1 if
-                          ** p->pRight is not the field of any table */
+  int idxLeft;            /* p->pLeft is a column in this table number. -1 if
+                          ** p->pLeft is not the column of any table */
+  int idxRight;           /* p->pRight is a column in this table number. -1 if
+                          ** p->pRight is not the column of any table */
   unsigned prereqLeft;    /* Tables referenced by p->pLeft */
   unsigned prereqRight;   /* Tables referenced by p->pRight */
 };
@@ -94,7 +94,7 @@ static int exprSplit(int nSlot, ExprInfo *aSlot, Expr *pExpr){
 static int exprTableUsage(int base, Expr *p){
   unsigned int mask = 0;
   if( p==0 ) return 0;
-  if( p->op==TK_FIELD ){
+  if( p->op==TK_COLUMN ){
     return 1<< (p->iTable - base);
   }
   if( p->pRight ){
@@ -124,11 +124,11 @@ static void exprAnalyze(int base, ExprInfo *pInfo){
   pInfo->idxLeft = -1;
   pInfo->idxRight = -1;
   if( pExpr->op==TK_EQ && (pInfo->prereqRight & pInfo->prereqLeft)==0 ){
-    if( pExpr->pRight->op==TK_FIELD ){
+    if( pExpr->pRight->op==TK_COLUMN ){
       pInfo->idxRight = pExpr->pRight->iTable - base;
       pInfo->indexable = 1;
     }
-    if( pExpr->pLeft->op==TK_FIELD ){
+    if( pExpr->pLeft->op==TK_COLUMN ){
       pInfo->idxLeft = pExpr->pLeft->iTable - base;
       pInfo->indexable = 1;
     }
@@ -225,41 +225,41 @@ WhereInfo *sqliteWhereBegin(
     ** the most specific usable index.
     **
     ** "Most specific" means that pBestIdx is the usable index that
-    ** has the largest value for nField.  A usable index is one for
-    ** which there are subexpressions to compute every field of the
+    ** has the largest value for nColumn.  A usable index is one for
+    ** which there are subexpressions to compute every column of the
     ** index.
     */
     for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
       int j;
-      int fieldMask = 0;
+      int columnMask = 0;
 
-      if( pIdx->nField>32 ) continue;
+      if( pIdx->nColumn>32 ) continue;
       for(j=0; j<nExpr; j++){
         if( aExpr[j].idxLeft==idx 
              && (aExpr[j].prereqRight & loopMask)==aExpr[j].prereqRight ){
-          int iField = aExpr[j].p->pLeft->iField;
+          int iColumn = aExpr[j].p->pLeft->iColumn;
           int k;
-          for(k=0; k<pIdx->nField; k++){
-            if( pIdx->aiField[k]==iField ){
-              fieldMask |= 1<<k;
+          for(k=0; k<pIdx->nColumn; k++){
+            if( pIdx->aiColumn[k]==iColumn ){
+              columnMask |= 1<<k;
               break;
             }
           }
         }
         if( aExpr[j].idxRight==idx 
              && (aExpr[j].prereqLeft & loopMask)==aExpr[j].prereqLeft ){
-          int iField = aExpr[j].p->pRight->iField;
+          int iColumn = aExpr[j].p->pRight->iColumn;
           int k;
-          for(k=0; k<pIdx->nField; k++){
-            if( pIdx->aiField[k]==iField ){
-              fieldMask |= 1<<k;
+          for(k=0; k<pIdx->nColumn; k++){
+            if( pIdx->aiColumn[k]==iColumn ){
+              columnMask |= 1<<k;
               break;
             }
           }
         }
       }
-      if( fieldMask + 1 == (1<<pIdx->nField) ){
-        if( pBestIdx==0 || pBestIdx->nField<pIdx->nField ){
+      if( columnMask + 1 == (1<<pIdx->nColumn) ){
+        if( pBestIdx==0 || pBestIdx->nColumn<pIdx->nColumn ){
           pBestIdx = pIdx;
         }
       }
@@ -297,12 +297,12 @@ WhereInfo *sqliteWhereBegin(
     }else{
       /* Case 2:  We do have a usable index in pIdx.
       */
-      for(j=0; j<pIdx->nField; j++){
+      for(j=0; j<pIdx->nColumn; j++){
         for(k=0; k<nExpr; k++){
           if( aExpr[k].p==0 ) continue;
           if( aExpr[k].idxLeft==idx 
              && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight 
-             && aExpr[k].p->pLeft->iField==pIdx->aiField[j]
+             && aExpr[k].p->pLeft->iColumn==pIdx->aiColumn[j]
           ){
             sqliteExprCode(pParse, aExpr[k].p->pRight);
             aExpr[k].p = 0;
@@ -310,7 +310,7 @@ WhereInfo *sqliteWhereBegin(
           }
           if( aExpr[k].idxRight==idx 
              && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft
-             && aExpr[k].p->pRight->iField==pIdx->aiField[j]
+             && aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
           ){
             sqliteExprCode(pParse, aExpr[k].p->pLeft);
             aExpr[k].p = 0;
@@ -318,7 +318,7 @@ WhereInfo *sqliteWhereBegin(
           }
         }
       }
-      sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nField, 0, 0, 0);
+      sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nColumn, 0, 0, 0);
       sqliteVdbeAddOp(v, OP_Fetch, base+pTabList->nId+i, 0, 0, 0);
       sqliteVdbeAddOp(v, OP_NextIdx, base+pTabList->nId+i, brk, 0, cont);
       if( i==pTabList->nId-1 && pushKey ){
index 9bebd86fdf47d67bb01cb2b96e975928d9bb7b7d..b00e3c0d3e0dd8e5c65ab12377122ccb79710a31 100644 (file)
@@ -23,7 +23,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the DELETE FROM statement.
 #
-# $Id: delete.test,v 1.5 2000/06/08 15:10:48 drh Exp $
+# $Id: delete.test,v 1.6 2000/06/21 13:59:13 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -72,7 +72,7 @@ do_test delete-4.1 {
   execsql {CREATE TABLE table2(f1 int, f2 int)}
   set v [catch {execsql {DELETE FROM table2 WHERE f3=5}} msg]
   lappend v $msg
-} {1 {no such field: f3}}
+} {1 {no such column: f3}}
 
 do_test delete-4.2 {
   set v [catch {execsql {DELETE FROM table2 WHERE xyzzy(f1+4)}} msg]
index 01276b79a786174e93d0dc11099abf598cb6443b..bd77c1fef28d58e5beca5bf9a2b0f2ad905a71a8 100644 (file)
@@ -23,7 +23,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the IN and BETWEEN operator.
 #
-# $Id: in.test,v 1.2 2000/06/07 23:51:51 drh Exp $
+# $Id: in.test,v 1.3 2000/06/21 13:59:13 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -106,7 +106,7 @@ do_test in-2.10 {
 do_test in-2.11 {
   set v [catch {execsql {SELECT a FROM t1 WHERE c IN (10,20)}} msg]
   lappend v $msg
-} {1 {no such field: c}}
+} {1 {no such column: c}}
 
 # Testing the IN operator where the right-hand side is a SELECT
 #
index b415a596b1330abd66e63912a692a834f9b5ed52..b9b6e5eae38d6f81df8dce838a262e059577c175 100644 (file)
@@ -23,7 +23,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the SELECT statement.
 #
-# $Id: select1.test,v 1.5 2000/06/07 15:11:27 drh Exp $
+# $Id: select1.test,v 1.6 2000/06/21 13:59:13 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -49,7 +49,7 @@ do_test select1-1.3 {
 execsql {INSERT INTO test1(f1,f2) VALUES(11,22)}
 
 
-# Make sure the fields are extracted correctly.
+# Make sure the columns are extracted correctly.
 #
 do_test select1-1.4 {
   execsql {SELECT f1 FROM test1}
@@ -244,7 +244,7 @@ do_test select1-5.1 {
 execsql {CREATE TABLE test2(t1 test, t2 text)}
 execsql {INSERT INTO test2 VALUES('abc','xyz')}
 
-# Check for field naming
+# Check for column naming
 #
 do_test select1-6.1 {
   set v [catch {execsql2 {SELECT f1 FROM test1 ORDER BY f2}} msg]
@@ -280,17 +280,17 @@ do_test select1-6.8 {
   set v [catch {execsql2 {SELECT A.f1, f1 FROM test1 as A, test1 as B 
          ORDER BY f2}} msg]
   lappend v $msg
-} {1 {ambiguous field name: f1}}
+} {1 {ambiguous column name: f1}}
 do_test select1-6.8b {
   set v [catch {execsql2 {SELECT A.f1, B.f1 FROM test1 as A, test1 as B 
          ORDER BY f2}} msg]
   lappend v $msg
-} {1 {ambiguous field name: f2}}
+} {1 {ambiguous column name: f2}}
 do_test select1-6.8c {
   set v [catch {execsql2 {SELECT A.f1, f1 FROM test1 as A, test1 as A 
          ORDER BY f2}} msg]
   lappend v $msg
-} {1 {ambiguous field name: A.f1}}
+} {1 {ambiguous column name: A.f1}}
 do_test select1-6.9 {
   set v [catch {execsql2 {SELECT A.f1, B.f1 FROM test1 as A, test1 as B 
          ORDER BY A.f1, B.f1}} msg]
index 664e12995be191164cceb348f1e4bf5e936beabc..59d759d5595415a87019d8489355fad1916f3220 100644 (file)
@@ -23,7 +23,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the SELECT statement.
 #
-# $Id: select2.test,v 1.6 2000/06/08 16:54:40 drh Exp $
+# $Id: select2.test,v 1.7 2000/06/21 13:59:13 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -106,7 +106,7 @@ do_test select2-3.2c {
 do_test select2-3.2d {
   set t1 [lindex [time {execsql {SELECT f1 FROM tbl2 WHERE 1000=f2}} 1] 0]
   set t2 [lindex [time {execsql {SELECT f1 FROM tbl2 WHERE f2=1000}} 1] 0]
-  expr {$t1*0.9<$t2 && $t2*0.9<$t1}
+  expr {$t1*0.8<$t2 && $t2*0.8<$t1}
 } {1}
 
 # Make sure queries run faster with an index than without
index f6bd150979a026d8d584007f546c6ee26b5ada96..816e88da88e163f264a869e9bd3a939a6195dc94 100644 (file)
@@ -24,7 +24,7 @@
 # focus of this file is testing aggregate functions and the
 # GROUP BY and HAVING clauses of SELECT statements.
 #
-# $Id: select5.test,v 1.3 2000/06/08 16:26:25 drh Exp $
+# $Id: select5.test,v 1.4 2000/06/21 13:59:13 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -66,7 +66,7 @@ do_test select5-2.1 {
     SELECT y, count(*) FROM t1 GROUP BY z ORDER BY y
   }} msg]
   lappend v $msg
-} {1 {no such field: z}}
+} {1 {no such column: z}}
 do_test select5-2.2 {
   set v [catch {execsql {
     SELECT y, count(*) FROM t1 GROUP BY z(y) ORDER BY y
@@ -90,7 +90,7 @@ do_test select5-2.5 {
     SELECT y, count(*) FROM t1 GROUP BY y HAVING count(*)<z ORDER BY y
   }} msg]
   lappend v $msg
-} {1 {no such field: z}}
+} {1 {no such column: z}}
 
 # Get the Agg function to rehash in vdbe.c
 #
index dea0db3e2309e62a2fce28c7c59e1f3b97257079..d9559e89e618ca7492a33667d719543de21034b6 100644 (file)
@@ -23,7 +23,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the UPDATE statement.
 #
-# $Id: update.test,v 1.3 2000/06/19 19:09:09 drh Exp $
+# $Id: update.test,v 1.4 2000/06/21 13:59:14 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -54,20 +54,20 @@ do_test update-3.1 {
   execsql {SELECT * FROM test1 ORDER BY f1}
 } {1 2 2 4 3 8 4 16 5 32 6 64 7 128 8 256 9 512 10 1024}
 
-# Unknown field name in an expression
+# Unknown column name in an expression
 #
 do_test update-3.2 {
   set v [catch {execsql {UPDATE test1 SET f1=f3*2 WHERE f2==32}} msg]
   lappend v $msg
-} {1 {no such field: f3}}
+} {1 {no such column: f3}}
 do_test update-3.3 {
   set v [catch {execsql {UPDATE test1 SET f1=test2.f1*2 WHERE f2==32}} msg]
   lappend v $msg
-} {1 {no such field: test2.f1}}
+} {1 {no such column: test2.f1}}
 do_test update-3.4 {
   set v [catch {execsql {UPDATE test1 SET f3=f1*2 WHERE f2==32}} msg]
   lappend v $msg
-} {1 {no such field: f3}}
+} {1 {no such column: f3}}
 
 # Actually do some updates
 #
@@ -117,7 +117,7 @@ do_test update-4.1 {
     UPDATE test1 SET x=11 WHERE f1=1025
   }} msg]
   lappend v $msg
-} {1 {no such field: x}}
+} {1 {no such column: x}}
 do_test update-4.2 {
   set v [catch {execsql {
     UPDATE test1 SET f1=x(11) WHERE f1=1025
@@ -129,7 +129,7 @@ do_test update-4.3 {
     UPDATE test1 SET f1=11 WHERE x=1025
   }} msg]
   lappend v $msg
-} {1 {no such field: x}}
+} {1 {no such column: x}}
 do_test update-4.4 {
   set v [catch {execsql {
     UPDATE test1 SET f1=11 WHERE x(f1)=1025
index f5b46aa315907171a472c25eb8eeb5352f6c15cf..ea5e03a51674d6b894310e44acfaa7b1013fe66a 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Run this Tcl script to generate the sqlite.html file.
 #
-set rcsid {$Id: c_interface.tcl,v 1.4 2000/06/06 18:24:42 drh Exp $}
+set rcsid {$Id: c_interface.tcl,v 1.5 2000/06/21 13:59:14 drh Exp $}
 
 puts {<html>
 <head>
@@ -88,7 +88,7 @@ for any reason.</p>
 
 <h2>Closing the database</h2>
 
-<p>To close an SQLite database, just call the <b>sqlite_close()</b>
+<p>To close an SQLite database, call the <b>sqlite_close()</b>
 function passing it the sqlite structure pointer that was obtained
 from a prior call to <b>sqlite_open</b>.
 
@@ -147,6 +147,62 @@ argv[i] == 0
 function returns non-zero, the query is immediately aborted and 
 <b>sqlite_exec()</b> will return SQLITE_ABORT.</p>
 
+<p>The <b>sqlite_exec()</b> function returns an integer to indicate
+success or failure of the operation.  The following are possible
+return values:</p>
+
+<blockquote>
+<dl>
+<dt>SQLITE_OK</dt>
+<dd><p>This value is returned if everything worked and there were no errors.
+</p></dd>
+<dt>SQLITE_INTERNAL</dt>
+<dd><p>This value indicates that an internal consistency check within
+the SQLite library failed.  This can only happen if there is a bug in
+the SQLite library.  If you ever get an SQLITE_INTERNAL reply from
+an <b>sqlite_exec()</b> call, please report the problem on the SQLite
+mailing list.
+</p></dd>
+<dt>SQLITE_ERROR</dt>
+<dd><p>This return value indicates that there was an error in the SQL
+that was passed into the <b>sqlite_exec()</b>.
+</p></dd>
+<dt>SQLITE_PERM</dt>
+<dd><p>This return value says that the access permissions on one of the
+GDBM files is such that the file cannot be opened.
+</p></dd>
+<dt>SQLITE_ABORT</dt>
+<dd><p>This value is returned if the callback function returns non-zero.
+</p></dd>
+<dt>SQLITE_BUSY</dt>
+<dd><p>This return code indicates that one of the underlying GDBM files
+is locked because it is currently being accessed by another thread or
+process.  GDBM allows mutiple readers of the same file, but only one
+writer.  So multiple processes can query an SQLite database at once.
+But only a single process can write to an SQLite database at one time.
+If an attempt is made to write to an SQLite database that another
+process is currently reading, the write is not performed and 
+<b>sqlite_exec()</b> returns SQLITE_BUSY.  Similarly, an attempt to read
+an SQLite database that is currently being written by another process
+will return SQLITE_BUSY.  In both cases, the write or query attempt
+can be retried after the other process finishes.</p>
+<p>Note that locking is done at the file level.  One process can
+write to table ABC (for example) while another process simultaneously
+reads from a different table XYZ.  But you cannot have two processes reading
+and writing table ABC at the same time.
+</p></dd>
+<dt>SQLITE_NOMEM</dt>
+<dd><p>This value is returned if a call to <b>malloc()</b> fails.
+</p></dd>
+<dt>SQLITE_READONLY</dt>
+<dd><p>This return code indicates that an attempt was made to write to
+a database file that was originally opened for reading only.  This can
+happen if the callback from a query attempts to update the table
+being queried.
+</p></dd>
+</dl>
+</blockquote>
+
 <h2>Testing for a complete SQL statement</h2>
 
 <p>The last interface routine to SQLite is a convenience function used
index b17c653bb59c6707bccb7945cf9e00bbe87cae70..b3ee4708056efc9994b271bef34ff31abb52d7da 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Run this Tcl script to generate the sqlite.html file.
 #
-set rcsid {$Id: sqlite.tcl,v 1.8 2000/06/08 19:43:40 drh Exp $}
+set rcsid {$Id: sqlite.tcl,v 1.9 2000/06/21 13:59:14 drh Exp $}
 
 puts {<html>
 <head>
@@ -150,6 +150,7 @@ sqlite> (((.help)))
 .help                  Show this message
 .indices TABLE         Show names of all indices on TABLE
 .mode MODE             Set mode to one of "line", "column", "list", or "html"
+.mode insert TABLE     Generate SQL insert statements for TABLE
 .output FILENAME       Send output to FILENAME
 .output stdout         Send output to the screen
 .schema ?TABLE?        Show the CREATE statements
@@ -163,13 +164,13 @@ puts {
 <h2>Changing Output Formats</h2>
 
 <p>The sqlite program is able to show the results of a query
-in four different formats: "line", "column", "list", and "html".
+in five different formats: "line", "column", "list", "html", and "insert".
 You can use the ".mode" dot command to switch between these three output
 formats.</p>
 
 <p>The default output mode is "list".  In
 list mode, each record of a query result is written on one line of
-output and each field within that record is separated by a specific
+output and each column within that record is separated by a specific
 separator string.  The default separator is a pipe symbol ("|").
 List mode is especially useful when you are going to send the output
 of a query to another program (such as AWK) for additional processing.</p>}
@@ -196,9 +197,9 @@ sqlite>
 }
 
 puts {
-<p>In "line" mode, each field in a record of the database
-is shown on a line by itself.  Each line consists of the field
-name, an equal sign and the field data.  Successive records are
+<p>In "line" mode, each column in a row of the database
+is shown on a line by itself.  Each line consists of the column
+name, an equal sign and the column data.  Successive records are
 separated by a blank line.  Here is an example of line mode
 output:</p>}
 
@@ -263,6 +264,11 @@ sqlite>
 }
 
 puts {
+<p>Another useful output mode is "insert".  In insert mode, the output
+is formatted to look like SQL INSERT statements.  You can use insert
+mode to generate text that can later be used to input data into a 
+different database.</p>
+
 <p>The last output mode is "html".  In this mode, sqlite writes
 the results of the query as an XHTML table.  The beginning
 &lt;TABLE&gt; and the ending &lt;/TABLE&gt; are not written, but