1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-12 13:01:09 +03:00

Logic is in place to handle multiple ON CONFLICT clauses, but it does not work.

Any use of ON CONFLICT will likely lead to memory faults.  This is an
incremental check-in to save my place.

FossilOrigin-Name: 155142314feb007d526f8f67723636fd50dc52d1cd4d3a67dd93b105c9d5c2be
This commit is contained in:
drh
2020-12-11 01:17:06 +00:00
parent daf2761c62
commit 61e280ad8a
5 changed files with 142 additions and 61 deletions

View File

@@ -208,6 +208,38 @@ int sqlite3UpsertAnalyzeTarget(
return SQLITE_OK;
}
/*
** Return true if pUpsert is the last ON CONFLICT clause with a
** conflict target, or if pUpsert is followed by another ON CONFLICT
** clause that targets the INTEGER PRIMARY KEY.
*/
int sqlite3UpsertNextIsIPK(Upsert *pUpsert){
Upsert *pNext;
if( pUpsert==0 ) return 0;
pNext = pUpsert->pNextUpsert;
if( pNext==0 ) return 1;
if( pNext->pUpsertTarget==0 ) return 1;
if( pNext->pUpsertIdx==0 ) return 1;
return 0;
}
/*
** Given the list of ON CONFLICT clauses described by pUpsert, and
** a particular index pIdx, return a pointer to the particular ON CONFLICT
** clause that applies to the index. Or, if the index is not subject to
** any ON CONFLICT clause, return NULL.
*/
Upsert *sqlite3UpsertOfIndex(Upsert *pUpsert, Index *pIdx){
while(
pUpsert
&& pUpsert->pUpsertTarget!=0
&& pUpsert->pUpsertIdx!=pIdx
){
pUpsert = pUpsert->pNextUpsert;
}
return pUpsert;
}
/*
** Generate bytecode that does an UPDATE as part of an upsert.
**
@@ -234,14 +266,7 @@ void sqlite3UpsertDoUpdate(
assert( v!=0 );
assert( pUpsert!=0 );
iDataCur = pUpsert->iDataCur;
while(
pUpsert->pUpsertTarget!=0
&& (pUpsert->pUpsertIdx==0 ? pIdx!=0 :
pUpsert->pUpsertIdx->zName!=pIdx->zName)
){
assert( pUpsert->pNextUpsert!=0 );
pUpsert = pUpsert->pNextUpsert;
}
pUpsert = sqlite3UpsertOfIndex(pTop, pIdx);
if( pUpsert->addrGenericUpdate>0 ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, pUpsert->addrGenericUpdate);
return;