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

Alternative fix for ticket #3810. This is a replacement for check-in (6956). (CVS 6960)

FossilOrigin-Name: ba1afc040171810d0c996708d7b9cb11abcd99d8
This commit is contained in:
drh
2009-08-06 17:43:31 +00:00
parent e33b0ed3b7
commit 3d5f74b275
6 changed files with 70 additions and 32 deletions

View File

@@ -1,5 +1,5 @@
C Change\sa\shyperlink\slabel\son\sshared\scache\smode\sdocumentation.\s\sNo\schanges\nto\scode.\s(CVS\s6959) C Alternative\sfix\sfor\sticket\s#3810.\s\sThis\sis\sa\sreplacement\sfor\scheck-in\s(6956).\s(CVS\s6960)
D 2009-08-06T17:40:46 D 2009-08-06T17:43:31
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in df9359da7a726ccb67a45db905c5447d5c00c6ef F Makefile.in df9359da7a726ccb67a45db905c5447d5c00c6ef
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -154,7 +154,7 @@ F src/pcache.c c92ffd4f3e1279b3766854c6d18b5bf4aac0d1fa
F src/pcache.h 435ef324197f79391f9c92b71d7f92b548ad7a36 F src/pcache.h 435ef324197f79391f9c92b71d7f92b548ad7a36
F src/pcache1.c 6dc833c89feac405dd8b4858232c97e679f182ec F src/pcache1.c 6dc833c89feac405dd8b4858232c97e679f182ec
F src/pragma.c 9eb44ac1d3dc1ac3ea4f444abe1a10ae8acaa16c F src/pragma.c 9eb44ac1d3dc1ac3ea4f444abe1a10ae8acaa16c
F src/prepare.c 153f3eb168c3447ff770c445609bfec012daeba1 F src/prepare.c 0b966d20979237121ec5fec449c9db45f6b9789a
F src/printf.c 508a1c59433353552b6553cba175eaa7331f8fc1 F src/printf.c 508a1c59433353552b6553cba175eaa7331f8fc1
F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628 F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628
F src/resolve.c 4a61d03e49b15440878096e6030863fc628828f0 F src/resolve.c 4a61d03e49b15440878096e6030863fc628828f0
@@ -163,7 +163,7 @@ F src/select.c 67b0778c9585905c8aa75aaa469e76ef3c1d315a
F src/shell.c db2643650b9268df89a4bedca3f1c6d9e786f1bb F src/shell.c db2643650b9268df89a4bedca3f1c6d9e786f1bb
F src/sqlite.h.in eb42257503a48f6f12ff0b23a81067ba9b5ac1eb F src/sqlite.h.in eb42257503a48f6f12ff0b23a81067ba9b5ac1eb
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17 F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
F src/sqliteInt.h 3de9749ac963f77327a014afebe2903240dff4f6 F src/sqliteInt.h 2f8dae0ff826acddcaab941dabb96acbcbf84ecf
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76 F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d
@@ -199,7 +199,7 @@ F src/test_tclvar.c 9e42fa59d3d2f064b7ab8628e7ab2dc8a9fe93d4
F src/test_thread.c b8a1ab7ca1a632f18e8a361880d5d65eeea08eac F src/test_thread.c b8a1ab7ca1a632f18e8a361880d5d65eeea08eac
F src/test_wsd.c 3ae5101de6cbfda2720152ab659ea84079719241 F src/test_wsd.c 3ae5101de6cbfda2720152ab659ea84079719241
F src/tokenize.c af8a56e6a50c5042fc305bfa796275e9bf26ff2b F src/tokenize.c af8a56e6a50c5042fc305bfa796275e9bf26ff2b
F src/trigger.c c07c5157c58fcdb704f65d5f5e4775276e45bb8b F src/trigger.c f248851055abbb6fc583b1809b69a234a85a01b2
F src/update.c 245a652c0c1b1affd7ccf2a1970a465977e7bfa2 F src/update.c 245a652c0c1b1affd7ccf2a1970a465977e7bfa2
F src/utf.c 9541d28f40441812c0b40f00334372a0542c00ff F src/utf.c 9541d28f40441812c0b40f00334372a0542c00ff
F src/util.c c2416f60ae704a8c4990e4909aa810f90cbffa07 F src/util.c c2416f60ae704a8c4990e4909aa810f90cbffa07
@@ -646,7 +646,7 @@ F test/tkt3762.test 2a9f3b03df44ec49ec0cfa8d5da6574c2a7853df
F test/tkt3773.test 430b06567ce40285dfd2c4834a2a61816403efeb F test/tkt3773.test 430b06567ce40285dfd2c4834a2a61816403efeb
F test/tkt3791.test a6624b9a80b216a26cf473607f42f3e51898c267 F test/tkt3791.test a6624b9a80b216a26cf473607f42f3e51898c267
F test/tkt3793.test 754b73f0e6a9349c70dc57e522cf3247272ecd5d F test/tkt3793.test 754b73f0e6a9349c70dc57e522cf3247272ecd5d
F test/tkt3810.test 1d19763ba1c6b04fce9f559a2992d39f2647aa76 F test/tkt3810.test 616cfde9c93397dcb6aea079f6e00b4b35e5022c
F test/tkt3824.test 3da2f5c81b057e3ff355f5dfc9aa0cf0a92e0206 F test/tkt3824.test 3da2f5c81b057e3ff355f5dfc9aa0cf0a92e0206
F test/tkt3832.test 7ebd5ac82d1e430accd5eec9768044133a94c2aa F test/tkt3832.test 7ebd5ac82d1e430accd5eec9768044133a94c2aa
F test/tkt3838.test 2a1525946bc9d3751e1d49ce95f3a2472f2b7408 F test/tkt3838.test 2a1525946bc9d3751e1d49ce95f3a2472f2b7408
@@ -741,7 +741,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746 F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746
P a1c184cd2ac5a7559d787e6c34b1d0ce034d10cf P 3d08ca0e54dd4c292b3db3a8364ab237713c5c43
R 7c39bc4481f5dcf21ff41954bbcf32f0 R b16b828bf8d4073d3a6b41a86bf881b8
U drh U drh
Z 8b3beb0979c7513ef5a6160122ef1253 Z 2ac22dbeee3a31e054e7b5b1178ce1e8

View File

@@ -1 +1 @@
3d08ca0e54dd4c292b3db3a8364ab237713c5c43 ba1afc040171810d0c996708d7b9cb11abcd99d8

View File

@@ -13,7 +13,7 @@
** interface, and routines that contribute to loading the database schema ** interface, and routines that contribute to loading the database schema
** from disk. ** from disk.
** **
** $Id: prepare.c,v 1.130 2009/08/01 16:27:00 drh Exp $ ** $Id: prepare.c,v 1.131 2009/08/06 17:43:31 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -27,11 +27,6 @@ static void corruptSchema(
const char *zExtra /* Error information */ const char *zExtra /* Error information */
){ ){
sqlite3 *db = pData->db; sqlite3 *db = pData->db;
if( pData->iDb==1 && zObj && zExtra ){
*pData->pzErrMsg = sqlite3MPrintf(db, "in %s: %s", zObj, zExtra);
pData->rc = SQLITE_ERROR;
return;
}
if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){ if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){
if( zObj==0 ) zObj = "?"; if( zObj==0 ) zObj = "?";
sqlite3SetString(pData->pzErrMsg, db, sqlite3SetString(pData->pzErrMsg, db,
@@ -85,15 +80,20 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
assert( db->init.busy ); assert( db->init.busy );
db->init.iDb = iDb; db->init.iDb = iDb;
db->init.newTnum = atoi(argv[1]); db->init.newTnum = atoi(argv[1]);
db->init.orphanTrigger = 0;
rc = sqlite3_exec(db, argv[2], 0, 0, &zErr); rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
db->init.iDb = 0; db->init.iDb = 0;
assert( rc!=SQLITE_OK || zErr==0 ); assert( rc!=SQLITE_OK || zErr==0 );
if( SQLITE_OK!=rc ){ if( SQLITE_OK!=rc ){
pData->rc = rc; if( db->init.orphanTrigger ){
if( rc==SQLITE_NOMEM ){ assert( iDb==1 );
db->mallocFailed = 1; }else{
}else if( rc!=SQLITE_INTERRUPT && rc!=SQLITE_LOCKED ){ pData->rc = rc;
corruptSchema(pData, argv[0], zErr); if( rc==SQLITE_NOMEM ){
db->mallocFailed = 1;
}else if( rc!=SQLITE_INTERRUPT && rc!=SQLITE_LOCKED ){
corruptSchema(pData, argv[0], zErr);
}
} }
sqlite3DbFree(db, zErr); sqlite3DbFree(db, zErr);
} }

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** Internal interface definitions for SQLite. ** Internal interface definitions for SQLite.
** **
** @(#) $Id: sqliteInt.h,v 1.896 2009/07/28 16:44:26 danielk1977 Exp $ ** @(#) $Id: sqliteInt.h,v 1.897 2009/08/06 17:43:31 drh Exp $
*/ */
#ifndef _SQLITEINT_H_ #ifndef _SQLITEINT_H_
#define _SQLITEINT_H_ #define _SQLITEINT_H_
@@ -800,6 +800,7 @@ struct sqlite3 {
int iDb; /* When back is being initialized */ int iDb; /* When back is being initialized */
int newTnum; /* Rootpage of table being initialized */ int newTnum; /* Rootpage of table being initialized */
u8 busy; /* TRUE if currently initializing */ u8 busy; /* TRUE if currently initializing */
u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */
} init; } init;
int nExtension; /* Number of loaded extensions */ int nExtension; /* Number of loaded extensions */
void **aExtension; /* Array of shared library handles */ void **aExtension; /* Array of shared library handles */

View File

@@ -10,7 +10,7 @@
************************************************************************* *************************************************************************
** **
** **
** $Id: trigger.c,v 1.141 2009/05/28 01:00:55 drh Exp $ ** $Id: trigger.c,v 1.142 2009/08/06 17:43:31 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -86,14 +86,14 @@ void sqlite3BeginTrigger(
int isTemp, /* True if the TEMPORARY keyword is present */ int isTemp, /* True if the TEMPORARY keyword is present */
int noErr /* Suppress errors if the trigger already exists */ int noErr /* Suppress errors if the trigger already exists */
){ ){
Trigger *pTrigger = 0; Trigger *pTrigger = 0; /* The new trigger */
Table *pTab; Table *pTab; /* Table that the trigger fires off of */
char *zName = 0; /* Name of the trigger */ char *zName = 0; /* Name of the trigger */
sqlite3 *db = pParse->db; sqlite3 *db = pParse->db; /* The database connection */
int iDb; /* The database to store the trigger in */ int iDb; /* The database to store the trigger in */
Token *pName; /* The unqualified db name */ Token *pName; /* The unqualified db name */
DbFixer sFix; DbFixer sFix; /* State vector for the DB fixer */
int iTabDb; int iTabDb; /* Index of the database holding pTab */
assert( pName1!=0 ); /* pName1->z might be NULL, but not pName1 itself */ assert( pName1!=0 ); /* pName1->z might be NULL, but not pName1 itself */
assert( pName2!=0 ); assert( pName2!=0 );
@@ -138,6 +138,17 @@ void sqlite3BeginTrigger(
pTab = sqlite3SrcListLookup(pParse, pTableName); pTab = sqlite3SrcListLookup(pParse, pTableName);
if( !pTab ){ if( !pTab ){
/* The table does not exist. */ /* The table does not exist. */
if( db->init.iDb==1 ){
/* Ticket #3810.
** Normally, whenever a table is dropped, all associated triggers are
** dropped too. But if a TEMP trigger is created on a non-TEMP table
** and the table is dropped by a different database connection, the
** trigger is not visible to the database connection that does the
** drop so the trigger cannot be dropped. This results in an
** "orphaned trigger" - a trigger whose associated table is missing.
*/
db->init.orphanTrigger = 1;
}
goto trigger_cleanup; goto trigger_cleanup;
} }
if( IsVirtual(pTab) ){ if( IsVirtual(pTab) ){

View File

@@ -11,7 +11,7 @@
# #
# Tests to make sure #3810 is fixed. # Tests to make sure #3810 is fixed.
# #
# $Id: tkt3810.test,v 1.3 2009/08/01 18:22:30 drh Exp $ # $Id: tkt3810.test,v 1.4 2009/08/06 17:43:31 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@@ -23,6 +23,8 @@ do_test tkt3810-1.1 {
CREATE TABLE t1(x); CREATE TABLE t1(x);
INSERT INTO t1 VALUES(123); INSERT INTO t1 VALUES(123);
SELECT * FROM t1; SELECT * FROM t1;
CREATE TABLE t2(y);
CREATE TABLE t3(z);
} }
} 123 } 123
@@ -44,13 +46,37 @@ do_test tkt3810-3 {
execsql {DROP TABLE t1} db2 execsql {DROP TABLE t1} db2
execsql { execsql {
CREATE TEMP TRIGGER r1 AFTER INSERT ON t1 BEGIN CREATE TEMP TRIGGER r1 AFTER INSERT ON t1 BEGIN
INSERT INTO t1 VALUES(2345); INSERT INTO t2 VALUES(new.rowid);
END; END;
} }
catchsql { catchsql {
SELECT * FROM t1; SELECT * FROM t3;
} }
} {1 {in r1: no such table: t1}} } {0 {}}
# Trigger still exists in the sqlite_temp_master table, but now it is
# an orphan.
#
do_test tkt3810-4 {
execsql {SELECT name FROM sqlite_temp_master ORDER BY name}
} {r1}
# Because it is an orphan, it cannot be dropped.
#
do_test tkt3810-5 {
catchsql {DROP TRIGGER r1}
} {1 {no such trigger: r1}}
# Create a table t1 then drop the table in order to drop the orphaned
# trigger.
#
do_test tkt3810-6 {
execsql {CREATE TABLE t1(x)} db2
execsql {DROP TABLE t1}
execsql {
SELECT name FROM sqlite_temp_master;
}
} {}
db2 close db2 close