diff options
author | drh <drh@noemail.net> | 2018-04-20 13:18:51 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2018-04-20 13:18:51 +0000 |
commit | 7fc3aba8623e703cfdb2eade8ec3d1362da38907 (patch) | |
tree | 52282a5e1fb3fdfc8ae4575116ef4e9e0375ffb2 /src | |
parent | 2ac4e5cca9b882d142fd21c83a0e930f9bbd56da (diff) | |
download | sqlite-7fc3aba8623e703cfdb2eade8ec3d1362da38907.tar.gz sqlite-7fc3aba8623e703cfdb2eade8ec3d1362da38907.zip |
Enhance UPSERT so that the UPDATE uses the same set of cursors as the INSERT.
FossilOrigin-Name: c37f39d18d41ae5ba6c4561d87cbbf71f3b6896b86cc5cff9cdf046b02dc521a
Diffstat (limited to 'src')
-rw-r--r-- | src/insert.c | 2 | ||||
-rw-r--r-- | src/sqliteInt.h | 6 | ||||
-rw-r--r-- | src/update.c | 7 | ||||
-rw-r--r-- | src/upsert.c | 9 |
4 files changed, 16 insertions, 8 deletions
diff --git a/src/insert.c b/src/insert.c index b3a313836..782244a13 100644 --- a/src/insert.c +++ b/src/insert.c @@ -812,6 +812,8 @@ void sqlite3Insert( pTabList->a[0].iCursor = iDataCur; pUpsert->pUpsertSrc = pTabList; pUpsert->regData = regData; + pUpsert->iDataCur = iDataCur; + pUpsert->iIdxCur = iIdxCur; if( pUpsert->pUpsertTarget ){ sqlite3UpsertAnalyzeTarget(pParse, pTabList, pUpsert); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 73cb6299d..ccbf8467f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2743,8 +2743,14 @@ struct Upsert { Index *pUpsertIdx; /* Constraint that pUpsertTarget identifies */ ExprList *pUpsertSet; /* The SET clause from an ON CONFLICT UPDATE */ Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */ + /* The fields above comprise the parse tree for the upsert clause. + ** The fields below are used to transfer information from the INSERT + ** processing down into the UPDATE processing while generating code. + ** Upsert owns the memory allocated above, but not the memory below. */ SrcList *pUpsertSrc; /* Table to be updated */ int regData; /* First register holding array of VALUES */ + int iDataCur; /* Index of the data cursor */ + int iIdxCur; /* Index of the first index cursor */ }; /* diff --git a/src/update.c b/src/update.c index dd08b1668..92164b626 100644 --- a/src/update.c +++ b/src/update.c @@ -211,6 +211,11 @@ void sqlite3Update( } pParse->nTab++; } + if( pUpsert ){ + iDataCur = pUpsert->iDataCur; + iIdxCur = pUpsert->iIdxCur; + pParse->nTab = iBaseCur; + } pTabList->a[0].iCursor = iDataCur; /* Allocate space for aXRef[], aRegIdx[], and aToOpen[]. @@ -476,7 +481,7 @@ void sqlite3Update( } labelBreak = sqlite3VdbeMakeLabel(v); - if( !isView ){ + if( !isView && pUpsert==0 ){ int addrOnce = 0; /* Open every index that needs updating. */ diff --git a/src/upsert.c b/src/upsert.c index 9e23c86bf..80c0056c0 100644 --- a/src/upsert.c +++ b/src/upsert.c @@ -222,7 +222,7 @@ void sqlite3UpsertDoUpdate( pE1 = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); if( pE1 ){ pE1->pTab = pTab; - pE1->iTable = pParse->nTab; + pE1->iTable = pUpsert->iDataCur; pE1->iColumn = -1; } pE2 = sqlite3ExprAlloc(db, TK_REGISTER, 0, 0); @@ -234,11 +234,6 @@ void sqlite3UpsertDoUpdate( }else{ /* a WITHOUT ROWID table */ int i, j; - int iTab = pParse->nTab+1; - Index *pX; - for(pX=pTab->pIndex; ALWAYS(pX) && !IsPrimaryKeyIndex(pX); pX=pX->pNext){ - iTab++; - } for(i=0; i<pIdx->nKeyCol; i++){ regKey = ++pParse->nMem; sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regKey); @@ -247,7 +242,7 @@ void sqlite3UpsertDoUpdate( pE1 = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); if( pE1 ){ pE1->pTab = pTab; - pE1->iTable = iTab; + pE1->iTable = pUpsert->iDataCur; pE1->iColumn = j; } pE2 = sqlite3ExprAlloc(db, TK_REGISTER, 0, 0); |