/ Check-in [0c31a468]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Apply the same restrictions on constant refactoring to statements within a trigger program as top-level statements. Candidate fix for [ae3c5670b6].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | constant-refactoring-in-triggers
Files: files | file ages | folders
SHA1: 0c31a46801746191d1a53332d75beda880fe1fd7
User & Date: dan 2012-12-06 19:37:22
Context
2012-12-06
19:41
Merge the constant-refactoring-in-triggers branch with the trunk. check-in: 79ef8e3c user: dan tags: trunk
19:37
Apply the same restrictions on constant refactoring to statements within a trigger program as top-level statements. Candidate fix for [ae3c5670b6]. Closed-Leaf check-in: 0c31a468 user: dan tags: constant-refactoring-in-triggers
19:01
Add the SQLITE_FCNTL_TEMPFILENAME file control that asks the underlying VFS to return a new temporary filename. Per request from NSS team at Mozilla. check-in: 1a63b1d5 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

   123    123   ** Note that if an error occurred, it might be the case that
   124    124   ** no VDBE code was generated.
   125    125   */
   126    126   void sqlite3FinishCoding(Parse *pParse){
   127    127     sqlite3 *db;
   128    128     Vdbe *v;
   129    129   
          130  +  assert( pParse->pToplevel==0 );
   130    131     db = pParse->db;
   131    132     if( db->mallocFailed ) return;
   132    133     if( pParse->nested ) return;
   133    134     if( pParse->nErr ) return;
   134    135   
   135    136     /* Begin by generating some termination code at the end of the
   136    137     ** vdbe program
................................................................................
  3585   3586   ** If iDb<0 then code the OP_Goto only - don't set flag to verify the
  3586   3587   ** schema on any databases.  This can be used to position the OP_Goto
  3587   3588   ** early in the code, before we know if any database tables will be used.
  3588   3589   */
  3589   3590   void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
  3590   3591     Parse *pToplevel = sqlite3ParseToplevel(pParse);
  3591   3592   
         3593  +#ifndef SQLITE_OMIT_TRIGGER
         3594  +  if( pToplevel!=pParse ){
         3595  +    /* This branch is taken if a trigger is currently being coded. In this
         3596  +    ** case, set cookieGoto to a non-zero value to show that this function
         3597  +    ** has been called. This is used by the sqlite3ExprCodeConstants()
         3598  +    ** function. */
         3599  +    pParse->cookieGoto = -1;
         3600  +  }
         3601  +#endif
  3592   3602     if( pToplevel->cookieGoto==0 ){
  3593   3603       Vdbe *v = sqlite3GetVdbe(pToplevel);
  3594   3604       if( v==0 ) return;  /* This only happens if there was a prior error */
  3595   3605       pToplevel->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1;
  3596   3606     }
  3597   3607     if( iDb>=0 ){
  3598   3608       sqlite3 *db = pToplevel->db;

Changes to src/trigger.c.

   724    724       **     INSERT OR REPLACE INTO t2 VALUES(new.a, new.b);
   725    725       **   END;
   726    726       **
   727    727       **   INSERT INTO t1 ... ;            -- insert into t2 uses REPLACE policy
   728    728       **   INSERT OR IGNORE INTO t1 ... ;  -- insert into t2 uses IGNORE policy
   729    729       */
   730    730       pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;
          731  +
          732  +    /* Clear the cookieGoto flag. When coding triggers, the cookieGoto 
          733  +    ** variable is used as a flag to indicate to sqlite3ExprCodeConstants()
          734  +    ** that it is not safe to refactor constants (this happens after the
          735  +    ** start of the first loop in the SQL statement is coded - at that 
          736  +    ** point code may be conditionally executed, so it is no longer safe to 
          737  +    ** initialize constant register values).  */
          738  +    assert( pParse->cookieGoto==0 || pParse->cookieGoto==-1 );
          739  +    pParse->cookieGoto = 0;
   731    740   
   732    741       switch( pStep->op ){
   733    742         case TK_UPDATE: {
   734    743           sqlite3Update(pParse, 
   735    744             targetSrcList(pParse, pStep),
   736    745             sqlite3ExprListDup(db, pStep->pExprList, 0), 
   737    746             sqlite3ExprDup(db, pStep->pWhere, 0), 

Changes to test/triggerC.test.

   945    945       UPDATE t12 SET a=new.a+1, b=new.b+1;
   946    946     END;
   947    947   } {}
   948    948   do_catchsql_test triggerC-13.2 {
   949    949     UPDATE t12 SET a=a+1, b=b+1;
   950    950   } {1 {too many levels of trigger recursion}}
   951    951   
          952  +#-------------------------------------------------------------------------
          953  +# The following tests seek to verify that constant values (i.e. literals)
          954  +# are not factored out of loops within trigger programs. SQLite does
          955  +# not factor constants out of loops within trigger programs as it may only
          956  +# do so in code generated before the first table or index is opened. And
          957  +# by the time a trigger program is coded, at least one table or index has
          958  +# always been opened.
          959  +#
          960  +# At one point, due to a bug allowing constant factoring within triggers,
          961  +# the following SQL would produce the wrong result.
          962  +#
          963  +set SQL {
          964  +  CREATE TABLE t1(a, b, c);
          965  +  CREATE INDEX i1 ON t1(a, c);
          966  +  CREATE INDEX i2 ON t1(b, c);
          967  +  INSERT INTO t1 VALUES(1, 2, 3);
          968  +
          969  +  CREATE TABLE t2(e, f);
          970  +  CREATE INDEX i3 ON t2(e);
          971  +  INSERT INTO t2 VALUES(1234567, 3);
          972  +
          973  +  CREATE TABLE empty(x);
          974  +  CREATE TABLE not_empty(x);
          975  +  INSERT INTO not_empty VALUES(2);
          976  +
          977  +  CREATE TABLE t4(x);
          978  +  CREATE TABLE t5(g, h, i);
          979  +
          980  +  CREATE TRIGGER trig BEFORE INSERT ON t4 BEGIN
          981  +    INSERT INTO t5 SELECT * FROM t1 WHERE 
          982  +        (a IN (SELECT x FROM empty) OR b IN (SELECT x FROM not_empty)) 
          983  +        AND c IN (SELECT f FROM t2 WHERE e=1234567);
          984  +  END;
          985  +
          986  +  INSERT INTO t4 VALUES(0);
          987  +  SELECT * FROM t5;
          988  +}
   952    989   
          990  +reset_db
          991  +do_execsql_test triggerC-14.1 $SQL {1 2 3}
          992  +reset_db
          993  +optimization_control db factor-constants 0
          994  +do_execsql_test triggerC-14.2 $SQL {1 2 3}
   953    995   
   954    996   finish_test