-C Fix\sa\scomment\sin\sexpr.c\sand\sadd\sa\sCORRUPT_DB\sto\san\sassert()\sin\sbtree.c.
-D 2015-10-16T23:55:08.882
+C Change\sthe\scode\sgenerator\sfor\sUPDATE\sto\sgenerate\scode\sin\san\sorder\sthat\smight\nrun\smore\sefficiently\sin\smany\scases.
+D 2015-10-17T01:00:03.352
F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 4eb750e0fdf52050a06d881e1b060f4bb116ed7e
F src/tokenize.c 338bc8f7c9dd103188952cda7964696bacac6d22
F src/treeview.c 154f0acc622fa3514de8777dcedf4c8a8802b4ce
F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f
-F src/update.c aa10336a2719bd1b9f89004f3d7ba6d566623a49
+F src/update.c 04ed5f0334d313221cd084d46c5c2e0ad29ecb52
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c fc612367108b74573c5fd13a85d0a23027f438bd
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 39e8a5d93fa370afb03223bf0c20ea0f3448b9fc
-R 7f916530a28273810e372e1a6552332a
+P 0df371d1a51c2028aefa4c704707773750317689
+R 54a047417394c2361e73646ac2a70fb9
+T *branch * improved-update
+T *sym-improved-update *
+T -sym-trunk *
U drh
-Z 831fa17e60715846d1a74c0ef53a246d
+Z 6145fe123cad180747a41342b799e5b4
** table and index records, and as the values for any new.* references
** made by triggers.
**
+ ** As an optimization, the array is loaded in two passes. The first pass
+ ** loads unchanged values using OP_Column opcodes so that they can be
+ ** cached and potentially reused by subsequent expressions. Also, the
+ ** OP_Columns are loaded in reverse order so that the row type/offset cache
+ ** inside the OP_Column implementation in the VDBE will warm up completely
+ ** on the first opcode, rather than incrementally across each opcode.
+ **
** If there are one or more BEFORE triggers, then do not populate the
** registers associated with columns that are (a) not modified by
** this UPDATE statement and (b) not accessed by new.* references. The
newmask = sqlite3TriggerColmask(
pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError
);
- for(i=0; i<pTab->nCol; i++){
- if( i==pTab->iPKey ){
- sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
+ for(i=pTab->nCol-1; i>=0; i--){
+ if( aXRef[i]>=0 && i!=pTab->iPKey ) continue;
+ if( i!=pTab->iPKey
+ && (0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask & MASKBIT32(i))!=0)
+ ){
+ testcase( i==31 );
+ testcase( i==32 );
+ sqlite3ExprCodeGetColumnToReg(pParse, pTab, i, iDataCur, regNew+i);
}else{
- j = aXRef[i];
- if( j>=0 ){
- sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i);
- }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask & MASKBIT32(i)) ){
- /* This branch loads the value of a column that will not be changed
- ** into a register. This is done if there are no BEFORE triggers, or
- ** if there are one or more BEFORE triggers that use this value via
- ** a new.* reference in a trigger program.
- */
- testcase( i==31 );
- testcase( i==32 );
- sqlite3ExprCodeGetColumnToReg(pParse, pTab, i, iDataCur, regNew+i);
- }else{
- sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
- }
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
+ }
+ }
+ for(i=0; i<pTab->nCol; i++){
+ if( (j = aXRef[i])>=0 && i!=pTab->iPKey ){
+ sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i);
}
}