aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/build.c1
-rw-r--r--src/delete.c14
-rw-r--r--src/insert.c4
-rw-r--r--src/sqliteInt.h1
-rw-r--r--src/update.c4
-rw-r--r--src/vdbe.c22
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 * * *