aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/insert.c20
-rw-r--r--src/sqliteInt.h13
2 files changed, 24 insertions, 9 deletions
diff --git a/src/insert.c b/src/insert.c
index f399f1417..df2f3f6ea 100644
--- a/src/insert.c
+++ b/src/insert.c
@@ -1396,6 +1396,15 @@ void sqlite3GenerateConstraintChecks(
VdbeCoverage(v);
}
+ /* figure out whether or not upsert applies in this case */
+ if( pUpsert && (pUpsert->pUpsertTarget==0 || pUpsert->pUpsertIdx==0) ){
+ if( pUpsert->pUpsertSet==0 ){
+ onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */
+ }else{
+ onError = OE_Update; /* DO UPDATE */
+ }
+ }
+
/* If the response to a rowid conflict is REPLACE but the response
** to some other UNIQUE constraint is FAIL or IGNORE, then we need
** to defer the running of the rowid conflict checking until after
@@ -1415,7 +1424,6 @@ void sqlite3GenerateConstraintChecks(
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData);
VdbeCoverage(v);
- /* Generate code that deals with a rowid collision */
switch( onError ){
default: {
onError = OE_Abort;
@@ -1478,7 +1486,6 @@ void sqlite3GenerateConstraintChecks(
break;
}
case OE_Ignore: {
- /*assert( seenReplace==0 );*/
sqlite3VdbeGoto(v, ignoreDest);
break;
}
@@ -1569,6 +1576,15 @@ void sqlite3GenerateConstraintChecks(
onError = OE_Abort;
}
+ /* Figure out if the upsert clause applies to this index */
+ if( pUpsert && (pUpsert->pUpsertTarget==0 || pUpsert->pUpsertIdx==pIdx) ){
+ if( pUpsert->pUpsertSet==0 ){
+ onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */
+ }else{
+ onError = OE_Update; /* DO UPDATE */
+ }
+ }
+
/* Collision detection may be omitted if all of the following are true:
** (1) The conflict resolution algorithm is REPLACE
** (2) The table is a WITHOUT ROWID table
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 7bbe255bc..d611f4913 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -2047,13 +2047,12 @@ struct FKey {
#define OE_Fail 3 /* Stop the operation but leave all prior changes */
#define OE_Ignore 4 /* Ignore the error. Do not do the INSERT or UPDATE */
#define OE_Replace 5 /* Delete existing record, then do INSERT or UPDATE */
-
-#define OE_Restrict 6 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */
-#define OE_SetNull 7 /* Set the foreign key value to NULL */
-#define OE_SetDflt 8 /* Set the foreign key value to its default */
-#define OE_Cascade 9 /* Cascade the changes */
-
-#define OE_Default 10 /* Do whatever the default action is */
+#define OE_Update 6 /* Process as a DO UPDATE in an upsert */
+#define OE_Restrict 7 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */
+#define OE_SetNull 8 /* Set the foreign key value to NULL */
+#define OE_SetDflt 9 /* Set the foreign key value to its default */
+#define OE_Cascade 10 /* Cascade the changes */
+#define OE_Default 11 /* Do whatever the default action is */
/*