Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch constant-refactoring-in-triggers Excluding Merge-Ins
This is equivalent to a diff from 1a63b1d5fa to 0c31a46801
2012-12-06
| ||
19:41 | Merge the constant-refactoring-in-triggers branch with the trunk. (check-in: 79ef8e3c77 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: 0c31a46801 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: 1a63b1d5fa user: drh tags: trunk) | |
04:33 | For the sqlite3-all.c target, use backslashes when calling the splitter script via the MSVC makefile. (check-in: d507648d82 user: mistachkin tags: trunk) | |
Changes to src/build.c.
︙ | ︙ | |||
123 124 125 126 127 128 129 130 131 132 133 134 135 136 | ** Note that if an error occurred, it might be the case that ** no VDBE code was generated. */ void sqlite3FinishCoding(Parse *pParse){ sqlite3 *db; Vdbe *v; db = pParse->db; if( db->mallocFailed ) return; if( pParse->nested ) return; if( pParse->nErr ) return; /* Begin by generating some termination code at the end of the ** vdbe program | > | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | ** Note that if an error occurred, it might be the case that ** no VDBE code was generated. */ void sqlite3FinishCoding(Parse *pParse){ sqlite3 *db; Vdbe *v; assert( pParse->pToplevel==0 ); db = pParse->db; if( db->mallocFailed ) return; if( pParse->nested ) return; if( pParse->nErr ) return; /* Begin by generating some termination code at the end of the ** vdbe program |
︙ | ︙ | |||
3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 | ** If iDb<0 then code the OP_Goto only - don't set flag to verify the ** schema on any databases. This can be used to position the OP_Goto ** early in the code, before we know if any database tables will be used. */ void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ Parse *pToplevel = sqlite3ParseToplevel(pParse); if( pToplevel->cookieGoto==0 ){ Vdbe *v = sqlite3GetVdbe(pToplevel); if( v==0 ) return; /* This only happens if there was a prior error */ pToplevel->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1; } if( iDb>=0 ){ sqlite3 *db = pToplevel->db; | > > > > > > > > > | 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 | ** If iDb<0 then code the OP_Goto only - don't set flag to verify the ** schema on any databases. This can be used to position the OP_Goto ** early in the code, before we know if any database tables will be used. */ 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 */ pToplevel->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1; } if( iDb>=0 ){ sqlite3 *db = pToplevel->db; |
︙ | ︙ |
Changes to src/trigger.c.
︙ | ︙ | |||
724 725 726 727 728 729 730 731 732 733 734 735 736 737 | ** INSERT OR REPLACE INTO t2 VALUES(new.a, new.b); ** END; ** ** INSERT INTO t1 ... ; -- insert into t2 uses REPLACE policy ** INSERT OR IGNORE INTO t1 ... ; -- insert into t2 uses IGNORE policy */ pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf; switch( pStep->op ){ case TK_UPDATE: { sqlite3Update(pParse, targetSrcList(pParse, pStep), sqlite3ExprListDup(db, pStep->pExprList, 0), sqlite3ExprDup(db, pStep->pWhere, 0), | > > > > > > > > > | 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 | ** INSERT OR REPLACE INTO t2 VALUES(new.a, new.b); ** END; ** ** INSERT INTO t1 ... ; -- insert into t2 uses REPLACE policy ** INSERT OR IGNORE INTO t1 ... ; -- insert into t2 uses IGNORE policy */ 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, targetSrcList(pParse, pStep), sqlite3ExprListDup(db, pStep->pExprList, 0), sqlite3ExprDup(db, pStep->pWhere, 0), |
︙ | ︙ |
Changes to test/triggerC.test.
︙ | ︙ | |||
945 946 947 948 949 950 951 | UPDATE t12 SET a=new.a+1, b=new.b+1; END; } {} do_catchsql_test triggerC-13.2 { UPDATE t12 SET a=a+1, b=b+1; } {1 {too many levels of trigger recursion}} | > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 | UPDATE t12 SET a=new.a+1, b=new.b+1; END; } {} 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 |