:-) (CVS 101)
FossilOrigin-Name: 6ed35a1d477906dc7e35bea0579951484fcdc858
diff --git a/src/build.c b/src/build.c
index 692b61a..4d0e1c7 100644
--- a/src/build.c
+++ b/src/build.c
@@ -23,7 +23,7 @@
*************************************************************************
** This file contains C code routines that are called by the parser
** when syntax rules are reduced. The routines in this file handle
-** the following kinds of rules:
+** the following kinds of syntax:
**
** CREATE TABLE
** DROP TABLE
@@ -33,14 +33,14 @@
** COPY
** VACUUM
**
-** $Id: build.c,v 1.17 2000/06/08 13:36:40 drh Exp $
+** $Id: build.c,v 1.18 2000/06/17 13:12:39 drh Exp $
*/
#include "sqliteInt.h"
/*
** This routine is called after a single SQL statement has been
-** parsed and we want to execute the code to implement
-** the statement. Prior action routines should have already
+** parsed and we want to execute the VDBE code to implement
+** that statement. Prior action routines should have already
** constructed VDBE code to do the work of the SQL statement.
** This routine just has to execute the VDBE code.
**
@@ -132,8 +132,8 @@
/*
** Locate the in-memory structure that describes the
-** format of a particular index table given the name
-** of that table. Return NULL if not found.
+** format of a particular index given the name
+** of that index. Return NULL if not found.
*/
Index *sqliteFindIndex(sqlite *db, char *zName){
Index *p;
@@ -197,7 +197,7 @@
}
/*
-** Construct the name of a user table from a token.
+** Construct the name of a user table or index from a token.
**
** Space to hold the name is obtained from sqliteMalloc() and must
** be freed by the calling function.
@@ -295,9 +295,9 @@
**
** The table structure is added to the internal hash tables.
**
-** An entry for the table is made in the master table, unless
-** initFlag==1. When initFlag==1, it means we are reading the
-** master table because we just connected to the database, so
+** An entry for the table is made in the master table on disk,
+** unless initFlag==1. When initFlag==1, it means we are reading
+** the master table because we just connected to the database, so
** the entry for this table already exists in the master table.
** We do not want to create it again.
*/
@@ -377,7 +377,9 @@
return;
}
- /* Generate code to remove the table and its reference in sys_master */
+ /* Generate code to remove the table from the master table
+ ** on disk.
+ */
v = sqliteGetVdbe(pParse);
if( v ){
static VdbeOp dropTable[] = {
@@ -407,7 +409,7 @@
}
}
- /* Remove the table structure and free its memory.
+ /* Remove the in-memory table structure and free its memory.
**
** Exception: if the SQL statement began with the EXPLAIN keyword,
** then no changes are made.
@@ -433,14 +435,14 @@
** be NULL for a primary key. In that case, use pParse->pNewTable as the
** table to be indexed.
**
-** pList is a list of fields to be indexed. pList will be NULL if the
-** most recently added field of the table is labeled as the primary key.
+** pList is a list of columns to be indexed. pList will be NULL if the
+** most recently added column of the table is labeled as the primary key.
*/
void sqliteCreateIndex(
Parse *pParse, /* All information about this parse */
Token *pName, /* Name of the index. May be NULL */
Token *pTable, /* Name of the table to index. Use pParse->pNewTable if 0 */
- IdList *pList, /* A list of fields to be indexed */
+ IdList *pList, /* A list of columns to be indexed */
Token *pStart, /* The CREATE token that begins a CREATE TABLE statement */
Token *pEnd /* The ")" that closes the CREATE INDEX statement */
){
@@ -490,7 +492,7 @@
}
/* If pList==0, it means this routine was called to make a primary
- ** key out of the last field added to the table under construction.
+ ** key out of the last column added to the table under construction.
** So create a fake list to simulate this.
*/
if( pList==0 ){
@@ -516,9 +518,9 @@
pIndex->pTable = pTab;
pIndex->nField = pList->nId;
- /* Scan the names of the fields of the table to be indexed and
- ** load the field indices into the Index structure. Report an error
- ** if any field is not found.
+ /* Scan the names of the columns of the table to be indexed and
+ ** load the column indices into the Index structure. Report an error
+ ** if any column is not found.
*/
for(i=0; i<pList->nId; i++){
for(j=0; j<pTab->nCol; j++){
@@ -526,7 +528,7 @@
}
if( j>=pTab->nCol ){
sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName,
- " has no field named ", pList->a[i].zName, 0);
+ " has no column named ", pList->a[i].zName, 0);
pParse->nErr++;
sqliteFree(pIndex);
goto exit_create_index;
diff --git a/src/dbbe.c b/src/dbbe.c
index 3b3f403..c8b0beb 100644
--- a/src/dbbe.c
+++ b/src/dbbe.c
@@ -21,7 +21,7 @@
** http://www.hwaci.com/drh/
**
*************************************************************************
-** This file contains code to implement the database baseend (DBBE)
+** This file contains code to implement the database backend (DBBE)
** for sqlite. The database backend is the interface between
** sqlite and the code that does the actually reading and writing
** of information to the disk.
@@ -30,7 +30,7 @@
** relatively simple to convert to a different database such
** as NDBM, SDBM, or BerkeleyDB.
**
-** $Id: dbbe.c,v 1.13 2000/06/08 15:10:47 drh Exp $
+** $Id: dbbe.c,v 1.14 2000/06/17 13:12:39 drh Exp $
*/
#include "sqliteInt.h"
#include <gdbm.h>
@@ -40,7 +40,12 @@
#include <time.h>
/*
-** Each open database file is an instance of this structure.
+** 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
+** created but there is only a single BeFile structure with an
+** nRef of 2.
*/
typedef struct BeFile BeFile;
struct BeFile {
@@ -53,9 +58,13 @@
};
/*
-** The following are state variables for the RC4 algorithm. We
-** use RC4 as a random number generator. Each call to RC4 gives
+** The following structure holds the current state of the RC4 algorithm.
+** We use RC4 as a random number generator. Each call to RC4 gives
** a random 8-bit number.
+**
+** Nothing in this file or anywhere else in SQLite does any kind of
+** encryption. The RC4 algorithm is being used as a PRNG (pseudo-random
+** number generator) not as an encryption device.
*/
struct rc4 {
int i, j;
@@ -76,8 +85,12 @@
};
/*
-** Each file within the database is an instance of this
-** structure.
+** 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
+** a cursor pointing to a particular part of the open BeFile. The
+** BeFile.nRef field hold a count of the number of DbbeTable structures
+** associated with the same disk file.
*/
struct DbbeTable {
Dbbe *pBe; /* The database of which this record is a part */
@@ -89,16 +102,17 @@
};
/*
-** Initialize the RC4 algorithm.
+** Initialize the RC4 PRNG. "seed" is a pointer to some random
+** data used to initialize the PRNG.
*/
-static void rc4init(struct rc4 *p, char *key, int keylen){
+static void rc4init(struct rc4 *p, char *seed, int seedlen){
int i;
char k[256];
p->j = 0;
p->i = 0;
for(i=0; i<256; i++){
p->s[i] = i;
- k[i] = key[i%keylen];
+ k[i] = seed[i%seedlen];
}
for(i=0; i<256; i++){
int t;
@@ -110,7 +124,7 @@
}
/*
-** Get a single 8-bit random value from the RC4 algorithm.
+** Get a single 8-bit random value from the RC4 PRNG.
*/
static int rc4byte(struct rc4 *p){
int t;
@@ -233,7 +247,10 @@
}
/*
-** Generate a random filename with the given prefix.
+** Generate a random filename with the given prefix. The new filename
+** is written into zBuf[]. The calling function must insure that
+** zBuf[] is big enough to hold the prefix plus 20 or so extra
+** characters.
**
** Very random names are chosen so that the chance of a
** collision with an existing filename is very very small.
diff --git a/src/dbbe.h b/src/dbbe.h
index b30e04a..0edab79 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.4 2000/06/02 01:17:37 drh Exp $
+** $Id: dbbe.h,v 1.5 2000/06/17 13:12:39 drh Exp $
*/
#ifndef _SQLITE_DBBE_H_
#define _SQLITE_DBBE_H_
@@ -37,7 +37,14 @@
/*
** 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 DbbeTable is a 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
+** single arbitrary-length key and corresponding arbitrary-length
+** data. The differences between tables and indices, and the
+** 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 key and data from the last retrieval. For this reason,
@@ -91,7 +98,10 @@
int sqliteDbbeCopyKey(DbbeTable*, int offset, int size, char *zBuf);
int sqliteDbbeCopyData(DbbeTable*, int offset, int size, char *zBuf);
-/* Retrieve the key or data. The result is ephemeral.
+/* 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);
diff --git a/src/delete.c b/src/delete.c
index 493d399..e81272f 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.4 2000/06/07 23:51:50 drh Exp $
+** $Id: delete.c,v 1.5 2000/06/17 13:12:39 drh Exp $
*/
#include "sqliteInt.h"
@@ -45,8 +45,8 @@
Index *pIdx; /* For looping over indices of the table */
int base; /* Index of the first available table cursor */
- /* Locate the table which we want to update. This table has to be
- ** put in an IdList structure because some of the subroutines will
+ /* Locate the table which we want to delete. This table has to be
+ ** put in an IdList structure because some of the subroutines we
** will be calling are designed to work with multiple tables and expect
** an IdList* parameter instead of just a Table* parameger.
*/
@@ -91,7 +91,7 @@
pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1);
if( pWInfo==0 ) goto delete_from_cleanup;
- /* Remember the index of every item to be deleted.
+ /* Remember the key of every item to be deleted.
*/
sqliteVdbeAddOp(v, OP_ListWrite, 0, 0, 0, 0);
@@ -99,7 +99,9 @@
*/
sqliteWhereEnd(pWInfo);
- /* Delete every item identified in the list.
+ /* Delete every item whose key was written to the list during the
+ ** database scan. We have to delete items after the scan is complete
+ ** because deleting an item can change the scan order.
*/
base = pParse->nTab;
sqliteVdbeAddOp(v, OP_ListRewind, 0, 0, 0, 0);
diff --git a/src/expr.c b/src/expr.c
index 7ca7123..74873bc 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -21,9 +21,10 @@
** http://www.hwaci.com/drh/
**
*************************************************************************
-** This file contains C code routines used for processing expressions
+** This file contains routines used for analyzing expressions and
+** for generating VDBE code that evaluates expressions.
**
-** $Id: expr.c,v 1.16 2000/06/16 20:51:26 drh Exp $
+** $Id: expr.c,v 1.17 2000/06/17 13:12:40 drh Exp $
*/
#include "sqliteInt.h"
@@ -59,7 +60,7 @@
**
** These operators have to be processed before field names are
** resolved because each such operator increments pParse->nTab
-** to reserve a cursor number for its own use. But pParse->nTab
+** to reserve cursor numbers for its own use. But pParse->nTab
** needs to be constant once we begin resolving field names.
**
** Actually, the processing of IN-SELECT is only started by this
@@ -439,7 +440,7 @@
/*
** Generate code into the current Vdbe to evaluate the given
-** expression and leave the result on the stack.
+** expression and leave the result on the top of stack.
*/
void sqliteExprCode(Parse *pParse, Expr *pExpr){
Vdbe *v = pParse->pVdbe;
@@ -542,7 +543,7 @@
sqliteFree(z);
break;
}
- /* Fall true into TK_NOT */
+ /* Fall through into TK_NOT */
}
case TK_NOT: {
sqliteExprCode(pParse, pExpr->pLeft);
diff --git a/src/insert.c b/src/insert.c
index 2d838d4..a40ea91 100644
--- a/src/insert.c
+++ b/src/insert.c
@@ -24,23 +24,31 @@
** This file contains C code routines that are called by the parser
** to handle INSERT statements.
**
-** $Id: insert.c,v 1.9 2000/06/07 23:51:50 drh Exp $
+** $Id: insert.c,v 1.10 2000/06/17 13:12:40 drh Exp $
*/
#include "sqliteInt.h"
/*
-** This routine is call to handle SQL of the following form:
+** This routine is call to handle SQL of the following forms:
**
** insert into TABLE (IDLIST) values(EXPRLIST)
+** insert into TABLE (IDLIST) select
**
-** The parameters are the table name and the expression list.
+** 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.
+**
+** The pList parameter holds EXPRLIST in the first form of the INSERT
+** statement above, and pSelect is NULL. For the second form, pList is
+** NULL and pSelect is a pointer to the select statement used to generate
+** data for the insert.
*/
void sqliteInsert(
Parse *pParse, /* Parser context */
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 name corresponding to pList. Might be NULL */
+ IdList *pField /* Field names corresponding to IDLIST. */
){
Table *pTab; /* The table to insert into */
char *zTab; /* Name of the table into which we are inserting */
@@ -52,6 +60,8 @@
int base; /* First available cursor */
int iCont, iBreak; /* Beginning and end of the loop over srcTab */
+ /* Locate the table into which we will be inserting new information.
+ */
zTab = sqliteTableNameFromToken(pTableName);
pTab = sqliteFindTable(pParse->db, zTab);
sqliteFree(zTab);
@@ -67,8 +77,18 @@
pParse->nErr++;
goto insert_cleanup;
}
+
+ /* Allocate a VDBE
+ */
v = sqliteGetVdbe(pParse);
if( v==0 ) goto insert_cleanup;
+
+ /* Figure out how many columns of data are supplied. If the data
+ ** is comming from a SELECT statement, then this step has to generate
+ ** all the code to implement the SELECT statement and leave the data
+ ** in a temporary table. If data is coming from an expression list,
+ ** then we just have to count the number of expressions.
+ */
if( pSelect ){
int rc;
srcTab = pParse->nTab++;
@@ -82,6 +102,10 @@
assert( pList );
nField = 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 ){
char zNum1[30];
char zNum2[30];
@@ -103,6 +127,11 @@
pParse->nErr++;
goto insert_cleanup;
}
+
+ /* If the INSERT statement included an IDLIST term, then make sure
+ ** all elements of the IDLIST really are columns of the table and
+ ** remember the column indices.
+ */
if( pField ){
for(i=0; i<pField->nId; i++){
pField->a[i].idx = -1;
@@ -122,16 +151,29 @@
}
}
}
+
+ /* Open cursors into the table that is received the new data and
+ ** all indices of that table.
+ */
base = pParse->nTab;
sqliteVdbeAddOp(v, OP_Open, base, 1, pTab->zName, 0);
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
sqliteVdbeAddOp(v, OP_Open, idx+base, 1, pIdx->zName, 0);
}
+
+ /* If the data source is a SELECT statement, then we have to create
+ ** a loop because there might be multiple rows of data. If the data
+ ** source is an expression list, then exactly one row will be inserted
+ ** and the loop is not used.
+ */
if( srcTab>=0 ){
sqliteVdbeAddOp(v, OP_Rewind, srcTab, 0, 0, 0);
iBreak = sqliteVdbeMakeLabel(v);
iCont = sqliteVdbeAddOp(v, OP_Next, srcTab, iBreak, 0, 0);
}
+
+ /* Create a new entry in the table and fill it with data.
+ */
sqliteVdbeAddOp(v, OP_New, 0, 0, 0, 0);
if( pTab->pIndex ){
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
@@ -159,7 +201,10 @@
}
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0, 0, 0);
sqliteVdbeAddOp(v, OP_Put, base, 0, 0, 0);
- /* sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0); */
+
+ /* Create appropriate entries for the new data row in all indices
+ ** of the table.
+ */
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
if( pIdx->pNext ){
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
@@ -188,8 +233,10 @@
}
sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nField, 0, 0, 0);
sqliteVdbeAddOp(v, OP_PutIdx, idx+base, 0, 0, 0);
- /* sqliteVdbeAddOp(v, OP_Close, idx, 0, 0, 0); */
}
+
+ /* The bottom of the loop, if the data source is a SELECT statement
+ */
if( srcTab>=0 ){
sqliteVdbeAddOp(v, OP_Goto, 0, iCont, 0, 0);
sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, iBreak);
diff --git a/src/update.c b/src/update.c
index 2b5c444..15c7bbf 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.5 2000/06/07 23:51:51 drh Exp $
+** $Id: update.c,v 1.6 2000/06/17 13:12:40 drh Exp $
*/
#include "sqliteInt.h"
@@ -52,7 +52,7 @@
** aXRef[i]==-1 if the i-th field 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 will
+ ** put in an IdList structure because some of the subroutines we
** will be calling are designed to work with multiple tables and expect
** an IdList* parameter instead of just a Table* parameger.
*/
@@ -104,7 +104,6 @@
}
for(j=0; j<pTab->nCol; j++){
if( strcmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
- /* pChanges->a[i].idx = j; */
aXRef[j] = i;
break;
}
@@ -167,7 +166,7 @@
/* Loop over every record that needs updating. We have to load
** the old data for each record to be updated because some fields
- ** might not change and we will need to copy the old value, therefore.
+ ** might not change and we will need to copy the old value.
** Also, the old data is needed to delete the old index entires.
*/
end = sqliteVdbeMakeLabel(v);