]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Apply the same restrictions on constant refactoring to statements within a trigger... constant-refactoring-in-triggers
authordan <dan@noemail.net>
Thu, 6 Dec 2012 19:37:22 +0000 (19:37 +0000)
committerdan <dan@noemail.net>
Thu, 6 Dec 2012 19:37:22 +0000 (19:37 +0000)
FossilOrigin-Name: 0c31a46801746191d1a53332d75beda880fe1fd7

manifest
manifest.uuid
src/build.c
src/trigger.c
test/triggerC.test

index 8b6632de602fdb02186ec5f73baa2b6325228d8a..6a5a27c92a05a44af173ae91d289b6ddb2dcf538 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sthe\sSQLITE_FCNTL_TEMPFILENAME\sfile\scontrol\sthat\sasks\sthe\sunderlying\sVFS\nto\sreturn\sa\snew\stemporary\sfilename.\s\sPer\srequest\sfrom\sNSS\steam\sat\sMozilla.
-D 2012-12-06T19:01:42.467
+C Apply\sthe\ssame\srestrictions\son\sconstant\srefactoring\sto\sstatements\swithin\sa\strigger\sprogram\sas\stop-level\sstatements.\sCandidate\sfix\sfor\s[ae3c5670b6].
+D 2012-12-06T19:37:22.521
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 690d441a758cbffd13e814dc2724a721a6ebd400
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -124,7 +124,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
 F src/btree.c eccee944cb2221e919d7a855e5928d8643194b14
 F src/btree.h 3ad7964d6c5b1c7bff569aab6adfa075f8bf06cd
 F src/btreeInt.h 4e5c2bd0f9b36b2a815a6d84f771a61a65830621
-F src/build.c f35dac52924a6e8e6346a90f0c195a84e28b6f21
+F src/build.c fd68fb1bee609b88f4f7c8ebe4dc9560c583c39d
 F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc
 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
 F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e
@@ -232,7 +232,7 @@ F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2
 F src/test_wholenumber.c 3d2b9ed1505c40ad5c5ca2ad16ae7a289d6cc251
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/tokenize.c 1e86210d3976717a19238ea7b047fac481fe8c12
-F src/trigger.c 3f258307040173aff383eb23fb74c44fe829078c
+F src/trigger.c cd95ac64efa60e39faf9b5597443192ff27a22fa
 F src/update.c 28d2d098b43a2c70dae399896ea8a02f622410ef
 F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f
 F src/util.c 0af2e515dc0dabacec931bca39525f6c3f1c5455
@@ -899,7 +899,7 @@ F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4
 F test/trigger9.test 5b0789f1c5c4600961f8e68511b825b87be53e31
 F test/triggerA.test e0aaba16d3547193d36bbd82a1b0ed75e9c88d40
 F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe
-F test/triggerC.test 29173df06f8e91bec2b95ea7048b30d1e1c7b9db
+F test/triggerC.test a7b4367392c755bc5fd5fff88011753e6b6afe90
 F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650
 F test/tt3_checkpoint.c 415eccce672d681b297485fc20f44cdf0eac93af
 F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff
@@ -1025,7 +1025,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P d507648d820cfea70e17f3d21c35c932a2d20367
-R eb2cb26563b5f98893b41a686dd89dac
-U drh
-Z a78031be2e88797bf9b27c616571dbb4
+P 1a63b1d5fa5d79f96eddbda6d94bc10248863710
+R 919f27f45c7dc1e6e97e702080115442
+T *branch * constant-refactoring-in-triggers
+T *sym-constant-refactoring-in-triggers *
+T -sym-trunk *
+U dan
+Z 10c6ff069df8e2b9b146f1c13827ef9e
index 3e42a7d077fb5353a4f3c5a9db9c04ab1e647598..515161250df5f4f8dcea912dda988a38ba2eb7d6 100644 (file)
@@ -1 +1 @@
-1a63b1d5fa5d79f96eddbda6d94bc10248863710
\ No newline at end of file
+0c31a46801746191d1a53332d75beda880fe1fd7
\ No newline at end of file
index 4c45a9272789259ef063592e59dec554229f2f6a..382b6cb33a224aab8d6ebbcdf7470df641d0060b 100644 (file)
@@ -127,6 +127,7 @@ void sqlite3FinishCoding(Parse *pParse){
   sqlite3 *db;
   Vdbe *v;
 
+  assert( pParse->pToplevel==0 );
   db = pParse->db;
   if( db->mallocFailed ) return;
   if( pParse->nested ) return;
@@ -3589,6 +3590,15 @@ int sqlite3OpenTempDatabase(Parse *pParse){
 void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
   Parse *pToplevel = sqlite3ParseToplevel(pParse);
 
+#ifndef SQLITE_OMIT_TRIGGER
+  if( pToplevel!=pParse ){
+    /* This branch is taken if a trigger is currently being coded. In this
+    ** case, set cookieGoto to a non-zero value to show that this function
+    ** has been called. This is used by the sqlite3ExprCodeConstants()
+    ** function. */
+    pParse->cookieGoto = -1;
+  }
+#endif
   if( pToplevel->cookieGoto==0 ){
     Vdbe *v = sqlite3GetVdbe(pToplevel);
     if( v==0 ) return;  /* This only happens if there was a prior error */
index 8985ec6eb8726bbe2a1ca70ad0cc33a03539504e..f1ff766e202a4518ec10e527120cd30e83fbd034 100644 (file)
@@ -729,6 +729,15 @@ static int codeTriggerProgram(
     */
     pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;
 
+    /* Clear the cookieGoto flag. When coding triggers, the cookieGoto 
+    ** variable is used as a flag to indicate to sqlite3ExprCodeConstants()
+    ** that it is not safe to refactor constants (this happens after the
+    ** start of the first loop in the SQL statement is coded - at that 
+    ** point code may be conditionally executed, so it is no longer safe to 
+    ** initialize constant register values).  */
+    assert( pParse->cookieGoto==0 || pParse->cookieGoto==-1 );
+    pParse->cookieGoto = 0;
+
     switch( pStep->op ){
       case TK_UPDATE: {
         sqlite3Update(pParse, 
index db37ab3b662011ebd22153b4db733ee16194e2ad..8d9848794ad65eef345157f71a0290b86117100f 100644 (file)
@@ -949,6 +949,48 @@ do_catchsql_test triggerC-13.2 {
   UPDATE t12 SET a=a+1, b=b+1;
 } {1 {too many levels of trigger recursion}}
 
+#-------------------------------------------------------------------------
+# The following tests seek to verify that constant values (i.e. literals)
+# are not factored out of loops within trigger programs. SQLite does
+# not factor constants out of loops within trigger programs as it may only
+# do so in code generated before the first table or index is opened. And
+# by the time a trigger program is coded, at least one table or index has
+# always been opened.
+#
+# At one point, due to a bug allowing constant factoring within triggers,
+# the following SQL would produce the wrong result.
+#
+set SQL {
+  CREATE TABLE t1(a, b, c);
+  CREATE INDEX i1 ON t1(a, c);
+  CREATE INDEX i2 ON t1(b, c);
+  INSERT INTO t1 VALUES(1, 2, 3);
+
+  CREATE TABLE t2(e, f);
+  CREATE INDEX i3 ON t2(e);
+  INSERT INTO t2 VALUES(1234567, 3);
+
+  CREATE TABLE empty(x);
+  CREATE TABLE not_empty(x);
+  INSERT INTO not_empty VALUES(2);
+
+  CREATE TABLE t4(x);
+  CREATE TABLE t5(g, h, i);
+
+  CREATE TRIGGER trig BEFORE INSERT ON t4 BEGIN
+    INSERT INTO t5 SELECT * FROM t1 WHERE 
+        (a IN (SELECT x FROM empty) OR b IN (SELECT x FROM not_empty)) 
+        AND c IN (SELECT f FROM t2 WHERE e=1234567);
+  END;
+
+  INSERT INTO t4 VALUES(0);
+  SELECT * FROM t5;
+}
 
+reset_db
+do_execsql_test triggerC-14.1 $SQL {1 2 3}
+reset_db
+optimization_control db factor-constants 0
+do_execsql_test triggerC-14.2 $SQL {1 2 3}
 
 finish_test