Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Clarification of the behavior of a BEFORE UPDATE trigger when the trigger changes the values of some of the columns used to compute new columns in the UPDATE. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
7bb23c2a3d37f0d5e5515b9178608189 |
User & Date: | drh 2018-04-26 15:04:18.138 |
Context
2018-04-26
| ||
16:13 | When processing an "ORDER BY ... LIMIT" that does not use an index, check whether or not a record may appear in the final result set before adding it to the sorter. (Closed-Leaf check-in: 71bf91c218 user: dan tags: sorter-limit-opt) | |
15:50 | Ensure that new.* values of an UPDATE do not get clobbered after the BEFORE triggers run when unmodified columns of the row being updated are reloaded. Fix for ticket [d85fffd6ffe856092ed8da] (check-in: 0a514e62ad user: drh tags: trunk) | |
15:04 | Clarification of the behavior of a BEFORE UPDATE trigger when the trigger changes the values of some of the columns used to compute new columns in the UPDATE. (check-in: 7bb23c2a3d user: drh tags: trunk) | |
12:27 | Improved VDBE comment on the OP_Param opcode. No substantial changes. (check-in: 368c14da86 user: drh tags: trunk) | |
Changes
Changes to src/update.c.
︙ | ︙ | |||
635 636 637 638 639 640 641 | sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue,regKey,nKey); VdbeCoverage(v); }else{ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid); VdbeCoverage(v); } | | | | > > > | 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 | sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue,regKey,nKey); VdbeCoverage(v); }else{ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid); VdbeCoverage(v); } /* If it did not delete it, the BEFORE trigger may still have modified ** some of the columns of the row being updated. Load the values for ** all columns not modified by the update statement into their registers ** in case this has happened. Only unmodified columns are reloaded. ** The values computed for modified columns use the values before the ** BEFORE trigger runs. See test case trigger1-18.0 (added 2018-04-26) ** for an example. */ for(i=0; i<pTab->nCol; i++){ if( aXRef[i]<0 && i!=pTab->iPKey ){ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i); } } } |
︙ | ︙ |
Changes to test/trigger1.test.
︙ | ︙ | |||
724 725 726 727 728 729 730 731 | CREATE TRIGGER t17b_ai AFTER INSERT ON t17b BEGIN UPDATE t17b SET ss = 4; END; INSERT INTO t17a(ii) VALUES('1'); PRAGMA integrity_check; } {ok} finish_test | > > > > > > > > > > > > > > > > > > > > > > > | 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 | CREATE TRIGGER t17b_ai AFTER INSERT ON t17b BEGIN UPDATE t17b SET ss = 4; END; INSERT INTO t17a(ii) VALUES('1'); PRAGMA integrity_check; } {ok} # 2018-04-26 # When a BEFORE UPDATE trigger changes a column value in a row being # updated, and that column value is used by the UPDATE to change other # column, the value used to compute the update is from before the trigger. # In the example that follows, the value of "b" in "c=b" is 2 (the value # prior to running the BEFORE UPDATE trigger) not 1000. # do_execsql_test trigger1-18.0 { CREATE TABLE t18(a PRIMARY KEY,b,c); INSERT INTO t18(a,b,c) VALUES(1,2,3); CREATE TRIGGER t18r1 BEFORE UPDATE ON t18 BEGIN UPDATE t18 SET b=1000 WHERE a=old.a; END; UPDATE t18 SET c=b WHERE a=1; SELECT * FROM t18; } {1 1000 2} ;# Not: 1 1000 1000 do_execsql_test trigger1-18.1 { DELETE FROM t18; INSERT INTO t18(a,b,c) VALUES(1,2,3); UPDATE t18 SET c=b, b=b+1 WHERE a=1; SELECT * FROM t18; } {1 3 2} ;# Not: 1 1001 1000 finish_test |