/ Changes On Branch improved-update
Login

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

Changes In Branch improved-update Excluding Merge-Ins

This is equivalent to a diff from 0df371d1a5 to c6239bf943

2015-10-17
19:49
Handle equality and range constraints on the "term" column of fts5vocab tables. Also have the same module report columns using names instead of indexes. (check-in: 6020d96ab4 user: dan tags: trunk)
01:00
Change the code generator for UPDATE to generate code in an order that might run more efficiently in many cases. (Leaf check-in: c6239bf943 user: drh tags: improved-update)
2015-10-16
23:55
Fix a comment in expr.c and add a CORRUPT_DB to an assert() in btree.c. (check-in: 0df371d1a5 user: drh tags: trunk)
20:13
Enhancements to the MSVC makefile. (check-in: 39e8a5d93f user: mistachkin tags: trunk)

Changes to src/update.c.

492
493
494
495
496
497
498







499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522

523
524
525
526
527
528




529
530
531
532
533
534
535
  }

  /* Populate the array of registers beginning at regNew with the new
  ** row data. This array is used to check constants, create the new
  ** table and index records, and as the values for any new.* references
  ** made by triggers.
  **







  ** 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
  ** values for registers not modified by the UPDATE must be reloaded from 
  ** the database after the BEFORE triggers are fired anyway (as the trigger 
  ** may have modified them). So not loading those that are not going to
  ** be used eliminates some redundant opcodes.
  */
  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);
    }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);
      }




    }
  }

  /* Fire any BEFORE UPDATE triggers. This happens before constraints are
  ** verified. One could argue that this is wrong.
  */
  if( tmask&TRIGGER_BEFORE ){







>
>
>
>
>
>
>











|
|
<
<
<
|
<
|
<
<
<
<
<
>
|
|
|
|
|
|
>
>
>
>







492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518



519

520





521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
  }

  /* Populate the array of registers beginning at regNew with the new
  ** row data. This array is used to check constants, create the new
  ** 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
  ** values for registers not modified by the UPDATE must be reloaded from 
  ** the database after the BEFORE triggers are fired anyway (as the trigger 
  ** may have modified them). So not loading those that are not going to
  ** be used eliminates some redundant opcodes.
  */
  newmask = sqlite3TriggerColmask(
      pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError
  );
  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{
      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);
    }
  }

  /* Fire any BEFORE UPDATE triggers. This happens before constraints are
  ** verified. One could argue that this is wrong.
  */
  if( tmask&TRIGGER_BEFORE ){