mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-06 15:49:35 +03:00
Replace OP_List with OP_Fifo. This is the first step toward allowing
recursive delete triggers and later foreign keys with cascading deletes. (CVS 2538) FossilOrigin-Name: 94c120bb782fed53142317d1755e70c858930486
This commit is contained in:
@@ -118,7 +118,8 @@ LIBOBJ = alter.lo analyze.lo attach.lo auth.lo btree.lo build.lo \
|
|||||||
main.lo opcodes.lo os_unix.lo os_win.lo \
|
main.lo opcodes.lo os_unix.lo os_win.lo \
|
||||||
pager.lo parse.lo pragma.lo prepare.lo printf.lo random.lo \
|
pager.lo parse.lo pragma.lo prepare.lo printf.lo random.lo \
|
||||||
select.lo table.lo tokenize.lo trigger.lo update.lo \
|
select.lo table.lo tokenize.lo trigger.lo update.lo \
|
||||||
util.lo vacuum.lo vdbe.lo vdbeapi.lo vdbeaux.lo vdbemem.lo \
|
util.lo vacuum.lo \
|
||||||
|
vdbe.lo vdbeapi.lo vdbeaux.lo vdbefifo.lo vdbemem.lo \
|
||||||
where.lo utf.lo legacy.lo
|
where.lo utf.lo legacy.lo
|
||||||
|
|
||||||
# All of the source code files.
|
# All of the source code files.
|
||||||
@@ -166,6 +167,7 @@ SRC = \
|
|||||||
$(TOP)/src/vdbe.h \
|
$(TOP)/src/vdbe.h \
|
||||||
$(TOP)/src/vdbeapi.c \
|
$(TOP)/src/vdbeapi.c \
|
||||||
$(TOP)/src/vdbeaux.c \
|
$(TOP)/src/vdbeaux.c \
|
||||||
|
$(TOP)/src/vdbefifo.c \
|
||||||
$(TOP)/src/vdbemem.c \
|
$(TOP)/src/vdbemem.c \
|
||||||
$(TOP)/src/vdbeInt.h \
|
$(TOP)/src/vdbeInt.h \
|
||||||
$(TOP)/src/where.c
|
$(TOP)/src/where.c
|
||||||
@@ -392,6 +394,9 @@ vdbeapi.lo: $(TOP)/src/vdbeapi.c $(VDBEHDR)
|
|||||||
vdbeaux.lo: $(TOP)/src/vdbeaux.c $(VDBEHDR)
|
vdbeaux.lo: $(TOP)/src/vdbeaux.c $(VDBEHDR)
|
||||||
$(LTCOMPILE) -c $(TOP)/src/vdbeaux.c
|
$(LTCOMPILE) -c $(TOP)/src/vdbeaux.c
|
||||||
|
|
||||||
|
vdbefifo.lo: $(TOP)/src/vdbefifo.c $(VDBEHDR)
|
||||||
|
$(LTCOMPILE) -c $(TOP)/src/vdbefifo.c
|
||||||
|
|
||||||
vdbemem.lo: $(TOP)/src/vdbemem.c $(VDBEHDR)
|
vdbemem.lo: $(TOP)/src/vdbemem.c $(VDBEHDR)
|
||||||
$(LTCOMPILE) -c $(TOP)/src/vdbemem.c
|
$(LTCOMPILE) -c $(TOP)/src/vdbemem.c
|
||||||
|
|
||||||
|
|||||||
6
main.mk
6
main.mk
@@ -61,7 +61,7 @@ LIBOBJ+= alter.o analyze.o attach.o auth.o btree.o build.o \
|
|||||||
pager.o parse.o pragma.o prepare.o printf.o random.o \
|
pager.o parse.o pragma.o prepare.o printf.o random.o \
|
||||||
select.o table.o tclsqlite.o tokenize.o trigger.o \
|
select.o table.o tclsqlite.o tokenize.o trigger.o \
|
||||||
update.o util.o vacuum.o \
|
update.o util.o vacuum.o \
|
||||||
vdbe.o vdbeapi.o vdbeaux.o vdbemem.o \
|
vdbe.o vdbeapi.o vdbeaux.o vdbefifo.o vdbemem.o \
|
||||||
where.o utf.o legacy.o
|
where.o utf.o legacy.o
|
||||||
|
|
||||||
# All of the source code files.
|
# All of the source code files.
|
||||||
@@ -109,6 +109,7 @@ SRC = \
|
|||||||
$(TOP)/src/vdbe.h \
|
$(TOP)/src/vdbe.h \
|
||||||
$(TOP)/src/vdbeapi.c \
|
$(TOP)/src/vdbeapi.c \
|
||||||
$(TOP)/src/vdbeaux.c \
|
$(TOP)/src/vdbeaux.c \
|
||||||
|
$(TOP)/src/vdbefifo.c \
|
||||||
$(TOP)/src/vdbemem.c \
|
$(TOP)/src/vdbemem.c \
|
||||||
$(TOP)/src/vdbeInt.h \
|
$(TOP)/src/vdbeInt.h \
|
||||||
$(TOP)/src/where.c
|
$(TOP)/src/where.c
|
||||||
@@ -328,6 +329,9 @@ vdbeapi.o: $(TOP)/src/vdbeapi.c $(VDBEHDR)
|
|||||||
vdbeaux.o: $(TOP)/src/vdbeaux.c $(VDBEHDR)
|
vdbeaux.o: $(TOP)/src/vdbeaux.c $(VDBEHDR)
|
||||||
$(TCCX) -c $(TOP)/src/vdbeaux.c
|
$(TCCX) -c $(TOP)/src/vdbeaux.c
|
||||||
|
|
||||||
|
vdbefifo.o: $(TOP)/src/vdbefifo.c $(VDBEHDR)
|
||||||
|
$(TCCX) -c $(TOP)/src/vdbefifo.c
|
||||||
|
|
||||||
vdbemem.o: $(TOP)/src/vdbemem.c $(VDBEHDR)
|
vdbemem.o: $(TOP)/src/vdbemem.c $(VDBEHDR)
|
||||||
$(TCCX) -c $(TOP)/src/vdbemem.c
|
$(TCCX) -c $(TOP)/src/vdbemem.c
|
||||||
|
|
||||||
|
|||||||
25
manifest
25
manifest
@@ -1,6 +1,6 @@
|
|||||||
C Add\sinfrastructure\sfor\sthe\sANALYZE\scommand.\s\sDoes\snot\syet\sactually\ndo\sanything.\s(CVS\s2537)
|
C Replace\sOP_List\swith\sOP_Fifo.\s\sThis\sis\sthe\sfirst\sstep\stoward\sallowing\nrecursive\sdelete\striggers\sand\slater\sforeign\skeys\swith\scascading\sdeletes.\s(CVS\s2538)
|
||||||
D 2005-07-08T12:13:04
|
D 2005-07-08T13:08:00
|
||||||
F Makefile.in bc7bffc4ca6f09f2ffa9c9f5c43fc624fb566970
|
F Makefile.in 3c10cd7bc3ecbd60fe4d5a5c0f59bfa7fb217a66
|
||||||
F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
|
F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
|
||||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||||
F VERSION 44fad0bf0996660a11bf8187361de03941d9b7b0
|
F VERSION 44fad0bf0996660a11bf8187361de03941d9b7b0
|
||||||
@@ -16,7 +16,7 @@ F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
|
|||||||
F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
|
F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
|
||||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
||||||
F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826
|
F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826
|
||||||
F main.mk 675e435ca670e30513907265cc9cc0c011b40c17
|
F main.mk b2d38013a10e1c6a821e3d117294bf785deecf97
|
||||||
F mkdll.sh 5ec23622515d5bf8969404e80cfb5e220ddf0512
|
F mkdll.sh 5ec23622515d5bf8969404e80cfb5e220ddf0512
|
||||||
F mkopcodec.awk bd46ad001c98dfbab07b1713cb8e692fa0e5415d
|
F mkopcodec.awk bd46ad001c98dfbab07b1713cb8e692fa0e5415d
|
||||||
F mkopcodeh.awk 7563ad235670e864ead95cf672be3fe081450ae0
|
F mkopcodeh.awk 7563ad235670e864ead95cf672be3fe081450ae0
|
||||||
@@ -36,7 +36,7 @@ F src/btree.h 41a71ce027db9ddee72cb43df2316bbe3a1d92af
|
|||||||
F src/build.c 1f40c07a11e0a4eed1cef1ad4e52cf3f9770f220
|
F src/build.c 1f40c07a11e0a4eed1cef1ad4e52cf3f9770f220
|
||||||
F src/callback.c 0910b611e0c158f107ee3ff86f8a371654971e2b
|
F src/callback.c 0910b611e0c158f107ee3ff86f8a371654971e2b
|
||||||
F src/date.c 7444b0900a28da77e57e3337a636873cff0ae940
|
F src/date.c 7444b0900a28da77e57e3337a636873cff0ae940
|
||||||
F src/delete.c 9bb19ede439cf325bc6d6f5995b6393fb85b5162
|
F src/delete.c 250d436a68fe371b4ab403d1c0f6fdc9a6860c39
|
||||||
F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d
|
F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d
|
||||||
F src/expr.c fdc8b82babbb266eeded4a314fd2f1d315133797
|
F src/expr.c fdc8b82babbb266eeded4a314fd2f1d315133797
|
||||||
F src/func.c cbdf7256400ac7d5f020d131261bb2bd41bb631f
|
F src/func.c cbdf7256400ac7d5f020d131261bb2bd41bb631f
|
||||||
@@ -74,15 +74,16 @@ F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df
|
|||||||
F src/test5.c 64f08b2a50ef371a1bd68ff206829e7b1b9997f5
|
F src/test5.c 64f08b2a50ef371a1bd68ff206829e7b1b9997f5
|
||||||
F src/tokenize.c 57ec9926612fb9e325b57a141303573bc20c79bf
|
F src/tokenize.c 57ec9926612fb9e325b57a141303573bc20c79bf
|
||||||
F src/trigger.c f51dec15921629591cb98bf2e350018e268b109a
|
F src/trigger.c f51dec15921629591cb98bf2e350018e268b109a
|
||||||
F src/update.c e96c7b342cd8903c672162f4cf84d2c737943347
|
F src/update.c 49a9c618c3ba1ca57038d9ce41f14e958442fe58
|
||||||
F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c
|
F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c
|
||||||
F src/util.c 1acbe299cbe51f45176ac1e48ded9bea206c3c23
|
F src/util.c 1acbe299cbe51f45176ac1e48ded9bea206c3c23
|
||||||
F src/vacuum.c 829d9e1a6d7c094b80e0899686670932eafd768c
|
F src/vacuum.c 829d9e1a6d7c094b80e0899686670932eafd768c
|
||||||
F src/vdbe.c 56e892e351eb3ed634c3c239e4ad5c03aecfc2bf
|
F src/vdbe.c 87dda3fc214e4828641dd53527777f1b7d37b85f
|
||||||
F src/vdbe.h 75e466d84d362b0c4498978a9d6b1e6bd32ecf3b
|
F src/vdbe.h 75e466d84d362b0c4498978a9d6b1e6bd32ecf3b
|
||||||
F src/vdbeInt.h 4312faf41630a6c215924b6c7c2f39ebb1af8ffb
|
F src/vdbeInt.h 9be9a6c43d38124bd03cc5cf05715605b1789fd9
|
||||||
F src/vdbeapi.c 7f392f0792d1258c958083d7de9eae7c3530c9a6
|
F src/vdbeapi.c 7f392f0792d1258c958083d7de9eae7c3530c9a6
|
||||||
F src/vdbeaux.c 38332d91887817a2146f46b58fff2a8a88ed0278
|
F src/vdbeaux.c 3732a86566a6be4da4c606e9334baf3fd98667af
|
||||||
|
F src/vdbefifo.c b8805850afe13b43f1de78d58088cb5d66f88e1e
|
||||||
F src/vdbemem.c da8e8d6f29dd1323f782f000d7cd120027c9ff03
|
F src/vdbemem.c da8e8d6f29dd1323f782f000d7cd120027c9ff03
|
||||||
F src/where.c 97f356317024597e684b750658f2e8822cb15f10
|
F src/where.c 97f356317024597e684b750658f2e8822cb15f10
|
||||||
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
|
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
|
||||||
@@ -284,7 +285,7 @@ F www/tclsqlite.tcl 425be741b8ae664f55cb1ef2371aab0a75109cf9
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
||||||
F www/whentouse.tcl 528299b8316726dbcc5548e9aa0648c8b1bd055b
|
F www/whentouse.tcl 528299b8316726dbcc5548e9aa0648c8b1bd055b
|
||||||
P b34647a2ebec6f915f9914034e9370459873215e
|
P 05b6ac9a76fd5765c50e81588f8e71c59fe35ce4
|
||||||
R e47c1bc2e59627b5b8cf84918bbd5426
|
R ad75c3dbc9b87159735faff9e7381646
|
||||||
U drh
|
U drh
|
||||||
Z 50fe8e6711c2298fa85b1472b5a9b5e5
|
Z 29241e9900ff613d77be112c57ad8310
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
05b6ac9a76fd5765c50e81588f8e71c59fe35ce4
|
94c120bb782fed53142317d1755e70c858930486
|
||||||
12
src/delete.c
12
src/delete.c
@@ -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.107 2005/06/24 03:53:06 drh Exp $
|
** $Id: delete.c,v 1.108 2005/07/08 13:08:00 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ void sqlite3DeleteFrom(
|
|||||||
/* Remember the rowid of every item to be deleted.
|
/* Remember the rowid of every item to be deleted.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0);
|
sqlite3VdbeAddOp(v, OP_FifoWrite, 0, 0);
|
||||||
if( db->flags & SQLITE_CountRows ){
|
if( db->flags & SQLITE_CountRows ){
|
||||||
sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
|
sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
|
||||||
}
|
}
|
||||||
@@ -260,14 +260,13 @@ void sqlite3DeleteFrom(
|
|||||||
** database scan. We have to delete items after the scan is complete
|
** database scan. We have to delete items after the scan is complete
|
||||||
** because deleting an item can change the scan order.
|
** because deleting an item can change the scan order.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_ListRewind, 0, 0);
|
|
||||||
end = sqlite3VdbeMakeLabel(v);
|
end = sqlite3VdbeMakeLabel(v);
|
||||||
|
|
||||||
/* This is the beginning of the delete loop when there are
|
/* This is the beginning of the delete loop when there are
|
||||||
** row triggers.
|
** row triggers.
|
||||||
*/
|
*/
|
||||||
if( triggers_exist ){
|
if( triggers_exist ){
|
||||||
addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end);
|
addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end);
|
||||||
if( !isView ){
|
if( !isView ){
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
||||||
sqlite3OpenTableForReading(v, iCur, pTab);
|
sqlite3OpenTableForReading(v, iCur, pTab);
|
||||||
@@ -288,7 +287,7 @@ void sqlite3DeleteFrom(
|
|||||||
if( !isView ){
|
if( !isView ){
|
||||||
/* Open cursors for the table we are deleting from and all its
|
/* Open cursors for the table we are deleting from and all its
|
||||||
** indices. If there are row triggers, this happens inside the
|
** indices. If there are row triggers, this happens inside the
|
||||||
** OP_ListRead loop because the cursor have to all be closed
|
** OP_FifoRead loop because the cursor have to all be closed
|
||||||
** before the trigger fires. If there are no row triggers, the
|
** before the trigger fires. If there are no row triggers, the
|
||||||
** cursors are opened only once on the outside the loop.
|
** cursors are opened only once on the outside the loop.
|
||||||
*/
|
*/
|
||||||
@@ -297,7 +296,7 @@ void sqlite3DeleteFrom(
|
|||||||
/* This is the beginning of the delete loop when there are no
|
/* This is the beginning of the delete loop when there are no
|
||||||
** row triggers */
|
** row triggers */
|
||||||
if( !triggers_exist ){
|
if( !triggers_exist ){
|
||||||
addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end);
|
addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete the row */
|
/* Delete the row */
|
||||||
@@ -322,7 +321,6 @@ void sqlite3DeleteFrom(
|
|||||||
/* End of the delete loop */
|
/* End of the delete loop */
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
|
sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
|
||||||
sqlite3VdbeResolveLabel(v, end);
|
sqlite3VdbeResolveLabel(v, end);
|
||||||
sqlite3VdbeAddOp(v, OP_ListReset, 0, 0);
|
|
||||||
|
|
||||||
/* Close the cursors after the loop if there are no row triggers */
|
/* Close the cursors after the loop if there are no row triggers */
|
||||||
if( !triggers_exist ){
|
if( !triggers_exist ){
|
||||||
|
|||||||
11
src/update.c
11
src/update.c
@@ -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.108 2005/06/12 21:35:53 drh Exp $
|
** $Id: update.c,v 1.109 2005/07/08 13:08:00 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -273,7 +273,7 @@ void sqlite3Update(
|
|||||||
/* Remember the index of every item to be updated.
|
/* Remember the index of every item to be updated.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0);
|
sqlite3VdbeAddOp(v, OP_FifoWrite, 0, 0);
|
||||||
|
|
||||||
/* End the database scan loop.
|
/* End the database scan loop.
|
||||||
*/
|
*/
|
||||||
@@ -295,8 +295,7 @@ void sqlite3Update(
|
|||||||
|
|
||||||
/* The top of the update loop for when there are triggers.
|
/* The top of the update loop for when there are triggers.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_ListRewind, 0, 0);
|
addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, 0);
|
||||||
addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, 0);
|
|
||||||
|
|
||||||
if( !isView ){
|
if( !isView ){
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
||||||
@@ -389,8 +388,7 @@ void sqlite3Update(
|
|||||||
** So make the cursor point at the old record.
|
** So make the cursor point at the old record.
|
||||||
*/
|
*/
|
||||||
if( !triggers_exist ){
|
if( !triggers_exist ){
|
||||||
sqlite3VdbeAddOp(v, OP_ListRewind, 0, 0);
|
addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, 0);
|
||||||
addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, 0);
|
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr);
|
sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr);
|
||||||
@@ -468,7 +466,6 @@ void sqlite3Update(
|
|||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
|
sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
|
||||||
sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
|
sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
|
||||||
sqlite3VdbeAddOp(v, OP_ListReset, 0, 0);
|
|
||||||
|
|
||||||
/* Close all tables if there were no FOR EACH ROW triggers */
|
/* Close all tables if there were no FOR EACH ROW triggers */
|
||||||
if( !triggers_exist ){
|
if( !triggers_exist ){
|
||||||
|
|||||||
89
src/vdbe.c
89
src/vdbe.c
@@ -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.472 2005/06/25 18:42:15 drh Exp $
|
** $Id: vdbe.c,v 1.473 2005/07/08 13:08:00 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -3975,86 +3975,35 @@ case OP_IntegrityCk: {
|
|||||||
}
|
}
|
||||||
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
|
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
|
||||||
|
|
||||||
/* Opcode: ListWrite * * *
|
/* Opcode: FifoWrite * * *
|
||||||
**
|
**
|
||||||
** Write the integer on the top of the stack
|
** Write the integer on the top of the stack
|
||||||
** into the temporary storage list.
|
** into the Fifo.
|
||||||
*/
|
*/
|
||||||
case OP_ListWrite: { /* no-push */
|
case OP_FifoWrite: { /* no-push */
|
||||||
Keylist *pKeylist;
|
|
||||||
assert( pTos>=p->aStack );
|
assert( pTos>=p->aStack );
|
||||||
pKeylist = p->pList;
|
|
||||||
if( pKeylist==0 || pKeylist->nUsed>=pKeylist->nKey ){
|
|
||||||
pKeylist = sqliteMallocRaw( sizeof(Keylist)+999*sizeof(pKeylist->aKey[0]) );
|
|
||||||
if( pKeylist==0 ) goto no_mem;
|
|
||||||
pKeylist->nKey = 1000;
|
|
||||||
pKeylist->nRead = 0;
|
|
||||||
pKeylist->nUsed = 0;
|
|
||||||
pKeylist->pNext = p->pList;
|
|
||||||
p->pList = pKeylist;
|
|
||||||
}
|
|
||||||
Integerify(pTos);
|
Integerify(pTos);
|
||||||
pKeylist->aKey[pKeylist->nUsed++] = pTos->i;
|
sqlite3VdbeFifoPush(&p->sFifo, pTos->i);
|
||||||
assert( (pTos->flags & MEM_Dyn)==0 );
|
assert( (pTos->flags & MEM_Dyn)==0 );
|
||||||
pTos--;
|
pTos--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: ListRewind * * *
|
/* Opcode: FifoRead * P2 *
|
||||||
**
|
**
|
||||||
** Rewind the temporary buffer back to the beginning.
|
** Attempt to read a single integer from the Fifo
|
||||||
*/
|
** and push it onto the stack. If the Fifo is empty
|
||||||
case OP_ListRewind: { /* no-push */
|
|
||||||
/* What this opcode codes, really, is reverse the order of the
|
|
||||||
** linked list of Keylist structures so that they are read out
|
|
||||||
** in the same order that they were read in. */
|
|
||||||
Keylist *pRev, *pTop;
|
|
||||||
pRev = 0;
|
|
||||||
while( p->pList ){
|
|
||||||
pTop = p->pList;
|
|
||||||
p->pList = pTop->pNext;
|
|
||||||
pTop->pNext = pRev;
|
|
||||||
pRev = pTop;
|
|
||||||
}
|
|
||||||
p->pList = pRev;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Opcode: ListRead * P2 *
|
|
||||||
**
|
|
||||||
** Attempt to read an integer from the temporary storage buffer
|
|
||||||
** and push it onto the stack. If the storage buffer is empty,
|
|
||||||
** push nothing but instead jump to P2.
|
** push nothing but instead jump to P2.
|
||||||
*/
|
*/
|
||||||
case OP_ListRead: {
|
case OP_FifoRead: {
|
||||||
Keylist *pKeylist;
|
i64 v;
|
||||||
CHECK_FOR_INTERRUPT;
|
CHECK_FOR_INTERRUPT;
|
||||||
pKeylist = p->pList;
|
if( sqlite3VdbeFifoPop(&p->sFifo, &v)==SQLITE_DONE ){
|
||||||
if( pKeylist!=0 ){
|
|
||||||
assert( pKeylist->nRead>=0 );
|
|
||||||
assert( pKeylist->nRead<pKeylist->nUsed );
|
|
||||||
assert( pKeylist->nRead<pKeylist->nKey );
|
|
||||||
pTos++;
|
|
||||||
pTos->i = pKeylist->aKey[pKeylist->nRead++];
|
|
||||||
pTos->flags = MEM_Int;
|
|
||||||
if( pKeylist->nRead>=pKeylist->nUsed ){
|
|
||||||
p->pList = pKeylist->pNext;
|
|
||||||
sqliteFree(pKeylist);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}else{
|
||||||
break;
|
pTos++;
|
||||||
}
|
pTos->i = v;
|
||||||
|
pTos->flags = MEM_Int;
|
||||||
/* Opcode: ListReset * * *
|
|
||||||
**
|
|
||||||
** Reset the temporary storage buffer so that it holds nothing.
|
|
||||||
*/
|
|
||||||
case OP_ListReset: { /* no-push */
|
|
||||||
if( p->pList ){
|
|
||||||
sqlite3VdbeKeylistFree(p->pList);
|
|
||||||
p->pList = 0;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -4105,8 +4054,8 @@ case OP_ContextPush: { /* no-push */
|
|||||||
pContext = &p->contextStack[i];
|
pContext = &p->contextStack[i];
|
||||||
pContext->lastRowid = db->lastRowid;
|
pContext->lastRowid = db->lastRowid;
|
||||||
pContext->nChange = p->nChange;
|
pContext->nChange = p->nChange;
|
||||||
pContext->pList = p->pList;
|
pContext->sFifo = p->sFifo;
|
||||||
p->pList = 0;
|
sqlite3VdbeFifoInit(&p->sFifo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4121,8 +4070,8 @@ case OP_ContextPop: { /* no-push */
|
|||||||
assert( p->contextStackTop>=0 );
|
assert( p->contextStackTop>=0 );
|
||||||
db->lastRowid = pContext->lastRowid;
|
db->lastRowid = pContext->lastRowid;
|
||||||
p->nChange = pContext->nChange;
|
p->nChange = pContext->nChange;
|
||||||
sqlite3VdbeKeylistFree(p->pList);
|
sqlite3VdbeFifoClear(&p->sFifo);
|
||||||
p->pList = pContext->pList;
|
p->sFifo = pContext->sFifo;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* #ifndef SQLITE_OMIT_TRIGGER */
|
#endif /* #ifndef SQLITE_OMIT_TRIGGER */
|
||||||
|
|||||||
@@ -260,17 +260,29 @@ struct Set {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** A Keylist is a bunch of keys into a table. The keylist can
|
** A FifoPage structure holds a single page of valves. Pages are arranged
|
||||||
** grow without bound. The keylist stores the ROWIDs of database
|
** in a list.
|
||||||
** records that need to be deleted or updated.
|
|
||||||
*/
|
*/
|
||||||
typedef struct Keylist Keylist;
|
typedef struct FifoPage FifoPage;
|
||||||
struct Keylist {
|
struct FifoPage {
|
||||||
int nKey; /* Number of slots in aKey[] */
|
u16 nSlot; /* Number of entries aSlot[] */
|
||||||
int nUsed; /* Next unwritten slot in aKey[] */
|
u16 iWrite; /* Push the next value into this entry in aSlot[] */
|
||||||
int nRead; /* Next unread slot in aKey[] */
|
i16 iRead; /* Read the next value from this entry in aSlot[] */
|
||||||
Keylist *pNext; /* Next block of keys */
|
FifoPage *pNext; /* Next page in the fifo */
|
||||||
i64 aKey[1]; /* One or more keys. Extra space allocated as needed */
|
i64 aSlot[1]; /* One or more slots for rowid values */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The Fifo structure is typedef-ed in vdbeInt.h. But the implementation
|
||||||
|
** of that structure is private to this file.
|
||||||
|
**
|
||||||
|
** The Fifo structure describes the entire fifo.
|
||||||
|
*/
|
||||||
|
typedef struct Fifo Fifo;
|
||||||
|
struct Fifo {
|
||||||
|
int nEntry; /* Total number of entries */
|
||||||
|
FifoPage *pFirst; /* First page on the list */
|
||||||
|
FifoPage *pLast; /* Last page on the list */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -286,7 +298,7 @@ typedef struct Context Context;
|
|||||||
struct Context {
|
struct Context {
|
||||||
int lastRowid; /* Last insert rowid (sqlite3.lastRowid) */
|
int lastRowid; /* Last insert rowid (sqlite3.lastRowid) */
|
||||||
int nChange; /* Statement changes (Vdbe.nChanges) */
|
int nChange; /* Statement changes (Vdbe.nChanges) */
|
||||||
Keylist *pList; /* Records that will participate in a DELETE or UPDATE */
|
Fifo sFifo; /* Records that will participate in a DELETE or UPDATE */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -325,7 +337,7 @@ struct Vdbe {
|
|||||||
Agg *apAgg; /* Array of aggregate contexts */
|
Agg *apAgg; /* Array of aggregate contexts */
|
||||||
Agg *pAgg; /* Current aggregate context */
|
Agg *pAgg; /* Current aggregate context */
|
||||||
int nCallback; /* Number of callbacks invoked so far */
|
int nCallback; /* Number of callbacks invoked so far */
|
||||||
Keylist *pList; /* A list of ROWIDs */
|
Fifo sFifo; /* A list of ROWIDs */
|
||||||
int contextStackTop; /* Index of top element in the context stack */
|
int contextStackTop; /* Index of top element in the context stack */
|
||||||
int contextStackDepth; /* The size of the "context" stack */
|
int contextStackDepth; /* The size of the "context" stack */
|
||||||
Context *contextStack; /* Stack used by opcodes ContextPush & ContextPop*/
|
Context *contextStack; /* Stack used by opcodes ContextPush & ContextPop*/
|
||||||
@@ -362,7 +374,6 @@ struct Vdbe {
|
|||||||
void sqlite3VdbeFreeCursor(Cursor*);
|
void sqlite3VdbeFreeCursor(Cursor*);
|
||||||
void sqlite3VdbeSorterReset(Vdbe*);
|
void sqlite3VdbeSorterReset(Vdbe*);
|
||||||
int sqlite3VdbeAggReset(sqlite3*, Agg *, KeyInfo *);
|
int sqlite3VdbeAggReset(sqlite3*, Agg *, KeyInfo *);
|
||||||
void sqlite3VdbeKeylistFree(Keylist*);
|
|
||||||
void sqliteVdbePopStack(Vdbe*,int);
|
void sqliteVdbePopStack(Vdbe*,int);
|
||||||
int sqlite3VdbeCursorMoveto(Cursor*);
|
int sqlite3VdbeCursorMoveto(Cursor*);
|
||||||
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
|
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
|
||||||
@@ -411,3 +422,7 @@ int sqlite3VdbeOpcodeNoPush(u8);
|
|||||||
int sqlite3VdbeMemTranslate(Mem*, u8);
|
int sqlite3VdbeMemTranslate(Mem*, u8);
|
||||||
void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf, int nBuf);
|
void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf, int nBuf);
|
||||||
int sqlite3VdbeMemHandleBom(Mem *pMem);
|
int sqlite3VdbeMemHandleBom(Mem *pMem);
|
||||||
|
void sqlite3VdbeFifoInit(Fifo*);
|
||||||
|
int sqlite3VdbeFifoPush(Fifo*, i64);
|
||||||
|
int sqlite3VdbeFifoPop(Fifo*, i64*);
|
||||||
|
void sqlite3VdbeFifoClear(Fifo*);
|
||||||
|
|||||||
@@ -952,18 +952,6 @@ int sqlite3VdbeAggReset(sqlite3 *db, Agg *pAgg, KeyInfo *pKeyInfo){
|
|||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Delete a keylist
|
|
||||||
*/
|
|
||||||
void sqlite3VdbeKeylistFree(Keylist *p){
|
|
||||||
while( p ){
|
|
||||||
Keylist *pNext = p->pNext;
|
|
||||||
sqliteFree(p);
|
|
||||||
p = pNext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Close a cursor and release all the resources that cursor happens
|
** Close a cursor and release all the resources that cursor happens
|
||||||
** to hold.
|
** to hold.
|
||||||
@@ -1010,13 +998,10 @@ static void Cleanup(Vdbe *p){
|
|||||||
}
|
}
|
||||||
closeAllCursors(p);
|
closeAllCursors(p);
|
||||||
releaseMemArray(p->aMem, p->nMem);
|
releaseMemArray(p->aMem, p->nMem);
|
||||||
if( p->pList ){
|
sqlite3VdbeFifoClear(&p->sFifo);
|
||||||
sqlite3VdbeKeylistFree(p->pList);
|
|
||||||
p->pList = 0;
|
|
||||||
}
|
|
||||||
if( p->contextStack ){
|
if( p->contextStack ){
|
||||||
for(i=0; i<p->contextStackTop; i++){
|
for(i=0; i<p->contextStackTop; i++){
|
||||||
sqlite3VdbeKeylistFree(p->contextStack[i].pList);
|
sqlite3VdbeFifoClear(&p->contextStack[i].sFifo);
|
||||||
}
|
}
|
||||||
sqliteFree(p->contextStack);
|
sqliteFree(p->contextStack);
|
||||||
}
|
}
|
||||||
|
|||||||
109
src/vdbefifo.c
Normal file
109
src/vdbefifo.c
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
** 2005 June 16
|
||||||
|
**
|
||||||
|
** The author disclaims copyright to this source code. In place of
|
||||||
|
** a legal notice, here is a blessing:
|
||||||
|
**
|
||||||
|
** May you do good and not evil.
|
||||||
|
** May you find forgiveness for yourself and forgive others.
|
||||||
|
** May you share freely, never taking more than you give.
|
||||||
|
**
|
||||||
|
*************************************************************************
|
||||||
|
** This file implements a FIFO queue of rowids used for processing
|
||||||
|
** UPDATE and DELETE statements.
|
||||||
|
*/
|
||||||
|
#include "sqliteInt.h"
|
||||||
|
#include "vdbeInt.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Allocate a new FifoPage and return a pointer to it. Return NULL if
|
||||||
|
** we run out of memory. Leave space on the page for nEntry entries.
|
||||||
|
*/
|
||||||
|
static FifoPage *allocatePage(int nEntry){
|
||||||
|
FifoPage *pPage;
|
||||||
|
pPage = sqliteMallocRaw( sizeof(FifoPage) + sizeof(i64)*(nEntry-1) );
|
||||||
|
if( pPage ){
|
||||||
|
pPage->nSlot = nEntry;
|
||||||
|
pPage->iWrite = 0;
|
||||||
|
pPage->iRead = 0;
|
||||||
|
pPage->pNext = 0;
|
||||||
|
}
|
||||||
|
return pPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Initialize a Fifo structure.
|
||||||
|
*/
|
||||||
|
void sqlite3VdbeFifoInit(Fifo *pFifo){
|
||||||
|
memset(pFifo, 0, sizeof(*pFifo));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Push a single 64-bit integer value into the Fifo. Return SQLITE_OK
|
||||||
|
** normally. SQLITE_NOMEM is returned if we are unable to allocate
|
||||||
|
** memory.
|
||||||
|
*/
|
||||||
|
int sqlite3VdbeFifoPush(Fifo *pFifo, i64 val){
|
||||||
|
FifoPage *pPage;
|
||||||
|
pPage = pFifo->pLast;
|
||||||
|
if( pPage==0 ){
|
||||||
|
pPage = pFifo->pLast = pFifo->pFirst = allocatePage(20);
|
||||||
|
if( pPage==0 ){
|
||||||
|
return SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
}else if( pPage->iWrite>=pPage->nSlot ){
|
||||||
|
pPage->pNext = allocatePage(pFifo->nEntry);
|
||||||
|
if( pPage->pNext==0 ){
|
||||||
|
return SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
pPage = pFifo->pLast = pPage->pNext;
|
||||||
|
}
|
||||||
|
pPage->aSlot[pPage->iWrite++] = val;
|
||||||
|
pFifo->nEntry++;
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Extract a single 64-bit integer value from the Fifo. The integer
|
||||||
|
** extracted is the one least recently inserted. If the Fifo is empty
|
||||||
|
** return SQLITE_DONE.
|
||||||
|
*/
|
||||||
|
int sqlite3VdbeFifoPop(Fifo *pFifo, i64 *pVal){
|
||||||
|
FifoPage *pPage;
|
||||||
|
if( pFifo->nEntry==0 ){
|
||||||
|
return SQLITE_DONE;
|
||||||
|
}
|
||||||
|
assert( pFifo->nEntry>0 );
|
||||||
|
pPage = pFifo->pFirst;
|
||||||
|
assert( pPage!=0 );
|
||||||
|
assert( pPage->iWrite>pPage->iRead );
|
||||||
|
assert( pPage->iRead<pPage->nSlot );
|
||||||
|
*pVal = pPage->aSlot[pPage->iRead++];
|
||||||
|
pFifo->nEntry--;
|
||||||
|
if( pPage->iRead>=pPage->iWrite ){
|
||||||
|
pFifo->pFirst = pPage->pNext;
|
||||||
|
sqliteFree(pPage);
|
||||||
|
if( pFifo->nEntry==0 ){
|
||||||
|
assert( pFifo->pLast==pPage );
|
||||||
|
pFifo->pLast = 0;
|
||||||
|
}else{
|
||||||
|
assert( pFifo->pFirst!=0 );
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
assert( pFifo->nEntry>0 );
|
||||||
|
}
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Delete all information from a Fifo object. Free all memory held
|
||||||
|
** by the Fifo.
|
||||||
|
*/
|
||||||
|
void sqlite3VdbeFifoClear(Fifo *pFifo){
|
||||||
|
FifoPage *pPage, *pNextPage;
|
||||||
|
for(pPage=pFifo->pFirst; pPage; pPage=pNextPage){
|
||||||
|
pNextPage = pPage->pNext;
|
||||||
|
sqliteFree(pPage);
|
||||||
|
}
|
||||||
|
sqlite3VdbeFifoInit(pFifo);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user