diff --git a/manifest b/manifest
index 2ec09d6d89..91411719ac 100644
--- 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
diff --git a/manifest.uuid b/manifest.uuid
index 842ff3b586..75bd74aa24 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-af14a5b3ba4a13665142b700e8864bf63d591d95
\ No newline at end of file
+e1bf96a467b739373191bf75e6a097fc0f24bffc
\ No newline at end of file
diff --git a/src/build.c b/src/build.c
index 4d0e1c78de..a49072e080 100644
--- a/src/build.c
+++ b/src/build.c
@@ -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; inField; i++){
- sqliteVdbeAddOp(v, OP_Field, 0, pIndex->aiField[i], 0, 0);
+ for(i=0; inColumn; 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; jnField; j++){
- sqliteVdbeAddOp(v, OP_FileField, pIdx->aiField[j], 0, 0, 0);
+ for(j=0; jnColumn; 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);
diff --git a/src/dbbe.c b/src/dbbe.c
index c8b0beb280..d690329beb 100644
--- a/src/dbbe.c
+++ b/src/dbbe.c
@@ -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
@@ -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;
}
diff --git a/src/dbbe.h b/src/dbbe.h
index 0edab794a4..8ccb53f18f 100644
--- a/src/dbbe.h
+++ b/src/dbbe.h
@@ -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
@@ -46,13 +46,13 @@
** 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**);
diff --git a/src/delete.c b/src/delete.c
index e81272f735..f6822f9ab5 100644
--- a/src/delete.c
+++ b/src/delete.c
@@ -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; jnField; j++){
- sqliteVdbeAddOp(v, OP_Field, base, pIdx->aiField[j], 0, 0);
+ for(j=0; jnColumn; 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);
}
}
diff --git a/src/expr.c b/src/expr.c
index 74873bc1e2..c94fd247a4 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -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->iAggCountnAgg );
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; inAgg; 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;
}
diff --git a/src/insert.c b/src/insert.c
index a40ea91c1c..a044bc1448 100644
--- a/src/insert.c
+++ b/src/insert.c
@@ -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; inId; i++){
- pField->a[i].idx = -1;
+ if( pColumn ){
+ for(i=0; inId; i++){
+ pColumn->a[i].idx = -1;
}
- for(i=0; inId; i++){
+ for(i=0; inId; i++){
for(j=0; jnCol; 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; inCol; i++){
- if( pField==0 ){
+ if( pColumn==0 ){
j = i;
}else{
- for(j=0; jnId; j++){
- if( pField->a[j].idx==i ) break;
+ for(j=0; jnId; 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; inField; i++){
- int idx = pIdx->aiField[i];
- if( pField==0 ){
+ for(i=0; inColumn; i++){
+ int idx = pIdx->aiColumn[i];
+ if( pColumn==0 ){
j = idx;
}else{
- for(j=0; jnId; j++){
- if( pField->a[j].idx==idx ) break;
+ for(j=0; jnId; 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);
}
diff --git a/src/main.c b/src/main.c
index 3c81beca33..06423b5453 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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.
**
diff --git a/src/parse.y b/src/parse.y
index 862e1d6309..f59b662b64 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -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.
diff --git a/src/select.c b/src/select.c
index e39e415a4c..d9d21c76a3 100644
--- a/src/select.c
+++ b/src/select.c
@@ -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; inExpr; i++){
sqliteExprCode(pParse, pEList->a[i].pExpr);
}
- nField = pEList->nExpr;
+ nColumn = pEList->nExpr;
}else{
- for(i=0; inExpr + 1 );
if( zSortOrder==0 ) return 1;
for(i=0; inExpr; 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; inExpr; 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;
diff --git a/src/shell.c b/src/shell.c
index e3bf5e9645..b34557dd3b 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -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
#include
@@ -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 */
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index d4069eac86..9eef275306 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -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"
@@ -35,7 +35,20 @@
#include
#include
-/* #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 */
};
/*
diff --git a/src/update.c b/src/update.c
index 982d125893..6902a94e3c 100644
--- a/src/update.c
+++ b/src/update.c
@@ -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; inCol; 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; inField; i++){
- if( aXRef[pIdx->aiField[i]]>=0 ) break;
+ for(i=0; inColumn; i++){
+ if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
}
- if( inField ) nIdx++;
+ if( inColumn ) 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; inField; i++){
- if( aXRef[pIdx->aiField[i]]>=0 ) break;
+ for(i=0; inColumn; i++){
+ if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
}
- if( inField ) apIdx[nIdx++] = pIdx;
+ if( inColumn ) 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; inField; j++){
- sqliteVdbeAddOp(v, OP_Field, base, pIdx->aiField[j], 0, 0);
+ for(j=0; jnColumn; 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; inCol, 0, 0, 0); /* The KEY */
pIdx = apIdx[i];
- for(j=0; jnField; j++){
- sqliteVdbeAddOp(v, OP_Dup, j+pTab->nCol-pIdx->aiField[j], 0, 0, 0);
+ for(j=0; jnColumn; 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);
}
diff --git a/src/util.c b/src/util.c
index 5d53beb98d..0d96bcdd5d 100644
--- a/src/util.c
+++ b/src/util.c
@@ -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
@@ -360,7 +360,7 @@ int sqliteHashNoCase(const char *z, int n){
}
/*
-** Some system shave stricmp(). Others have strcasecmp(). Because
+** Some systems have stricmp(). Others have strcasecmp(). Because
** there is no consistency, we will define our own.
*/
int sqliteStrICmp(const char *zLeft, const char *zRight){
diff --git a/src/vdbe.c b/src/vdbe.c
index 6dc03010cc..eb2b821e6b 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -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
@@ -54,15 +54,21 @@
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; inTable; i++){
- if( p->aTab[i].pTable ){
- sqliteDbbeCloseTable(p->aTab[i].pTable);
- p->aTab[i].pTable = 0;
+ for(i=0; inCursor; 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; inMem; 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 && inOp; 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);
+ 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 = sqliteDbbeOpenTable(p->pBe, pOp->p3, pOp->p2, &p->aTab[i].pTable);
+ 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 && inTable && p->aTab[i].pTable ){
- sqliteDbbeCloseTable(p->aTab[i].pTable);
- p->aTab[i].pTable = 0;
+ if( i>=0 && inCursor && 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 && inTable && p->aTab[i].pTable ){
+ if( i>=0 && inCursor && 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 && inTable && p->aTab[i].pTable ){
+ if( i>=0 && inCursor && 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 && inTable && p->aTab[i].pTable!=0 ){
+ if( i>=0 && inCursor && 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 && inTable && p->aTab[i].pTable!=0 ){
+ if( i>=0 && inCursor && 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 && inTable && p->aTab[i].pTable!=0 ){
- p->aTab[i].keyAsData = pOp->p2;
+ if( i>=0 && inCursor && 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 && inTable && (pTab = p->aTab[i].pTable)!=0 ){
- if( p->aTab[i].keyAsData ){
- amt = sqliteDbbeKeyLength(pTab);
+ if( i>=0 && inCursor && (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 && inTable && (pTab = p->aTab[i].pTable)!=0 ){
- char *z = sqliteDbbeReadKey(pTab, 0);
- if( p->aTab[i].keyAsData ){
+ if( i>=0 && inCursor && (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 && inTable && p->aTab[i].pTable!=0 ){
- sqliteDbbeRewind(p->aTab[i].pTable);
+ if( i>=0 && inCursor && 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 && inTable && p->aTab[i].pTable!=0 ){
- if( sqliteDbbeNextKey(p->aTab[i].pTable)==0 ){
+ if( i>=0 && inCursor && 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 && inTable ){
- p->aTab[i].index = 0;
+ if( i>=0 && inCursor ){
+ 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 && inTable && (pTab = p->aTab[i].pTable)!=0 ){
+ if( i>=0 && inCursor && (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; jaCsr[i].index; jaStack[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 && inTable && (pTab = p->aTab[i].pTable)!=0 ){
+ if( i>=0 && inCursor && (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 && inTable && (pTab = p->aTab[i].pTable)!=0 ){
+ if( i>=0 && inCursor && (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 ) 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);
diff --git a/src/where.c b/src/where.c
index bfdd2a7829..5cf7d7a3af 100644
--- a/src/where.c
+++ b/src/where.c
@@ -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; jpLeft->iField;
+ int iColumn = aExpr[j].p->pLeft->iColumn;
int k;
- for(k=0; knField; k++){
- if( pIdx->aiField[k]==iField ){
- fieldMask |= 1<nColumn; k++){
+ if( pIdx->aiColumn[k]==iColumn ){
+ columnMask |= 1<pRight->iField;
+ int iColumn = aExpr[j].p->pRight->iColumn;
int k;
- for(k=0; knField; k++){
- if( pIdx->aiField[k]==iField ){
- fieldMask |= 1<nColumn; k++){
+ if( pIdx->aiColumn[k]==iColumn ){
+ columnMask |= 1<nField) ){
- if( pBestIdx==0 || pBestIdx->nFieldnField ){
+ if( columnMask + 1 == (1<nColumn) ){
+ if( pBestIdx==0 || pBestIdx->nColumnnColumn ){
pBestIdx = pIdx;
}
}
@@ -297,12 +297,12 @@ WhereInfo *sqliteWhereBegin(
}else{
/* Case 2: We do have a usable index in pIdx.
*/
- for(j=0; jnField; j++){
+ for(j=0; jnColumn; j++){
for(k=0; kpLeft->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 ){
diff --git a/test/delete.test b/test/delete.test
index 9bebd86fdf..b00e3c0d3e 100644
--- a/test/delete.test
+++ b/test/delete.test
@@ -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]
diff --git a/test/in.test b/test/in.test
index 01276b79a7..bd77c1fef2 100644
--- a/test/in.test
+++ b/test/in.test
@@ -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
#
diff --git a/test/select1.test b/test/select1.test
index b415a596b1..b9b6e5eae3 100644
--- a/test/select1.test
+++ b/test/select1.test
@@ -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]
diff --git a/test/select2.test b/test/select2.test
index 664e12995b..59d759d559 100644
--- a/test/select2.test
+++ b/test/select2.test
@@ -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
diff --git a/test/select5.test b/test/select5.test
index f6bd150979..816e88da88 100644
--- a/test/select5.test
+++ b/test/select5.test
@@ -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(*)
@@ -88,7 +88,7 @@ for any reason.
Closing the database
-To close an SQLite database, just call the sqlite_close()
+
To close an SQLite database, call the sqlite_close()
function passing it the sqlite structure pointer that was obtained
from a prior call to sqlite_open.
@@ -147,6 +147,62 @@ argv[i] == 0
function returns non-zero, the query is immediately aborted and
sqlite_exec() will return SQLITE_ABORT.
+The sqlite_exec() function returns an integer to indicate
+success or failure of the operation. The following are possible
+return values:
+
+
+
+- SQLITE_OK
+This value is returned if everything worked and there were no errors.
+
+- SQLITE_INTERNAL
+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 sqlite_exec() call, please report the problem on the SQLite
+mailing list.
+
+- SQLITE_ERROR
+This return value indicates that there was an error in the SQL
+that was passed into the sqlite_exec().
+
+- SQLITE_PERM
+This return value says that the access permissions on one of the
+GDBM files is such that the file cannot be opened.
+
+- SQLITE_ABORT
+This value is returned if the callback function returns non-zero.
+
+- SQLITE_BUSY
+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
+sqlite_exec() 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.
+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.
+
+- SQLITE_NOMEM
+This value is returned if a call to malloc() fails.
+
+- SQLITE_READONLY
+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.
+
+
+
+
Testing for a complete SQL statement
The last interface routine to SQLite is a convenience function used
diff --git a/www/sqlite.tcl b/www/sqlite.tcl
index b17c653bb5..b3ee470805 100644
--- a/www/sqlite.tcl
+++ b/www/sqlite.tcl
@@ -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 {
@@ -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 {
Changing Output Formats
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.
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.
}
@@ -196,9 +197,9 @@ sqlite>
}
puts {
-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
+
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:
}
@@ -263,6 +264,11 @@ sqlite>
}
puts {
+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.
+
The last output mode is "html". In this mode, sqlite writes
the results of the query as an XHTML table. The beginning
<TABLE> and the ending </TABLE> are not written, but