/ Check-in [6afadd3b]
Login

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

Overview
Comment:When an INSERT is receiving content from a SELECT, run an OP_ReleaseReg opcode at the top of each iteration of the loop in order to prevent spurious OP_SCopy misuse complaints. Ticket [de4b04149b9fdeae]
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 6afadd3b3a40b0ef29fd14fb24c2a4b9479483e5f8b9125ce02d8daae662207f
User & Date: drh 2019-12-28 01:52:46
Context
2019-12-28
02:40
Convert an assert() back into a conditional. The conditional was converted into an assert() by check-in [6ae4ad6ebee4db88] (2009-05-28) because we were unable to find a test case for it. Yongheng's fuzzer just now found that test case. (check-in: 4d0b9109 user: drh tags: trunk)
01:52
When an INSERT is receiving content from a SELECT, run an OP_ReleaseReg opcode at the top of each iteration of the loop in order to prevent spurious OP_SCopy misuse complaints. Ticket [de4b04149b9fdeae] (check-in: 6afadd3b user: drh tags: trunk)
00:36
Recompute the values for all generated columns after NOT NULL ON CONFLICT REPLACE constraints fire. Tickets [37823501c68a09f9] and [5fbc159eeb092130]. (check-in: 4cc12c18 user: drh tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/insert.c.

1016
1017
1018
1019
1020
1021
1022

1023
1024
1025
1026
1027
1028
1029
....
1276
1277
1278
1279
1280
1281
1282









1283
1284
1285
1286
1287
1288
1289
    ** following pseudocode (template 3):
    **
    **      C: yield X, at EOF goto D
    **         insert the select result into <table> from R..R+n
    **         goto C
    **      D: ...
    */

    addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
    VdbeCoverage(v);
    if( ipkColumn>=0 ){
      /* tag-20191021-001: If the INTEGER PRIMARY KEY is being generated by the
      ** SELECT, go ahead and copy the value into the rowid slot now, so that
      ** the value does not get overwritten by a NULL at tag-20191021-002. */
      sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid);
................................................................................
  sqlite3VdbeResolveLabel(v, endOfLoop);
  if( useTempTable ){
    sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont); VdbeCoverage(v);
    sqlite3VdbeJumpHere(v, addrInsTop);
    sqlite3VdbeAddOp1(v, OP_Close, srcTab);
  }else if( pSelect ){
    sqlite3VdbeGoto(v, addrCont);









    sqlite3VdbeJumpHere(v, addrInsTop);
  }

insert_end:
  /* Update the sqlite_sequence table by storing the content of the
  ** maximum rowid counter values recorded while inserting into
  ** autoincrement tables.







>







 







>
>
>
>
>
>
>
>
>







1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
....
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
    ** following pseudocode (template 3):
    **
    **      C: yield X, at EOF goto D
    **         insert the select result into <table> from R..R+n
    **         goto C
    **      D: ...
    */
    sqlite3VdbeReleaseRegisters(pParse, regData, pTab->nCol, 0);
    addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
    VdbeCoverage(v);
    if( ipkColumn>=0 ){
      /* tag-20191021-001: If the INTEGER PRIMARY KEY is being generated by the
      ** SELECT, go ahead and copy the value into the rowid slot now, so that
      ** the value does not get overwritten by a NULL at tag-20191021-002. */
      sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid);
................................................................................
  sqlite3VdbeResolveLabel(v, endOfLoop);
  if( useTempTable ){
    sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont); VdbeCoverage(v);
    sqlite3VdbeJumpHere(v, addrInsTop);
    sqlite3VdbeAddOp1(v, OP_Close, srcTab);
  }else if( pSelect ){
    sqlite3VdbeGoto(v, addrCont);
#ifdef SQLITE_DEBUG
    /* If we are jumping back to an OP_Yield that is preceded by an
    ** OP_ReleaseReg, set the p5 flag on the OP_Goto so that the
    ** OP_ReleaseReg will be included in the loop. */
    if( sqlite3VdbeGetOp(v, addrCont-1)->opcode==OP_ReleaseReg ){
      assert( sqlite3VdbeGetOp(v, addrCont)->opcode==OP_Yield );
      sqlite3VdbeChangeP5(v, 1);
    }
#endif
    sqlite3VdbeJumpHere(v, addrInsTop);
  }

insert_end:
  /* Update the sqlite_sequence table by storing the content of the
  ** maximum rowid counter values recorded while inserting into
  ** autoincrement tables.

Changes to src/vdbe.c.

841
842
843
844
845
846
847














848
849
850
851
852
853
854
**
** The P1 parameter is not actually used by this opcode.  However, it
** is sometimes set to 1 instead of 0 as a hint to the command-line shell
** that this Goto is the bottom of a loop and that the lines from P2 down
** to the current line should be indented for EXPLAIN output.
*/
case OP_Goto: {             /* jump */














jump_to_p2_and_check_for_interrupt:
  pOp = &aOp[pOp->p2 - 1];

  /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
  ** OP_VNext, or OP_SorterNext) all jump here upon
  ** completion.  Check to see if sqlite3_interrupt() has been called
  ** or if the progress callback needs to be invoked. 







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







841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
**
** The P1 parameter is not actually used by this opcode.  However, it
** is sometimes set to 1 instead of 0 as a hint to the command-line shell
** that this Goto is the bottom of a loop and that the lines from P2 down
** to the current line should be indented for EXPLAIN output.
*/
case OP_Goto: {             /* jump */

#ifdef SQLITE_DEBUG
  /* In debuggging mode, when the p5 flags is set on an OP_Goto, that
  ** means we should really jump back to the preceeding OP_ReleaseReg
  ** instruction. */
  if( pOp->p5 ){
    assert( pOp->p2 < (int)(pOp - aOp) );
    assert( pOp->p2 > 1 );
    pOp = &aOp[pOp->p2 - 2];
    assert( pOp[1].opcode==OP_ReleaseReg );
    goto check_for_interrupt;
  }
#endif

jump_to_p2_and_check_for_interrupt:
  pOp = &aOp[pOp->p2 - 1];

  /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
  ** OP_VNext, or OP_SorterNext) all jump here upon
  ** completion.  Check to see if sqlite3_interrupt() has been called
  ** or if the progress callback needs to be invoked. 

Changes to src/where.c.

866
867
868
869
870
871
872
873
874

875
876
877
878
879
880
881
    assert( pLevel->iIdxCur>0 );
    translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
                          pTabItem->regResult, pLevel->iIdxCur);
    sqlite3VdbeGoto(v, addrTop);
    pTabItem->fg.viaCoroutine = 0;
  }else{
    sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
  }
  sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);

  sqlite3VdbeJumpHere(v, addrTop);
  sqlite3ReleaseTempReg(pParse, regRecord);
  
  /* Jump here when skipping the initialization */
  sqlite3VdbeJumpHere(v, addrInit);

end_auto_index_create:







<
|
>







866
867
868
869
870
871
872

873
874
875
876
877
878
879
880
881
    assert( pLevel->iIdxCur>0 );
    translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
                          pTabItem->regResult, pLevel->iIdxCur);
    sqlite3VdbeGoto(v, addrTop);
    pTabItem->fg.viaCoroutine = 0;
  }else{
    sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);

    sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
  }
  sqlite3VdbeJumpHere(v, addrTop);
  sqlite3ReleaseTempReg(pParse, regRecord);
  
  /* Jump here when skipping the initialization */
  sqlite3VdbeJumpHere(v, addrInit);

end_auto_index_create:

Changes to test/gencol1.test.

544
545
546
547
548
549
550

551









552
553
554
  SELECT * FROM t0;
} {0 0 {}}
do_execsql_test gencol1-18.20 {
  UPDATE t0 SET c1=0, c2=0 WHERE c0>=0;
  SELECT * FROM t0;
} {0 0 0}














finish_test







>
|
>
>
>
>
>
>
>
>
>

<

544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562

563
  SELECT * FROM t0;
} {0 0 {}}
do_execsql_test gencol1-18.20 {
  UPDATE t0 SET c1=0, c2=0 WHERE c0>=0;
  SELECT * FROM t0;
} {0 0 0}

# 2019-12-27 ticket de4b04149b9fdeae
#
reset_db
do_catchsql_test gencol1-19.10 {
  CREATE TABLE t0(
    c0 INT AS(2) UNIQUE,
    c1 TEXT UNIQUE,
    FOREIGN KEY(c0) REFERENCES t0(c1)
  );
  INSERT INTO t0(c1) VALUES(0.16334143182538696), (0);
} {1 {UNIQUE constraint failed: t0.c0}}


finish_test