diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/insert.c | 20 | ||||
-rw-r--r-- | src/sqliteInt.h | 13 |
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 */ /* |