aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2016-11-09 00:10:33 +0000
committerdrh <drh@noemail.net>2016-11-09 00:10:33 +0000
commit9b4eaebc68ec3a209c698b1220ef2bc49cdb41dc (patch)
treeddc38da5766092a4f8d19dbdd4ecc892152599a4
parent3b908d41a0d3800a6ebe5dff42f4117fc342105c (diff)
downloadsqlite-9b4eaebc68ec3a209c698b1220ef2bc49cdb41dc.tar.gz
sqlite-9b4eaebc68ec3a209c698b1220ef2bc49cdb41dc.zip
Enhance the OP_IdxInsert opcode to optionally accept unpacked key material.
FossilOrigin-Name: 89d958abbac45f2ca5954080cd9e74ec9a07ebb2
-rw-r--r--manifest35
-rw-r--r--manifest.uuid2
-rw-r--r--src/btree.c11
-rw-r--r--src/btree.h2
-rw-r--r--src/build.c2
-rw-r--r--src/delete.c2
-rw-r--r--src/expr.c2
-rw-r--r--src/insert.c4
-rw-r--r--src/select.c15
-rw-r--r--src/update.c2
-rw-r--r--src/vdbe.c16
-rw-r--r--src/wherecode.c3
12 files changed, 60 insertions, 36 deletions
diff --git a/manifest b/manifest
index 9c94df9ef..725dfb913 100644
--- a/manifest
+++ b/manifest
@@ -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);
}