Style fixes to triggers code in various *.c files (partial fix to ticket #39) (CVS 571)
FossilOrigin-Name: 8a4195c7466962291a296e8f53034ea8cb25005f
This commit is contained in:
parent
633ed08d95
commit
f29ce55958
28
manifest
28
manifest
@ -1,5 +1,5 @@
|
||||
C Stylistic\schanges\sto\ssrc/trigger.c\s(partial\sfix\sto\sticket\s#39).\sAlso\smore\scomments.\s(CVS\s570)
|
||||
D 2002-05-17T00:05:59
|
||||
C Style\sfixes\sto\striggers\scode\sin\svarious\s*.c\sfiles\s(partial\sfix\sto\sticket\s#39)\s(CVS\s571)
|
||||
D 2002-05-19T23:43:13
|
||||
F Makefile.in 6291a33b87d2a395aafd7646ee1ed562c6f2c28c
|
||||
F Makefile.template 4e11752e0b5c7a043ca50af4296ec562857ba495
|
||||
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
|
||||
@ -20,15 +20,15 @@ F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
|
||||
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
|
||||
F src/btree.c c01b404b9373ae1c0daf7d1f9211c72ead67638e
|
||||
F src/btree.h 8abeabfe6e0b1a990b64fa457592a6482f6674f3
|
||||
F src/build.c 705ebd993ac708bb3d04f4b9019d42dc205408cc
|
||||
F src/delete.c 48e4c533b39d6edfcfca23fb500129b80b7cad30
|
||||
F src/build.c f6d2f428801e636c802fa63e951772569fa133a5
|
||||
F src/delete.c f9ab9738c5a6fed434ec9e7721a178f58f65f57a
|
||||
F src/encode.c 346b12b46148506c32038524b95c4631ab46d760
|
||||
F src/expr.c 6888e37e4eecdc20567aedd442328df752465723
|
||||
F src/expr.c 2c7535ba013b731ed73f12b6cc1cd5b466efb3e2
|
||||
F src/func.c a31dcba85bc2ecb9b752980289cf7e6cd0cafbce
|
||||
F src/hash.c cc259475e358baaf299b00a2c7370f2b03dda892
|
||||
F src/hash.h dca065dda89d4575f3176e75e9a3dc0f4b4fb8b9
|
||||
F src/insert.c 26ca700fb4055c34970ebac1d9a9a067bebef3b0
|
||||
F src/main.c de486c893c0a34a91aa5660c3ab5ce3d08746eaf
|
||||
F src/insert.c 5233701a402cf5f4329525a654928c5de8d9a4e8
|
||||
F src/main.c 3f0db74a3e8385322a3b69f51bea6ce19caeff19
|
||||
F src/md5.c 0ae1f3e2cac92d06fc6246d1b4b8f61a2fe66d3b
|
||||
F src/os.c 5ab8b6b4590d0c1ab8e96c67996c170e4462e0fc
|
||||
F src/os.h 4a361fccfbc4e7609b3e1557f604f94c1e96ad10
|
||||
@ -49,12 +49,12 @@ F src/test2.c 669cc22781c6461a273416ec1a7414d25c081730
|
||||
F src/test3.c 4e52fff8b01f08bd202f7633feda5639b7ba2b5e
|
||||
F src/threadtest.c 81f0598e0f031c1bd506af337fdc1b7e8dff263f
|
||||
F src/tokenize.c f12f78c58b2a79ea4eee880efad63a328e103c62
|
||||
F src/trigger.c e61b4a9ecdfdef8e5d7d074e720dacf7abe5f361
|
||||
F src/update.c f9b53d46cc651b9630fc53342b9e792031f6fc5c
|
||||
F src/trigger.c 43dbeb68ba379049a78d270db0db27fa01deec12
|
||||
F src/update.c 6b1d80b5058e686c2e3197d72c567ea27d35f42e
|
||||
F src/util.c 707c30f8c13cddace7c08556ac450c0b786660b3
|
||||
F src/vdbe.c 42281b4e0e0c4a089018a14d6840ada5a1896e51
|
||||
F src/vdbe.c 5fd717e6a42e98e4f244a2149267004f71f23679
|
||||
F src/vdbe.h 126a651ba26f05de075dcc6da5466244a31af6b8
|
||||
F src/where.c d1c05aca90d2a9d7000c40db5a4b1ac9d6d1169d
|
||||
F src/where.c 7e482af684197f5137380aa5c9ae0693f7fe7be4
|
||||
F test/all.test e4d3821eeba751829b419cd47814bd20af4286d1
|
||||
F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
|
||||
F test/btree.test bf326f546a666617367a7033fa2c07451bd4f8e1
|
||||
@ -134,7 +134,7 @@ F www/speed.tcl da8afcc1d3ccc5696cfb388a68982bc3d9f7f00f
|
||||
F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
|
||||
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
|
||||
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
||||
P 9ec8a2b139ce38312284d7b4eb61221b1e1e3052
|
||||
R 6c59ff9d8d542bc14ae8632c3c69e144
|
||||
P b1d72cb5847a9f5f08e40b36ad117b5493232ea7
|
||||
R 6a41d52fabcd64a48785213ecafaf488
|
||||
U danielk1977
|
||||
Z d967dbf67c63f0da8b2c7467d5b0888a
|
||||
Z f416062573015e51faa69ab13000e10e
|
||||
|
@ -1 +1 @@
|
||||
b1d72cb5847a9f5f08e40b36ad117b5493232ea7
|
||||
8a4195c7466962291a296e8f53034ea8cb25005f
|
20
src/build.c
20
src/build.c
@ -25,7 +25,7 @@
|
||||
** ROLLBACK
|
||||
** PRAGMA
|
||||
**
|
||||
** $Id: build.c,v 1.90 2002/05/15 12:45:43 drh Exp $
|
||||
** $Id: build.c,v 1.91 2002/05/19 23:43:14 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -259,7 +259,7 @@ void sqliteCommitInternalChanges(sqlite *db){
|
||||
|
||||
/* Delete the structures for triggers removed this transaction */
|
||||
pElem = sqliteHashFirst(&db->trigDrop);
|
||||
while (pElem) {
|
||||
while( pElem ){
|
||||
Trigger *pTrigger = sqliteHashData(pElem);
|
||||
sqliteDeleteTrigger(pTrigger);
|
||||
pElem = sqliteHashNext(pElem);
|
||||
@ -323,7 +323,7 @@ void sqliteRollbackInternalChanges(sqlite *db){
|
||||
|
||||
/* Remove any triggers that haven't been commited yet */
|
||||
for(pElem = sqliteHashFirst(&db->trigHash); pElem;
|
||||
pElem = (pElem?sqliteHashNext(pElem):0)) {
|
||||
pElem = (pElem?sqliteHashNext(pElem):0)){
|
||||
Trigger *pTrigger = sqliteHashData(pElem);
|
||||
if( !pTrigger->isCommit ){
|
||||
Table *pTbl = sqliteFindTable(db, pTrigger->table);
|
||||
@ -333,7 +333,7 @@ void sqliteRollbackInternalChanges(sqlite *db){
|
||||
}else{
|
||||
Trigger *cc = pTbl->pTrigger;
|
||||
while( cc ){
|
||||
if (cc->pNext == pTrigger) {
|
||||
if( cc->pNext == pTrigger ){
|
||||
cc->pNext = cc->pNext->pNext;
|
||||
break;
|
||||
}
|
||||
@ -351,13 +351,13 @@ void sqliteRollbackInternalChanges(sqlite *db){
|
||||
|
||||
/* Any triggers that were dropped - put 'em back in place */
|
||||
for(pElem = sqliteHashFirst(&db->trigDrop); pElem;
|
||||
pElem = sqliteHashNext(pElem)) {
|
||||
Trigger * pTrigger = sqliteHashData(pElem);
|
||||
Table * tab = sqliteFindTable(db, pTrigger->table);
|
||||
pElem = sqliteHashNext(pElem)){
|
||||
Trigger *pTrigger = sqliteHashData(pElem);
|
||||
Table *pTbl = sqliteFindTable(db, pTrigger->table);
|
||||
sqliteHashInsert(&db->trigHash, pTrigger->name,
|
||||
strlen(pTrigger->name) + 1, pTrigger);
|
||||
pTrigger->pNext = tab->pTrigger;
|
||||
tab->pTrigger = pTrigger;
|
||||
pTrigger->pNext = pTbl->pTrigger;
|
||||
pTbl->pTrigger = pTrigger;
|
||||
}
|
||||
|
||||
sqliteHashClear(&db->trigDrop);
|
||||
@ -1755,7 +1755,7 @@ void sqliteBeginMultiWriteOperation(Parse *pParse){
|
||||
*/
|
||||
void sqliteEndWriteOperation(Parse *pParse){
|
||||
Vdbe *v;
|
||||
if (pParse->trigStack) return; /* if this is in a trigger */
|
||||
if( pParse->trigStack ) return; /* if this is in a trigger */
|
||||
v = sqliteGetVdbe(pParse);
|
||||
if( v==0 ) return;
|
||||
if( pParse->db->flags & SQLITE_InTrans ){
|
||||
|
46
src/delete.c
46
src/delete.c
@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle DELETE FROM statements.
|
||||
**
|
||||
** $Id: delete.c,v 1.32 2002/05/15 11:44:14 drh Exp $
|
||||
** $Id: delete.c,v 1.33 2002/05/19 23:43:14 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -94,15 +94,15 @@ void sqliteDeleteFrom(
|
||||
db = pParse->db;
|
||||
|
||||
/* Check for the special case of a VIEW with one or more ON DELETE triggers
|
||||
* defined
|
||||
*/
|
||||
** defined
|
||||
*/
|
||||
{
|
||||
Table * pTab;
|
||||
char * zTab = sqliteTableNameFromToken(pTableName);
|
||||
Table *pTab;
|
||||
char *zTab = sqliteTableNameFromToken(pTableName);
|
||||
|
||||
if(zTab != 0) {
|
||||
if( zTab != 0 ){
|
||||
pTab = sqliteFindTable(pParse->db, zTab);
|
||||
if (pTab) {
|
||||
if( pTab ){
|
||||
row_triggers_exist =
|
||||
sqliteTriggersExist(pParse, pTab->pTrigger,
|
||||
TK_DELETE, TK_BEFORE, TK_ROW, 0) ||
|
||||
@ -110,7 +110,7 @@ void sqliteDeleteFrom(
|
||||
TK_DELETE, TK_AFTER, TK_ROW, 0);
|
||||
}
|
||||
sqliteFree(zTab);
|
||||
if (row_triggers_exist && pTab->pSelect ) {
|
||||
if( row_triggers_exist && pTab->pSelect ){
|
||||
/* Just fire VIEW triggers */
|
||||
sqliteViewTriggers(pParse, pTab, pWhere, OE_Replace, 0);
|
||||
return;
|
||||
@ -129,8 +129,9 @@ void sqliteDeleteFrom(
|
||||
pTab = pTabList->a[0].pTab;
|
||||
assert( pTab->pSelect==0 ); /* This table is not a view */
|
||||
|
||||
if (row_triggers_exist)
|
||||
if( row_triggers_exist ){
|
||||
oldIdx = pParse->nTab++;
|
||||
}
|
||||
|
||||
/* Resolve the column names in all the expressions.
|
||||
*/
|
||||
@ -147,11 +148,14 @@ void sqliteDeleteFrom(
|
||||
/* Begin generating code.
|
||||
*/
|
||||
v = sqliteGetVdbe(pParse);
|
||||
if( v==0 ) goto delete_from_cleanup;
|
||||
if (row_triggers_exist)
|
||||
if( v==0 ){
|
||||
goto delete_from_cleanup;
|
||||
}
|
||||
if( row_triggers_exist ){
|
||||
sqliteBeginMultiWriteOperation(pParse);
|
||||
else
|
||||
} else {
|
||||
sqliteBeginWriteOperation(pParse);
|
||||
}
|
||||
|
||||
/* Initialize the counter of the number of rows deleted, if
|
||||
** we are counting rows.
|
||||
@ -163,7 +167,7 @@ void sqliteDeleteFrom(
|
||||
/* Special case: A DELETE without a WHERE clause deletes everything.
|
||||
** It is easier just to erase the whole table.
|
||||
*/
|
||||
if( pWhere==0 && !row_triggers_exist){
|
||||
if( pWhere==0 && !row_triggers_exist ){
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
/* If counting rows deleted, just count the total number of
|
||||
** entries in the table. */
|
||||
@ -211,7 +215,7 @@ void sqliteDeleteFrom(
|
||||
sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
|
||||
end = sqliteVdbeMakeLabel(v);
|
||||
|
||||
if (row_triggers_exist) {
|
||||
if( row_triggers_exist ){
|
||||
int ii;
|
||||
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end);
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||
@ -222,11 +226,12 @@ void sqliteDeleteFrom(
|
||||
sqliteVdbeAddOp(v, OP_OpenTemp, oldIdx, 0);
|
||||
|
||||
sqliteVdbeAddOp(v, OP_Integer, 13, 0);
|
||||
for (ii = 0; ii < pTab->nCol; ii++) {
|
||||
if (ii == pTab->iPKey)
|
||||
for(ii = 0; ii<pTab->nCol; ii++){
|
||||
if( ii==pTab->iPKey ){
|
||||
sqliteVdbeAddOp(v, OP_Recno, base, 0);
|
||||
else
|
||||
} else {
|
||||
sqliteVdbeAddOp(v, OP_Column, base, ii);
|
||||
}
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
||||
sqliteVdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
|
||||
@ -244,12 +249,13 @@ void sqliteDeleteFrom(
|
||||
sqliteVdbeAddOp(v, openOp, pParse->nTab++, pIdx->tnum);
|
||||
}
|
||||
|
||||
if (!row_triggers_exist)
|
||||
if( !row_triggers_exist ){
|
||||
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end);
|
||||
}
|
||||
|
||||
sqliteGenerateRowDelete(v, pTab, base, pParse->trigStack?0:1);
|
||||
|
||||
if (row_triggers_exist) {
|
||||
if( row_triggers_exist ){
|
||||
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
||||
sqliteVdbeAddOp(v, OP_Close, base + i, pIdx->tnum);
|
||||
}
|
||||
@ -262,7 +268,7 @@ void sqliteDeleteFrom(
|
||||
sqliteVdbeResolveLabel(v, end);
|
||||
sqliteVdbeAddOp(v, OP_ListReset, 0, 0);
|
||||
|
||||
if (!row_triggers_exist) {
|
||||
if( !row_triggers_exist ){
|
||||
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
||||
sqliteVdbeAddOp(v, OP_Close, base + i, pIdx->tnum);
|
||||
}
|
||||
|
23
src/expr.c
23
src/expr.c
@ -12,7 +12,7 @@
|
||||
** This file contains routines used for analyzing expressions and
|
||||
** for generating VDBE code that evaluates expressions in SQLite.
|
||||
**
|
||||
** $Id: expr.c,v 1.59 2002/05/15 08:30:13 danielk1977 Exp $
|
||||
** $Id: expr.c,v 1.60 2002/05/19 23:43:14 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -484,28 +484,29 @@ int sqliteExprResolveIds(
|
||||
|
||||
/* If we have not already resolved this *.* expression, then maybe
|
||||
* it is a new.* or old.* trigger argument reference */
|
||||
if (cnt == 0 && pParse->trigStack != 0) {
|
||||
TriggerStack * tt = pParse->trigStack;
|
||||
int j;
|
||||
if( cnt == 0 && pParse->trigStack != 0 ){
|
||||
TriggerStack *pTriggerStack = pParse->trigStack;
|
||||
int t = 0;
|
||||
if (tt->newIdx != -1 && sqliteStrICmp("new", zLeft) == 0) {
|
||||
pExpr->iTable = tt->newIdx;
|
||||
if( pTriggerStack->newIdx != -1 && sqliteStrICmp("new", zLeft) == 0 ){
|
||||
pExpr->iTable = pTriggerStack->newIdx;
|
||||
cntTab++;
|
||||
t = 1;
|
||||
}
|
||||
if (tt->oldIdx != -1 && sqliteStrICmp("old", zLeft) == 0) {
|
||||
pExpr->iTable = tt->oldIdx;
|
||||
if( pTriggerStack->oldIdx != -1 && sqliteStrICmp("old", zLeft) == 0 ){
|
||||
pExpr->iTable = pTriggerStack->oldIdx;
|
||||
cntTab++;
|
||||
t = 1;
|
||||
}
|
||||
|
||||
if (t)
|
||||
for(j=0; j<tt->pTab->nCol; j++) {
|
||||
if( sqliteStrICmp(tt->pTab->aCol[j].zName, zRight)==0 ){
|
||||
if( t ){
|
||||
int j;
|
||||
for(j=0; j < pTriggerStack->pTab->nCol; j++) {
|
||||
if( sqliteStrICmp(pTriggerStack->pTab->aCol[j].zName, zRight)==0 ){
|
||||
cnt++;
|
||||
pExpr->iColumn = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( cnt==0 && cntTab==1 && sqliteIsRowid(zRight) ){
|
||||
|
64
src/insert.c
64
src/insert.c
@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle INSERT statements in SQLite.
|
||||
**
|
||||
** $Id: insert.c,v 1.54 2002/05/15 11:44:14 drh Exp $
|
||||
** $Id: insert.c,v 1.55 2002/05/19 23:43:14 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -102,8 +102,9 @@ void sqliteInsert(
|
||||
}
|
||||
|
||||
/* if there are row triggers, allocate a temp table for new.* references. */
|
||||
if (row_triggers_exist)
|
||||
if( row_triggers_exist ){
|
||||
newIdx = pParse->nTab++;
|
||||
}
|
||||
|
||||
/* Figure out how many columns of data are supplied. If the data
|
||||
** is coming from a SELECT statement, then this step has to generate
|
||||
@ -204,17 +205,18 @@ void sqliteInsert(
|
||||
}
|
||||
|
||||
/* Open the temp table for FOR EACH ROW triggers */
|
||||
if (row_triggers_exist)
|
||||
if( row_triggers_exist ){
|
||||
sqliteVdbeAddOp(v, OP_OpenTemp, newIdx, 0);
|
||||
}
|
||||
|
||||
/* Initialize the count of rows to be inserted
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows && !pParse->trigStack){
|
||||
if( db->flags & SQLITE_CountRows && !pParse->trigStack ){
|
||||
sqliteVdbeAddOp(v, OP_Integer, 0, 0); /* Initialize the row count */
|
||||
}
|
||||
|
||||
/* Open tables and indices if there are no row triggers */
|
||||
if (!row_triggers_exist) {
|
||||
if( !row_triggers_exist ){
|
||||
base = pParse->nTab;
|
||||
openOp = pTab->isTemp ? OP_OpenWrAux : OP_OpenWrite;
|
||||
sqliteVdbeAddOp(v, openOp, base, pTab->tnum);
|
||||
@ -237,7 +239,7 @@ void sqliteInsert(
|
||||
iCont = sqliteVdbeCurrentAddr(v);
|
||||
}
|
||||
|
||||
if (row_triggers_exist) {
|
||||
if( row_triggers_exist ){
|
||||
|
||||
/* build the new.* reference row */
|
||||
sqliteVdbeAddOp(v, OP_Integer, 13, 0);
|
||||
@ -263,13 +265,13 @@ void sqliteInsert(
|
||||
sqliteVdbeAddOp(v, OP_Rewind, newIdx, 0);
|
||||
|
||||
/* Fire BEFORE triggers */
|
||||
if (
|
||||
sqliteCodeRowTrigger(pParse, TK_INSERT, 0, TK_BEFORE, pTab, newIdx, -1,
|
||||
onError)
|
||||
) goto insert_cleanup;
|
||||
if( sqliteCodeRowTrigger(pParse, TK_INSERT, 0, TK_BEFORE, pTab, newIdx, -1,
|
||||
onError) ){
|
||||
goto insert_cleanup;
|
||||
}
|
||||
|
||||
/* Open the tables and indices for the INSERT */
|
||||
if (!pTab->pSelect) {
|
||||
if( !pTab->pSelect ){
|
||||
base = pParse->nTab;
|
||||
openOp = pTab->isTemp ? OP_OpenWrAux : OP_OpenWrite;
|
||||
sqliteVdbeAddOp(v, openOp, base, pTab->tnum);
|
||||
@ -287,7 +289,7 @@ void sqliteInsert(
|
||||
** except when the table has an INTEGER PRIMARY KEY column, in which
|
||||
** case the record number is the same as that column.
|
||||
*/
|
||||
if (!pTab->pSelect) {
|
||||
if( !pTab->pSelect ){
|
||||
if( keyColumn>=0 ){
|
||||
if( srcTab>=0 ){
|
||||
sqliteVdbeAddOp(v, OP_Column, srcTab, keyColumn);
|
||||
@ -296,8 +298,8 @@ void sqliteInsert(
|
||||
sqliteExprCode(pParse, pList->a[keyColumn].pExpr);
|
||||
|
||||
/* If the PRIMARY KEY expression is NULL, then use OP_NewRecno
|
||||
** to generate a unique primary key value.
|
||||
*/
|
||||
** to generate a unique primary key value.
|
||||
*/
|
||||
addr = sqliteVdbeAddOp(v, OP_Dup, 0, 1);
|
||||
sqliteVdbeAddOp(v, OP_NotNull, 0, addr+4);
|
||||
sqliteVdbeAddOp(v, OP_Pop, 1, 0);
|
||||
@ -309,14 +311,14 @@ void sqliteInsert(
|
||||
}
|
||||
|
||||
/* Push onto the stack, data for all columns of the new entry, beginning
|
||||
** with the first column.
|
||||
*/
|
||||
** with the first column.
|
||||
*/
|
||||
for(i=0; i<pTab->nCol; i++){
|
||||
if( i==pTab->iPKey ){
|
||||
/* The value of the INTEGER PRIMARY KEY column is always a NULL.
|
||||
** Whenever this column is read, the record number will be substituted
|
||||
** in its place. So will fill this column with a NULL to avoid
|
||||
** taking up data space with information that will never be used. */
|
||||
** Whenever this column is read, the record number will be substituted
|
||||
** in its place. So will fill this column with a NULL to avoid
|
||||
** taking up data space with information that will never be used. */
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
continue;
|
||||
}
|
||||
@ -338,22 +340,22 @@ void sqliteInsert(
|
||||
}
|
||||
|
||||
/* Generate code to check constraints and generate index keys and
|
||||
** do the insertion.
|
||||
*/
|
||||
** do the insertion.
|
||||
*/
|
||||
endOfLoop = sqliteVdbeMakeLabel(v);
|
||||
sqliteGenerateConstraintChecks(pParse, pTab, base, 0,0,0,onError,endOfLoop);
|
||||
sqliteCompleteInsertion(pParse, pTab, base, 0,0,0);
|
||||
|
||||
/* Update the count of rows that are inserted
|
||||
*/
|
||||
*/
|
||||
if( (db->flags & SQLITE_CountRows)!=0 && !pParse->trigStack){
|
||||
sqliteVdbeAddOp(v, OP_AddImm, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (row_triggers_exist) {
|
||||
if( row_triggers_exist ){
|
||||
/* Close all tables opened */
|
||||
if (!pTab->pSelect) {
|
||||
if( !pTab->pSelect ){
|
||||
sqliteVdbeAddOp(v, OP_Close, base, 0);
|
||||
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
|
||||
sqliteVdbeAddOp(v, OP_Close, idx+base, 0);
|
||||
@ -361,14 +363,14 @@ void sqliteInsert(
|
||||
}
|
||||
|
||||
/* Code AFTER triggers */
|
||||
if (
|
||||
sqliteCodeRowTrigger(pParse, TK_INSERT, 0, TK_AFTER, pTab, newIdx, -1,
|
||||
onError)
|
||||
) goto insert_cleanup;
|
||||
if( sqliteCodeRowTrigger(pParse, TK_INSERT, 0, TK_AFTER, pTab, newIdx, -1,
|
||||
onError) ){
|
||||
goto insert_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* The bottom of the loop, if the data source is a SELECT statement
|
||||
*/
|
||||
*/
|
||||
sqliteVdbeResolveLabel(v, endOfLoop);
|
||||
if( srcTab>=0 ){
|
||||
sqliteVdbeAddOp(v, OP_Next, srcTab, iCont);
|
||||
@ -376,7 +378,7 @@ void sqliteInsert(
|
||||
sqliteVdbeAddOp(v, OP_Close, srcTab, 0);
|
||||
}
|
||||
|
||||
if (!row_triggers_exist) {
|
||||
if( !row_triggers_exist ){
|
||||
/* Close all tables opened */
|
||||
sqliteVdbeAddOp(v, OP_Close, base, 0);
|
||||
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
|
||||
@ -387,7 +389,7 @@ void sqliteInsert(
|
||||
sqliteEndWriteOperation(pParse);
|
||||
|
||||
/*
|
||||
** Return the number of rows inserted.
|
||||
** Return the number of rows inserted.
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows && !pParse->trigStack ){
|
||||
sqliteVdbeAddOp(v, OP_ColumnCount, 1, 0);
|
||||
|
@ -14,7 +14,7 @@
|
||||
** other files are for internal use by SQLite and should not be
|
||||
** accessed by users of the library.
|
||||
**
|
||||
** $Id: main.c,v 1.74 2002/05/15 14:17:45 drh Exp $
|
||||
** $Id: main.c,v 1.75 2002/05/19 23:43:14 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@ -394,14 +394,14 @@ static void clearHashTable(sqlite *db, int preserveTemps){
|
||||
sqliteHashInit(&db->trigHash, SQLITE_HASH_STRING, 0);
|
||||
sqliteHashClear(&db->idxHash);
|
||||
|
||||
for (pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
|
||||
for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
|
||||
Trigger * pTrigger = sqliteHashData(pElem);
|
||||
Table *pTab = sqliteFindTable(db, pTrigger->table);
|
||||
assert(pTab);
|
||||
if (pTab->isTemp) {
|
||||
if( pTab->isTemp ){
|
||||
sqliteHashInsert(&db->trigHash, pTrigger->name, strlen(pTrigger->name),
|
||||
pTrigger);
|
||||
} else {
|
||||
}else{
|
||||
sqliteDeleteTrigger(pTrigger);
|
||||
}
|
||||
}
|
||||
@ -434,7 +434,6 @@ static void clearHashTable(sqlite *db, int preserveTemps){
|
||||
}
|
||||
}
|
||||
sqliteHashClear(&temp1);
|
||||
|
||||
db->flags &= ~SQLITE_Initialized;
|
||||
}
|
||||
|
||||
|
@ -80,9 +80,11 @@ void sqliteCreateTrigger(
|
||||
sqliteExprMoveStrings(nt->pWhen, offset);
|
||||
|
||||
ss = nt->step_list;
|
||||
while (ss) {
|
||||
while( ss ){
|
||||
sqliteSelectMoveStrings(ss->pSelect, offset);
|
||||
if (ss->target.z) ss->target.z += offset;
|
||||
if( ss->target.z ){
|
||||
ss->target.z += offset;
|
||||
}
|
||||
sqliteExprMoveStrings(ss->pWhere, offset);
|
||||
sqliteExprListMoveStrings(ss->pExprList, offset);
|
||||
|
||||
@ -130,7 +132,7 @@ void sqliteCreateTrigger(
|
||||
nt->pNext = tab->pTrigger;
|
||||
tab->pTrigger = nt;
|
||||
return;
|
||||
} else {
|
||||
}else{
|
||||
sqliteFree(nt->strings);
|
||||
sqliteFree(nt->name);
|
||||
sqliteFree(nt->table);
|
||||
@ -146,7 +148,7 @@ trigger_cleanup:
|
||||
TriggerStep * nn;
|
||||
|
||||
pp = pStepList;
|
||||
while (pp) {
|
||||
while( pp ){
|
||||
nn = pp->pNext;
|
||||
sqliteExprDelete(pp->pWhere);
|
||||
sqliteExprListDelete(pp->pExprList);
|
||||
@ -228,7 +230,7 @@ void sqliteDeleteTrigger(Trigger *pTrigger)
|
||||
TriggerStep *pTriggerStep;
|
||||
|
||||
pTriggerStep = pTrigger->step_list;
|
||||
while (pTriggerStep) {
|
||||
while( pTriggerStep ){
|
||||
TriggerStep * pTmp = pTriggerStep;
|
||||
pTriggerStep = pTriggerStep->pNext;
|
||||
|
||||
@ -287,7 +289,7 @@ void sqliteDropTrigger(Parse *pParse, Token *pName, int nested)
|
||||
assert(pTable);
|
||||
if( pTable->pTrigger == pTrigger ){
|
||||
pTable->pTrigger = pTrigger->pNext;
|
||||
} else {
|
||||
}else{
|
||||
Trigger *cc = pTable->pTrigger;
|
||||
while( cc ){
|
||||
if( cc->pNext == pTrigger ){
|
||||
@ -346,13 +348,16 @@ void sqliteDropTrigger(Parse *pParse, Token *pName, int nested)
|
||||
static int checkColumnOverLap(IdList * pIdList, ExprList * pEList)
|
||||
{
|
||||
int i, e;
|
||||
if (!pIdList) return 1;
|
||||
if (!pEList) return 1;
|
||||
if( !pIdList )return 1;
|
||||
if( !pEList )return 1;
|
||||
|
||||
for (i = 0; i < pIdList->nId; i++)
|
||||
for (e = 0; e < pEList->nExpr; e++)
|
||||
if (!sqliteStrICmp(pIdList->a[i].zName, pEList->a[e].zName))
|
||||
for(i = 0; i < pIdList->nId; i++){
|
||||
for(e = 0; e < pEList->nExpr; e++){
|
||||
if( !sqliteStrICmp(pIdList->a[i].zName, pEList->a[e].zName) ){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -394,8 +399,10 @@ int sqliteTriggersExist(
|
||||
checkColumnOverLap(pTriggerCursor->pColumns, pChanges) ){
|
||||
TriggerStack * ss;
|
||||
ss = pParse->trigStack;
|
||||
while (ss && ss->pTrigger != pTrigger) ss = ss->pNext;
|
||||
if (!ss) return 1;
|
||||
while( ss && ss->pTrigger != pTrigger ){
|
||||
ss = ss->pNext;
|
||||
}
|
||||
if( !ss )return 1;
|
||||
}
|
||||
pTriggerCursor = pTriggerCursor->pNext;
|
||||
}
|
||||
@ -493,24 +500,27 @@ int sqliteCodeRowTrigger(
|
||||
assert(newIdx != -1 || oldIdx != -1);
|
||||
|
||||
pTrigger = pTab->pTrigger;
|
||||
while (pTrigger) {
|
||||
while( pTrigger ){
|
||||
int fire_this = 0;
|
||||
|
||||
/* determine whether we should code this trigger */
|
||||
if (pTrigger->op == op && pTrigger->tr_tm == tr_tm &&
|
||||
pTrigger->foreach == TK_ROW) {
|
||||
if( pTrigger->op == op && pTrigger->tr_tm == tr_tm &&
|
||||
pTrigger->foreach == TK_ROW ){
|
||||
fire_this = 1;
|
||||
pTriggerStack = pParse->trigStack;
|
||||
while (pTriggerStack) {
|
||||
if (pTriggerStack->pTrigger == pTrigger) fire_this = 0;
|
||||
while( pTriggerStack ){
|
||||
if( pTriggerStack->pTrigger == pTrigger ){
|
||||
fire_this = 0;
|
||||
}
|
||||
pTriggerStack = pTriggerStack->pNext;
|
||||
}
|
||||
if (op == TK_UPDATE && pTrigger->pColumns &&
|
||||
!checkColumnOverLap(pTrigger->pColumns, pChanges))
|
||||
if( op == TK_UPDATE && pTrigger->pColumns &&
|
||||
!checkColumnOverLap(pTrigger->pColumns, pChanges) ){
|
||||
fire_this = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (fire_this) {
|
||||
if( fire_this ){
|
||||
int endTrigger;
|
||||
IdList dummyTablist;
|
||||
Expr * whenExpr;
|
||||
@ -530,7 +540,7 @@ int sqliteCodeRowTrigger(
|
||||
/* code the WHEN clause */
|
||||
endTrigger = sqliteVdbeMakeLabel(pParse->pVdbe);
|
||||
whenExpr = sqliteExprDup(pTrigger->pWhen);
|
||||
if (sqliteExprResolveIds(pParse, 0, &dummyTablist, 0, whenExpr)) {
|
||||
if( sqliteExprResolveIds(pParse, 0, &dummyTablist, 0, whenExpr) ){
|
||||
pParse->trigStack = pParse->trigStack->pNext;
|
||||
sqliteFree(pTriggerStack);
|
||||
sqliteExprDelete(whenExpr);
|
||||
@ -636,8 +646,9 @@ void sqliteViewTriggers(
|
||||
for(ii=0; ii<pChanges->nExpr; ii++){
|
||||
int jj;
|
||||
if( sqliteExprResolveIds(pParse, oldIdx, theSelect.pSrc , 0,
|
||||
pChanges->a[ii].pExpr) )
|
||||
pChanges->a[ii].pExpr) ){
|
||||
goto trigger_cleanup;
|
||||
}
|
||||
|
||||
if( sqliteExprCheck(pParse, pChanges->a[ii].pExpr, 0, 0) )
|
||||
goto trigger_cleanup;
|
||||
@ -661,7 +672,7 @@ void sqliteViewTriggers(
|
||||
for(ii = 0; ii<pTab->nCol; ii++){
|
||||
if( aXRef[ii] < 0 ){
|
||||
sqliteVdbeAddOp(v, OP_Column, oldIdx, ii);
|
||||
} else {
|
||||
}else{
|
||||
sqliteExprCode(pParse, pChanges->a[aXRef[ii]].pExpr);
|
||||
}
|
||||
}
|
||||
@ -674,7 +685,7 @@ void sqliteViewTriggers(
|
||||
pTab, newIdx, oldIdx, orconf);
|
||||
sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_AFTER,
|
||||
pTab, newIdx, oldIdx, orconf);
|
||||
} else {
|
||||
}else{
|
||||
sqliteCodeRowTrigger(pParse, TK_DELETE, 0, TK_BEFORE, pTab, -1, oldIdx,
|
||||
orconf);
|
||||
sqliteCodeRowTrigger(pParse, TK_DELETE, 0, TK_AFTER, pTab, -1, oldIdx,
|
||||
|
53
src/update.c
53
src/update.c
@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle UPDATE statements.
|
||||
**
|
||||
** $Id: update.c,v 1.38 2002/05/15 11:44:15 drh Exp $
|
||||
** $Id: update.c,v 1.39 2002/05/19 23:43:14 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -59,11 +59,11 @@ void sqliteUpdate(
|
||||
* defined
|
||||
*/
|
||||
{
|
||||
char * zTab = sqliteTableNameFromToken(pTableName);
|
||||
char *zTab = sqliteTableNameFromToken(pTableName);
|
||||
|
||||
if(zTab != 0) {
|
||||
if( zTab != 0 ){
|
||||
pTab = sqliteFindTable(pParse->db, zTab);
|
||||
if (pTab) {
|
||||
if( pTab ){
|
||||
row_triggers_exist =
|
||||
sqliteTriggersExist(pParse, pTab->pTrigger,
|
||||
TK_UPDATE, TK_BEFORE, TK_ROW, pChanges) ||
|
||||
@ -71,7 +71,7 @@ void sqliteUpdate(
|
||||
TK_UPDATE, TK_AFTER, TK_ROW, pChanges);
|
||||
}
|
||||
sqliteFree(zTab);
|
||||
if (row_triggers_exist && pTab->pSelect ) {
|
||||
if( row_triggers_exist && pTab->pSelect ){
|
||||
/* Just fire VIEW triggers */
|
||||
sqliteViewTriggers(pParse, pTab, pWhere, onError, pChanges);
|
||||
return;
|
||||
@ -92,7 +92,8 @@ void sqliteUpdate(
|
||||
if( aXRef==0 ) goto update_cleanup;
|
||||
for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
|
||||
|
||||
if (row_triggers_exist) {
|
||||
/* If there are FOR EACH ROW triggers, allocate temp tables */
|
||||
if( row_triggers_exist ){
|
||||
newIdx = pParse->nTab++;
|
||||
oldIdx = pParse->nTab++;
|
||||
}
|
||||
@ -197,7 +198,7 @@ void sqliteUpdate(
|
||||
sqliteVdbeAddOp(v, OP_Integer, 0, 0);
|
||||
}
|
||||
|
||||
if (row_triggers_exist) {
|
||||
if( row_triggers_exist ){
|
||||
int ii;
|
||||
|
||||
sqliteVdbeAddOp(v, OP_OpenTemp, oldIdx, 0);
|
||||
@ -212,22 +213,24 @@ void sqliteUpdate(
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
|
||||
|
||||
sqliteVdbeAddOp(v, OP_Integer, 13, 0);
|
||||
for (ii = 0; ii < pTab->nCol; ii++) {
|
||||
if (ii == pTab->iPKey)
|
||||
sqliteVdbeAddOp(v, OP_Recno, base, 0);
|
||||
else
|
||||
sqliteVdbeAddOp(v, OP_Column, base, ii);
|
||||
for(ii = 0; ii < pTab->nCol; ii++){
|
||||
if( ii == pTab->iPKey ){
|
||||
sqliteVdbeAddOp(v, OP_Recno, base, 0);
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_Column, base, ii);
|
||||
}
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
||||
sqliteVdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
|
||||
|
||||
sqliteVdbeAddOp(v, OP_Integer, 13, 0);
|
||||
for (ii = 0; ii < pTab->nCol; ii++){
|
||||
for(ii = 0; ii < pTab->nCol; ii++){
|
||||
if( aXRef[ii] < 0 ){
|
||||
if (ii == pTab->iPKey)
|
||||
if( ii == pTab->iPKey ){
|
||||
sqliteVdbeAddOp(v, OP_Recno, base, 0);
|
||||
else
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_Column, base, ii);
|
||||
}
|
||||
}else{
|
||||
sqliteExprCode(pParse, pChanges->a[aXRef[ii]].pExpr);
|
||||
}
|
||||
@ -239,8 +242,10 @@ void sqliteUpdate(
|
||||
sqliteVdbeAddOp(v, OP_Rewind, oldIdx, 0);
|
||||
sqliteVdbeAddOp(v, OP_Rewind, newIdx, 0);
|
||||
|
||||
if (sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_BEFORE, pTab,
|
||||
newIdx, oldIdx, onError)) goto update_cleanup;
|
||||
if( sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_BEFORE, pTab,
|
||||
newIdx, oldIdx, onError) ){
|
||||
goto update_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* Rewind the list of records that need to be updated and
|
||||
@ -276,7 +281,7 @@ void sqliteUpdate(
|
||||
** Also, the old data is needed to delete the old index entires.
|
||||
** So make the cursor point at the old record.
|
||||
*/
|
||||
if (!row_triggers_exist) {
|
||||
if( !row_triggers_exist ){
|
||||
int ii;
|
||||
sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
|
||||
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, 0);
|
||||
@ -337,7 +342,7 @@ void sqliteUpdate(
|
||||
sqliteVdbeAddOp(v, OP_AddImm, 1, 0);
|
||||
}
|
||||
|
||||
if (row_triggers_exist) {
|
||||
if( row_triggers_exist ){
|
||||
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||
if( openAll || aIdxUsed[i] )
|
||||
sqliteVdbeAddOp(v, OP_Close, base+i+1, 0);
|
||||
@ -345,8 +350,10 @@ void sqliteUpdate(
|
||||
sqliteVdbeAddOp(v, OP_Close, base, 0);
|
||||
pParse->nTab = base;
|
||||
|
||||
if (sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_AFTER, pTab,
|
||||
newIdx, oldIdx, onError)) goto update_cleanup;
|
||||
if( sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_AFTER, pTab,
|
||||
newIdx, oldIdx, onError) ){
|
||||
goto update_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* Repeat the above with the next record to be updated, until
|
||||
@ -357,7 +364,7 @@ void sqliteUpdate(
|
||||
sqliteVdbeAddOp(v, OP_ListReset, 0, 0);
|
||||
|
||||
/* Close all tables if there were no FOR EACH ROW triggers */
|
||||
if (!row_triggers_exist) {
|
||||
if( !row_triggers_exist ){
|
||||
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||
if( openAll || aIdxUsed[i] ){
|
||||
sqliteVdbeAddOp(v, OP_Close, base+i+1, 0);
|
||||
@ -365,7 +372,7 @@ void sqliteUpdate(
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Close, base, 0);
|
||||
pParse->nTab = base;
|
||||
} else {
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_Close, newIdx, 0);
|
||||
sqliteVdbeAddOp(v, OP_Close, oldIdx, 0);
|
||||
}
|
||||
|
13
src/vdbe.c
13
src/vdbe.c
@ -30,7 +30,7 @@
|
||||
** But other routines are also provided to help in building up
|
||||
** a program instruction by instruction.
|
||||
**
|
||||
** $Id: vdbe.c,v 1.143 2002/05/15 11:44:15 drh Exp $
|
||||
** $Id: vdbe.c,v 1.144 2002/05/19 23:43:14 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -249,9 +249,8 @@ struct Vdbe {
|
||||
int nCallback; /* Number of callbacks invoked so far */
|
||||
int iLimit; /* Limit on the number of callbacks remaining */
|
||||
int iOffset; /* Offset before beginning to do callbacks */
|
||||
|
||||
int keylistStackDepth;
|
||||
Keylist ** keylistStack;
|
||||
int keylistStackDepth; /* The size of the "keylist" stack */
|
||||
Keylist **keylistStack; /* The stack used by opcodes PushList & PopList */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1002,9 +1001,9 @@ static void Cleanup(Vdbe *p){
|
||||
sqliteFree(p->aSet);
|
||||
p->aSet = 0;
|
||||
p->nSet = 0;
|
||||
if (p->keylistStackDepth > 0) {
|
||||
if( p->keylistStackDepth > 0 ){
|
||||
int ii;
|
||||
for (ii = 0; ii < p->keylistStackDepth; ii++) {
|
||||
for(ii = 0; ii < p->keylistStackDepth; ii++){
|
||||
KeylistFree(p->keylistStack[ii]);
|
||||
}
|
||||
sqliteFree(p->keylistStack);
|
||||
@ -4577,7 +4576,7 @@ case OP_PopList: {
|
||||
KeylistFree(p->pList);
|
||||
p->pList = p->keylistStack[p->keylistStackDepth];
|
||||
p->keylistStack[p->keylistStackDepth] = 0;
|
||||
if (p->keylistStackDepth == 0) {
|
||||
if( p->keylistStackDepth == 0 ){
|
||||
sqliteFree(p->keylistStack);
|
||||
p->keylistStack = 0;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
** the WHERE clause of SQL statements. Also found here are subroutines
|
||||
** to generate VDBE code to evaluate expressions.
|
||||
**
|
||||
** $Id: where.c,v 1.43 2002/05/15 11:44:15 drh Exp $
|
||||
** $Id: where.c,v 1.44 2002/05/19 23:43:14 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -216,7 +216,7 @@ WhereInfo *sqliteWhereBegin(
|
||||
*/
|
||||
for(i=0; i<nExpr; i++){
|
||||
exprAnalyze(base, &aExpr[i]);
|
||||
if (pParse->trigStack && pParse->trigStack->newIdx >= 0) {
|
||||
if( pParse->trigStack && pParse->trigStack->newIdx >= 0 ){
|
||||
aExpr[i].prereqRight =
|
||||
aExpr[i].prereqRight & ~(1 << pParse->trigStack->newIdx - base);
|
||||
aExpr[i].prereqLeft =
|
||||
@ -224,7 +224,7 @@ WhereInfo *sqliteWhereBegin(
|
||||
aExpr[i].prereqAll =
|
||||
aExpr[i].prereqAll & ~(1 << pParse->trigStack->newIdx - base);
|
||||
}
|
||||
if (pParse->trigStack && pParse->trigStack->oldIdx >= 0) {
|
||||
if( pParse->trigStack && pParse->trigStack->oldIdx >= 0 ){
|
||||
aExpr[i].prereqRight =
|
||||
aExpr[i].prereqRight & ~(1 << pParse->trigStack->oldIdx - base);
|
||||
aExpr[i].prereqLeft =
|
||||
|
Loading…
Reference in New Issue
Block a user