-C Tcl\sinterface\stransfers\svalues\sdirectly\sbetween\sSQLite\sand\sTcl_Objs,\swithout\nat\stranslation\sto\sstrings.\s(CVS\s1898)
-D 2004-08-20T18:34:20
+C Optimizations\sto\sthe\scode\sgenerator.\s(CVS\s1899)
+D 2004-08-21T17:54:45
F Makefile.in 4a5e570a9e2d35b09c31b3cf01b78cea764ade4b
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F src/auth.c 60db23b98bb94c8b0178180faaf49dc116674217
F src/btree.c 14c20dfb320473a1fd4e37d43eba5e2afd606757
F src/btree.h 94dfec0a1722d33359b23e7e310f2b64ffedf029
-F src/build.c bad6652b33a447a06fca79a257f74932412fc110
+F src/build.c 7d93b19d03bffd171f7c7873739688cab7e300c5
F src/date.c edff4aa851eeca8abbc737dc3933a2f0671156ce
-F src/delete.c e81545e546f6bc87d7508a93a09ca70695265af3
+F src/delete.c 0ccc3424d72e5aaded165a8861b9d958c9d0afe6
F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
-F src/expr.c 39ef5c141483f88c82472dbe0b5606b14d0a766d
+F src/expr.c 3694386726ca140dddb839837ba24b58563d10af
F src/func.c 7e2eeebe219aa612ce7a04c74ae6d57379c6656b
F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
-F src/insert.c bedcba371401395033a1a1c578d8fdc3fec87bec
+F src/insert.c fc1ce65a0fe68f226143de9b43c3582164a92aff
F src/legacy.c 2f3617c61bcdcd1d776154a9cfebf99facda8ad8
-F src/main.c a779422c5402df92c390e233ac32ab718fc4436b
+F src/main.c 581ccf00909842d05c42ce02bb19b92859f447db
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
F src/os.h d1780e0db95cad01f213d48da22ab490eb4fd345
F src/os_common.h cd7eb025fdab7dc91e0e97bf6310f1648205857f
F src/pager.c 2698653a3bd895b2156c108a37a32d240a55bb0e
F src/pager.h 67739fe649f33be55dba522ca8a9cc4e42d14f71
F src/parse.y 8b4cab1901900927f717d10885b7a1bd3375345b
-F src/pragma.c 5cf335adfdac453a2d03ab0c82f93847c43bea81
+F src/pragma.c a7cea75286fcff6666a5412b04478fcf0ecef5c4
F src/printf.c 17b28a1eedfe8129b05de981719306c18c3f1327
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
-F src/select.c cbed45f4af76ad7fdfc0a0df6878b2b3827ae1d4
+F src/select.c 24b9ab865e34c0d5e7f2447558f93d1fe6f9d588
F src/shell.c 42f65424a948f197f389e13bc7aaa3cf24dafd0c
F src/sqlite.h.in de2be4043f0bfa16958d33392a3e7a5e7d4bd50b
-F src/sqliteInt.h 251662c89dd35c4ed745681ff00758d19ffd0906
+F src/sqliteInt.h c7ed161ecc40f9fd0f080fbcc00e34bd7d6735ee
F src/table.c 4521c278892f60e4d630788c0ea5cf4db1e75c49
F src/tclsqlite.c 2e044cb0638c03fa38575fe607bdd4ee4885e1f4
F src/test1.c b87fae63b2994c150a579c4101f302be48ad77bc
F src/test4.c c38766914e924091516030b6a8b677d849c08bf0
F src/test5.c b001fa7f1b9e2dc5c2331de62fc641b5ab2bd7a1
F src/tokenize.c b96043fdf662d93ccfc758d3e1cdf2513f23eca2
-F src/trigger.c 360cf8f12edd4eb3a8a2895b136aac238c3cf44e
-F src/update.c b66b1896c9da54678ba3eff2bf0b4d291a95986a
+F src/trigger.c 8b147c6b8ae0bab3a13463a4ca9ab6ad61f1361d
+F src/update.c 151f1869ce532ed883f1ce26306f0b0fa7b2589a
F src/utf.c 3d8f7bffcbefcced69a436c9e0a1c7eb9e0bb4fa
F src/util.c e2c631849cc9e035f6fd387f507ad8886f77cedd
F src/vacuum.c 9978a5760c2c430bc5b5e66505a02dad76f25813
-F src/vdbe.c 281af7f601a3220e86be2152eeb2ec6d82a6f71a
-F src/vdbe.h 75b241c02431b9c0f16eaa9cdbb34146c6287f52
-F src/vdbeInt.h 5e57e36a03ebf09f2653caec0d9c18a904e0d060
-F src/vdbeapi.c 4f9b3072589dcad2fcd3abb3538e5e8f00d224a1
-F src/vdbeaux.c cc86e59cb56dad2f9335933f71268227f5f91bce
+F src/vdbe.c ea662188cc489934a567d1eaa3fb6754d5b92b7d
+F src/vdbe.h e081c72cd0f7c19d49b1927460aeefcf0fbc85ac
+F src/vdbeInt.h 16322cbfccf0b05631fcf0df68b115c46584d6c9
+F src/vdbeapi.c e20e646a0ec4e74934bfcb82bd0fbb3c3c4a21f7
+F src/vdbeaux.c 022c484dba235d2dcbb1faca0f1943702f4232ed
F src/vdbemem.c 68fefaf83adb48fe44135da01502c9327f6172b0
-F src/where.c cf8a54641eea01f1af5d09529ad69166db92f658
+F src/where.c a84eee276cd072158224da6b5f30733df2d56027
F test/all.test 3b692eb43583b52c99c344b2fa8934512d179016
F test/attach.test feb2ce54e78688df4c84553416d5aec3b2a0112e
F test/attach2.test 9be9656bc1e929b224861960299920c76d45b14d
F test/collate5.test 1dd5f0f508c46667f9d4606c7950c414b0bdc0d5
F test/collate6.test 2a45768914f04c1447a69d1358bbede376552675
F test/conflict.test c5b849b01cfbe0a4f63a90cba6f68e2fe3a75f87
-F test/crash.test 3ea432ce624369c04ba1a23a5288115e40f5daa2
+F test/crash.test 59a91b7fbb41e9e5cb8ab652f22a7e639a0adc78
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
F test/date.test fd3db29bba089578b1b008e3511ea9e74840377a
F test/delete.test ec0b455f2dcc0e189d96ee438438ba026c4e51d8
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P d3be0b7c5a39c02b9b2d6d85f1595d591984a569
-R 1cbcdf6d3d0885857959264a9f52fa75
+P e97c331362545ce21117776c7b61d3488668f2bf
+R b22d8f216bcbbb8b75e2380cdf547c74
U drh
-Z e2be1e764ed7eb73ae85dcaeb658f10f
+Z d01e8ee90bb832b679bd3adc8a30a5ef
-e97c331362545ce21117776c7b61d3488668f2bf
\ No newline at end of file
+bd6649c5aae1bf182610eb267b546c297a34481d
\ No newline at end of file
** ROLLBACK
** PRAGMA
**
-** $Id: build.c,v 1.248 2004/08/18 15:58:23 drh Exp $
+** $Id: build.c,v 1.249 2004/08/21 17:54:45 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
if( v && pParse->nErr==0 ){
FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
sqlite3VdbeTrace(v, trace);
- sqlite3VdbeMakeReady(v, pParse->nVar, pParse->explain);
+ sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem+3,
+ pParse->nTab+3, pParse->explain);
pParse->rc = pParse->nErr ? SQLITE_ERROR : SQLITE_DONE;
pParse->colNamesSet = 0;
}else if( pParse->rc==SQLITE_OK ){
** This file contains C code routines that are called by the parser
** to handle DELETE FROM statements.
**
-** $Id: delete.c,v 1.77 2004/06/21 18:14:47 drh Exp $
+** $Id: delete.c,v 1.78 2004/08/21 17:54:45 drh Exp $
*/
#include "sqliteInt.h"
*/
assert( pTabList->nSrc==1 );
iCur = pTabList->a[0].iCursor = pParse->nTab++;
- if( pWhere ){
- if( sqlite3ExprResolveIds(pParse, pTabList, 0, pWhere) ){
- goto delete_from_cleanup;
- }
- if( sqlite3ExprCheck(pParse, pWhere, 0, 0) ){
- goto delete_from_cleanup;
- }
+ if( sqlite3ExprResolveAndCheck(pParse, pTabList, 0, pWhere, 0, 0) ){
+ goto delete_from_cleanup;
}
/* Start the view context
** before the trigger fires. If there are no row triggers, the
** cursors are opened only once on the outside the loop.
*/
- pParse->nTab = iCur + 1;
- sqlite3OpenTableAndIndices(pParse, pTab, iCur);
+ sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);
/* This is the beginning of the delete loop when there are no
** row triggers */
sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
}
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
- pParse->nTab = iCur;
}
}
sqlite3EndWriteOperation(pParse);
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
-** $Id: expr.c,v 1.156 2004/08/20 16:02:39 drh Exp $
+** $Id: expr.c,v 1.157 2004/08/21 17:54:45 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
return nErr;
}
+/*
+** Call sqlite3ExprResolveIds() followed by sqlite3ExprCheck().
+**
+** This routine is provided as a convenience since it is very common
+** to call ResolveIds() and Check() back to back.
+*/
+int sqlite3ExprResolveAndCheck(
+ Parse *pParse, /* The parser context */
+ SrcList *pSrcList, /* List of tables used to resolve column names */
+ ExprList *pEList, /* List of expressions used to resolve "AS" */
+ Expr *pExpr, /* The expression to be analyzed. */
+ int allowAgg, /* True to allow aggregate expressions */
+ int *pIsAgg /* Set to TRUE if aggregates are found */
+){
+ if( pExpr==0 ) return 0;
+ if( sqlite3ExprResolveIds(pParse,pSrcList,pEList,pExpr) ){
+ return 1;
+ }
+ return sqlite3ExprCheck(pParse, pExpr, allowAgg, pIsAgg);
+}
+
/*
** Generate an instruction that will put the integer describe by
** text z[0..n-1] on the stack.
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
-** $Id: insert.c,v 1.114 2004/07/24 17:38:29 drh Exp $
+** $Id: insert.c,v 1.115 2004/08/21 17:54:45 drh Exp $
*/
#include "sqliteInt.h"
nColumn = pList->nExpr;
dummy.nSrc = 0;
for(i=0; i<nColumn; i++){
- if( sqlite3ExprResolveIds(pParse, &dummy, 0, pList->a[i].pExpr) ){
- goto insert_cleanup;
- }
- if( sqlite3ExprCheck(pParse, pList->a[i].pExpr, 0, 0) ){
+ if( sqlite3ExprResolveAndCheck(pParse,&dummy,0,pList->a[i].pExpr,0,0) ){
goto insert_cleanup;
}
}
/* Open tables and indices if there are no row triggers */
if( !row_triggers_exist ){
base = pParse->nTab;
- idx = sqlite3OpenTableAndIndices(pParse, pTab, base);
- pParse->nTab += idx;
+ sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite);
}
/* If the data source is a temporary table, then we have to create
*/
if( row_triggers_exist && !isView ){
base = pParse->nTab;
- idx = sqlite3OpenTableAndIndices(pParse, pTab, base);
- pParse->nTab += idx;
+ sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite);
}
/* Push the record number for the new entry onto the stack. The
}
/*
-** Generate code that will open write cursors for a table and for all
+** Generate code that will open cursors for a table and for all
** indices of that table. The "base" parameter is the cursor number used
** for the table. Indices are opened on subsequent cursors.
-**
-** Return the total number of cursors opened. This is always at least
-** 1 (for the main table) plus more for each cursor.
*/
-int sqlite3OpenTableAndIndices(Parse *pParse, Table *pTab, int base){
+void sqlite3OpenTableAndIndices(
+ Parse *pParse, /* Parsing context */
+ Table *pTab, /* Table to be opened */
+ int base, /* Cursor number assigned to the table */
+ int op /* OP_OpenRead or OP_OpenWrite */
+){
int i;
Index *pIdx;
Vdbe *v = sqlite3GetVdbe(pParse);
assert( v!=0 );
sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
- sqlite3VdbeAddOp(v, OP_OpenWrite, base, pTab->tnum);
+ sqlite3VdbeAddOp(v, op, base, pTab->tnum);
sqlite3VdbeAddOp(v, OP_SetNumColumns, base, pTab->nCol);
for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
- sqlite3VdbeOp3(v, OP_OpenWrite, i+base, pIdx->tnum,
+ sqlite3VdbeOp3(v, op, i+base, pIdx->tnum,
(char*)&pIdx->keyInfo, P3_KEYINFO);
}
- return i;
+ if( pParse->nTab<=base+i ){
+ pParse->nTab = base+i;
+ }
}
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: main.c,v 1.252 2004/08/18 02:10:15 drh Exp $
+** $Id: main.c,v 1.253 2004/08/21 17:54:45 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
*/
int sqlite3_reset(sqlite3_stmt *pStmt){
int rc = sqlite3VdbeReset((Vdbe*)pStmt);
- sqlite3VdbeMakeReady((Vdbe*)pStmt, -1, 0);
+ sqlite3VdbeMakeReady((Vdbe*)pStmt, -1, 0, 0, 0);
return rc;
}
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
-** $Id: pragma.c,v 1.59 2004/08/08 20:22:18 drh Exp $
+** $Id: pragma.c,v 1.60 2004/08/21 17:54:45 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
{ OP_MemLoad, 0, 0, 0},
{ OP_Integer, 0, 0, 0},
{ OP_Ne, 0, 0, 0}, /* 2 */
- { OP_String8, 0, 0, "ok"},
+ { OP_String8, 0, 0, "ok"},
{ OP_Callback, 1, 0, 0},
};
int loopTop;
if( pTab->pIndex==0 ) continue;
- sqlite3VdbeAddOp(v, OP_Integer, i, 0);
- sqlite3VdbeAddOp(v, OP_OpenRead, 1, pTab->tnum);
- sqlite3VdbeAddOp(v, OP_SetNumColumns, 1, pTab->nCol);
- for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
- if( pIdx->tnum==0 ) continue;
- sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
- sqlite3VdbeOp3(v, OP_OpenRead, j+2, pIdx->tnum,
- (char*)&pIdx->keyInfo, P3_KEYINFO);
- }
+ sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
sqlite3VdbeAddOp(v, OP_MemStore, 1, 1);
loopTop = sqlite3VdbeAddOp(v, OP_Rewind, 1, 0);
int jmp2;
static VdbeOpList idxErr[] = {
{ OP_MemIncr, 0, 0, 0},
- { OP_String8, 0, 0, "rowid "},
+ { OP_String8, 0, 0, "rowid "},
{ OP_Recno, 1, 0, 0},
- { OP_String8, 0, 0, " missing from index "},
- { OP_String8, 0, 0, 0}, /* 4 */
- { OP_Concat8, 4, 0, 0},
+ { OP_String8, 0, 0, " missing from index "},
+ { OP_String8, 0, 0, 0}, /* 4 */
+ { OP_Concat8, 4, 0, 0},
{ OP_Callback, 1, 0, 0},
};
sqlite3GenerateIndexKey(v, pIdx, 1);
{ OP_MemLoad, 2, 0, 0},
{ OP_Eq, 0, 0, 0}, /* 7 */
{ OP_MemIncr, 0, 0, 0},
- { OP_String8, 0, 0, "wrong # of entries in index "},
- { OP_String8, 0, 0, 0}, /* 10 */
- { OP_Concat8, 2, 0, 0},
+ { OP_String8, 0, 0, "wrong # of entries in index "},
+ { OP_String8, 0, 0, 0}, /* 10 */
+ { OP_Concat8, 2, 0, 0},
{ OP_Callback, 1, 0, 0},
};
if( pIdx->tnum==0 ) continue;
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
-** $Id: select.c,v 1.202 2004/07/26 23:32:27 drh Exp $
+** $Id: select.c,v 1.203 2004/08/21 17:54:45 drh Exp $
*/
#include "sqliteInt.h"
Token *p;
static struct {
const char *zKeyword;
- int nChar;
- int code;
+ u8 nChar;
+ u8 code;
} keywords[] = {
{ "natural", 7, JT_NATURAL },
{ "left", 4, JT_LEFT|JT_OUTER },
Table *pTab;
int i, j;
ExprList *pEList;
- Column *aCol;
+ Column *aCol, *pCol;
if( fillInColumnList(pParse, pSelect) ){
return 0;
pTab->nCol = pEList->nExpr;
assert( pTab->nCol>0 );
pTab->aCol = aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol );
- for(i=0; i<pTab->nCol; i++){
+ for(i=0, pCol=aCol; i<pTab->nCol; i++, pCol++){
Expr *pR;
char *zType;
Expr *p = pEList->a[i].pExpr;
+ assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 );
if( pEList->a[i].zName ){
- aCol[i].zName = sqliteStrDup(pEList->a[i].zName);
+ pCol->zName = sqliteStrDup(pEList->a[i].zName);
}else if( p->op==TK_DOT
&& (pR=p->pRight)!=0 && pR->token.z && pR->token.z[0] ){
int cnt;
- sqlite3SetNString(&aCol[i].zName, pR->token.z, pR->token.n, 0);
+ sqlite3SetNString(&pCol->zName, pR->token.z, pR->token.n, 0);
for(j=cnt=0; j<i; j++){
- if( sqlite3StrICmp(aCol[j].zName, aCol[i].zName)==0 ){
+ if( sqlite3StrICmp(aCol[j].zName, pCol->zName)==0 ){
int n;
char zBuf[30];
sprintf(zBuf,"_%d",++cnt);
n = strlen(zBuf);
- sqlite3SetNString(&aCol[i].zName, pR->token.z, pR->token.n, zBuf,n,0);
+ sqlite3SetNString(&pCol->zName, pR->token.z, pR->token.n, zBuf,n,0);
j = -1;
}
}
}else if( p->span.z && p->span.z[0] ){
- sqlite3SetNString(&pTab->aCol[i].zName, p->span.z, p->span.n, 0);
+ sqlite3SetNString(&pCol->zName, p->span.z, p->span.n, 0);
}else{
char zBuf[30];
sprintf(zBuf, "column%d", i+1);
- pTab->aCol[i].zName = sqliteStrDup(zBuf);
+ pCol->zName = sqliteStrDup(zBuf);
}
- sqlite3Dequote(aCol[i].zName);
+ sqlite3Dequote(pCol->zName);
zType = sqliteStrDup(columnType(pParse, pSelect->pSrc ,p));
- pTab->aCol[i].zType = zType;
- pTab->aCol[i].affinity = SQLITE_AFF_NUMERIC;
+ pCol->zType = zType;
+ pCol->affinity = SQLITE_AFF_NUMERIC;
if( zType ){
- pTab->aCol[i].affinity = sqlite3AffinityType(zType, strlen(zType));
+ pCol->affinity = sqlite3AffinityType(zType, strlen(zType));
}
- pTab->aCol[i].pColl = sqlite3ExprCollSeq(pParse, p);
- if( !pTab->aCol[i].pColl ){
- pTab->aCol[i].pColl = pParse->db->pDfltColl;
+ pCol->pColl = sqlite3ExprCollSeq(pParse, p);
+ if( !pCol->pColl ){
+ pCol->pColl = pParse->db->pDfltColl;
}
}
pTab->iPKey = -1;
SrcList *pTabList;
ExprList *pEList;
Table *pTab;
+ struct SrcList_item *pFrom;
if( p==0 || p->pSrc==0 ) return 1;
pTabList = p->pSrc;
/* Look up every table in the table list.
*/
- for(i=0; i<pTabList->nSrc; i++){
- if( pTabList->a[i].pTab ){
+ for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
+ if( pFrom->pTab ){
/* This routine has run before! No need to continue */
return 0;
}
- if( pTabList->a[i].zName==0 ){
+ if( pFrom->zName==0 ){
/* A sub-query in the FROM clause of a SELECT */
- assert( pTabList->a[i].pSelect!=0 );
- if( pTabList->a[i].zAlias==0 ){
+ assert( pFrom->pSelect!=0 );
+ if( pFrom->zAlias==0 ){
char zFakeName[60];
- sprintf(zFakeName, "sqlite_subquery_%p_",
- (void*)pTabList->a[i].pSelect);
- sqlite3SetString(&pTabList->a[i].zAlias, zFakeName, 0);
+ sprintf(zFakeName, "sqlite_subquery_%p_", (void*)pFrom->pSelect);
+ sqlite3SetString(&pFrom->zAlias, zFakeName, 0);
}
- pTabList->a[i].pTab = pTab =
- sqlite3ResultSetOfSelect(pParse, pTabList->a[i].zAlias,
- pTabList->a[i].pSelect);
+ pFrom->pTab = pTab =
+ sqlite3ResultSetOfSelect(pParse, pFrom->zAlias, pFrom->pSelect);
if( pTab==0 ){
return 1;
}
pTab->isTransient = 1;
}else{
/* An ordinary table or view name in the FROM clause */
- pTabList->a[i].pTab = pTab =
- sqlite3LocateTable(pParse,pTabList->a[i].zName,pTabList->a[i].zDatabase);
+ pFrom->pTab = pTab =
+ sqlite3LocateTable(pParse,pFrom->zName,pFrom->zDatabase);
if( pTab==0 ){
return 1;
}
if( sqlite3ViewGetColumnNames(pParse, pTab) ){
return 1;
}
- /* If pTabList->a[i].pSelect!=0 it means we are dealing with a
+ /* If pFrom->pSelect!=0 it means we are dealing with a
** view within a view. The SELECT structure has already been
** copied by the outer view so we can skip the copy step here
** in the inner view.
*/
- if( pTabList->a[i].pSelect==0 ){
- pTabList->a[i].pSelect = sqlite3SelectDup(pTab->pSelect);
+ if( pFrom->pSelect==0 ){
+ pFrom->pSelect = sqlite3SelectDup(pTab->pSelect);
}
}
}
}else{
zTName = 0;
}
- for(i=0; i<pTabList->nSrc; i++){
- Table *pTab = pTabList->a[i].pTab;
- char *zTabName = pTabList->a[i].zAlias;
+ for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
+ Table *pTab = pFrom->pTab;
+ char *zTabName = pFrom->zAlias;
if( zTabName==0 || zTabName[0]==0 ){
zTabName = pTab->zName;
}
return v;
}
-#if 0 /***** This routine needs deleting *****/
-static void multiSelectAffinity(Select *p, char *zAff){
- int i;
-
- if( !p ) return;
- multiSelectAffinity(p->pPrior, zAff);
-
- for(i=0; i<p->pEList->nExpr; i++){
- if( zAff[i]=='\0' ){
- zAff[i] = sqlite3ExprAffinity(p->pEList->a[i].pExpr);
- }
- }
-}
-#endif
-
/*
** Compute the iLimit and iOffset fields of the SELECT based on the
** nLimit and nOffset fields. nLimit and nOffset hold the integers
return 1;
}
+/*
+** Analyze and ORDER BY or GROUP BY clause in a SELECT statement. Return
+** the number of errors seen.
+**
+** An ORDER BY or GROUP BY is a list of expressions. If any expression
+** is an integer constant, then that expression is replaced by the
+** corresponding entry in the result set.
+*/
+static int processOrderGroupBy(
+ Parse *pParse, /* Parsing context */
+ ExprList *pOrderBy, /* The ORDER BY or GROUP BY clause to be processed */
+ SrcList *pTabList, /* The FROM clause */
+ ExprList *pEList, /* The result set */
+ int isAgg, /* True if aggregate functions are involved */
+ const char *zType /* Either "ORDER" or "GROUP", as appropriate */
+){
+ int i;
+ if( pOrderBy==0 ) return 0;
+ for(i=0; i<pOrderBy->nExpr; i++){
+ int iCol;
+ Expr *pE = pOrderBy->a[i].pExpr;
+ if( sqlite3ExprIsInteger(pE, &iCol) && iCol>0 && iCol<=pEList->nExpr ){
+ sqlite3ExprDelete(pE);
+ pE = pOrderBy->a[i].pExpr = sqlite3ExprDup(pEList->a[iCol-1].pExpr);
+ }
+ if( sqlite3ExprResolveAndCheck(pParse, pTabList, pEList, pE, isAgg, 0) ){
+ return 1;
+ }
+ if( sqlite3ExprIsConstant(pE) ){
+ if( sqlite3ExprIsInteger(pE, &iCol)==0 ){
+ sqlite3ErrorMsg(pParse,
+ "%s BY terms must not be non-integer constants", zType);
+ return 1;
+ }else if( iCol<=0 || iCol>pEList->nExpr ){
+ sqlite3ErrorMsg(pParse,
+ "%s BY column number %d out of range - should be "
+ "between 1 and %d", zType, iCol, pEList->nExpr);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
/*
** Generate code for the given SELECT statement.
**
** Resolve the column names and do a semantics check on all the expressions.
*/
for(i=0; i<pEList->nExpr; i++){
- if( sqlite3ExprResolveIds(pParse, pTabList, 0, pEList->a[i].pExpr) ){
- goto select_end;
- }
- if( sqlite3ExprCheck(pParse, pEList->a[i].pExpr, 1, &isAgg) ){
+ if( sqlite3ExprResolveAndCheck(pParse, pTabList, 0, pEList->a[i].pExpr,
+ 1, &isAgg) ){
goto select_end;
}
}
- if( pWhere ){
- if( sqlite3ExprResolveIds(pParse, pTabList, pEList, pWhere) ){
- goto select_end;
- }
- if( sqlite3ExprCheck(pParse, pWhere, 0, 0) ){
- goto select_end;
- }
+ if( sqlite3ExprResolveAndCheck(pParse, pTabList, pEList, pWhere, 0, 0) ){
+ goto select_end;
}
if( pHaving ){
if( pGroupBy==0 ){
sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING");
goto select_end;
}
- if( sqlite3ExprResolveIds(pParse, pTabList, pEList, pHaving) ){
- goto select_end;
- }
- if( sqlite3ExprCheck(pParse, pHaving, 1, &isAgg) ){
+ if( sqlite3ExprResolveAndCheck(pParse, pTabList, pEList,pHaving,1,&isAgg) ){
goto select_end;
}
}
- if( pOrderBy ){
- for(i=0; i<pOrderBy->nExpr; i++){
- int iCol;
- Expr *pE = pOrderBy->a[i].pExpr;
- if( sqlite3ExprIsInteger(pE, &iCol) && iCol>0 && iCol<=pEList->nExpr ){
- sqlite3ExprDelete(pE);
- pE = pOrderBy->a[i].pExpr = sqlite3ExprDup(pEList->a[iCol-1].pExpr);
- }
- if( sqlite3ExprResolveIds(pParse, pTabList, pEList, pE) ){
- goto select_end;
- }
- if( sqlite3ExprCheck(pParse, pE, isAgg, 0) ){
- goto select_end;
- }
- if( sqlite3ExprIsConstant(pE) ){
- if( sqlite3ExprIsInteger(pE, &iCol)==0 ){
- sqlite3ErrorMsg(pParse,
- "ORDER BY terms must not be non-integer constants");
- goto select_end;
- }else if( iCol<=0 || iCol>pEList->nExpr ){
- sqlite3ErrorMsg(pParse,
- "ORDER BY column number %d out of range - should be "
- "between 1 and %d", iCol, pEList->nExpr);
- goto select_end;
- }
- }
- }
- }
- if( pGroupBy ){
- for(i=0; i<pGroupBy->nExpr; i++){
- int iCol;
- Expr *pE = pGroupBy->a[i].pExpr;
- if( sqlite3ExprIsInteger(pE, &iCol) && iCol>0 && iCol<=pEList->nExpr ){
- sqlite3ExprDelete(pE);
- pE = pGroupBy->a[i].pExpr = sqlite3ExprDup(pEList->a[iCol-1].pExpr);
- }
- if( sqlite3ExprResolveIds(pParse, pTabList, pEList, pE) ){
- goto select_end;
- }
- if( sqlite3ExprCheck(pParse, pE, isAgg, 0) ){
- goto select_end;
- }
- if( sqlite3ExprIsConstant(pE) ){
- if( sqlite3ExprIsInteger(pE, &iCol)==0 ){
- sqlite3ErrorMsg(pParse,
- "GROUP BY terms must not be non-integer constants");
- goto select_end;
- }else if( iCol<=0 || iCol>pEList->nExpr ){
- sqlite3ErrorMsg(pParse,
- "GROUP BY column number %d out of range - should be "
- "between 1 and %d", iCol, pEList->nExpr);
- goto select_end;
- }
- }
- }
+ if( processOrderGroupBy(pParse, pOrderBy, pTabList, pEList, isAgg, "ORDER")
+ || processOrderGroupBy(pParse, pGroupBy, pTabList, pEList, isAgg, "GROUP")
+ ){
+ goto select_end;
}
/* Begin generating code.
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.315 2004/08/08 20:22:18 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.316 2004/08/21 17:54:45 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
int iContinue; /* Jump here to continue with next record */
int iBreak; /* Jump here to break out of the loop */
int nLevel; /* Number of nested loop */
- int savedNTab; /* Value of pParse->nTab before WhereBegin() */
- int peakNTab; /* Value of pParse->nTab after WhereBegin() */
WhereLevel a[1]; /* Information about each nest loop in the WHERE */
};
int sqlite3ExprCompare(Expr*, Expr*);
int sqliteFuncId(Token*);
int sqlite3ExprResolveIds(Parse*, SrcList*, ExprList*, Expr*);
+int sqlite3ExprResolveAndCheck(Parse*,SrcList*,ExprList*,Expr*,int,int*);
int sqlite3ExprAnalyzeAggregates(Parse*, Expr*);
Vdbe *sqlite3GetVdbe(Parse*);
void sqlite3Randomness(int, void*);
void sqlite3GenerateIndexKey(Vdbe*, Index*, int);
void sqlite3GenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
void sqlite3CompleteInsertion(Parse*, Table*, int, char*, int, int, int);
-int sqlite3OpenTableAndIndices(Parse*, Table*, int);
+void sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
void sqlite3BeginWriteOperation(Parse*, int, int);
void sqlite3EndWriteOperation(Parse*);
Expr *sqlite3ExprDup(Expr*);
int orconf;
while( pTriggerStep ){
- int saveNTab = pParse->nTab;
-
orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
pParse->trigStack->orconf = orconf;
switch( pTriggerStep->op ){
default:
assert(0);
}
- pParse->nTab = saveNTab;
pTriggerStep = pTriggerStep->pNext;
}
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
-** $Id: update.c,v 1.85 2004/06/21 06:50:29 danielk1977 Exp $
+** $Id: update.c,v 1.86 2004/08/21 17:54:45 drh Exp $
*/
#include "sqliteInt.h"
*/
chngRecno = 0;
for(i=0; i<pChanges->nExpr; i++){
- if( sqlite3ExprResolveIds(pParse, pTabList, 0, pChanges->a[i].pExpr) ){
- goto update_cleanup;
- }
- if( sqlite3ExprCheck(pParse, pChanges->a[i].pExpr, 0, 0) ){
+ if( sqlite3ExprResolveAndCheck(pParse, pTabList, 0,
+ pChanges->a[i].pExpr, 0, 0) ){
goto update_cleanup;
}
for(j=0; j<pTab->nCol; j++){
/* Resolve the column names in all the expressions in the
** WHERE clause.
*/
- if( pWhere ){
- if( sqlite3ExprResolveIds(pParse, pTabList, 0, pWhere) ){
- goto update_cleanup;
- }
- if( sqlite3ExprCheck(pParse, pWhere, 0, 0) ){
- goto update_cleanup;
- }
+ if( sqlite3ExprResolveAndCheck(pParse, pTabList, 0, pWhere, 0, 0) ){
+ goto update_cleanup;
}
/* Start the view context
sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0);
}
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
- pParse->nTab = iCur;
}
if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_AFTER, pTab,
newIdx, oldIdx, onError, addr) ){
}
}
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
- pParse->nTab = iCur;
}else{
sqlite3VdbeAddOp(v, OP_Close, newIdx, 0);
sqlite3VdbeAddOp(v, OP_Close, oldIdx, 0);
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
-** $Id: vdbe.c,v 1.408 2004/08/08 23:39:19 drh Exp $
+** $Id: vdbe.c,v 1.409 2004/08/21 17:54:45 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
*/
static Cursor *allocateCursor(Vdbe *p, int iCur){
Cursor *pCx;
- if( iCur>=p->nCursor ){
- int i;
- p->apCsr = sqliteRealloc( p->apCsr, (iCur+1)*sizeof(Cursor*) );
- if( p->apCsr==0 ){
- p->nCursor = 0;
- return 0;
- }
- for(i=p->nCursor; i<iCur; i++){
- p->apCsr[i] = 0;
- }
- p->nCursor = iCur+1;
- }else if( p->apCsr[iCur] ){
+ assert( iCur<p->nCursor );
+ if( p->apCsr[iCur] ){
sqlite3VdbeFreeCursor(p->apCsr[iCur]);
}
p->apCsr[iCur] = pCx = sqliteMalloc( sizeof(Cursor) );
assert( j>=0 && j<p->nVar );
pTos++;
- /* sqlite3VdbeMemCopyStatic(pTos, &p->apVar[j]); */
- memcpy(pTos, &p->apVar[j], sizeof(*pTos)-NBFS);
+ memcpy(pTos, &p->aVar[j], sizeof(*pTos)-NBFS);
pTos->xDel = 0;
if( pTos->flags&(MEM_Str|MEM_Blob) ){
pTos->flags &= ~(MEM_Dyn|MEM_Ephem|MEM_Short);
p->pSort = pElem->pNext;
pElem->pNext = 0;
for(i=0; i<NSORT-1; i++){
- if( apSorter[i]==0 ){
+ if( apSorter[i]==0 ){
apSorter[i] = pElem;
break;
}else{
int i = pOp->p1;
Mem *pMem;
assert( pTos>=p->aStack );
- if( i>=p->nMem ){
- int nOld = p->nMem;
- Mem *aMem;
- p->nMem = i + 5;
- aMem = sqliteRealloc(p->aMem, p->nMem*sizeof(p->aMem[0]));
- if( aMem==0 ) goto no_mem;
- if( aMem!=p->aMem ){
- int j;
- for(j=0; j<nOld; j++){
- if( aMem[j].flags & MEM_Short ){
- aMem[j].z = aMem[j].zShort;
- }
- }
- }
- p->aMem = aMem;
- if( nOld<p->nMem ){
- memset(&p->aMem[nOld], 0, sizeof(p->aMem[0])*(p->nMem-nOld));
- }
- }
+ assert( i<p->nMem );
Deephemeralize(pTos);
pMem = &p->aMem[i];
Release(pMem);
*pMem = *pTos;
- if( pMem->flags & MEM_Dyn ){
- if( pOp->p2 ){
- pTos->flags = MEM_Null;
- }else{
- pMem->z = sqliteMallocRaw( pMem->n+2 );
- if( pMem->z==0 ) goto no_mem;
- memcpy(pMem->z, pTos->z, pMem->n);
- memcpy(&pMem->z[pMem->n], "\000", 2);
- pMem->flags |= MEM_Term;
- }
- }else if( pMem->flags & MEM_Short ){
+ pTos->flags = MEM_Null;
+ if( pMem->flags & MEM_Short ){
pMem->z = pMem->zShort;
}
+ pTos--;
+
+ /* If P2 is 0 then fall thru to the next opcode, OP_MemLoad, that will
+ ** restore the top of the stack to its original value.
+ */
if( pOp->p2 ){
- Release(pTos);
- pTos--;
+ break;
}
- break;
}
-
/* Opcode: MemLoad P1 * *
**
** Push a copy of the value in memory location P1 onto the stack.
if( res==0 ){
rc = sqlite3BtreeData(p->agg.pCsr, 0, sizeof(AggElem*),
(char *)&p->agg.pCurrent);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
pc = pOp->p2 - 1;
}else{
rc = AggInsert(&p->agg, zKey, nKey);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
+ }
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
}
Release(pTos);
pTos--;
pMem = &pFocus->aMem[i];
Release(pMem);
*pMem = *pTos;
- if( pMem->flags & MEM_Dyn ){
- pTos->flags = MEM_Null;
- }else if( pMem->flags & MEM_Short ){
+ pTos->flags = MEM_Null;
+ if( pMem->flags & MEM_Short ){
pMem->z = pMem->zShort;
}
pTos--;
*/
case OP_AggNext: {
int res;
+ assert( rc==SQLITE_OK );
CHECK_FOR_INTERRUPT;
if( p->agg.searching==0 ){
p->agg.searching = 1;
if( p->agg.pCsr ){
rc = sqlite3BtreeFirst(p->agg.pCsr, &res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
}else{
res = 0;
}
}else{
if( p->agg.pCsr ){
rc = sqlite3BtreeNext(p->agg.pCsr, &res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
}else{
res = 1;
}
}
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
if( res!=0 ){
pc = pOp->p2 - 1;
}else{
}
aMem = p->agg.pCurrent->aMem;
for(i=0; i<p->agg.nMem; i++){
- int freeCtx;
- if( p->agg.apFunc[i]==0 ) continue;
- if( p->agg.apFunc[i]->xFinalize==0 ) continue;
+ FuncDef *pFunc = p->agg.apFunc[i];
+ Mem *pMem = &aMem[i];
+ if( pFunc==0 || pFunc->xFinalize==0 ) continue;
ctx.s.flags = MEM_Null;
- ctx.s.z = aMem[i].zShort;
- ctx.pAgg = (void*)aMem[i].z;
- ctx.cnt = aMem[i].i;
+ ctx.s.z = pMem->zShort;
+ ctx.pAgg = (void*)pMem->z;
+ ctx.cnt = pMem->i;
ctx.isStep = 0;
- ctx.pFunc = p->agg.apFunc[i];
- (*p->agg.apFunc[i]->xFinalize)(&ctx);
- aMem[i].z = ctx.pAgg;
- freeCtx = aMem[i].z && aMem[i].z!=aMem[i].zShort;
- if( freeCtx ){
- sqliteFree( aMem[i].z );
+ ctx.pFunc = pFunc;
+ pFunc->xFinalize(&ctx);
+ pMem->z = ctx.pAgg;
+ if( pMem->z && pMem->z!=pMem->zShort ){
+ sqliteFree( pMem->z );
}
- aMem[i] = ctx.s;
- if( aMem[i].flags & MEM_Short ){
- aMem[i].z = aMem[i].zShort;
+ *pMem = ctx.s;
+ if( pMem->flags & MEM_Short ){
+ pMem->z = pMem->zShort;
}
}
}
** or VDBE. The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
-** $Id: vdbe.h,v 1.89 2004/06/27 21:31:40 drh Exp $
+** $Id: vdbe.h,v 1.90 2004/08/21 17:54:45 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
int sqlite3VdbeMakeLabel(Vdbe*);
void sqlite3VdbeDelete(Vdbe*);
-void sqlite3VdbeMakeReady(Vdbe*,int,int);
+void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int);
int sqlite3VdbeFinalize(Vdbe*);
void sqlite3VdbeResolveLabel(Vdbe*, int);
int sqlite3VdbeCurrentAddr(Vdbe*);
int nCursor; /* Number of slots in apCsr[] */
Cursor **apCsr; /* One element of this array for each open cursor */
Sorter *pSort; /* A linked list of objects to be sorted */
- FILE *pFile; /* At most one open file handler */
- int nField; /* Number of file fields */
- char **azField; /* Data for each file field */
- int nVar; /* Number of entries in apVar[] */
- Mem *apVar; /* Values for the OP_Variable opcode. */
+ int nVar; /* Number of entries in aVar[] */
+ Mem *aVar; /* Values for the OP_Variable opcode. */
char **azVar; /* Name of variables */
int okVar; /* True if azVar[] has been initialized */
- char *zLine; /* A single line from the input file */
- int nLineAlloc; /* Number of spaces allocated for zLine */
int magic; /* Magic number for sanity checking */
int nMem; /* Number of memory locations currently allocated */
Mem *aMem; /* The memory locations */
return SQLITE_RANGE;
}
i--;
- pVar = &p->apVar[i];
+ pVar = &p->aVar[i];
sqlite3VdbeMemRelease(pVar);
pVar->flags = MEM_Null;
sqlite3Error(p->db, SQLITE_OK, 0);
if( rc || zData==0 ){
return rc;
}
- pVar = &p->apVar[i-1];
+ pVar = &p->aVar[i-1];
rc = sqlite3VdbeMemSetStr(pVar, zData, nData, 0, xDel);
return rc;
}
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
- sqlite3VdbeMemSetDouble(&p->apVar[i-1], rValue);
+ sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue);
}
return rc;
}
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
- sqlite3VdbeMemSetInt64(&p->apVar[i-1], iValue);
+ sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue);
}
return rc;
}
if( rc || zData==0 ){
return rc;
}
- pVar = &p->apVar[i-1];
+ pVar = &p->aVar[i-1];
rc = sqlite3VdbeMemSetStr(pVar, zData, nData, SQLITE_UTF8, xDel);
if( rc ){
return rc;
if( rc || zData==0 ){
return rc;
}
- pVar = &p->apVar[i-1];
+ pVar = &p->aVar[i-1];
rc = sqlite3VdbeMemSetStr(pVar, zData, nData, SQLITE_UTF16NATIVE, xDel);
if( rc ){
void sqlite3VdbeMakeReady(
Vdbe *p, /* The VDBE */
int nVar, /* Number of '?' see in the SQL statement */
+ int nMem, /* Number of memory cells to allocate */
+ int nCursor, /* Number of cursors to allocate */
int isExplain /* True if the EXPLAIN keywords is present */
){
int n;
** Allocation all the stack space we will ever need.
*/
if( p->aStack==0 ){
- p->nVar = nVar;
assert( nVar>=0 );
n = isExplain ? 10 : p->nOp;
p->aStack = sqliteMalloc(
n*(sizeof(p->aStack[0])+sizeof(Mem*)) /* aStack, apArg */
- + p->nVar*sizeof(Mem) /* apVar */
- + p->nVar*sizeof(char*) /* apVarName */
+ + nVar*sizeof(Mem) /* aVar */
+ + nVar*sizeof(char*) /* azVar */
+ + nMem*sizeof(Mem) /* aMem */
+ + nCursor*sizeof(Cursor*) /* apCsr */
);
- p->apArg = (Mem **)&p->aStack[n];
- p->apVar = (Mem *)&p->apArg[n];
- p->azVar = (char**)&p->apVar[p->nVar];
- p->okVar = 0;
- for(n=0; n<p->nVar; n++){
- p->apVar[n].flags = MEM_Null;
+ if( !sqlite3_malloc_failed ){
+ p->apArg = (Mem **)&p->aStack[n];
+ p->aVar = (Mem *)&p->apArg[n];
+ p->azVar = (char**)&p->aVar[nVar];
+ p->okVar = 0;
+ p->nVar = nVar;
+ p->aMem = (Mem*)&p->azVar[nVar];
+ p->nMem = nMem;
+ p->apCsr = (Cursor**)&p->aMem[nMem];
+ p->nCursor = nCursor;
+ for(n=0; n<nVar; n++){
+ p->aVar[n].flags = MEM_Null;
+ }
+ for(n=0; n<nMem; n++){
+ p->aMem[n].flags = MEM_Null;
+ }
}
}
*/
static void closeAllCursors(Vdbe *p){
int i;
+ if( p->apCsr==0 ) return;
for(i=0; i<p->nCursor; i++){
sqlite3VdbeFreeCursor(p->apCsr[i]);
+ p->apCsr[i] = 0;
}
- sqliteFree(p->apCsr);
- p->apCsr = 0;
- p->nCursor = 0;
}
/*
p->pTos = pTos;
}
closeAllCursors(p);
- if( p->aMem ){
- for(i=0; i<p->nMem; i++){
- sqlite3VdbeMemRelease(&p->aMem[i]);
- }
+ for(i=0; i<p->nMem; i++){
+ sqlite3VdbeMemRelease(&p->aMem[i]);
}
- sqliteFree(p->aMem);
- p->aMem = 0;
- p->nMem = 0;
if( p->pList ){
sqlite3VdbeKeylistFree(p->pList);
p->pList = 0;
}
sqlite3VdbeSorterReset(p);
- if( p->pFile ){
- if( p->pFile!=stdin ) fclose(p->pFile);
- p->pFile = 0;
- }
- if( p->azField ){
- sqliteFree(p->azField);
- p->azField = 0;
- }
- p->nField = 0;
- if( p->zLine ){
- sqliteFree(p->zLine);
- p->zLine = 0;
- }
- p->nLineAlloc = 0;
sqlite3VdbeAggReset(0, &p->agg, 0);
if( p->keylistStack ){
int ii;
}
}
for(i=0; i<p->nVar; i++){
- sqlite3VdbeMemRelease(&p->apVar[i]);
+ sqlite3VdbeMemRelease(&p->aVar[i]);
}
sqliteFree(p->aOp);
sqliteFree(p->aLabel);
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.
**
-** $Id: where.c,v 1.111 2004/07/20 18:23:15 drh Exp $
+** $Id: where.c,v 1.112 2004/08/21 17:54:45 drh Exp $
*/
#include "sqliteInt.h"
}
pWInfo->pParse = pParse;
pWInfo->pTabList = pTabList;
- pWInfo->peakNTab = pWInfo->savedNTab = pParse->nTab;
pWInfo->iBreak = sqlite3VdbeMakeLabel(v);
/* Special case: a WHERE clause that is constant. Evaluate the
loopMask |= mask;
if( pBestIdx ){
pWInfo->a[i].iCur = pParse->nTab++;
- pWInfo->peakNTab = pParse->nTab;
}
}
if( pIdx==0 ){
pWInfo->a[0].pIdx = pSortIdx;
pWInfo->a[0].iCur = pParse->nTab++;
- pWInfo->peakNTab = pParse->nTab;
}
pWInfo->a[0].bRev = bRev;
*ppOrderBy = 0;
sqlite3VdbeAddOp(v, OP_Close, pLevel->iCur, 0);
}
}
-#if 0 /* Never reuse a cursor */
- if( pWInfo->pParse->nTab==pWInfo->peakNTab ){
- pWInfo->pParse->nTab = pWInfo->savedNTab;
- }
-#endif
sqliteFree(pWInfo);
return;
}
# The special crash-test module with its os_test.c backend only works
# on Unix.
#
-# $Id: crash.test,v 1.7 2004/06/28 04:52:31 danielk1977 Exp $
+# $Id: crash.test,v 1.8 2004/08/21 17:54:46 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
execsql { COMMIT }
set ::sig [signature]
execsql { SELECT sum(a), sum(b), sum(c) from abc }
-} {499500 999000 1498500}
+} {499500.0 999000.0 1498500.0}
do_test crash-2.2 {
expr [file size test.db] / 1024
} {19}
} $sig2
}
set i 0
+set i 55
while {[incr i]} {
set sig [signature]
set sig2 [signature2]