mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Fix issues with ALTER TABLE and triggers containing "UPDATE...FROM" statements.
FossilOrigin-Name: 2fba0d41b781d226915fa2bf888a7bc640c046ce22670ceb53f62a09f3975259
This commit is contained in:
15
manifest
15
manifest
@ -1,5 +1,5 @@
|
||||
C Correct\shandling\sof\souter\sjoins\sin\sthe\sFROM\sclause\sof\san\sUPDATE\sstatement\nthat\soccurs\sinside\sof\sa\strigger.\s\sFollow-on\sto\s[98b3816bbaf539ea].
|
||||
D 2022-05-26T17:33:42.057
|
||||
C Fix\sissues\swith\sALTER\sTABLE\sand\striggers\scontaining\s"UPDATE...FROM"\sstatements.
|
||||
D 2022-05-26T19:10:11.700
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -500,7 +500,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c d8872f9d1863d8e31c37475e318de746e1b5ca57c0e477e35042a9ebbb6e0298
|
||||
F src/alter.c 379c644a32c64a18b592affac5ef173eb6024638b70ed4c593896e901702c78c
|
||||
F src/analyze.c aabdf3769c7fd9954a8ec508eb7041ae174b66f88d12c47199fabbea9a646467
|
||||
F src/attach.c 4431f82f0247bf3aaf91589acafdff77d1882235c95407b36da1585c765fbbc8
|
||||
F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
|
||||
@ -685,6 +685,7 @@ F test/alterqf.test ff6c6f881485c29ed699b8ef4774864ca1b0c01a6c08f5cdd624a008e4b4
|
||||
F test/altertab.test 7273b8506eab46342be016af78028df49f3bd99037412f997a8f1011b37a6912
|
||||
F test/altertab2.test 62597b6fd08feaba1b6bfe7d31dac6117c67e06dc9ce9c478a3abe75b5926de0
|
||||
F test/altertab3.test 8af5c6eb4a7dd2fc73235b865b53561bf07428d1d6a9cd59a067abf51141891e
|
||||
F test/altertrig.test f621cb3b209a2e72974e580840365b046537cd97b2df6b52088218a95dcbd58d
|
||||
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
|
||||
F test/analyze.test 547bb700f903107b38611b014ca645d6b5bb819f5210d7bf39c40802aafeb7d7
|
||||
F test/analyze3.test 4440c4932247adb2b4e0c838f657c19dc7af4f56859255436dc4e855f39b9324
|
||||
@ -1969,8 +1970,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P f22f41d2c8a676b9a339e7f00c29c163bbb7079b1a4a76ee1a6a96aaf7de5f9e
|
||||
R 96c2f1a4243ab0b57b68e0f3b4978a15
|
||||
U drh
|
||||
Z 723fac70f8b090aa70201f7f985c54bc
|
||||
P 664a49fa813144b6fa5a7ae3f65af5412f150dd5def261c4d581d706b39f7846
|
||||
R 4d839461e9af3d0a5ea1b8ddf72bf796
|
||||
U dan
|
||||
Z 14299f1b8c4a8b0632845b66e1aabf6a
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
664a49fa813144b6fa5a7ae3f65af5412f150dd5def261c4d581d706b39f7846
|
||||
2fba0d41b781d226915fa2bf888a7bc640c046ce22670ceb53f62a09f3975259
|
22
src/alter.c
22
src/alter.c
@ -1318,6 +1318,8 @@ static int renameResolveTrigger(Parse *pParse){
|
||||
SrcList *pSrc = sqlite3TriggerStepSrc(pParse, pStep);
|
||||
if( pSrc ){
|
||||
int i;
|
||||
assert( pSrc->nSrc==1 || pSrc->nSrc==2 );
|
||||
assert( pSrc->a[0].pSelect==0 );
|
||||
for(i=0; i<pSrc->nSrc && rc==SQLITE_OK; i++){
|
||||
SrcItem *p = &pSrc->a[i];
|
||||
p->iCursor = pParse->nTab++;
|
||||
@ -1325,8 +1327,6 @@ static int renameResolveTrigger(Parse *pParse){
|
||||
sqlite3SelectPrep(pParse, p->pSelect, 0);
|
||||
sqlite3ExpandSubquery(pParse, p);
|
||||
assert( i>0 );
|
||||
assert( pStep->pFrom->a[i-1].pSelect );
|
||||
sqlite3SelectPrep(pParse, pStep->pFrom->a[i-1].pSelect, 0);
|
||||
}else{
|
||||
p->pTab = sqlite3LocateTableItem(pParse, 0, p);
|
||||
if( p->pTab==0 ){
|
||||
@ -1337,6 +1337,15 @@ static int renameResolveTrigger(Parse *pParse){
|
||||
}
|
||||
}
|
||||
}
|
||||
if( pStep->pFrom ){
|
||||
for(i=0; i<pStep->pFrom->nSrc && rc==SQLITE_OK; i++){
|
||||
SrcItem *p = &pStep->pFrom->a[i];
|
||||
if( p->pSelect ){
|
||||
sqlite3SelectPrep(pParse, p->pSelect, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK && db->mallocFailed ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}
|
||||
@ -1789,6 +1798,15 @@ static void renameTableFunc(
|
||||
if( pStep->zTarget && 0==sqlite3_stricmp(pStep->zTarget, zOld) ){
|
||||
renameTokenFind(&sParse, &sCtx, pStep->zTarget);
|
||||
}
|
||||
if( pStep->pFrom ){
|
||||
int i;
|
||||
for(i=0; i<pStep->pFrom->nSrc; i++){
|
||||
SrcItem *pItem = &pStep->pFrom->a[i];
|
||||
if( pItem->zName && 0==sqlite3_stricmp(pItem->zName, zOld) ){
|
||||
renameTokenFind(&sParse, &sCtx, pItem->zName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
130
test/altertrig.test
Normal file
130
test/altertrig.test
Normal file
@ -0,0 +1,130 @@
|
||||
# 2022 May 27
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#*************************************************************************
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix altertrig
|
||||
|
||||
# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
|
||||
ifcapable !altertable {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
proc collapse_whitespace {in} {
|
||||
regsub -all {[ \t\n]+} [string trim $in] { }
|
||||
}
|
||||
|
||||
proc do_whitespace_sql_test {tn sql res} {
|
||||
set got [execsql $sql]
|
||||
set wgot [list]
|
||||
set wres [list]
|
||||
foreach g $got { lappend wgot [collapse_whitespace $g] }
|
||||
foreach r $res { lappend wres [collapse_whitespace $r] }
|
||||
|
||||
uplevel [list do_test $tn [list set {} $wgot] $wres]
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(x);
|
||||
CREATE TABLE t2(y);
|
||||
CREATE TABLE t3(z);
|
||||
CREATE TABLE t4(a);
|
||||
|
||||
CREATE TRIGGER r1 INSERT ON t1 BEGIN
|
||||
UPDATE t1 SET d='xyz' FROM t2, t3;
|
||||
END;
|
||||
}
|
||||
|
||||
do_whitespace_sql_test 1.1 {
|
||||
ALTER TABLE t3 RENAME TO t5;
|
||||
SELECT sql FROM sqlite_schema WHERE type='trigger';
|
||||
} {{
|
||||
CREATE TRIGGER r1 INSERT ON t1 BEGIN
|
||||
UPDATE t1 SET d='xyz' FROM t2, "t5";
|
||||
END
|
||||
}}
|
||||
|
||||
do_execsql_test 1.2 {
|
||||
DROP TRIGGER r1;
|
||||
CREATE TRIGGER r1 INSERT ON t1 BEGIN
|
||||
UPDATE t1 SET d='xyz' FROM t2, (SELECT * FROM t5);
|
||||
END;
|
||||
}
|
||||
|
||||
do_whitespace_sql_test 1.3 {
|
||||
ALTER TABLE t5 RENAME TO t3;
|
||||
SELECT sql FROM sqlite_schema WHERE type='trigger';
|
||||
} {{
|
||||
CREATE TRIGGER r1 INSERT ON t1 BEGIN
|
||||
UPDATE t1 SET d='xyz' FROM t2, (SELECT * FROM "t3");
|
||||
END
|
||||
}}
|
||||
|
||||
foreach {tn alter update final} {
|
||||
1 {
|
||||
ALTER TABLE t3 RENAME TO t10
|
||||
} {
|
||||
UPDATE t1 SET d='xyz' FROM t2, (SELECT * FROM t3)
|
||||
} {
|
||||
UPDATE t1 SET d='xyz' FROM t2, (SELECT * FROM "t10")
|
||||
}
|
||||
|
||||
2 {
|
||||
ALTER TABLE t3 RENAME TO t10
|
||||
} {
|
||||
UPDATE t1 SET d='xyz' FROM t3, (SELECT * FROM (SELECT e FROM t3))
|
||||
} {
|
||||
UPDATE t1 SET d='xyz' FROM "t10", (SELECT * FROM (SELECT e FROM "t10"))
|
||||
}
|
||||
|
||||
3 {
|
||||
ALTER TABLE t3 RENAME e TO abc
|
||||
} {
|
||||
UPDATE t1 SET d='xyz' FROM t3, (SELECT * FROM (SELECT e FROM t3))
|
||||
} {
|
||||
UPDATE t1 SET d='xyz' FROM t3, (SELECT * FROM (SELECT abc FROM t3))
|
||||
}
|
||||
|
||||
4 {
|
||||
ALTER TABLE t2 RENAME c TO abc
|
||||
} {
|
||||
UPDATE t1 SET d='xyz' FROM t3, (SELECT 1 FROM t2 WHERE c)
|
||||
} {
|
||||
UPDATE t1 SET d='xyz' FROM t3, (SELECT 1 FROM t2 WHERE abc)
|
||||
}
|
||||
|
||||
} {
|
||||
reset_db
|
||||
do_execsql_test 2.$tn.1 {
|
||||
CREATE TABLE t1(a,b);
|
||||
CREATE TABLE t2(c,d);
|
||||
CREATE TABLE t3(e,f);
|
||||
}
|
||||
do_execsql_test 2.$tn.2 "
|
||||
CREATE TRIGGER r1 INSERT ON t1 BEGIN
|
||||
$update;
|
||||
END
|
||||
"
|
||||
do_execsql_test 2.$tn.3 $alter
|
||||
|
||||
do_whitespace_sql_test 2.$tn.4 {
|
||||
SELECT sqL FROM sqlite_schema WHERE type='trigger'
|
||||
} "{
|
||||
CREATE TRIGGER r1 INSERT ON t1 BEGIN
|
||||
$final;
|
||||
END
|
||||
}"
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
Reference in New Issue
Block a user