diff options
author | drh <> | 2024-08-27 13:57:43 +0000 |
---|---|---|
committer | drh <> | 2024-08-27 13:57:43 +0000 |
commit | fcd65efcf10957ef84cccf0f2bd9381b69dd6dde (patch) | |
tree | a7e2f567f27186780dd500f8bfe0cf295fd9ffef /src/upsert.c | |
parent | 3a39c44c21a801927f98aa3cdb2240f00e701b8a (diff) | |
parent | c013fa50db60dad905aff1c2202edfa7223bdd67 (diff) | |
download | sqlite-fcd65efcf10957ef84cccf0f2bd9381b69dd6dde.tar.gz sqlite-fcd65efcf10957ef84cccf0f2bd9381b69dd6dde.zip |
Merge all the latests trunk enhancements into the win-dupe-crt-fio branch.
FossilOrigin-Name: 2d52db98f47fbcda0622c034b21c2fb19bf4345b88c5c565ae9e6f7128642e43
Diffstat (limited to 'src/upsert.c')
-rw-r--r-- | src/upsert.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/src/upsert.c b/src/upsert.c index be0d0550d..82295d52a 100644 --- a/src/upsert.c +++ b/src/upsert.c @@ -90,7 +90,8 @@ Upsert *sqlite3UpsertNew( int sqlite3UpsertAnalyzeTarget( Parse *pParse, /* The parsing context */ SrcList *pTabList, /* Table into which we are inserting */ - Upsert *pUpsert /* The ON CONFLICT clauses */ + Upsert *pUpsert, /* The ON CONFLICT clauses */ + Upsert *pAll /* Complete list of all ON CONFLICT clauses */ ){ Table *pTab; /* That table into which we are inserting */ int rc; /* Result code */ @@ -103,7 +104,7 @@ int sqlite3UpsertAnalyzeTarget( int nClause = 0; /* Counter of ON CONFLICT clauses */ assert( pTabList->nSrc==1 ); - assert( pTabList->a[0].pTab!=0 ); + assert( pTabList->a[0].pSTab!=0 ); assert( pUpsert!=0 ); assert( pUpsert->pUpsertTarget!=0 ); @@ -122,7 +123,7 @@ int sqlite3UpsertAnalyzeTarget( if( rc ) return rc; /* Check to see if the conflict target matches the rowid. */ - pTab = pTabList->a[0].pTab; + pTab = pTabList->a[0].pSTab; pTarget = pUpsert->pUpsertTarget; iCursor = pTabList->a[0].iCursor; if( HasRowid(pTab) @@ -193,6 +194,14 @@ int sqlite3UpsertAnalyzeTarget( continue; } pUpsert->pUpsertIdx = pIdx; + if( sqlite3UpsertOfIndex(pAll,pIdx)!=pUpsert ){ + /* Really this should be an error. The isDup ON CONFLICT clause will + ** never fire. But this problem was not discovered until three years + ** after multi-CONFLICT upsert was added, and so we silently ignore + ** the problem to prevent breaking applications that might actually + ** have redundant ON CONFLICT clauses. */ + pUpsert->isDup = 1; + } break; } if( pUpsert->pUpsertIdx==0 ){ @@ -219,9 +228,13 @@ int sqlite3UpsertNextIsIPK(Upsert *pUpsert){ Upsert *pNext; if( NEVER(pUpsert==0) ) return 0; pNext = pUpsert->pNextUpsert; - if( pNext==0 ) return 1; - if( pNext->pUpsertTarget==0 ) return 1; - if( pNext->pUpsertIdx==0 ) return 1; + while( 1 /*exit-by-return*/ ){ + if( pNext==0 ) return 1; + if( pNext->pUpsertTarget==0 ) return 1; + if( pNext->pUpsertIdx==0 ) return 1; + if( !pNext->isDup ) return 0; + pNext = pNext->pNextUpsert; + } return 0; } |