diff options
author | drh <drh@noemail.net> | 2016-11-09 00:10:33 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2016-11-09 00:10:33 +0000 |
commit | 9b4eaebc68ec3a209c698b1220ef2bc49cdb41dc (patch) | |
tree | ddc38da5766092a4f8d19dbdd4ecc892152599a4 | |
parent | 3b908d41a0d3800a6ebe5dff42f4117fc342105c (diff) | |
download | sqlite-9b4eaebc68ec3a209c698b1220ef2bc49cdb41dc.tar.gz sqlite-9b4eaebc68ec3a209c698b1220ef2bc49cdb41dc.zip |
Enhance the OP_IdxInsert opcode to optionally accept unpacked key material.
FossilOrigin-Name: 89d958abbac45f2ca5954080cd9e74ec9a07ebb2
-rw-r--r-- | manifest | 35 | ||||
-rw-r--r-- | manifest.uuid | 2 | ||||
-rw-r--r-- | src/btree.c | 11 | ||||
-rw-r--r-- | src/btree.h | 2 | ||||
-rw-r--r-- | src/build.c | 2 | ||||
-rw-r--r-- | src/delete.c | 2 | ||||
-rw-r--r-- | src/expr.c | 2 | ||||
-rw-r--r-- | src/insert.c | 4 | ||||
-rw-r--r-- | src/select.c | 15 | ||||
-rw-r--r-- | src/update.c | 2 | ||||
-rw-r--r-- | src/vdbe.c | 16 | ||||
-rw-r--r-- | src/wherecode.c | 3 |
12 files changed, 60 insertions, 36 deletions
@@ -1,5 +1,5 @@ -C Avoid\ssuperfluous\scursor\sseeks\sin\s"INSERT\sOR\sREPLACE"\sstatements. -D 2016-11-08T19:22:32.125 +C Enhance\sthe\sOP_IdxInsert\sopcode\sto\soptionally\saccept\sunpacked\skey\smaterial. +D 2016-11-09T00:10:33.633 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -330,17 +330,17 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 6ae1c17347fb2888b2b28a260b947b7717a9fca9 -F src/btree.h d05b2fcc290991a8a3d9ea1816ddd55a4359dcde +F src/btree.c fa0e4f2656562f18a8aeab5faa5747fc2d6bc497 +F src/btree.h 630303068c82a359f6ddf202b205ae927721b090 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c fcd220ccf7cae1b50b700b37eca950cd72c64ff0 +F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d -F src/delete.c cb3f6300df24c26c609778b2731f82644b5532ec -F src/expr.c ce7110980fac6dfdfbe1e393443bdb79bad29339 +F src/delete.c 6cac3a6c3f3c5ad4cacc402aee1610fc94ebc3dc +F src/expr.c ddd46bafbbd77b83c8daa733ebbe906093b558dc F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 F src/func.c 7057bc2c105b82faa668d8e2ec85fad4540e5c51 @@ -349,7 +349,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 8c1346304a9a386b036652475296103bae27e0a1 +F src/insert.c dff61f28a53a485210b48518f9ec1a5822d7c032 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c 694ac90557abdaa62151a6090670e107b0f2c2ab @@ -387,7 +387,7 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3fac1b2737ea5a724f20b921ac7e259c9be2100b F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c ea3af83e2d0f245fef81ea4cf04cb730ce67f722 +F src/select.c 7788e48a651bef02993531a41aad2ca516d1d4a2 F src/shell.c 63e54cfa1c7ec5b70a4c9a86502bc10280c3d5a3 F src/sqlite.h.in 97e9b0f952306677db82b055147ed1d99cb7ba66 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -450,11 +450,11 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 78c8085bc7af1922aa687f0f4bbd716821330de5 F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c 3419bb9862983d84d70735fb4c94b21b934cd0c5 -F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 +F src/update.c 771335a33c958a186b66ef7e349f978d6bb2aac4 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 20307c93ad55af6ab8f50b17147a4704d4f17dab +F src/vdbe.c 8044db96efdc586273e2c41aab3cc8f3d8ccb761 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h d8a56a491b752dbb5f671963b8c861ec72ea875e F src/vdbeapi.c 97129bec6b1553da50d8e73f523c278bda66d9f6 @@ -470,7 +470,7 @@ F src/wal.h bf03a23da3100ab25e5c0363450233cfee09cfc2 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 952f76e7a03727480b274b66ca6641b1657cd591 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d -F src/wherecode.c 717a65294df46f30e9b9933d2a63a4bcbca5a9a8 +F src/wherecode.c 507738d957dcc3cfa93020bcc1e4b02d11ecab9e F src/whereexpr.c a83d70154f3bbce5051a7e9710021f647c0fe4f2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1530,7 +1530,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8cb8516d2009d52d35a22263e4c892f162b34b81 -R 36e33fba7941647bfb228c5ae67f2b63 -U dan -Z a11930824d648f16d0f222498c7f4b67 +P bec5b6d4d083556d111a89186b4f7b35b5e7cebf +R 91f828c4f65c4334fdcc0da90044f102 +T *branch * unpacked-IdxInsert +T *sym-unpacked-IdxInsert * +T -sym-trunk * +U drh +Z 760e23a13de3588aeee4a9588e9f1a85 diff --git a/manifest.uuid b/manifest.uuid index 0835b36eb..4c6818ed4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bec5b6d4d083556d111a89186b4f7b35b5e7cebf
\ No newline at end of file +89d958abbac45f2ca5954080cd9e74ec9a07ebb2
\ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 4564bda7b..541a581e5 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8019,7 +8019,16 @@ int sqlite3BtreeInsert( if( rc ) return rc; } }else if( loc==0 ){ - rc = btreeMoveto(pCur, pX->pKey, pX->nKey, appendBias, &loc); + if( pX->nMem ){ + UnpackedRecord r; + memset(&r, 0, sizeof(r)); + r.pKeyInfo = pCur->pKeyInfo; + r.aMem = pX->aMem; + r.nField = pX->nMem; + rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, appendBias, &loc); + }else{ + rc = btreeMoveto(pCur, pX->pKey, pX->nKey, appendBias, &loc); + } if( rc ) return rc; } assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) ); diff --git a/src/btree.h b/src/btree.h index 0df98a3a6..8b421e420 100644 --- a/src/btree.h +++ b/src/btree.h @@ -275,6 +275,8 @@ struct BtreePayload { const void *pKey; /* Key content for indexes. NULL for tables */ sqlite3_int64 nKey; /* Size of pKey for indexes. PRIMARY KEY for tabs */ const void *pData; /* Data for tables. NULL for indexes */ + struct Mem *aMem; /* First of nMem value in the unpacked pKey */ + u16 nMem; /* Number of aMem[] value. Might be zero */ int nData; /* Size of pData. 0 if none. */ int nZero; /* Extra zero data appended after pData,nData */ }; diff --git a/src/build.c b/src/build.c index 350cf9f71..0fe203268 100644 --- a/src/build.c +++ b/src/build.c @@ -2818,7 +2818,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ } sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx); sqlite3VdbeAddOp3(v, OP_Last, iIdx, 0, -1); - sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); sqlite3ReleaseTempReg(pParse, regRecord); sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v); diff --git a/src/delete.c b/src/delete.c index ec8571824..e16e9485b 100644 --- a/src/delete.c +++ b/src/delete.c @@ -449,7 +449,7 @@ void sqlite3DeleteFrom( nKey = 0; /* Zero tells OP_Found to use a composite key */ sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey, sqlite3IndexAffinityStr(pParse->db, pPk), nPk); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEphCur, iKey, iPk, nPk); }else{ /* Add the rowid of the row to be deleted to the RowSet */ nKey = 1; /* OP_Seek always uses a single rowid */ diff --git a/src/expr.c b/src/expr.c index c2b9c8fe4..0e9c7e783 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2538,7 +2538,7 @@ int sqlite3CodeSubselect( }else{ sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1); sqlite3ExprCacheAffinityChange(pParse, r3, 1); - sqlite3VdbeAddOp2(v, OP_IdxInsert, pExpr->iTable, r2); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pExpr->iTable, r2, r3, 1); } } } diff --git a/src/insert.c b/src/insert.c index 6ea3810a2..14186b231 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2180,8 +2180,8 @@ static int xferOptimization( if( !HasRowid(pSrc) && pDestIdx->idxType==2 ){ idxInsFlags |= OPFLAG_NCHANGE; } - sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1); - sqlite3VdbeChangeP5(v, idxInsFlags); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData); + sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND); sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); diff --git a/src/select.c b/src/select.c index 199e13f11..91ff220d6 100644 --- a/src/select.c +++ b/src/select.c @@ -655,7 +655,7 @@ static void codeDistinct( r1 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iTab, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r1, iMem, N); sqlite3ReleaseTempReg(pParse, r1); } @@ -808,7 +808,7 @@ static void selectInnerLoop( int r1; r1 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); sqlite3ReleaseTempReg(pParse, r1); break; } @@ -845,7 +845,7 @@ static void selectInnerLoop( int addr = sqlite3VdbeCurrentAddr(v) + 4; sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm+1, r1,regResult,nResultCol); assert( pSort==0 ); } #endif @@ -881,7 +881,7 @@ static void selectInnerLoop( sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, r1, pDest->zAffSdst, nResultCol); sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); sqlite3ReleaseTempReg(pParse, r1); } break; @@ -967,7 +967,7 @@ static void selectInnerLoop( } sqlite3VdbeAddOp2(v, OP_Sequence, iParm, r2+nKey); sqlite3VdbeAddOp3(v, OP_MakeRecord, r2, nKey+2, r1); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, r2, nKey+2); if( addrTest ) sqlite3VdbeJumpHere(v, addrTest); sqlite3ReleaseTempReg(pParse, r1); sqlite3ReleaseTempRange(pParse, r2, nKey+2); @@ -1264,7 +1264,7 @@ static void generateSortTail( sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid, pDest->zAffSdst, nColumn); sqlite3ExprCacheAffinityChange(pParse, regRow, nColumn); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, regRowid, regRow, nColumn); break; } case SRT_Mem: { @@ -2640,7 +2640,8 @@ static int generateOutputSubroutine( sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1, pDest->zAffSdst, pIn->nSdst); sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst); - sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1, + pIn->iSdst, pIn->nSdst); sqlite3ReleaseTempReg(pParse, r1); break; } diff --git a/src/update.c b/src/update.c index 15e58e34c..1fa53e3d1 100644 --- a/src/update.c +++ b/src/update.c @@ -398,7 +398,7 @@ void sqlite3Update( }else{ sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey, sqlite3IndexAffinityStr(db, pPk), nPk); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, regKey); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEph, regKey, iPk, nPk); } sqlite3WhereEnd(pWInfo); } diff --git a/src/vdbe.c b/src/vdbe.c index c2abeced0..e7e936da8 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5017,15 +5017,20 @@ next_tail: goto check_for_interrupt; } -/* Opcode: IdxInsert P1 P2 P3 * P5 +/* Opcode: IdxInsert P1 P2 P3 P4 P5 ** Synopsis: key=r[P2] ** ** Register P2 holds an SQL index key made using the ** MakeRecord instructions. This opcode writes that key ** into the index P1. Data for the entry is nil. ** -** P3 is a flag that provides a hint to the b-tree layer that this -** insert is likely to be an append. +** If P4 is not zero, the it is the number of values in the unpacked +** key of reg(P2). In that case, P3 is the index of the first register +** for the unpacked key. The availability of the unpacked key can sometimes +** be an optimization. +** +** If P5 has the OPFLAG_APPEND bit set, that is a hint to the b-tree layer +** that this insert is likely to be an append. ** ** If P5 has the OPFLAG_NCHANGE bit set, then the change counter is ** incremented by this instruction. If the OPFLAG_NCHANGE bit is clear, @@ -5066,7 +5071,10 @@ case OP_IdxInsert: { /* in2 */ }else{ x.nKey = pIn2->n; x.pKey = pIn2->z; - rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, pOp->p3, + x.aMem = aMem + pOp->p3; + x.nMem = (u16)pOp->p4.i; + rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, + (pOp->p5 & OPFLAG_APPEND)!=0, ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) ); assert( pC->deferredMoveto==0 ); diff --git a/src/wherecode.c b/src/wherecode.c index c095ce7c8..d547a7117 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1844,7 +1844,8 @@ Bitmask sqlite3WhereCodeOneLoopStart( } if( iSet>=0 ){ sqlite3VdbeAddOp3(v, OP_MakeRecord, r, nPk, regRowid); - sqlite3VdbeAddOp3(v, OP_IdxInsert, regRowset, regRowid, 0); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, regRowset, regRowid, + r, nPk); if( iSet ) sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); } |