1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Registerify the SRT_Subroutine destination for SELECT results. (CVS 4690)

FossilOrigin-Name: 8201f71729c3afbb41764cea3cda65b03150cb0c
This commit is contained in:
drh
2008-01-06 00:25:21 +00:00
parent 477df4b3ac
commit 1013c9320d
12 changed files with 85 additions and 61 deletions

View File

@@ -1,5 +1,5 @@
C Modify\sOP_RegMakeRec\sto\stake\sa\sbase\sregister\sand\scount\sand\soptionally\nstore\sresults\sin\sthe\sregister\sspecified\sby\sP3.\s(CVS\s4689) C Registerify\sthe\sSRT_Subroutine\sdestination\sfor\sSELECT\sresults.\s(CVS\s4690)
D 2008-01-05T18:48:24 D 2008-01-06T00:25:22
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9 F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -86,17 +86,17 @@ F src/btmutex.c 5d39da37c9d1282f3c6f9967afae6a34ee36b7ff
F src/btree.c 5164b32950cfd41f2c5c31e8ff82c4a499918aef F src/btree.c 5164b32950cfd41f2c5c31e8ff82c4a499918aef
F src/btree.h 19dcf5ad23c17b98855da548e9a8e3eb4429d5eb F src/btree.h 19dcf5ad23c17b98855da548e9a8e3eb4429d5eb
F src/btreeInt.h 1c5a9da165718ef7de81e35ce9ab5d9ba9283f76 F src/btreeInt.h 1c5a9da165718ef7de81e35ce9ab5d9ba9283f76
F src/build.c 26690c519a4e4d77f128cf3e9865e63bec24afd0 F src/build.c 22b50a462d7b2be82e29071069d1c3daf29e953f
F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0 F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0
F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131 F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6 F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6
F src/delete.c 209f33fdf34dcbaa08752437bf53aff0cef0eca6 F src/delete.c 09c7b312a061d08df8a95b1f75cb10c6af14114a
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
F src/expr.c cb8b65c3adc8bb39f67503dfe8db8da24ebe5d21 F src/expr.c 99efbe91c16bc8a8dde1bb2d208a1246c07180d6
F src/func.c 996071cf0af9d967e58b69fce1909555059ebc7d F src/func.c 996071cf0af9d967e58b69fce1909555059ebc7d
F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53 F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
F src/insert.c 7082993775c4c17edbb6cb8a042d5e399c721a54 F src/insert.c 20325a8c7cde8148859d58f0516f749a67f854ea
F src/journal.c 807bed7a158979ac8d63953e1774e8d85bff65e2 F src/journal.c 807bed7a158979ac8d63953e1774e8d85bff65e2
F src/legacy.c 4ac53191fad2e3c4d59bde1228879b2dc5a96d66 F src/legacy.c 4ac53191fad2e3c4d59bde1228879b2dc5a96d66
F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35 F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
@@ -131,12 +131,12 @@ F src/pragma.c dfb200ec383b5ab3e81cd7bc4e1305e71053ef9a
F src/prepare.c f1bb8eb642082e618a359c08e3e107490eafe0e3 F src/prepare.c f1bb8eb642082e618a359c08e3e107490eafe0e3
F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910 F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910
F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
F src/select.c faf793d135bdc6136c38db898ccf05a28d634d87 F src/select.c 3dc81bc22d54b4b08a825f926587e1f96ded57c3
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
F src/shell.c 5391e889384d2062249f668110d64ed16f601c4b F src/shell.c 5391e889384d2062249f668110d64ed16f601c4b
F src/sqlite.h.in 2a7e3776534bbe6ff2cdc058f3abebe91e7e429f F src/sqlite.h.in 2a7e3776534bbe6ff2cdc058f3abebe91e7e429f
F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb
F src/sqliteInt.h 29a9502c0d9152580c3de8cb115da9aa8f9ce094 F src/sqliteInt.h 95cdddce11ee871fad1d91d6b6e405969dcc405f
F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e
F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4 F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4
F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf
@@ -163,12 +163,12 @@ F src/test_server.c a6ece6c835e7eae835054124e09e947e422b1ac5
F src/test_tclvar.c b2d1115e4d489179d3f029e765211b2ad527ba59 F src/test_tclvar.c b2d1115e4d489179d3f029e765211b2ad527ba59
F src/test_thread.c e297dd41db0b249646e69f97d36ec13e56e8b730 F src/test_thread.c e297dd41db0b249646e69f97d36ec13e56e8b730
F src/tokenize.c a4e04438c11fed2c67ec47fe3edbef9cca2d1b48 F src/tokenize.c a4e04438c11fed2c67ec47fe3edbef9cca2d1b48
F src/trigger.c 91ff1552b5c2cd66a077563a026d183c1dc993d6 F src/trigger.c 33071215111825634b85567bfc36c14094eebe54
F src/update.c f322317ee492c0a648f8a44fd805dd85dbbe2f05 F src/update.c 38e9e4c27896df2d189927e3b483cadf5641f47c
F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736 F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736
F src/util.c 05f31144bbd3f1a24f4139ae029c42545cb72624 F src/util.c 05f31144bbd3f1a24f4139ae029c42545cb72624
F src/vacuum.c 3f34f278809bf3eb0b62ec46ff779e9c385b28f0 F src/vacuum.c 3f34f278809bf3eb0b62ec46ff779e9c385b28f0
F src/vdbe.c 2dda056501489818fc5e1fc2d90454718a1c7a61 F src/vdbe.c d30764669b30ca901993fa8f5854e4b3d021d25c
F src/vdbe.h bb128757b84280504a1243c450fd13ead248ede5 F src/vdbe.h bb128757b84280504a1243c450fd13ead248ede5
F src/vdbeInt.h 31bd686595356284d5484592e2dc6e58025aa346 F src/vdbeInt.h 31bd686595356284d5484592e2dc6e58025aa346
F src/vdbeapi.c f14174843bf4be2c9afdf2ef48b61e7c3ac62d7c F src/vdbeapi.c f14174843bf4be2c9afdf2ef48b61e7c3ac62d7c
@@ -335,7 +335,7 @@ F test/insert.test aef273dd1cee84cc92407469e6bd1b3cdcb76908
F test/insert2.test 5a20e1ace5fa0800b58d28284212290189b49aed F test/insert2.test 5a20e1ace5fa0800b58d28284212290189b49aed
F test/insert3.test 9a4ef3526fd3cca8b05278020ec3100448b4c677 F test/insert3.test 9a4ef3526fd3cca8b05278020ec3100448b4c677
F test/insert4.test 6919ddacd79c2cfeb9785b0f84217f9cb14853b5 F test/insert4.test 6919ddacd79c2cfeb9785b0f84217f9cb14853b5
F test/insert5.test d577901d50e90791ad6bceeb2626bfecd0c1332f F test/insert5.test 509017213328147d3acdfa2c441bfd82362dda41
F test/interrupt.test 81555fb0f8179bb2d0dc7151fd75428223f93cf2 F test/interrupt.test 81555fb0f8179bb2d0dc7151fd75428223f93cf2
F test/intpkey.test 537669fd535f62632ca64828e435b9e54e8d677f F test/intpkey.test 537669fd535f62632ca64828e435b9e54e8d677f
F test/io.test 80a7a7f1a2792e037d447b03e8c22ee1f6eaf339 F test/io.test 80a7a7f1a2792e037d447b03e8c22ee1f6eaf339
@@ -604,7 +604,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
P 2b98b0fca82e285ae6b38384587aafa27985fa34 P 6bb1b1bc1858028b743a4f660d42d5e9595dc022
R 39c27616db1d209bf42cb60b3febdbfc R b9dfb6958eba47fbda8ba22262d4cfe6
U drh U drh
Z d2a8f69e443e5ecf651b682bda1fceaf Z 16b2a7371bc928893099feda1e3b8325

View File

@@ -1 +1 @@
6bb1b1bc1858028b743a4f660d42d5e9595dc022 8201f71729c3afbb41764cea3cda65b03150cb0c

View File

@@ -22,7 +22,7 @@
** COMMIT ** COMMIT
** ROLLBACK ** ROLLBACK
** **
** $Id: build.c,v 1.460 2008/01/05 18:48:24 drh Exp $ ** $Id: build.c,v 1.461 2008/01/06 00:25:22 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -1491,11 +1491,13 @@ void sqlite3EndTable(
** be redundant. ** be redundant.
*/ */
if( pSelect ){ if( pSelect ){
SelectDest dest = {SRT_Table, 0, 1}; SelectDest dest;
Table *pSelTab; Table *pSelTab;
sqlite3VdbeAddOp0(v, OP_Copy); sqlite3VdbeAddOp0(v, OP_Copy);
sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, 0, iDb); sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, 0, iDb);
pParse->nTab = 2; pParse->nTab = 2;
sqlite3SelectDestInit(&dest, SRT_Table, 1);
sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0); sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0);
sqlite3VdbeAddOp1(v, OP_Close, 1); sqlite3VdbeAddOp1(v, OP_Close, 1);
if( pParse->nErr==0 ){ if( pParse->nErr==0 ){

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser ** This file contains C code routines that are called by the parser
** in order to generate code for DELETE FROM statements. ** in order to generate code for DELETE FROM statements.
** **
** $Id: delete.c,v 1.151 2008/01/05 17:39:30 danielk1977 Exp $ ** $Id: delete.c,v 1.152 2008/01/06 00:25:22 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -261,10 +261,12 @@ void sqlite3DeleteFrom(
** a ephemeral table. ** a ephemeral table.
*/ */
if( isView ){ if( isView ){
SelectDest dest = {SRT_EphemTab, 0, 0}; SelectDest dest;
Select *pView = sqlite3SelectDup(db, pTab->pSelect); Select *pView;
pView = sqlite3SelectDup(db, pTab->pSelect);
sqlite3SelectMask(pParse, pView, old_col_mask); sqlite3SelectMask(pParse, pView, old_col_mask);
dest.iParm = iCur; sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
sqlite3Select(pParse, pView, &dest, 0, 0, 0, 0); sqlite3Select(pParse, pView, &dest, 0, 0, 0, 0);
sqlite3SelectDelete(pView); sqlite3SelectDelete(pView);
} }

View File

@@ -12,7 +12,7 @@
** This file contains routines used for analyzing expressions and ** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite. ** for generating VDBE code that evaluates expressions in SQLite.
** **
** $Id: expr.c,v 1.334 2008/01/05 16:29:28 drh Exp $ ** $Id: expr.c,v 1.335 2008/01/06 00:25:22 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -1738,10 +1738,11 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
** Generate code to write the results of the select into the temporary ** Generate code to write the results of the select into the temporary
** table allocated and opened above. ** table allocated and opened above.
*/ */
SelectDest dest = {SRT_Set, 0, 0}; SelectDest dest;
dest.iParm = pExpr->iTable;
dest.affinity = (int)affinity;
ExprList *pEList; ExprList *pEList;
sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
dest.affinity = (int)affinity;
assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
if( sqlite3Select(pParse, pExpr->pSelect, &dest, 0, 0, 0, 0) ){ if( sqlite3Select(pParse, pExpr->pSelect, &dest, 0, 0, 0, 0) ){
return; return;
@@ -1803,7 +1804,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
SelectDest dest; SelectDest dest;
pSel = pExpr->pSelect; pSel = pExpr->pSelect;
dest.iParm = ++pParse->nMem; sqlite3SelectDestInit(&dest, 0, ++pParse->nMem);
if( pExpr->op==TK_SELECT ){ if( pExpr->op==TK_SELECT ){
dest.eDest = SRT_Mem; dest.eDest = SRT_Mem;
sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iParm); sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iParm);

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser ** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite. ** to handle INSERT statements in SQLite.
** **
** $Id: insert.c,v 1.213 2008/01/05 05:20:10 drh Exp $ ** $Id: insert.c,v 1.214 2008/01/06 00:25:22 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -359,6 +359,7 @@ void sqlite3Insert(
int iCleanup = 0; /* Address of the cleanup code */ int iCleanup = 0; /* Address of the cleanup code */
int iInsertBlock = 0; /* Address of the subroutine used to insert data */ int iInsertBlock = 0; /* Address of the subroutine used to insert data */
int iCntMem = 0; /* Memory cell used for the row counter */ int iCntMem = 0; /* Memory cell used for the row counter */
int iBaseReg; /* Base register for data */
int newIdx = -1; /* Cursor for the NEW table */ int newIdx = -1; /* Cursor for the NEW table */
Db *pDb; /* The database containing table being inserted into */ Db *pDb; /* The database containing table being inserted into */
int counterMem = 0; /* Memory cell holding AUTOINCREMENT counter */ int counterMem = 0; /* Memory cell holding AUTOINCREMENT counter */
@@ -471,12 +472,13 @@ void sqlite3Insert(
if( pSelect ){ if( pSelect ){
/* Data is coming from a SELECT. Generate code to implement that SELECT /* Data is coming from a SELECT. Generate code to implement that SELECT
*/ */
SelectDest dest = {SRT_Subroutine, 0, 0}; SelectDest dest;
int rc, iInitCode; int rc, iInitCode;
iInitCode = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); iInitCode = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
iSelectLoop = sqlite3VdbeCurrentAddr(v); iSelectLoop = sqlite3VdbeCurrentAddr(v);
iInsertBlock = sqlite3VdbeMakeLabel(v); iInsertBlock = sqlite3VdbeMakeLabel(v);
dest.iParm = iInsertBlock; sqlite3SelectDestInit(&dest, SRT_Subroutine, iInsertBlock);
/* Resolve the expressions in the SELECT statement and execute it. */ /* Resolve the expressions in the SELECT statement and execute it. */
rc = sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0); rc = sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0);
@@ -484,6 +486,7 @@ void sqlite3Insert(
goto insert_cleanup; goto insert_cleanup;
} }
iBaseReg = dest.iMem;
iCleanup = sqlite3VdbeMakeLabel(v); iCleanup = sqlite3VdbeMakeLabel(v);
sqlite3VdbeAddOp2(v, OP_Goto, 0, iCleanup); sqlite3VdbeAddOp2(v, OP_Goto, 0, iCleanup);
assert( pSelect->pEList ); assert( pSelect->pEList );
@@ -507,8 +510,7 @@ void sqlite3Insert(
*/ */
srcTab = pParse->nTab++; srcTab = pParse->nTab++;
sqlite3VdbeResolveLabel(v, iInsertBlock); sqlite3VdbeResolveLabel(v, iInsertBlock);
sqlite3VdbeAddOp2(v, OP_StackDepth, -1, 0); sqlite3VdbeAddOp2(v, OP_RegMakeRec, iBaseReg, nColumn);
sqlite3VdbeAddOp2(v, OP_MakeRecord, nColumn, 0);
sqlite3VdbeAddOp1(v, OP_NewRowid, srcTab); sqlite3VdbeAddOp1(v, OP_NewRowid, srcTab);
sqlite3VdbeAddOp2(v, OP_Pull, 1, 0); sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
sqlite3CodeInsert(pParse, srcTab, OPFLAG_APPEND); sqlite3CodeInsert(pParse, srcTab, OPFLAG_APPEND);
@@ -640,6 +642,7 @@ void sqlite3Insert(
}else if( pSelect ){ }else if( pSelect ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, iSelectLoop); sqlite3VdbeAddOp2(v, OP_Goto, 0, iSelectLoop);
sqlite3VdbeResolveLabel(v, iInsertBlock); sqlite3VdbeResolveLabel(v, iInsertBlock);
sqlite3RegToStack(pParse, iBaseReg, nColumn);
sqlite3VdbeAddOp2(v, OP_StackDepth, -1, 0); sqlite3VdbeAddOp2(v, OP_StackDepth, -1, 0);
} }

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser ** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite. ** to handle SELECT statements in SQLite.
** **
** $Id: select.c,v 1.389 2008/01/05 18:48:24 drh Exp $ ** $Id: select.c,v 1.390 2008/01/06 00:25:22 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -33,6 +33,16 @@ static void clearSelect(Select *p){
sqlite3ExprDelete(p->pOffset); sqlite3ExprDelete(p->pOffset);
} }
/*
** Initialize a SelectDest structure.
*/
void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){
pDest->eDest = eDest;
pDest->iParm = iParm;
pDest->affinity = 0;
pDest->iMem = 0;
}
/* /*
** Allocate a new Select structure and return a pointer to that ** Allocate a new Select structure and return a pointer to that
@@ -542,8 +552,12 @@ static int selectInnerLoop(
}else{ }else{
n = pEList->nExpr; n = pEList->nExpr;
} }
iMem = pParse->nMem+1; if( pDest->iMem>0 ){
pParse->nMem += n; iMem = pDest->iMem;
}else{
pDest->iMem = iMem = pParse->nMem+1;
pParse->nMem += n;
}
if( nColumn>0 ){ if( nColumn>0 ){
for(i=0; i<nColumn; i++){ for(i=0; i<nColumn; i++){
sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, iMem+i); sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, iMem+i);
@@ -679,7 +693,6 @@ static int selectInnerLoop(
sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, nColumn); sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, nColumn);
pushOntoSorter(pParse, pOrderBy, p); pushOntoSorter(pParse, pOrderBy, p);
}else if( eDest==SRT_Subroutine ){ }else if( eDest==SRT_Subroutine ){
for(i=0; i<nColumn; i++) sqlite3VdbeAddOp2(v, OP_SCopy, iMem+i, 0);
sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm); sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm);
}else{ }else{
sqlite3VdbeAddOp2(v, OP_ResultRow, iMem, nColumn); sqlite3VdbeAddOp2(v, OP_ResultRow, iMem, nColumn);
@@ -816,10 +829,10 @@ static void generateSortTail(
int i; int i;
sqlite3CodeInsert(pParse, pseudoTab, 0); sqlite3CodeInsert(pParse, pseudoTab, 0);
for(i=0; i<nColumn; i++){ for(i=0; i<nColumn; i++){
sqlite3VdbeAddOp2(v, OP_Column, pseudoTab, i); sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iMem+i);
} }
if( eDest==SRT_Callback ){ if( eDest==SRT_Callback ){
sqlite3VdbeAddOp2(v, OP_Callback, nColumn, 0); sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn);
}else{ }else{
sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm); sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm);
} }
@@ -1867,11 +1880,9 @@ static int multiSelect(
ExprList *pOrderBy; /* The ORDER BY clause on p */ ExprList *pOrderBy; /* The ORDER BY clause on p */
int aSetP2[2]; /* Set P2 value of these op to number of columns */ int aSetP2[2]; /* Set P2 value of these op to number of columns */
int nSetP2 = 0; /* Number of slots in aSetP2[] used */ int nSetP2 = 0; /* Number of slots in aSetP2[] used */
SelectDest dest; /* Alternative data destination */
SelectDest dest; dest = *pDest;
dest.eDest = pDest->eDest;
dest.iParm = pDest->iParm;
dest.affinity = pDest->affinity;
/* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only
** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT. ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
@@ -1988,8 +1999,7 @@ static int multiSelect(
/* Code the SELECT statements to our left /* Code the SELECT statements to our left
*/ */
assert( !pPrior->pOrderBy ); assert( !pPrior->pOrderBy );
uniondest.eDest = priorOp; sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
uniondest.iParm = unionTab;
rc = sqlite3Select(pParse, pPrior, &uniondest, 0, 0, 0, aff); rc = sqlite3Select(pParse, pPrior, &uniondest, 0, 0, 0, aff);
if( rc ){ if( rc ){
goto multi_select_end; goto multi_select_end;
@@ -2060,7 +2070,7 @@ static int multiSelect(
int iCont, iBreak, iStart; int iCont, iBreak, iStart;
Expr *pLimit, *pOffset; Expr *pLimit, *pOffset;
int addr; int addr;
SelectDest intersectdest = {SRT_Union, 0, 0}; SelectDest intersectdest;
/* INTERSECT is different from the others since it requires /* INTERSECT is different from the others since it requires
** two temporary tables. Hence it has its own case. Begin ** two temporary tables. Hence it has its own case. Begin
@@ -2082,7 +2092,7 @@ static int multiSelect(
/* Code the SELECTs to our left into temporary table "tab1". /* Code the SELECTs to our left into temporary table "tab1".
*/ */
intersectdest.iParm = tab1; sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
rc = sqlite3Select(pParse, pPrior, &intersectdest, 0, 0, 0, aff); rc = sqlite3Select(pParse, pPrior, &intersectdest, 0, 0, 0, aff);
if( rc ){ if( rc ){
goto multi_select_end; goto multi_select_end;
@@ -2256,6 +2266,7 @@ static int multiSelect(
} }
multi_select_end: multi_select_end:
pDest->iMem = dest.iMem;
return rc; return rc;
} }
#endif /* SQLITE_OMIT_COMPOUND_SELECT */ #endif /* SQLITE_OMIT_COMPOUND_SELECT */
@@ -3252,7 +3263,7 @@ int sqlite3Select(
const char *zSavedAuthContext = 0; const char *zSavedAuthContext = 0;
int needRestoreContext; int needRestoreContext;
struct SrcList_item *pItem = &pTabList->a[i]; struct SrcList_item *pItem = &pTabList->a[i];
SelectDest dest = {SRT_EphemTab, 0, 0}; SelectDest dest;
if( pItem->pSelect==0 || pItem->isPopulated ) continue; if( pItem->pSelect==0 || pItem->isPopulated ) continue;
if( pItem->zName!=0 ){ if( pItem->zName!=0 ){
@@ -3272,7 +3283,7 @@ int sqlite3Select(
*/ */
pParse->nHeight += sqlite3SelectExprHeight(p); pParse->nHeight += sqlite3SelectExprHeight(p);
#endif #endif
dest.iParm = pItem->iCursor; sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
sqlite3Select(pParse, pItem->pSelect, &dest, p, i, &isAgg, 0); sqlite3Select(pParse, pItem->pSelect, &dest, p, i, &isAgg, 0);
if( db->mallocFailed ){ if( db->mallocFailed ){
goto select_end; goto select_end;
@@ -3647,8 +3658,8 @@ int sqlite3Select(
if( pMinMax ){ if( pMinMax ){
pMinMax->a[0].sortOrder = ((flag==ORDERBY_MIN)?0:1); pMinMax->a[0].sortOrder = ((flag==ORDERBY_MIN)?0:1);
pMinMax->a[0].pExpr->op = TK_COLUMN; pMinMax->a[0].pExpr->op = TK_COLUMN;
pDel = pMinMax;
} }
pDel = pMinMax;
} }
/* This case runs if the aggregate has no GROUP BY clause. The /* This case runs if the aggregate has no GROUP BY clause. The
@@ -3658,7 +3669,7 @@ int sqlite3Select(
resetAccumulator(pParse, &sAggInfo); resetAccumulator(pParse, &sAggInfo);
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax, flag); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax, flag);
if( pWInfo==0 ){ if( pWInfo==0 ){
sqlite3ExprListDelete(pMinMax); sqlite3ExprListDelete(pDel);
goto select_end; goto select_end;
} }
updateAccumulator(pParse, &sAggInfo); updateAccumulator(pParse, &sAggInfo);

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** Internal interface definitions for SQLite. ** Internal interface definitions for SQLite.
** **
** @(#) $Id: sqliteInt.h,v 1.640 2008/01/05 18:48:24 drh Exp $ ** @(#) $Id: sqliteInt.h,v 1.641 2008/01/06 00:25:22 drh Exp $
*/ */
#ifndef _SQLITEINT_H_ #ifndef _SQLITEINT_H_
#define _SQLITEINT_H_ #define _SQLITEINT_H_
@@ -1356,6 +1356,7 @@ struct SelectDest {
u8 eDest; /* How to dispose of the results */ u8 eDest; /* How to dispose of the results */
u8 affinity; /* Affinity used when eDest==SRT_Set */ u8 affinity; /* Affinity used when eDest==SRT_Set */
int iParm; /* A parameter used by the eDest disposal method */ int iParm; /* A parameter used by the eDest disposal method */
int iMem; /* Base register where results are written */
}; };
/* /*
@@ -1924,6 +1925,7 @@ void sqlite3StrAccumReset(StrAccum*);
void sqlite3CodeInsert(Parse *, int, u8); void sqlite3CodeInsert(Parse *, int, u8);
int sqlite3StackToReg(Parse *, int); int sqlite3StackToReg(Parse *, int);
void sqlite3RegToStack(Parse *, int, int); void sqlite3RegToStack(Parse *, int, int);
void sqlite3SelectDestInit(SelectDest*,int,int);
/* /*
** The interface to the LEMON-generated parser ** The interface to the LEMON-generated parser

View File

@@ -697,7 +697,9 @@ static int codeTriggerProgram(
case TK_SELECT: { case TK_SELECT: {
Select *ss = sqlite3SelectDup(db, pTriggerStep->pSelect); Select *ss = sqlite3SelectDup(db, pTriggerStep->pSelect);
if( ss ){ if( ss ){
SelectDest dest = {SRT_Discard, 0, 0}; SelectDest dest;
sqlite3SelectDestInit(&dest, SRT_Discard, 0);
sqlite3SelectResolve(pParse, ss, 0); sqlite3SelectResolve(pParse, ss, 0);
sqlite3Select(pParse, ss, &dest, 0, 0, 0, 0); sqlite3Select(pParse, ss, &dest, 0, 0, 0, 0);
sqlite3SelectDelete(ss); sqlite3SelectDelete(ss);

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser ** This file contains C code routines that are called by the parser
** to handle UPDATE statements. ** to handle UPDATE statements.
** **
** $Id: update.c,v 1.161 2008/01/05 17:39:30 danielk1977 Exp $ ** $Id: update.c,v 1.162 2008/01/06 00:25:22 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -329,10 +329,11 @@ void sqlite3Update(
*/ */
if( isView ){ if( isView ){
Select *pView; Select *pView;
SelectDest dest = {SRT_EphemTab, 0, 0}; SelectDest dest;
pView = sqlite3SelectDup(db, pTab->pSelect); pView = sqlite3SelectDup(db, pTab->pSelect);
sqlite3SelectMask(pParse, pView, old_col_mask|new_col_mask); sqlite3SelectMask(pParse, pView, old_col_mask|new_col_mask);
dest.iParm = iCur; sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
sqlite3Select(pParse, pView, &dest, 0, 0, 0, 0); sqlite3Select(pParse, pView, &dest, 0, 0, 0, 0);
sqlite3SelectDelete(pView); sqlite3SelectDelete(pView);
} }
@@ -595,7 +596,7 @@ static void updateVirtualTable(
int iReg; /* First register in set passed to OP_VUpdate */ int iReg; /* First register in set passed to OP_VUpdate */
sqlite3 *db = pParse->db; /* Database connection */ sqlite3 *db = pParse->db; /* Database connection */
const char *pVtab = (const char*)pTab->pVtab; const char *pVtab = (const char*)pTab->pVtab;
SelectDest dest = {SRT_Table, 0, 0}; SelectDest dest;
/* Construct the SELECT statement that will find the new values for /* Construct the SELECT statement that will find the new values for
** all updated rows. ** all updated rows.
@@ -626,7 +627,7 @@ static void updateVirtualTable(
/* fill the ephemeral table /* fill the ephemeral table
*/ */
dest.iParm = ephemTab; sqlite3SelectDestInit(&dest, SRT_Table, ephemTab);
sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0); sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0);
/* Generate code to scan the ephemeral table and call VUpdate. */ /* Generate code to scan the ephemeral table and call VUpdate. */

View File

@@ -43,7 +43,7 @@
** in this file for details. If in doubt, do not deviate from existing ** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code. ** commenting and indentation practices when changing or adding code.
** **
** $Id: vdbe.c,v 1.685 2008/01/05 18:48:24 drh Exp $ ** $Id: vdbe.c,v 1.686 2008/01/06 00:25:22 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -2670,6 +2670,7 @@ case OP_MakeRecord: { /* jump */
pOut->flags |= MEM_Zero; pOut->flags |= MEM_Zero;
} }
pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */ pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */
REGISTER_TRACE(pOp->p3, pOut);
/* If a NULL was encountered and jumpIfNull is non-zero, take the jump. */ /* If a NULL was encountered and jumpIfNull is non-zero, take the jump. */
if( jumpIfNull && containsNull ){ if( jumpIfNull && containsNull ){

View File

@@ -12,7 +12,7 @@
# The tests in this file ensure that a temporary table is used # The tests in this file ensure that a temporary table is used
# when required by an "INSERT INTO ... SELECT ..." statement. # when required by an "INSERT INTO ... SELECT ..." statement.
# #
# $Id: insert5.test,v 1.3 2007/12/13 07:58:51 danielk1977 Exp $ # $Id: insert5.test,v 1.4 2008/01/06 00:25:22 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@@ -52,10 +52,9 @@ do_test insert5-1.1 {
INSERT INTO B INSERT INTO B
SELECT * FROM B UNION ALL SELECT * FROM B UNION ALL
SELECT * FROM MAIN WHERE exists (select * FROM B WHERE B.Id = MAIN.Id); SELECT * FROM MAIN WHERE exists (select * FROM B WHERE B.Id = MAIN.Id);
SELECT * FROM B; SELECT * FROM B;
} }
} {2 3 2 3 2 3} } {2 3 2 3 2 3}
do_test insert5-2.1 { do_test insert5-2.1 {
uses_temp_table { INSERT INTO b SELECT * FROM main } uses_temp_table { INSERT INTO b SELECT * FROM main }
} {0} } {0}