Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix for bug #11: Output the correct row count when and INSERT does an IGNORE action. (CVS 524) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
bb83642e9a6c1c9ade861618496933c9 |
User & Date: | drh 2002-04-09 03:28:01.000 |
Context
2002-04-12
| ||
03:55 | Fix for bug #16: Check for invalid functions in the VALUES clause of an INSERT statement. (CVS 525) (check-in: 43a77f019d user: drh tags: trunk) | |
2002-04-09
| ||
03:28 | Fix for bug #11: Output the correct row count when and INSERT does an IGNORE action. (CVS 524) (check-in: bb83642e9a user: drh tags: trunk) | |
03:15 | Fix for bug #10: Pop the stack by the right amount on an IGNORE so that the stack does not grow without bound. (CVS 523) (check-in: f46acfc3b8 user: drh tags: trunk) | |
Changes
Changes to src/insert.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** ** $Id: insert.c,v 1.50 2002/04/09 03:28:01 drh Exp $ */ #include "sqliteInt.h" /* ** This routine is call to handle SQL of the following forms: ** ** insert into TABLE (IDLIST) values(EXPRLIST) |
︙ | ︙ | |||
178 179 180 181 182 183 184 185 186 187 188 189 190 191 | sqliteVdbeAddOp(v, openOp, base, pTab->tnum); sqliteVdbeChangeP3(v, -1, pTab->zName, P3_STATIC); for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ sqliteVdbeAddOp(v, openOp, idx+base, pIdx->tnum); sqliteVdbeChangeP3(v, -1, pIdx->zName, P3_STATIC); } pParse->nTab += idx; /* If the data source is a SELECT statement, then we have to create ** a loop because there might be multiple rows of data. If the data ** source is an expression list, then exactly one row will be inserted ** and the loop is not used. */ if( srcTab>=0 ){ | > > > > > > < < < | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | sqliteVdbeAddOp(v, openOp, base, pTab->tnum); sqliteVdbeChangeP3(v, -1, pTab->zName, P3_STATIC); for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ sqliteVdbeAddOp(v, openOp, idx+base, pIdx->tnum); sqliteVdbeChangeP3(v, -1, pIdx->zName, P3_STATIC); } pParse->nTab += idx; /* Initialize the count of rows to be inserted */ if( db->flags & SQLITE_CountRows ){ sqliteVdbeAddOp(v, OP_Integer, 0, 0); /* Initialize the row count */ } /* If the data source is a SELECT statement, then we have to create ** a loop because there might be multiple rows of data. If the data ** source is an expression list, then exactly one row will be inserted ** and the loop is not used. */ if( srcTab>=0 ){ iBreak = sqliteVdbeMakeLabel(v); sqliteVdbeAddOp(v, OP_Rewind, srcTab, iBreak); iCont = sqliteVdbeCurrentAddr(v); } /* Push the record number for the new entry onto the stack. The ** record number is a randomly generate integer created by NewRecno |
︙ | ︙ | |||
254 255 256 257 258 259 260 | /* Generate code to check constraints and generate index keys and ** do the insertion. */ endOfLoop = sqliteVdbeMakeLabel(v); sqliteGenerateConstraintChecks(pParse, pTab, base, 0,0,0, onError, endOfLoop); sqliteCompleteInsertion(pParse, pTab, base, 0,0,0); | < | | | 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | /* Generate code to check constraints and generate index keys and ** do the insertion. */ endOfLoop = sqliteVdbeMakeLabel(v); sqliteGenerateConstraintChecks(pParse, pTab, base, 0,0,0, onError, endOfLoop); sqliteCompleteInsertion(pParse, pTab, base, 0,0,0); /* Update the count of rows that are inserted */ if( (db->flags & SQLITE_CountRows)!=0 ){ sqliteVdbeAddOp(v, OP_AddImm, 1, 0); } /* The bottom of the loop, if the data source is a SELECT statement */ sqliteVdbeResolveLabel(v, endOfLoop); if( srcTab>=0 ){ |
︙ | ︙ | |||
282 283 284 285 286 287 288 | /* ** Return the number of rows inserted. */ if( db->flags & SQLITE_CountRows ){ sqliteVdbeAddOp(v, OP_ColumnCount, 1, 0); sqliteVdbeAddOp(v, OP_ColumnName, 0, 0); sqliteVdbeChangeP3(v, -1, "rows inserted", P3_STATIC); | < < < | 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | /* ** Return the number of rows inserted. */ if( db->flags & SQLITE_CountRows ){ sqliteVdbeAddOp(v, OP_ColumnCount, 1, 0); sqliteVdbeAddOp(v, OP_ColumnName, 0, 0); sqliteVdbeChangeP3(v, -1, "rows inserted", P3_STATIC); sqliteVdbeAddOp(v, OP_Callback, 1, 0); } insert_cleanup: if( pList ) sqliteExprListDelete(pList); if( pSelect ) sqliteSelectDelete(pSelect); sqliteIdListDelete(pColumn); |
︙ | ︙ |
Changes to test/conflict.test.
︙ | ︙ | |||
9 10 11 12 13 14 15 | # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests for the conflict resolution extension # to SQLite. # | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests for the conflict resolution extension # to SQLite. # # $Id: conflict.test,v 1.10 2002/04/09 03:28:01 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create tables for the first group of tests. # do_test conflict-1.0 { |
︙ | ︙ | |||
422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 | } {51} do_test conflict-7.7 { execsql { SELECT count(*) FROM t1; } } {1} do_test insert-99.1 { set x [execsql {PRAGMA integrity_check}] if {$x==""} {set x ok} set x } {ok} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 | } {51} do_test conflict-7.7 { execsql { SELECT count(*) FROM t1; } } {1} # Make sure the row count is right for rows that are ignored on # an insert. # do_test conflict-8.1 { execsql { DELETE FROM t1; INSERT INTO t1 VALUES(1,2); } execsql { INSERT OR IGNORE INTO t1 VALUES(2,3); } } {1} do_test conflict-8.2 { execsql { INSERT OR IGNORE INTO t1 VALUES(2,4); } } {0} do_test conflict-8.3 { execsql { INSERT OR REPLACE INTO t1 VALUES(2,4); } } {1} do_test conflict-8.4 { execsql { INSERT OR IGNORE INTO t1 SELECT * FROM t1; } } {0} do_test conflict-8.5 { execsql { INSERT OR IGNORE INTO t1 SELECT a+2,b+2 FROM t1; } } {2} do_test conflict-8.6 { execsql { INSERT OR IGNORE INTO t1 SELECT a+3,b+3 FROM t1; } } {3} do_test insert-99.1 { set x [execsql {PRAGMA integrity_check}] if {$x==""} {set x ok} set x } {ok} finish_test |