$(TOP)/src/test_tclvar.c \
$(TOP)/src/test_thread.c \
$(TOP)/src/test_vfs.c \
- $(TOP)/src/test_wsd.c \
+ $(TOP)/src/test_windirent.c \
+ $(TOP)/src/test_wsd.c \
$(TOP)/ext/fts3/fts3_term.c \
- $(TOP)/ext/fts3/fts3_test.c \
+ $(TOP)/ext/fts3/fts3_test.c \
+ $(TOP)/ext/session/test_session.c \
$(TOP)/ext/rbu/test_rbu.c
# Statically linked extensions
- C Merge\sthe\slatest\senhancements\sfrom\strunk.
- D 2015-11-19T19:40:40.385
- F Makefile.in c9dfc95717a5af63ab90b36f22afd11e865e3559
-C Remove\sunreachable\sbranches\sfrom\sthe\sdecltype\scomputation\slogic\sin\sthe\squery\nplanner.
-D 2015-12-02T19:46:12.775
-F Makefile.in 23d9a63484a383fc64951b25ef44067930f98dc6
++C Merge\srecent\senhancements\sfrom\strunk.
++D 2015-12-02T20:40:26.162
++F Makefile.in e7d3be066453d66f333e7cb98f4c9d3e700bfc09
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
- F Makefile.msc 4f04d3dbe993b706c956509b1437559d7f2469b1
-F Makefile.msc e8fdca1cb89a1b58b5f4d3a130ea9a3d28cb314d
++F Makefile.msc 820453f6340c500e2377a6ebd681cecfa92afd79
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
F VERSION 8b9d3ac6f1962f94e06ba05462422a544f9c4e36
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
- F main.mk 4f8d448adb9a7302cd5106f583ddc47067f1017d
-F main.mk 9001039f432baeba1074e2d1885f3dfd572b8636
++F main.mk 65524a49d6bbeb624b5953ed50a8c84d9dc34d16
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
F src/btree.c d3bdd8462a86492e2ebc9aca4a0168429017de25
F src/btree.h 2d76dee44704c47eed323356a758662724b674a0
F src/btreeInt.h 3ab435ed27adea54d040584b0bcc488ee7db1e38
- F src/build.c 5a3b71786e2b96d2bb92d40f190eb1fe736f25ca
+ F src/build.c e83da4d004a4e050c01acbb821ff7a7b1019c29b
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
- F src/ctime.c 509ef9c64d1321f42448f111da86400b1799218a
+ F src/ctime.c 58eda76364fb6f374e044aa4493219b13abf9400
F src/date.c fb1c99172017dcc8e237339132c91a21a0788584
F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78
-F src/delete.c 00af9f08a15ddc5cba5962d3d3e5bf2d67b2e7da
+F src/delete.c 86e3940d07fe69a40270c2aaf6ca6c7adf19246c
- F src/expr.c 0080c0f12806eca91e75a23a121a68918e9da357
+ F src/expr.c cb1a419508e5b27769a91e00e36e94724e7b1d51
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 31900763094a3736a5fc887469202eb579fef2d0
- F src/func.c ecdd69ec6a1e406f04cc73324be2ebbf6354197f
+ F src/func.c fe50a9ab977acc0bb0fcd46741e0071fa388888e
F src/global.c 508e4087f7b41d688e4762dcf4d4fe28cfbc87f9
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
F src/loadext.c 18586e45a215325f15096821e9c082035d4fb810
- F src/main.c 59798e68b7f93eaf243b2b4d054dd4eb6ead907a
-F src/main.c 3f2828fce1e45c3ad096c69eee1e96962c7281c5
++F src/main.c cf9fcb71ea8ea46ad20b37dc1af67c1a17cf73b5
F src/malloc.c 337bbe9c7d436ef9b7d06b5dd10bbfc8f3025972
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
F src/pragma.c f3e7147299ca05ef4304a36f1fd6e002729c72c6
F src/pragma.h 3d94aebbebd2089899fecc01909bf2608b39507d
F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1
- F src/printf.c f8fc8f04e75b1e983ef2793c27ec7a43b287e94a
+ F src/printf.c ca05561795ad6c2fa47acdd007702586282f7feb
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
- F src/resolve.c 1954a0f01bf65d78d7d559aea3d5c67f33376d91
+ F src/resolve.c f4c897ca76ca6d5e0b3f0499c627392ffe657c8e
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
- F src/select.c 2376d320907a5c28c55290f18fd94aa3400bf97c
- F src/shell.c 072fc3601b0ac02e50939b469fabeecfe3d66dcd
- F src/sqlite.h.in eed36953a0b5ce6c099b0cb2cb6b6ba220e6ca77
+ F src/select.c 1611828a7116e5f6cc1e69cd07d59b0d2c662ea9
-F src/shell.c 2796237990d42e6a5a7beafee65ef70cc8767d21
-F src/sqlite.h.in 5bd83191711d3dc85030326daa9e8e5226a495e7
++F src/shell.c 98bf4a35a121c9d4b91940a53794f2cbc354c45c
++F src/sqlite.h.in fc89d305439df88cfe018dbbaf1770645766fa2f
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
- F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924
- F src/sqliteInt.h d85782b8b5b2057ac015f7ec20195b7ce869960d
+ F src/sqlite3ext.h 41ef50b0418a7c5ad1337bb80db5a7928dee764f
-F src/sqliteInt.h 64256d193a16a147d9f6317cc4e095fdd3e0a2e9
++F src/sqliteInt.h 0bf170994dbc42d4344eed5d59d88ed0631aa4d1
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
F src/test_backup.c 2e6e6a081870150f20c526a2e9d0d29cda47d803
F src/test_blob.c e5a7a81d61a780da79101aeb1e60d300af169e07
F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
- F src/test_config.c a25edf31cc0dbe17f5d1d667b1320cbb4e52b6dd
-F src/test_config.c 48850687dd5abc8260e23835632511054ccae172
++F src/test_config.c bae65b68a216f31e225a46187497bdc007c1c5e5
F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
- F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
+ F src/test_fs.c aab47ac456316502faa265daadf9ac832fea12b9
F src/test_func.c 0d9c25956152adefee8881c6fadc8354793764d0
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32
F src/tokenize.c 5606871a377f390af7040ec3c12e0d183512d785
F src/treeview.c 78842e90c1f71269e7a73a1d4221b6fe360bab66
F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f
- F src/update.c c2fff3b60bfcabcb0372acbe8cf6f77c2bb515bc
-F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3
++F src/update.c d8d675aa299336ac086ad2039d7e812cd6237db0
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
- F src/util.c fc612367108b74573c5fd13a85d0a23027f438bd
+ F src/util.c e802e8e311a0d6c48cd1b3e89db164f6f0248d70
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
- F src/vdbe.c 9539aa0ccf4844b8b59466ef3c15dbffb479a390
-F src/vdbe.c 4d75375fa8bf911aa76ab8383d6f7eea0dec0fda
-F src/vdbe.h efb7a8c1459e31f3ea4377824c6a7e4cb5068637
-F src/vdbeInt.h 75c2e82ee3357e9210c06474f8d9bdf12c81105d
-F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca
-F src/vdbeaux.c 9a234c9aaab4ad725daf94667cfed441a437c52d
-F src/vdbeblob.c fdc4a81605ae7a35ae94a55bd768b66d6be16f15
-F src/vdbemem.c fdd1578e47bea61390d472de53c565781d81e045
++F src/vdbe.c 5c3dd0f49bfebfddbfa4d389ed394b2b28d48cbf
+F src/vdbe.h bfe3f80dba435377cdb64fd917f2529f0f48ab77
- F src/vdbeInt.h d6ae6e64ad16e213f37306b1735ff72fb98bec69
- F src/vdbeapi.c f5eda36a5c85ef578957ab4311e8d9b1f51a3552
- F src/vdbeaux.c 67db9a1c132207f4d6a8f4e76531cea39539fcaa
- F src/vdbeblob.c b400c25ac822af3c507ef84b5cd93c1583a70321
++F src/vdbeInt.h 4f3b46806b93faa92f0511c7ce30ed31aaec65be
++F src/vdbeapi.c ab2cb8fe23fb9f3195f1311eaa800495d83b6118
++F src/vdbeaux.c 514e93b162bf3e84c82478f174728cda9135b558
++F src/vdbeblob.c cc13eca96b8ec51b6248de785a1aec5df11f5805
+F src/vdbemem.c 25b6cfd665b5073480452426e84136edd94140c0
- F src/vdbesort.c 8b23930a1289526f6d2a3a9f2e965bcc963e4a68
+ F src/vdbesort.c a7ec02da4494c59dfd071126dd3726be5a11459d
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
F src/vtab.c 2a8b44aa372c33f6154208e7a7f6c44254549806
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
- F test/hexlit.test 1d312fa816dfd3650a3bb488093bc09a0c927f67
+ F test/hexlit.test d7b0a5f41123df1e43985b91b8b2e70f95282d21
F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711
-F test/hook.test 162d7cef7a2d2b04839fe14402934e6a1b79442f
+F test/hook.test aa41c095d26822b8a51aa4c82904a14347961be6
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
F test/ieee754.test 118b665a97a8df0e8f2fbdb07d113e596f4a6b53
F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
- F tool/sqldiff.c db1232df457fdd4cbf2a919a497fc44bb18fb933
+ F tool/sqldiff.c 653db1a9294e0b34849c4504599c282a18d8b8c6
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
-F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f
+F tool/symbols.sh c5a617b8c61a0926747a56c65f5671ef8ac0e148
F tool/tostr.tcl 96022f35ada2194f6f8ccf6fd95809e90ed277c4
F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003
F tool/vdbe-compress.tcl 5926c71f9c12d2ab73ef35c29376e756eb68361c
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
- P 78bc42e664e9fa9ee21ad9762c369f291fcdf5db 126b998cf163dcdd5a222634f1e929f04db3c700
- R d78a5057451ca68f4e40e727fe9ca899
-P 3e1d71fcaf57c0223ab9a7366c8607f8f66bb21c
-R 0397cf9717330ffe9055735c8207c81a
++P 7d6cfc79e7e5534ebacd980479917bc528a638f7 4f2bcff94c672312805be1400050a7026f93a9d7
++R 50fae771d9c27e855af8c38f94348078
U drh
- Z 251138aef0997d710e6be89ddc7546bd
-Z 6381d064415ccbeec9de47fb6017aaa8
++Z 355385643ee65578020d9d55249a7cd0
- 7d6cfc79e7e5534ebacd980479917bc528a638f7
-4f2bcff94c672312805be1400050a7026f93a9d7
++d1a1278d7f3306536dc9cbd8fb300898f1e373e8
assert( memIsValid(pData) );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
- assert( pC->pCursor!=0 );
- assert( pC->pseudoTableReg==0 );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->uc.pCursor!=0 );
assert( pC->isTable );
+ assert( pOp->p4type==P4_TABLE || pOp->p4type>=P4_STATIC );
REGISTER_TRACE(pOp->p2, pData);
if( pOp->opcode==OP_Insert ){
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
- assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->uc.pCursor!=0 );
assert( pC->deferredMoveto==0 );
- hasUpdateCallback = db->xUpdateCallback && pOp->p4.z && pC->isTable;
- if( pOp->p5 && hasUpdateCallback ){
- sqlite3BtreeKeySize(pC->uc.pCursor, &pC->movetoTarget);
- }
--
#ifdef SQLITE_DEBUG
- /* The seek operation that positioned the cursor prior to OP_Delete will
- ** have also set the pC->movetoTarget field to the rowid of the row that
- ** is being deleted */
- if( pOp->p4.z && pC->isTable && pOp->p5==0 ){
+ if( pOp->p4type==P4_TABLE && HasRowid(pOp->p4.pTab) && pOp->p5==0 ){
+ /* If p5 is zero, the seek operation that positioned the cursor prior to
+ ** OP_Delete will have also set the pC->movetoTarget field to the rowid of
+ ** the row that is being deleted */
i64 iKey = 0;
- sqlite3BtreeKeySize(pC->pCursor, &iKey);
+ sqlite3BtreeKeySize(pC->uc.pCursor, &iKey);
- assert( pC->movetoTarget==iKey );
+ assert( pC->movetoTarget==iKey );
+ }
+#endif
+
+ /* If the update-hook or pre-update-hook will be invoked, set zDb to
+ ** the name of the db to pass as to it. Also set local pTab to a copy
+ ** of p4.pTab. Finally, if p5 is true, indicating that this cursor was
+ ** last moved with OP_Next or OP_Prev, not Seek or NotFound, set
+ ** VdbeCursor.movetoTarget to the current rowid. */
+ if( pOp->p4.pTab && HAS_UPDATE_HOOK(db) ){
+ assert( pC->iDb>=0 );
+ zDb = db->aDb[pC->iDb].zName;
+ pTab = pOp->p4.pTab;
+ if( pOp->p5 && pC->isTable ){
- sqlite3BtreeKeySize(pC->pCursor, &pC->movetoTarget);
++ sqlite3BtreeKeySize(pC->uc.pCursor, &pC->movetoTarget);
+ }
+ }
+
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ /* Invoke the pre-update-hook if required. */
+ if( db->xPreUpdateCallback && pOp->p4.pTab && HasRowid(pTab) ){
+ assert( !(opflags & OPFLAG_ISUPDATE) || (aMem[pOp->p3].flags & MEM_Int) );
+ sqlite3VdbePreUpdateHook(p, pC,
+ (opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE,
+ zDb, pTab, pC->movetoTarget,
+ pOp->p3
+ );
}
#endif
+
+ if( opflags & OPFLAG_ISNOOP ) break;
- rc = sqlite3BtreeDelete(pC->pCursor, pOp->p5);
+ rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5);
pC->cacheStatus = CACHE_STALE;
/* Invoke the update-hook if required. */
return (int)v;
}
- rc = sqlite3BtreeDataSize(p->pCsr->pCursor, &nRec);
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+/*
+** Allocate and populate an UnpackedRecord structure based on the serialized
+** record in nKey/pKey. Return a pointer to the new UnpackedRecord structure
+** if successful, or a NULL pointer if an OOM error is encountered.
+*/
+static UnpackedRecord *vdbeUnpackRecord(
+ KeyInfo *pKeyInfo,
+ int nKey,
+ const void *pKey
+){
+ char *dummy; /* Dummy argument for AllocUnpackedRecord() */
+ UnpackedRecord *pRet; /* Return value */
+
+ pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo, 0, 0, &dummy);
+ if( pRet ){
+ memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nField+1));
+ sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet);
+ }
+ return pRet;
+}
+
+/*
+** This function is called from within a pre-update callback to retrieve
+** a field of the row currently being updated or deleted.
+*/
+int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
+ PreUpdate *p = db->pPreUpdate;
+ int rc = SQLITE_OK;
+
+ /* Test that this call is being made from within an SQLITE_DELETE or
+ ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */
+ if( !p || p->op==SQLITE_INSERT ){
+ rc = SQLITE_MISUSE_BKPT;
+ goto preupdate_old_out;
+ }
+ if( iIdx>=p->pCsr->nField || iIdx<0 ){
+ rc = SQLITE_RANGE;
+ goto preupdate_old_out;
+ }
+
+ /* If the old.* record has not yet been loaded into memory, do so now. */
+ if( p->pUnpacked==0 ){
+ u32 nRec;
+ u8 *aRec;
+
- rc = sqlite3BtreeData(p->pCsr->pCursor, 0, nRec, aRec);
++ rc = sqlite3BtreeDataSize(p->pCsr->uc.pCursor, &nRec);
+ if( rc!=SQLITE_OK ) goto preupdate_old_out;
+ aRec = sqlite3DbMallocRaw(db, nRec);
+ if( !aRec ) goto preupdate_old_out;
++ rc = sqlite3BtreeData(p->pCsr->uc.pCursor, 0, nRec, aRec);
+ if( rc==SQLITE_OK ){
+ p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec);
+ if( !p->pUnpacked ) rc = SQLITE_NOMEM;
+ }
+ if( rc!=SQLITE_OK ){
+ sqlite3DbFree(db, aRec);
+ goto preupdate_old_out;
+ }
+ p->aRecord = aRec;
+ }
+
+ if( iIdx>=p->pUnpacked->nField ){
+ *ppValue = (sqlite3_value *)columnNullValue();
+ }else{
+ *ppValue = &p->pUnpacked->aMem[iIdx];
+ if( iIdx==p->iPKey ){
+ sqlite3VdbeMemSetInt64(*ppValue, p->iKey1);
+ }
+ }
+
+ preupdate_old_out:
+ sqlite3Error(db, rc);
+ return sqlite3ApiExit(db, rc);
+}
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+/*
+** This function is called from within a pre-update callback to retrieve
+** the number of columns in the row being updated, deleted or inserted.
+*/
+int sqlite3_preupdate_count(sqlite3 *db){
+ PreUpdate *p = db->pPreUpdate;
+ return (p ? p->keyinfo.nField : 0);
+}
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+/*
+** This function is designed to be called from within a pre-update callback
+** only. It returns zero if the change that caused the callback was made
+** immediately by a user SQL statement. Or, if the change was made by a
+** trigger program, it returns the number of trigger programs currently
+** on the stack (1 for a top-level trigger, 2 for a trigger fired by a
+** top-level trigger etc.).
+**
+** For the purposes of the previous paragraph, a foreign key CASCADE, SET NULL
+** or SET DEFAULT action is considered a trigger.
+*/
+int sqlite3_preupdate_depth(sqlite3 *db){
+ PreUpdate *p = db->pPreUpdate;
+ return (p ? p->v->nFrame : 0);
+}
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+/*
+** This function is called from within a pre-update callback to retrieve
+** a field of the row currently being updated or inserted.
+*/
+int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
+ PreUpdate *p = db->pPreUpdate;
+ int rc = SQLITE_OK;
+ Mem *pMem;
+
+ if( !p || p->op==SQLITE_DELETE ){
+ rc = SQLITE_MISUSE_BKPT;
+ goto preupdate_new_out;
+ }
+ if( iIdx>=p->pCsr->nField || iIdx<0 ){
+ rc = SQLITE_RANGE;
+ goto preupdate_new_out;
+ }
+
+ if( p->op==SQLITE_INSERT ){
+ /* For an INSERT, memory cell p->iNewReg contains the serialized record
+ ** that is being inserted. Deserialize it. */
+ UnpackedRecord *pUnpack = p->pNewUnpacked;
+ if( !pUnpack ){
+ Mem *pData = &p->v->aMem[p->iNewReg];
+ rc = sqlite3VdbeMemExpandBlob(pData);
+ if( rc!=SQLITE_OK ) goto preupdate_new_out;
+ pUnpack = vdbeUnpackRecord(&p->keyinfo, pData->n, pData->z);
+ if( !pUnpack ){
+ rc = SQLITE_NOMEM;
+ goto preupdate_new_out;
+ }
+ p->pNewUnpacked = pUnpack;
+ }
+ if( iIdx>=pUnpack->nField ){
+ pMem = (sqlite3_value *)columnNullValue();
+ }else{
+ pMem = &pUnpack->aMem[iIdx];
+ if( iIdx==p->iPKey ){
+ sqlite3VdbeMemSetInt64(pMem, p->iKey2);
+ }
+ }
+ }else{
+ /* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required
+ ** value. Make a copy of the cell contents and return a pointer to it.
+ ** It is not safe to return a pointer to the memory cell itself as the
+ ** caller may modify the value text encoding.
+ */
+ assert( p->op==SQLITE_UPDATE );
+ if( !p->aNew ){
+ p->aNew = (Mem *)sqlite3DbMallocZero(db, sizeof(Mem) * p->pCsr->nField);
+ if( !p->aNew ){
+ rc = SQLITE_NOMEM;
+ goto preupdate_new_out;
+ }
+ }
+ assert( iIdx>=0 && iIdx<p->pCsr->nField );
+ pMem = &p->aNew[iIdx];
+ if( pMem->flags==0 ){
+ if( iIdx==p->iPKey ){
+ sqlite3VdbeMemSetInt64(pMem, p->iKey2);
+ }else{
+ rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]);
+ if( rc!=SQLITE_OK ) goto preupdate_new_out;
+ }
+ }
+ }
+ *ppValue = pMem;
+
+ preupdate_new_out:
+ sqlite3Error(db, rc);
+ return sqlite3ApiExit(db, rc);
+}
+#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
/*
** Return status data for a single loop within query pStmt.