diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/build.c | 1 | ||||
-rw-r--r-- | src/delete.c | 14 | ||||
-rw-r--r-- | src/insert.c | 4 | ||||
-rw-r--r-- | src/sqliteInt.h | 1 | ||||
-rw-r--r-- | src/update.c | 4 | ||||
-rw-r--r-- | src/vdbe.c | 22 |
6 files changed, 25 insertions, 21 deletions
diff --git a/src/build.c b/src/build.c index d53ff3b67..d225227de 100644 --- a/src/build.c +++ b/src/build.c @@ -173,6 +173,7 @@ void sqlite3FinishCoding(Parse *pParse){ if( pReturning->nRetCol==0 ){ assert( CORRUPT_DB ); }else{ + sqlite3VdbeAddOp0(v, OP_FkCheck); addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur); VdbeCoverage(v); diff --git a/src/delete.c b/src/delete.c index e2b283ea4..9c56858e7 100644 --- a/src/delete.c +++ b/src/delete.c @@ -44,6 +44,16 @@ Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ return pTab; } +/* Generate byte-code that will report the number of rows modified +** by a DELETE, INSERT, or UPDATE statement. +*/ +void sqlite3CodeChangeCount(Vdbe *v, int regCounter, const char *zColName){ + sqlite3VdbeAddOp0(v, OP_FkCheck); + sqlite3VdbeAddOp2(v, OP_ResultRow, regCounter, 1); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zColName, SQLITE_STATIC); +} + /* Return true if table pTab is read-only. ** ** A table is read-only if any of the following are true: @@ -619,9 +629,7 @@ void sqlite3DeleteFrom( ** invoke the callback function. */ if( memCnt ){ - sqlite3VdbeAddOp2(v, OP_ChngCntRow, memCnt, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC); + sqlite3CodeChangeCount(v, memCnt, "rows deleted"); } delete_from_cleanup: diff --git a/src/insert.c b/src/insert.c index 97205cb2a..96e86c9fb 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1382,9 +1382,7 @@ insert_end: ** invoke the callback function. */ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC); + sqlite3CodeChangeCount(v, regRowCount, "rows inserted"); } insert_cleanup: diff --git a/src/sqliteInt.h b/src/sqliteInt.h index b45151104..c1a0d9853 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4563,6 +4563,7 @@ void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*); #endif +void sqlite3CodeChangeCount(Vdbe*,int,const char*); void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*); void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*, Upsert*); diff --git a/src/update.c b/src/update.c index 484bee47c..ed96dc8b2 100644 --- a/src/update.c +++ b/src/update.c @@ -1121,9 +1121,7 @@ void sqlite3Update( ** that information. */ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC); + sqlite3CodeChangeCount(v, regRowCount, "rows updated"); } update_cleanup: diff --git a/src/vdbe.c b/src/vdbe.c index 3476c02da..7dfe37917 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1479,24 +1479,22 @@ case OP_IntCopy: { /* out2 */ break; } -/* Opcode: ChngCntRow P1 P2 * * * -** Synopsis: output=r[P1] +/* Opcode: FkCheck * * * * * ** -** Output value in register P1 as the chance count for a DML statement, -** due to the "PRAGMA count_changes=ON" setting. Or, if there was a -** foreign key error in the statement, trigger the error now. +** Halt with an SQLITE_CONSTRAINT error if there are any unresolved +** foreign key constraint violations. If there are no foreign key +** constraint violations, this is a no-op. ** -** This opcode is a variant of OP_ResultRow that checks the foreign key -** immediate constraint count and throws an error if the count is -** non-zero. The P2 opcode must be 1. +** FK constraint violations are also checked when the prepared statement +** exits. This opcode is used to raise foreign key constraint errors prior +** to returning results such as a row change count or the result of a +** RETURNING clause. */ -case OP_ChngCntRow: { - assert( pOp->p2==1 ); +case OP_FkCheck: { if( (rc = sqlite3VdbeCheckFk(p,0))!=SQLITE_OK ){ goto abort_due_to_error; } - /* Fall through to the next case, OP_ResultRow */ - /* no break */ deliberate_fall_through + break; } /* Opcode: ResultRow P1 P2 * * * |