mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
:-) (CVS 101)
FossilOrigin-Name: 6ed35a1d477906dc7e35bea0579951484fcdc858
This commit is contained in:
26
manifest
26
manifest
@ -1,17 +1,17 @@
|
||||
C :-)\s(CVS\s100)
|
||||
D 2000-06-16T20:51:26
|
||||
C :-)\s(CVS\s101)
|
||||
D 2000-06-17T13:12:39
|
||||
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 925a785da2758269cb8773691e157ea5269178ba
|
||||
F src/dbbe.c 4129779d7199c05200482046182f718a122f8c96
|
||||
F src/dbbe.h a8a46f71238e0f09f3ec08fd9d1c8c7f4cdc49bf
|
||||
F src/delete.c c267b93f7ccb5493b677fa18201880267c699aa8
|
||||
F src/expr.c a6797a4bd02b22835ffbbab8bd63dd91cc60ca3d
|
||||
F src/insert.c ac4edfff474589c00b2490f206317dc5822122e5
|
||||
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 766844e4c695d560b4df5b5999162d5e167e3c90
|
||||
F src/select.c 3a12d76074fa57d7c39c4436bdeb8d7e1eb6fdf4
|
||||
@ -20,7 +20,7 @@ F src/sqlite.h 58da0a8590133777b741f9836beaef3d58f40268
|
||||
F src/sqliteInt.h 19954bd2f75632849b265b9d7163a67391ec5148
|
||||
F src/tclsqlite.c 9f358618ae803bedf4fb96da5154fd45023bc1f7
|
||||
F src/tokenize.c 77ff8164a8751994bc9926ce282847f653ac0c16
|
||||
F src/update.c d8d90df714bac99c68446a0c49f3d957ca6fc3c8
|
||||
F src/update.c d75df0f725eb8f47c67f1745bf485607cd98cea3
|
||||
F src/util.c 38e4bb5edf6fa92e677698c45785bf73c69b9e9f
|
||||
F src/vdbe.c 00b2ab7e0c0df2ac6eb4bf659656afc30e76c66b
|
||||
F src/vdbe.h 5f58611b19799de2dbcdefa4eef33a255cfa8d0d
|
||||
@ -31,7 +31,7 @@ F test/dbbe.test 0a8e4293cf816e590dcbb01be4cd4e8f7f95bdc8
|
||||
F test/delete.test 30edd2c7484274fb2e7dbc4a1ac769bb330b322e
|
||||
F test/expr.test 09b55ccf81cb8cc2f9cd83d592a2ba187ee48ba8
|
||||
F test/in.test 962a605b6a3a619214f84d1950dfc44fcf0d8b8f
|
||||
F test/index.test 79550e86e5c6954f8b7a8a8c5221224dfd8c3f11
|
||||
F test/index.test 620ceab7165dd078d1266bdc2cac6147f04534ac
|
||||
F test/insert.test 66f4c3bd600fec8eb1e733b928cbe6fa885eff0c
|
||||
F test/insert2.test 732405e30331635af8d159fccabe835eea5cd0c6
|
||||
F test/main.test b7366cc6f3690915a11834bc1090deeff08acaf9
|
||||
@ -64,7 +64,7 @@ F www/index.tcl 4116afce6a8c63d68882d2b00aa10b079e0129cd
|
||||
F www/lang.tcl 1645e9107d75709be4c6099b643db235bbe0a151
|
||||
F www/opcode.tcl 3cdc4bb2515fcfcbe853e3f0c91cd9199e82dadd
|
||||
F www/sqlite.tcl 5420eab24b539928f80ea9b3088e2549d34f438d
|
||||
P ac38f460c8f5b9e5bb9d3cf2549f1787055f05cf
|
||||
R eb3ea9e7c9df77f640bf4616de9a692b
|
||||
P 1d4fe5599ed0bae18dba5842ab7ea1d34b8ec3ad
|
||||
R b71b1893baf0b52983e937418e80f686
|
||||
U drh
|
||||
Z 1e0f1e829cfb4a46f528efe2fb7a735b
|
||||
Z 91a05b26d5f5bffca90c2fad680404b8
|
||||
|
@ -1 +1 @@
|
||||
1d4fe5599ed0bae18dba5842ab7ea1d34b8ec3ad
|
||||
6ed35a1d477906dc7e35bea0579951484fcdc858
|
42
src/build.c
42
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 @@ Table *sqliteFindTable(sqlite *db, char *zName){
|
||||
|
||||
/*
|
||||
** 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 @@ void sqliteDeleteTable(sqlite *db, Table *pTable){
|
||||
}
|
||||
|
||||
/*
|
||||
** 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 @@ void sqliteAddDefaultValue(Parse *pParse, Token *pVal, int minusFlag){
|
||||
**
|
||||
** 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 @@ void sqliteDropTable(Parse *pParse, Token *pName){
|
||||
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 @@ void sqliteDropTable(Parse *pParse, Token *pName){
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 @@ void sqliteDropTable(Parse *pParse, Token *pName){
|
||||
** 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 @@ void sqliteCreateIndex(
|
||||
}
|
||||
|
||||
/* 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 @@ void sqliteCreateIndex(
|
||||
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 @@ void sqliteCreateIndex(
|
||||
}
|
||||
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;
|
||||
|
41
src/dbbe.c
41
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 @@ struct BeFile {
|
||||
};
|
||||
|
||||
/*
|
||||
** 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 @@ struct Dbbe {
|
||||
};
|
||||
|
||||
/*
|
||||
** 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 @@ struct DbbeTable {
|
||||
};
|
||||
|
||||
/*
|
||||
** 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 @@ static void rc4init(struct rc4 *p, char *key, int keylen){
|
||||
}
|
||||
|
||||
/*
|
||||
** 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 @@ static char *sqliteFileOfTable(Dbbe *pBe, const char *zTable){
|
||||
}
|
||||
|
||||
/*
|
||||
** 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.
|
||||
|
14
src/dbbe.h
14
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_
|
||||
@ -39,6 +39,13 @@
|
||||
** a context for the entire set of tables forming a complete
|
||||
** 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,
|
||||
** the backend must allow the creation of multiple independent
|
||||
@ -91,7 +98,10 @@ int sqliteDbbeTest(DbbeTable*, int nKey, char *pKey);
|
||||
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);
|
||||
|
12
src/delete.c
12
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 @@ void sqliteDeleteFrom(
|
||||
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 @@ void sqliteDeleteFrom(
|
||||
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 @@ void sqliteDeleteFrom(
|
||||
*/
|
||||
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);
|
||||
|
11
src/expr.c
11
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 @@ static int isConstant(Expr *p){
|
||||
**
|
||||
** 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 @@ int sqliteExprCheck(Parse *pParse, Expr *pExpr, int allowAgg, int *pIsAgg){
|
||||
|
||||
/*
|
||||
** 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 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
|
||||
sqliteFree(z);
|
||||
break;
|
||||
}
|
||||
/* Fall true into TK_NOT */
|
||||
/* Fall through into TK_NOT */
|
||||
}
|
||||
case TK_NOT: {
|
||||
sqliteExprCode(pParse, pExpr->pLeft);
|
||||
|
59
src/insert.c
59
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 @@ void sqliteInsert(
|
||||
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 @@ void sqliteInsert(
|
||||
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 @@ void sqliteInsert(
|
||||
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 @@ void sqliteInsert(
|
||||
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 @@ void sqliteInsert(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 @@ void sqliteInsert(
|
||||
}
|
||||
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 @@ void sqliteInsert(
|
||||
}
|
||||
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);
|
||||
|
@ -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 @@ void sqliteUpdate(
|
||||
** 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 @@ void sqliteUpdate(
|
||||
}
|
||||
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 @@ 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
|
||||
** 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);
|
||||
|
@ -23,7 +23,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the CREATE INDEX statement.
|
||||
#
|
||||
# $Id: index.test,v 1.4 2000/06/08 16:54:40 drh Exp $
|
||||
# $Id: index.test,v 1.5 2000/06/17 13:12:40 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -65,22 +65,22 @@ do_test index-2.1 {
|
||||
lappend v $msg
|
||||
} {1 {no such table: test1}}
|
||||
|
||||
# Try adding an index on a field of a table where the table
|
||||
# exists but the field does not.
|
||||
# Try adding an index on a column of a table where the table
|
||||
# exists but the column does not.
|
||||
#
|
||||
do_test index-2.1 {
|
||||
execsql {CREATE TABLE test1(f1 int, f2 int, f3 int)}
|
||||
set v [catch {execsql {CREATE INDEX index1 ON test1(f4)}} msg]
|
||||
lappend v $msg
|
||||
} {1 {table test1 has no field named f4}}
|
||||
} {1 {table test1 has no column named f4}}
|
||||
|
||||
# Try an index with some fields that match and others that do now.
|
||||
# Try an index with some columns that match and others that do now.
|
||||
#
|
||||
do_test index-2.2 {
|
||||
set v [catch {execsql {CREATE INDEX index1 ON test1(f1, f2, f4, f3)}} msg]
|
||||
execsql {DROP TABLE test1}
|
||||
lappend v $msg
|
||||
} {1 {table test1 has no field named f4}}
|
||||
} {1 {table test1 has no column named f4}}
|
||||
|
||||
# Try creating a bunch of indices on the same table
|
||||
#
|
||||
|
Reference in New Issue
Block a user