aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <Dan Kennedy>2021-04-21 20:52:17 +0000
committerdan <Dan Kennedy>2021-04-21 20:52:17 +0000
commita23a873fbb02bdb20923aae7d2476f07d4245bc3 (patch)
treef4b23113105b11a0e06da5f56a145cc0f2e24521 /src
parent7437c25b63be5cdf678dc5d2f25d1837c126c8b7 (diff)
downloadsqlite-a23a873fbb02bdb20923aae7d2476f07d4245bc3.tar.gz
sqlite-a23a873fbb02bdb20923aae7d2476f07d4245bc3.zip
Add the experimental sqlite3session_changeset_size() API.
FossilOrigin-Name: b5564a6fd54875db1de884fdc0e5eeabcd6aa5595ad03a8a60843503e830a2d8
Diffstat (limited to 'src')
-rw-r--r--src/sqlite.h.in10
-rw-r--r--src/vdbe.c4
-rw-r--r--src/vdbeInt.h4
-rw-r--r--src/vdbeapi.c11
-rw-r--r--src/vdbeaux.c4
-rw-r--r--src/vdbeblob.c2
6 files changed, 30 insertions, 5 deletions
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 9085dc882..56f23f2b0 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -9546,6 +9546,15 @@ int sqlite3_db_cacheflush(sqlite3*);
** triggers; or 2 for changes resulting from triggers called by top-level
** triggers; and so forth.
**
+** When the [sqlite3_blob_write()] API is used to update a blob column,
+** the pre-update hook is invoked with SQLITE_DELETE. This is because the
+** in this case the new values are not available. In this case, when a
+** callback made with op==SQLITE_DELETE is actuall a write using the
+** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns
+** the index of the column being written. In other cases, where the
+** pre-update hook is being invoked for some other reason, including a
+** regular DELETE, sqlite3_preupdate_blobwrite() returns -1.
+**
** See also: [sqlite3_update_hook()]
*/
#if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
@@ -9566,6 +9575,7 @@ int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
int sqlite3_preupdate_count(sqlite3 *);
int sqlite3_preupdate_depth(sqlite3 *);
int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
+int sqlite3_preupdate_blobwrite(sqlite3 *);
#endif
/*
diff --git a/src/vdbe.c b/src/vdbe.c
index cb4e5ea8d..c34ea7245 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -5080,7 +5080,7 @@ case OP_Insert: {
/* Invoke the pre-update hook, if any */
if( pTab ){
if( db->xPreUpdateCallback && !(pOp->p5 & OPFLAG_ISUPDATE) ){
- sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey,pOp->p2);
+ sqlite3VdbePreUpdateHook(p,pC,SQLITE_INSERT,zDb,pTab,x.nKey,pOp->p2,-1);
}
if( db->xUpdateCallback==0 || pTab->aCol==0 ){
/* Prevent post-update hook from running in cases when it should not */
@@ -5240,7 +5240,7 @@ case OP_Delete: {
sqlite3VdbePreUpdateHook(p, pC,
(opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE,
zDb, pTab, pC->movetoTarget,
- pOp->p3
+ pOp->p3, -1
);
}
if( opflags & OPFLAG_ISNOOP ) break;
diff --git a/src/vdbeInt.h b/src/vdbeInt.h
index cb423f20a..5e3e523f9 100644
--- a/src/vdbeInt.h
+++ b/src/vdbeInt.h
@@ -472,6 +472,7 @@ struct PreUpdate {
UnpackedRecord *pUnpacked; /* Unpacked version of aRecord[] */
UnpackedRecord *pNewUnpacked; /* Unpacked version of new.* record */
int iNewReg; /* Register for new.* values */
+ int iBlobWrite; /* Value returned by preupdate_blobwrite() */
i64 iKey1; /* First key value passed to hook */
i64 iKey2; /* Second key value passed to hook */
Mem *aNew; /* Array of new.* values */
@@ -560,7 +561,8 @@ void sqlite3VdbeFrameMemDel(void*); /* Destructor on Mem */
void sqlite3VdbeFrameDelete(VdbeFrame*); /* Actually deletes the Frame */
int sqlite3VdbeFrameRestore(VdbeFrame *);
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
-void sqlite3VdbePreUpdateHook(Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int);
+void sqlite3VdbePreUpdateHook(
+ Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int,int);
#endif
int sqlite3VdbeTransferError(Vdbe *p);
diff --git a/src/vdbeapi.c b/src/vdbeapi.c
index ba3bdf6a5..b21634dc8 100644
--- a/src/vdbeapi.c
+++ b/src/vdbeapi.c
@@ -1907,6 +1907,17 @@ int sqlite3_preupdate_depth(sqlite3 *db){
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
/*
+** This function is designed to be called from within a pre-update callback
+** only.
+*/
+int sqlite3_preupdate_blobwrite(sqlite3 *db){
+ PreUpdate *p = db->pPreUpdate;
+ return (p ? p->iBlobWrite : -1);
+}
+#endif
+
+#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.
*/
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 296408064..d22a6a559 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -5189,7 +5189,8 @@ void sqlite3VdbePreUpdateHook(
const char *zDb, /* Database name */
Table *pTab, /* Modified table */
i64 iKey1, /* Initial key value */
- int iReg /* Register for new.* record */
+ int iReg, /* Register for new.* record */
+ int iBlobWrite
){
sqlite3 *db = v->db;
i64 iKey2;
@@ -5225,6 +5226,7 @@ void sqlite3VdbePreUpdateHook(
preupdate.iKey1 = iKey1;
preupdate.iKey2 = iKey2;
preupdate.pTab = pTab;
+ preupdate.iBlobWrite = iBlobWrite;
db->pPreUpdate = &preupdate;
db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2);
diff --git a/src/vdbeblob.c b/src/vdbeblob.c
index 47e3497dd..a4e79bf89 100644
--- a/src/vdbeblob.c
+++ b/src/vdbeblob.c
@@ -420,7 +420,7 @@ static int blobReadWrite(
sqlite3_int64 iKey;
iKey = sqlite3BtreeIntegerKey(p->pCsr);
sqlite3VdbePreUpdateHook(
- v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1
+ v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol
);
}
#endif