]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix issues with ALTER TABLE and triggers containing "UPDATE...FROM" statements.
authordan <Dan Kennedy>
Thu, 26 May 2022 19:10:11 +0000 (19:10 +0000)
committerdan <Dan Kennedy>
Thu, 26 May 2022 19:10:11 +0000 (19:10 +0000)
FossilOrigin-Name: 2fba0d41b781d226915fa2bf888a7bc640c046ce22670ceb53f62a09f3975259

manifest
manifest.uuid
src/alter.c
test/altertrig.test [new file with mode: 0644]

index 2f209316a3949cb7aa5838da2e0b50dc1a9700cf..f83067ff4dd7d884c077372a0322f24f8d11e15c 100644 (file)
--- a/manifest
+++ b/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.
index 04ae0302b2bdd7af7b293ce13731b69f90234eb2..07e5cbd3c4f5224e7257a06d1d3166bc4350dcff 100644 (file)
@@ -1 +1 @@
-664a49fa813144b6fa5a7ae3f65af5412f150dd5def261c4d581d706b39f7846
\ No newline at end of file
+2fba0d41b781d226915fa2bf888a7bc640c046ce22670ceb53f62a09f3975259
\ No newline at end of file
index 538ba7d9f837eff88f0fc59051fdc52bf2cbac7f..8e19c0acead460d82f13f865525b2d93dee3cba3 100644 (file)
@@ -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);
+                  }
+                }
+              }
             }
           }
         }
diff --git a/test/altertrig.test b/test/altertrig.test
new file mode 100644 (file)
index 0000000..f418e58
--- /dev/null
@@ -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
+