/ Check-in [d1906689]
Login

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

Overview
Comment:Minor simplification of the previous checkin.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | upsert-opt2
Files: files | file ages | folders
SHA3-256: d1906689abdb685f78aa97bca4bf301204d12846016d27bc86dcc9ce2b024d24
User & Date: drh 2018-04-20 16:27:57
Context
2018-04-20
16:49
Improved VDBE comment on UPSERT code. Closed-Leaf check-in: 131ed95e user: drh tags: upsert-opt2
16:27
Minor simplification of the previous checkin. check-in: d1906689 user: drh tags: upsert-opt2
15:56
Avoid unnecessary cursor seeks during upsert processing. check-in: 7c4b6d54 user: drh tags: upsert-opt2
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/update.c.

389
390
391
392
393
394
395



























396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
    goto update_cleanup;
  }
#endif

  /* Jump to labelBreak to abandon further processing of this UPDATE */
  labelBreak = sqlite3VdbeMakeLabel(v);




























  if( pUpsert ){
    /* If this is an UPSERT, then all cursors have already been opened by
    ** the outer INSERT and the data cursor should be pointing at the row
    ** that is to be updated.  So bypass the code that searches for the
    ** row(s) to be updated.
    */
    pWInfo = 0;
    eOnePass = ONEPASS_SINGLE;
    labelContinue = labelBreak;
    if( !HasRowid(pTab) ){
      nPk = pPk->nKeyCol;
      iPk = pParse->nMem+1;
      pParse->nMem += nPk;
      regKey = ++pParse->nMem;
    }
    sqlite3ExprIfFalse(pParse, pWhere, labelBreak, SQLITE_JUMPIFNULL);
  }else{
    /* Not an UPSERT.  Normal processing.  Begin by
    ** initialize the count of updated rows */
    if( (db->flags&SQLITE_CountRows)!=0
     && !pParse->pTriggerTab
     && !pParse->nested
    ){
      regRowCount = ++pParse->nMem;
      sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
    }
  
    if( HasRowid(pTab) ){
      sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
    }else{
      assert( pPk!=0 );
      nPk = pPk->nKeyCol;
      iPk = pParse->nMem+1;
      pParse->nMem += nPk;
      regKey = ++pParse->nMem;
      iEph = pParse->nTab++;
  
      sqlite3VdbeAddOp3(v, OP_Null, 0, iPk, iPk+nPk-1);
      addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
      sqlite3VdbeSetP4KeyInfo(pParse, pPk);
    }
  
    /* Begin the database scan. 
    **
    ** Do not consider a single-pass strategy for a multi-row update if
    ** there are any triggers or foreign keys to process, or rows may
    ** be deleted as a result of REPLACE conflict handling. Any of these
    ** things might disturb a cursor being used to scan through the table
    ** or index, causing a single-pass approach to malfunction.  */







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









<
<
<
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431






432
433

























434
435
436
437
438
439
440
    goto update_cleanup;
  }
#endif

  /* Jump to labelBreak to abandon further processing of this UPDATE */
  labelBreak = sqlite3VdbeMakeLabel(v);

  /* Not an UPSERT.  Normal processing.  Begin by
  ** initialize the count of updated rows */
  if( (db->flags&SQLITE_CountRows)!=0
   && !pParse->pTriggerTab
   && !pParse->nested
   && pUpsert==0
  ){
    regRowCount = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
  }

  if( HasRowid(pTab) ){
    sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
  }else{
    assert( pPk!=0 );
    nPk = pPk->nKeyCol;
    iPk = pParse->nMem+1;
    pParse->nMem += nPk;
    regKey = ++pParse->nMem;
    if( pUpsert==0 ){
      iEph = pParse->nTab++;
        sqlite3VdbeAddOp3(v, OP_Null, 0, iPk, iPk+nPk-1);
      addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
      sqlite3VdbeSetP4KeyInfo(pParse, pPk);
    }
  }
  
  if( pUpsert ){
    /* If this is an UPSERT, then all cursors have already been opened by
    ** the outer INSERT and the data cursor should be pointing at the row
    ** that is to be updated.  So bypass the code that searches for the
    ** row(s) to be updated.
    */
    pWInfo = 0;
    eOnePass = ONEPASS_SINGLE;
    labelContinue = labelBreak;






    sqlite3ExprIfFalse(pParse, pWhere, labelBreak, SQLITE_JUMPIFNULL);
  }else{

























    /* Begin the database scan. 
    **
    ** Do not consider a single-pass strategy for a multi-row update if
    ** there are any triggers or foreign keys to process, or rows may
    ** be deleted as a result of REPLACE conflict handling. Any of these
    ** things might disturb a cursor being used to scan through the table
    ** or index, causing a single-pass approach to malfunction.  */