Add the sqlite3changegroup_schema() API. To allow changegroups to handle differences...
[sqlite.git] / ext / session / sqlite3session.c
blob1c291f51c0171519ed294aa761eed0b154268de3
2 #if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
3 #include "sqlite3session.h"
4 #include <assert.h>
5 #include <string.h>
7 #ifndef SQLITE_AMALGAMATION
8 # include "sqliteInt.h"
9 # include "vdbeInt.h"
10 #endif
12 typedef struct SessionTable SessionTable;
13 typedef struct SessionChange SessionChange;
14 typedef struct SessionBuffer SessionBuffer;
15 typedef struct SessionInput SessionInput;
18 ** Minimum chunk size used by streaming versions of functions.
20 #ifndef SESSIONS_STRM_CHUNK_SIZE
21 # ifdef SQLITE_TEST
22 # define SESSIONS_STRM_CHUNK_SIZE 64
23 # else
24 # define SESSIONS_STRM_CHUNK_SIZE 1024
25 # endif
26 #endif
28 #define SESSIONS_ROWID "_rowid_"
30 static int sessions_strm_chunk_size = SESSIONS_STRM_CHUNK_SIZE;
32 typedef struct SessionHook SessionHook;
33 struct SessionHook {
34 void *pCtx;
35 int (*xOld)(void*,int,sqlite3_value**);
36 int (*xNew)(void*,int,sqlite3_value**);
37 int (*xCount)(void*);
38 int (*xDepth)(void*);
42 ** Session handle structure.
44 struct sqlite3_session {
45 sqlite3 *db; /* Database handle session is attached to */
46 char *zDb; /* Name of database session is attached to */
47 int bEnableSize; /* True if changeset_size() enabled */
48 int bEnable; /* True if currently recording */
49 int bIndirect; /* True if all changes are indirect */
50 int bAutoAttach; /* True to auto-attach tables */
51 int bImplicitPK; /* True to handle tables with implicit PK */
52 int rc; /* Non-zero if an error has occurred */
53 void *pFilterCtx; /* First argument to pass to xTableFilter */
54 int (*xTableFilter)(void *pCtx, const char *zTab);
55 i64 nMalloc; /* Number of bytes of data allocated */
56 i64 nMaxChangesetSize;
57 sqlite3_value *pZeroBlob; /* Value containing X'' */
58 sqlite3_session *pNext; /* Next session object on same db. */
59 SessionTable *pTable; /* List of attached tables */
60 SessionHook hook; /* APIs to grab new and old data with */
64 ** Instances of this structure are used to build strings or binary records.
66 struct SessionBuffer {
67 u8 *aBuf; /* Pointer to changeset buffer */
68 int nBuf; /* Size of buffer aBuf */
69 int nAlloc; /* Size of allocation containing aBuf */
73 ** An object of this type is used internally as an abstraction for
74 ** input data. Input data may be supplied either as a single large buffer
75 ** (e.g. sqlite3changeset_start()) or using a stream function (e.g.
76 ** sqlite3changeset_start_strm()).
78 struct SessionInput {
79 int bNoDiscard; /* If true, do not discard in InputBuffer() */
80 int iCurrent; /* Offset in aData[] of current change */
81 int iNext; /* Offset in aData[] of next change */
82 u8 *aData; /* Pointer to buffer containing changeset */
83 int nData; /* Number of bytes in aData */
85 SessionBuffer buf; /* Current read buffer */
86 int (*xInput)(void*, void*, int*); /* Input stream call (or NULL) */
87 void *pIn; /* First argument to xInput */
88 int bEof; /* Set to true after xInput finished */
92 ** Structure for changeset iterators.
94 struct sqlite3_changeset_iter {
95 SessionInput in; /* Input buffer or stream */
96 SessionBuffer tblhdr; /* Buffer to hold apValue/zTab/abPK/ */
97 int bPatchset; /* True if this is a patchset */
98 int bInvert; /* True to invert changeset */
99 int bSkipEmpty; /* Skip noop UPDATE changes */
100 int rc; /* Iterator error code */
101 sqlite3_stmt *pConflict; /* Points to conflicting row, if any */
102 char *zTab; /* Current table */
103 int nCol; /* Number of columns in zTab */
104 int op; /* Current operation */
105 int bIndirect; /* True if current change was indirect */
106 u8 *abPK; /* Primary key array */
107 sqlite3_value **apValue; /* old.* and new.* values */
111 ** Each session object maintains a set of the following structures, one
112 ** for each table the session object is monitoring. The structures are
113 ** stored in a linked list starting at sqlite3_session.pTable.
115 ** The keys of the SessionTable.aChange[] hash table are all rows that have
116 ** been modified in any way since the session object was attached to the
117 ** table.
119 ** The data associated with each hash-table entry is a structure containing
120 ** a subset of the initial values that the modified row contained at the
121 ** start of the session. Or no initial values if the row was inserted.
123 ** pDfltStmt:
124 ** This is only used by the sqlite3changegroup_xxx() APIs, not by
125 ** regular sqlite3_session objects.
127 struct SessionTable {
128 SessionTable *pNext;
129 char *zName; /* Local name of table */
130 int nCol; /* Number of columns in table zName */
131 int bStat1; /* True if this is sqlite_stat1 */
132 int bRowid; /* True if this table uses rowid for PK */
133 const char **azCol; /* Column names */
134 const char **azDflt; /* Default value expressions */
135 u8 *abPK; /* Array of primary key flags */
136 int nEntry; /* Total number of entries in hash table */
137 int nChange; /* Size of apChange[] array */
138 SessionChange **apChange; /* Hash table buckets */
140 sqlite3_stmt *pDfltStmt;
144 ** RECORD FORMAT:
146 ** The following record format is similar to (but not compatible with) that
147 ** used in SQLite database files. This format is used as part of the
148 ** change-set binary format, and so must be architecture independent.
150 ** Unlike the SQLite database record format, each field is self-contained -
151 ** there is no separation of header and data. Each field begins with a
152 ** single byte describing its type, as follows:
154 ** 0x00: Undefined value.
155 ** 0x01: Integer value.
156 ** 0x02: Real value.
157 ** 0x03: Text value.
158 ** 0x04: Blob value.
159 ** 0x05: SQL NULL value.
161 ** Note that the above match the definitions of SQLITE_INTEGER, SQLITE_TEXT
162 ** and so on in sqlite3.h. For undefined and NULL values, the field consists
163 ** only of the single type byte. For other types of values, the type byte
164 ** is followed by:
166 ** Text values:
167 ** A varint containing the number of bytes in the value (encoded using
168 ** UTF-8). Followed by a buffer containing the UTF-8 representation
169 ** of the text value. There is no nul terminator.
171 ** Blob values:
172 ** A varint containing the number of bytes in the value, followed by
173 ** a buffer containing the value itself.
175 ** Integer values:
176 ** An 8-byte big-endian integer value.
178 ** Real values:
179 ** An 8-byte big-endian IEEE 754-2008 real value.
181 ** Varint values are encoded in the same way as varints in the SQLite
182 ** record format.
184 ** CHANGESET FORMAT:
186 ** A changeset is a collection of DELETE, UPDATE and INSERT operations on
187 ** one or more tables. Operations on a single table are grouped together,
188 ** but may occur in any order (i.e. deletes, updates and inserts are all
189 ** mixed together).
191 ** Each group of changes begins with a table header:
193 ** 1 byte: Constant 0x54 (capital 'T')
194 ** Varint: Number of columns in the table.
195 ** nCol bytes: 0x01 for PK columns, 0x00 otherwise.
196 ** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
198 ** Followed by one or more changes to the table.
200 ** 1 byte: Either SQLITE_INSERT (0x12), UPDATE (0x17) or DELETE (0x09).
201 ** 1 byte: The "indirect-change" flag.
202 ** old.* record: (delete and update only)
203 ** new.* record: (insert and update only)
205 ** The "old.*" and "new.*" records, if present, are N field records in the
206 ** format described above under "RECORD FORMAT", where N is the number of
207 ** columns in the table. The i'th field of each record is associated with
208 ** the i'th column of the table, counting from left to right in the order
209 ** in which columns were declared in the CREATE TABLE statement.
211 ** The new.* record that is part of each INSERT change contains the values
212 ** that make up the new row. Similarly, the old.* record that is part of each
213 ** DELETE change contains the values that made up the row that was deleted
214 ** from the database. In the changeset format, the records that are part
215 ** of INSERT or DELETE changes never contain any undefined (type byte 0x00)
216 ** fields.
218 ** Within the old.* record associated with an UPDATE change, all fields
219 ** associated with table columns that are not PRIMARY KEY columns and are
220 ** not modified by the UPDATE change are set to "undefined". Other fields
221 ** are set to the values that made up the row before the UPDATE that the
222 ** change records took place. Within the new.* record, fields associated
223 ** with table columns modified by the UPDATE change contain the new
224 ** values. Fields associated with table columns that are not modified
225 ** are set to "undefined".
227 ** PATCHSET FORMAT:
229 ** A patchset is also a collection of changes. It is similar to a changeset,
230 ** but leaves undefined those fields that are not useful if no conflict
231 ** resolution is required when applying the changeset.
233 ** Each group of changes begins with a table header:
235 ** 1 byte: Constant 0x50 (capital 'P')
236 ** Varint: Number of columns in the table.
237 ** nCol bytes: 0x01 for PK columns, 0x00 otherwise.
238 ** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
240 ** Followed by one or more changes to the table.
242 ** 1 byte: Either SQLITE_INSERT (0x12), UPDATE (0x17) or DELETE (0x09).
243 ** 1 byte: The "indirect-change" flag.
244 ** single record: (PK fields for DELETE, PK and modified fields for UPDATE,
245 ** full record for INSERT).
247 ** As in the changeset format, each field of the single record that is part
248 ** of a patchset change is associated with the correspondingly positioned
249 ** table column, counting from left to right within the CREATE TABLE
250 ** statement.
252 ** For a DELETE change, all fields within the record except those associated
253 ** with PRIMARY KEY columns are omitted. The PRIMARY KEY fields contain the
254 ** values identifying the row to delete.
256 ** For an UPDATE change, all fields except those associated with PRIMARY KEY
257 ** columns and columns that are modified by the UPDATE are set to "undefined".
258 ** PRIMARY KEY fields contain the values identifying the table row to update,
259 ** and fields associated with modified columns contain the new column values.
261 ** The records associated with INSERT changes are in the same format as for
262 ** changesets. It is not possible for a record associated with an INSERT
263 ** change to contain a field set to "undefined".
265 ** REBASE BLOB FORMAT:
267 ** A rebase blob may be output by sqlite3changeset_apply_v2() and its
268 ** streaming equivalent for use with the sqlite3_rebaser APIs to rebase
269 ** existing changesets. A rebase blob contains one entry for each conflict
270 ** resolved using either the OMIT or REPLACE strategies within the apply_v2()
271 ** call.
273 ** The format used for a rebase blob is very similar to that used for
274 ** changesets. All entries related to a single table are grouped together.
276 ** Each group of entries begins with a table header in changeset format:
278 ** 1 byte: Constant 0x54 (capital 'T')
279 ** Varint: Number of columns in the table.
280 ** nCol bytes: 0x01 for PK columns, 0x00 otherwise.
281 ** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
283 ** Followed by one or more entries associated with the table.
285 ** 1 byte: Either SQLITE_INSERT (0x12), DELETE (0x09).
286 ** 1 byte: Flag. 0x01 for REPLACE, 0x00 for OMIT.
287 ** record: (in the record format defined above).
289 ** In a rebase blob, the first field is set to SQLITE_INSERT if the change
290 ** that caused the conflict was an INSERT or UPDATE, or to SQLITE_DELETE if
291 ** it was a DELETE. The second field is set to 0x01 if the conflict
292 ** resolution strategy was REPLACE, or 0x00 if it was OMIT.
294 ** If the change that caused the conflict was a DELETE, then the single
295 ** record is a copy of the old.* record from the original changeset. If it
296 ** was an INSERT, then the single record is a copy of the new.* record. If
297 ** the conflicting change was an UPDATE, then the single record is a copy
298 ** of the new.* record with the PK fields filled in based on the original
299 ** old.* record.
303 ** For each row modified during a session, there exists a single instance of
304 ** this structure stored in a SessionTable.aChange[] hash table.
306 struct SessionChange {
307 u8 op; /* One of UPDATE, DELETE, INSERT */
308 u8 bIndirect; /* True if this change is "indirect" */
309 u16 nRecordField; /* Number of fields in aRecord[] */
310 int nMaxSize; /* Max size of eventual changeset record */
311 int nRecord; /* Number of bytes in buffer aRecord[] */
312 u8 *aRecord; /* Buffer containing old.* record */
313 SessionChange *pNext; /* For hash-table collisions */
317 ** Write a varint with value iVal into the buffer at aBuf. Return the
318 ** number of bytes written.
320 static int sessionVarintPut(u8 *aBuf, int iVal){
321 return putVarint32(aBuf, iVal);
325 ** Return the number of bytes required to store value iVal as a varint.
327 static int sessionVarintLen(int iVal){
328 return sqlite3VarintLen(iVal);
332 ** Read a varint value from aBuf[] into *piVal. Return the number of
333 ** bytes read.
335 static int sessionVarintGet(const u8 *aBuf, int *piVal){
336 return getVarint32(aBuf, *piVal);
339 /* Load an unaligned and unsigned 32-bit integer */
340 #define SESSION_UINT32(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
343 ** Read a 64-bit big-endian integer value from buffer aRec[]. Return
344 ** the value read.
346 static sqlite3_int64 sessionGetI64(u8 *aRec){
347 u64 x = SESSION_UINT32(aRec);
348 u32 y = SESSION_UINT32(aRec+4);
349 x = (x<<32) + y;
350 return (sqlite3_int64)x;
354 ** Write a 64-bit big-endian integer value to the buffer aBuf[].
356 static void sessionPutI64(u8 *aBuf, sqlite3_int64 i){
357 aBuf[0] = (i>>56) & 0xFF;
358 aBuf[1] = (i>>48) & 0xFF;
359 aBuf[2] = (i>>40) & 0xFF;
360 aBuf[3] = (i>>32) & 0xFF;
361 aBuf[4] = (i>>24) & 0xFF;
362 aBuf[5] = (i>>16) & 0xFF;
363 aBuf[6] = (i>> 8) & 0xFF;
364 aBuf[7] = (i>> 0) & 0xFF;
368 ** This function is used to serialize the contents of value pValue (see
369 ** comment titled "RECORD FORMAT" above).
371 ** If it is non-NULL, the serialized form of the value is written to
372 ** buffer aBuf. *pnWrite is set to the number of bytes written before
373 ** returning. Or, if aBuf is NULL, the only thing this function does is
374 ** set *pnWrite.
376 ** If no error occurs, SQLITE_OK is returned. Or, if an OOM error occurs
377 ** within a call to sqlite3_value_text() (may fail if the db is utf-16))
378 ** SQLITE_NOMEM is returned.
380 static int sessionSerializeValue(
381 u8 *aBuf, /* If non-NULL, write serialized value here */
382 sqlite3_value *pValue, /* Value to serialize */
383 sqlite3_int64 *pnWrite /* IN/OUT: Increment by bytes written */
385 int nByte; /* Size of serialized value in bytes */
387 if( pValue ){
388 int eType; /* Value type (SQLITE_NULL, TEXT etc.) */
390 eType = sqlite3_value_type(pValue);
391 if( aBuf ) aBuf[0] = eType;
393 switch( eType ){
394 case SQLITE_NULL:
395 nByte = 1;
396 break;
398 case SQLITE_INTEGER:
399 case SQLITE_FLOAT:
400 if( aBuf ){
401 /* TODO: SQLite does something special to deal with mixed-endian
402 ** floating point values (e.g. ARM7). This code probably should
403 ** too. */
404 u64 i;
405 if( eType==SQLITE_INTEGER ){
406 i = (u64)sqlite3_value_int64(pValue);
407 }else{
408 double r;
409 assert( sizeof(double)==8 && sizeof(u64)==8 );
410 r = sqlite3_value_double(pValue);
411 memcpy(&i, &r, 8);
413 sessionPutI64(&aBuf[1], i);
415 nByte = 9;
416 break;
418 default: {
419 u8 *z;
420 int n;
421 int nVarint;
423 assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
424 if( eType==SQLITE_TEXT ){
425 z = (u8 *)sqlite3_value_text(pValue);
426 }else{
427 z = (u8 *)sqlite3_value_blob(pValue);
429 n = sqlite3_value_bytes(pValue);
430 if( z==0 && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM;
431 nVarint = sessionVarintLen(n);
433 if( aBuf ){
434 sessionVarintPut(&aBuf[1], n);
435 if( n>0 ) memcpy(&aBuf[nVarint + 1], z, n);
438 nByte = 1 + nVarint + n;
439 break;
442 }else{
443 nByte = 1;
444 if( aBuf ) aBuf[0] = '\0';
447 if( pnWrite ) *pnWrite += nByte;
448 return SQLITE_OK;
452 ** Allocate and return a pointer to a buffer nByte bytes in size. If
453 ** pSession is not NULL, increase the sqlite3_session.nMalloc variable
454 ** by the number of bytes allocated.
456 static void *sessionMalloc64(sqlite3_session *pSession, i64 nByte){
457 void *pRet = sqlite3_malloc64(nByte);
458 if( pSession ) pSession->nMalloc += sqlite3_msize(pRet);
459 return pRet;
463 ** Free buffer pFree, which must have been allocated by an earlier
464 ** call to sessionMalloc64(). If pSession is not NULL, decrease the
465 ** sqlite3_session.nMalloc counter by the number of bytes freed.
467 static void sessionFree(sqlite3_session *pSession, void *pFree){
468 if( pSession ) pSession->nMalloc -= sqlite3_msize(pFree);
469 sqlite3_free(pFree);
473 ** This macro is used to calculate hash key values for data structures. In
474 ** order to use this macro, the entire data structure must be represented
475 ** as a series of unsigned integers. In order to calculate a hash-key value
476 ** for a data structure represented as three such integers, the macro may
477 ** then be used as follows:
479 ** int hash_key_value;
480 ** hash_key_value = HASH_APPEND(0, <value 1>);
481 ** hash_key_value = HASH_APPEND(hash_key_value, <value 2>);
482 ** hash_key_value = HASH_APPEND(hash_key_value, <value 3>);
484 ** In practice, the data structures this macro is used for are the primary
485 ** key values of modified rows.
487 #define HASH_APPEND(hash, add) ((hash) << 3) ^ (hash) ^ (unsigned int)(add)
490 ** Append the hash of the 64-bit integer passed as the second argument to the
491 ** hash-key value passed as the first. Return the new hash-key value.
493 static unsigned int sessionHashAppendI64(unsigned int h, i64 i){
494 h = HASH_APPEND(h, i & 0xFFFFFFFF);
495 return HASH_APPEND(h, (i>>32)&0xFFFFFFFF);
499 ** Append the hash of the blob passed via the second and third arguments to
500 ** the hash-key value passed as the first. Return the new hash-key value.
502 static unsigned int sessionHashAppendBlob(unsigned int h, int n, const u8 *z){
503 int i;
504 for(i=0; i<n; i++) h = HASH_APPEND(h, z[i]);
505 return h;
509 ** Append the hash of the data type passed as the second argument to the
510 ** hash-key value passed as the first. Return the new hash-key value.
512 static unsigned int sessionHashAppendType(unsigned int h, int eType){
513 return HASH_APPEND(h, eType);
517 ** This function may only be called from within a pre-update callback.
518 ** It calculates a hash based on the primary key values of the old.* or
519 ** new.* row currently available and, assuming no error occurs, writes it to
520 ** *piHash before returning. If the primary key contains one or more NULL
521 ** values, *pbNullPK is set to true before returning.
523 ** If an error occurs, an SQLite error code is returned and the final values
524 ** of *piHash asn *pbNullPK are undefined. Otherwise, SQLITE_OK is returned
525 ** and the output variables are set as described above.
527 static int sessionPreupdateHash(
528 sqlite3_session *pSession, /* Session object that owns pTab */
529 i64 iRowid,
530 SessionTable *pTab, /* Session table handle */
531 int bNew, /* True to hash the new.* PK */
532 int *piHash, /* OUT: Hash value */
533 int *pbNullPK /* OUT: True if there are NULL values in PK */
535 unsigned int h = 0; /* Hash value to return */
536 int i; /* Used to iterate through columns */
538 if( pTab->bRowid ){
539 assert( pTab->nCol-1==pSession->hook.xCount(pSession->hook.pCtx) );
540 h = sessionHashAppendI64(h, iRowid);
541 }else{
542 assert( *pbNullPK==0 );
543 assert( pTab->nCol==pSession->hook.xCount(pSession->hook.pCtx) );
544 for(i=0; i<pTab->nCol; i++){
545 if( pTab->abPK[i] ){
546 int rc;
547 int eType;
548 sqlite3_value *pVal;
550 if( bNew ){
551 rc = pSession->hook.xNew(pSession->hook.pCtx, i, &pVal);
552 }else{
553 rc = pSession->hook.xOld(pSession->hook.pCtx, i, &pVal);
555 if( rc!=SQLITE_OK ) return rc;
557 eType = sqlite3_value_type(pVal);
558 h = sessionHashAppendType(h, eType);
559 if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
560 i64 iVal;
561 if( eType==SQLITE_INTEGER ){
562 iVal = sqlite3_value_int64(pVal);
563 }else{
564 double rVal = sqlite3_value_double(pVal);
565 assert( sizeof(iVal)==8 && sizeof(rVal)==8 );
566 memcpy(&iVal, &rVal, 8);
568 h = sessionHashAppendI64(h, iVal);
569 }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
570 const u8 *z;
571 int n;
572 if( eType==SQLITE_TEXT ){
573 z = (const u8 *)sqlite3_value_text(pVal);
574 }else{
575 z = (const u8 *)sqlite3_value_blob(pVal);
577 n = sqlite3_value_bytes(pVal);
578 if( !z && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM;
579 h = sessionHashAppendBlob(h, n, z);
580 }else{
581 assert( eType==SQLITE_NULL );
582 assert( pTab->bStat1==0 || i!=1 );
583 *pbNullPK = 1;
589 *piHash = (h % pTab->nChange);
590 return SQLITE_OK;
594 ** The buffer that the argument points to contains a serialized SQL value.
595 ** Return the number of bytes of space occupied by the value (including
596 ** the type byte).
598 static int sessionSerialLen(const u8 *a){
599 int e = *a;
600 int n;
601 if( e==0 || e==0xFF ) return 1;
602 if( e==SQLITE_NULL ) return 1;
603 if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9;
604 return sessionVarintGet(&a[1], &n) + 1 + n;
608 ** Based on the primary key values stored in change aRecord, calculate a
609 ** hash key. Assume the has table has nBucket buckets. The hash keys
610 ** calculated by this function are compatible with those calculated by
611 ** sessionPreupdateHash().
613 ** The bPkOnly argument is non-zero if the record at aRecord[] is from
614 ** a patchset DELETE. In this case the non-PK fields are omitted entirely.
616 static unsigned int sessionChangeHash(
617 SessionTable *pTab, /* Table handle */
618 int bPkOnly, /* Record consists of PK fields only */
619 u8 *aRecord, /* Change record */
620 int nBucket /* Assume this many buckets in hash table */
622 unsigned int h = 0; /* Value to return */
623 int i; /* Used to iterate through columns */
624 u8 *a = aRecord; /* Used to iterate through change record */
626 for(i=0; i<pTab->nCol; i++){
627 int eType = *a;
628 int isPK = pTab->abPK[i];
629 if( bPkOnly && isPK==0 ) continue;
631 /* It is not possible for eType to be SQLITE_NULL here. The session
632 ** module does not record changes for rows with NULL values stored in
633 ** primary key columns. */
634 assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT
635 || eType==SQLITE_TEXT || eType==SQLITE_BLOB
636 || eType==SQLITE_NULL || eType==0
638 assert( !isPK || (eType!=0 && eType!=SQLITE_NULL) );
640 if( isPK ){
641 a++;
642 h = sessionHashAppendType(h, eType);
643 if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
644 h = sessionHashAppendI64(h, sessionGetI64(a));
645 a += 8;
646 }else{
647 int n;
648 a += sessionVarintGet(a, &n);
649 h = sessionHashAppendBlob(h, n, a);
650 a += n;
652 }else{
653 a += sessionSerialLen(a);
656 return (h % nBucket);
660 ** Arguments aLeft and aRight are pointers to change records for table pTab.
661 ** This function returns true if the two records apply to the same row (i.e.
662 ** have the same values stored in the primary key columns), or false
663 ** otherwise.
665 static int sessionChangeEqual(
666 SessionTable *pTab, /* Table used for PK definition */
667 int bLeftPkOnly, /* True if aLeft[] contains PK fields only */
668 u8 *aLeft, /* Change record */
669 int bRightPkOnly, /* True if aRight[] contains PK fields only */
670 u8 *aRight /* Change record */
672 u8 *a1 = aLeft; /* Cursor to iterate through aLeft */
673 u8 *a2 = aRight; /* Cursor to iterate through aRight */
674 int iCol; /* Used to iterate through table columns */
676 for(iCol=0; iCol<pTab->nCol; iCol++){
677 if( pTab->abPK[iCol] ){
678 int n1 = sessionSerialLen(a1);
679 int n2 = sessionSerialLen(a2);
681 if( n1!=n2 || memcmp(a1, a2, n1) ){
682 return 0;
684 a1 += n1;
685 a2 += n2;
686 }else{
687 if( bLeftPkOnly==0 ) a1 += sessionSerialLen(a1);
688 if( bRightPkOnly==0 ) a2 += sessionSerialLen(a2);
692 return 1;
696 ** Arguments aLeft and aRight both point to buffers containing change
697 ** records with nCol columns. This function "merges" the two records into
698 ** a single records which is written to the buffer at *paOut. *paOut is
699 ** then set to point to one byte after the last byte written before
700 ** returning.
702 ** The merging of records is done as follows: For each column, if the
703 ** aRight record contains a value for the column, copy the value from
704 ** their. Otherwise, if aLeft contains a value, copy it. If neither
705 ** record contains a value for a given column, then neither does the
706 ** output record.
708 static void sessionMergeRecord(
709 u8 **paOut,
710 int nCol,
711 u8 *aLeft,
712 u8 *aRight
714 u8 *a1 = aLeft; /* Cursor used to iterate through aLeft */
715 u8 *a2 = aRight; /* Cursor used to iterate through aRight */
716 u8 *aOut = *paOut; /* Output cursor */
717 int iCol; /* Used to iterate from 0 to nCol */
719 for(iCol=0; iCol<nCol; iCol++){
720 int n1 = sessionSerialLen(a1);
721 int n2 = sessionSerialLen(a2);
722 if( *a2 ){
723 memcpy(aOut, a2, n2);
724 aOut += n2;
725 }else{
726 memcpy(aOut, a1, n1);
727 aOut += n1;
729 a1 += n1;
730 a2 += n2;
733 *paOut = aOut;
737 ** This is a helper function used by sessionMergeUpdate().
739 ** When this function is called, both *paOne and *paTwo point to a value
740 ** within a change record. Before it returns, both have been advanced so
741 ** as to point to the next value in the record.
743 ** If, when this function is called, *paTwo points to a valid value (i.e.
744 ** *paTwo[0] is not 0x00 - the "no value" placeholder), a copy of the *paTwo
745 ** pointer is returned and *pnVal is set to the number of bytes in the
746 ** serialized value. Otherwise, a copy of *paOne is returned and *pnVal
747 ** set to the number of bytes in the value at *paOne. If *paOne points
748 ** to the "no value" placeholder, *pnVal is set to 1. In other words:
750 ** if( *paTwo is valid ) return *paTwo;
751 ** return *paOne;
754 static u8 *sessionMergeValue(
755 u8 **paOne, /* IN/OUT: Left-hand buffer pointer */
756 u8 **paTwo, /* IN/OUT: Right-hand buffer pointer */
757 int *pnVal /* OUT: Bytes in returned value */
759 u8 *a1 = *paOne;
760 u8 *a2 = *paTwo;
761 u8 *pRet = 0;
762 int n1;
764 assert( a1 );
765 if( a2 ){
766 int n2 = sessionSerialLen(a2);
767 if( *a2 ){
768 *pnVal = n2;
769 pRet = a2;
771 *paTwo = &a2[n2];
774 n1 = sessionSerialLen(a1);
775 if( pRet==0 ){
776 *pnVal = n1;
777 pRet = a1;
779 *paOne = &a1[n1];
781 return pRet;
785 ** This function is used by changeset_concat() to merge two UPDATE changes
786 ** on the same row.
788 static int sessionMergeUpdate(
789 u8 **paOut, /* IN/OUT: Pointer to output buffer */
790 SessionTable *pTab, /* Table change pertains to */
791 int bPatchset, /* True if records are patchset records */
792 u8 *aOldRecord1, /* old.* record for first change */
793 u8 *aOldRecord2, /* old.* record for second change */
794 u8 *aNewRecord1, /* new.* record for first change */
795 u8 *aNewRecord2 /* new.* record for second change */
797 u8 *aOld1 = aOldRecord1;
798 u8 *aOld2 = aOldRecord2;
799 u8 *aNew1 = aNewRecord1;
800 u8 *aNew2 = aNewRecord2;
802 u8 *aOut = *paOut;
803 int i;
805 if( bPatchset==0 ){
806 int bRequired = 0;
808 assert( aOldRecord1 && aNewRecord1 );
810 /* Write the old.* vector first. */
811 for(i=0; i<pTab->nCol; i++){
812 int nOld;
813 u8 *aOld;
814 int nNew;
815 u8 *aNew;
817 aOld = sessionMergeValue(&aOld1, &aOld2, &nOld);
818 aNew = sessionMergeValue(&aNew1, &aNew2, &nNew);
819 if( pTab->abPK[i] || nOld!=nNew || memcmp(aOld, aNew, nNew) ){
820 if( pTab->abPK[i]==0 ) bRequired = 1;
821 memcpy(aOut, aOld, nOld);
822 aOut += nOld;
823 }else{
824 *(aOut++) = '\0';
828 if( !bRequired ) return 0;
831 /* Write the new.* vector */
832 aOld1 = aOldRecord1;
833 aOld2 = aOldRecord2;
834 aNew1 = aNewRecord1;
835 aNew2 = aNewRecord2;
836 for(i=0; i<pTab->nCol; i++){
837 int nOld;
838 u8 *aOld;
839 int nNew;
840 u8 *aNew;
842 aOld = sessionMergeValue(&aOld1, &aOld2, &nOld);
843 aNew = sessionMergeValue(&aNew1, &aNew2, &nNew);
844 if( bPatchset==0
845 && (pTab->abPK[i] || (nOld==nNew && 0==memcmp(aOld, aNew, nNew)))
847 *(aOut++) = '\0';
848 }else{
849 memcpy(aOut, aNew, nNew);
850 aOut += nNew;
854 *paOut = aOut;
855 return 1;
859 ** This function is only called from within a pre-update-hook callback.
860 ** It determines if the current pre-update-hook change affects the same row
861 ** as the change stored in argument pChange. If so, it returns true. Otherwise
862 ** if the pre-update-hook does not affect the same row as pChange, it returns
863 ** false.
865 static int sessionPreupdateEqual(
866 sqlite3_session *pSession, /* Session object that owns SessionTable */
867 i64 iRowid, /* Rowid value if pTab->bRowid */
868 SessionTable *pTab, /* Table associated with change */
869 SessionChange *pChange, /* Change to compare to */
870 int op /* Current pre-update operation */
872 int iCol; /* Used to iterate through columns */
873 u8 *a = pChange->aRecord; /* Cursor used to scan change record */
875 if( pTab->bRowid ){
876 if( a[0]!=SQLITE_INTEGER ) return 0;
877 return sessionGetI64(&a[1])==iRowid;
880 assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
881 for(iCol=0; iCol<pTab->nCol; iCol++){
882 if( !pTab->abPK[iCol] ){
883 a += sessionSerialLen(a);
884 }else{
885 sqlite3_value *pVal; /* Value returned by preupdate_new/old */
886 int rc; /* Error code from preupdate_new/old */
887 int eType = *a++; /* Type of value from change record */
889 /* The following calls to preupdate_new() and preupdate_old() can not
890 ** fail. This is because they cache their return values, and by the
891 ** time control flows to here they have already been called once from
892 ** within sessionPreupdateHash(). The first two asserts below verify
893 ** this (that the method has already been called). */
894 if( op==SQLITE_INSERT ){
895 /* assert( db->pPreUpdate->pNewUnpacked || db->pPreUpdate->aNew ); */
896 rc = pSession->hook.xNew(pSession->hook.pCtx, iCol, &pVal);
897 }else{
898 /* assert( db->pPreUpdate->pUnpacked ); */
899 rc = pSession->hook.xOld(pSession->hook.pCtx, iCol, &pVal);
901 assert( rc==SQLITE_OK );
902 (void)rc; /* Suppress warning about unused variable */
903 if( sqlite3_value_type(pVal)!=eType ) return 0;
905 /* A SessionChange object never has a NULL value in a PK column */
906 assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT
907 || eType==SQLITE_BLOB || eType==SQLITE_TEXT
910 if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
911 i64 iVal = sessionGetI64(a);
912 a += 8;
913 if( eType==SQLITE_INTEGER ){
914 if( sqlite3_value_int64(pVal)!=iVal ) return 0;
915 }else{
916 double rVal;
917 assert( sizeof(iVal)==8 && sizeof(rVal)==8 );
918 memcpy(&rVal, &iVal, 8);
919 if( sqlite3_value_double(pVal)!=rVal ) return 0;
921 }else{
922 int n;
923 const u8 *z;
924 a += sessionVarintGet(a, &n);
925 if( sqlite3_value_bytes(pVal)!=n ) return 0;
926 if( eType==SQLITE_TEXT ){
927 z = sqlite3_value_text(pVal);
928 }else{
929 z = sqlite3_value_blob(pVal);
931 if( n>0 && memcmp(a, z, n) ) return 0;
932 a += n;
937 return 1;
941 ** If required, grow the hash table used to store changes on table pTab
942 ** (part of the session pSession). If a fatal OOM error occurs, set the
943 ** session object to failed and return SQLITE_ERROR. Otherwise, return
944 ** SQLITE_OK.
946 ** It is possible that a non-fatal OOM error occurs in this function. In
947 ** that case the hash-table does not grow, but SQLITE_OK is returned anyway.
948 ** Growing the hash table in this case is a performance optimization only,
949 ** it is not required for correct operation.
951 static int sessionGrowHash(
952 sqlite3_session *pSession, /* For memory accounting. May be NULL */
953 int bPatchset,
954 SessionTable *pTab
956 if( pTab->nChange==0 || pTab->nEntry>=(pTab->nChange/2) ){
957 int i;
958 SessionChange **apNew;
959 sqlite3_int64 nNew = 2*(sqlite3_int64)(pTab->nChange ? pTab->nChange : 128);
961 apNew = (SessionChange**)sessionMalloc64(
962 pSession, sizeof(SessionChange*) * nNew
964 if( apNew==0 ){
965 if( pTab->nChange==0 ){
966 return SQLITE_ERROR;
968 return SQLITE_OK;
970 memset(apNew, 0, sizeof(SessionChange *) * nNew);
972 for(i=0; i<pTab->nChange; i++){
973 SessionChange *p;
974 SessionChange *pNext;
975 for(p=pTab->apChange[i]; p; p=pNext){
976 int bPkOnly = (p->op==SQLITE_DELETE && bPatchset);
977 int iHash = sessionChangeHash(pTab, bPkOnly, p->aRecord, nNew);
978 pNext = p->pNext;
979 p->pNext = apNew[iHash];
980 apNew[iHash] = p;
984 sessionFree(pSession, pTab->apChange);
985 pTab->nChange = nNew;
986 pTab->apChange = apNew;
989 return SQLITE_OK;
993 ** This function queries the database for the names of the columns of table
994 ** zThis, in schema zDb.
996 ** Otherwise, if they are not NULL, variable *pnCol is set to the number
997 ** of columns in the database table and variable *pzTab is set to point to a
998 ** nul-terminated copy of the table name. *pazCol (if not NULL) is set to
999 ** point to an array of pointers to column names. And *pabPK (again, if not
1000 ** NULL) is set to point to an array of booleans - true if the corresponding
1001 ** column is part of the primary key.
1003 ** For example, if the table is declared as:
1005 ** CREATE TABLE tbl1(w, x, y, z, PRIMARY KEY(w, z));
1007 ** Then the four output variables are populated as follows:
1009 ** *pnCol = 4
1010 ** *pzTab = "tbl1"
1011 ** *pazCol = {"w", "x", "y", "z"}
1012 ** *pabPK = {1, 0, 0, 1}
1014 ** All returned buffers are part of the same single allocation, which must
1015 ** be freed using sqlite3_free() by the caller
1017 static int sessionTableInfo(
1018 sqlite3_session *pSession, /* For memory accounting. May be NULL */
1019 sqlite3 *db, /* Database connection */
1020 const char *zDb, /* Name of attached database (e.g. "main") */
1021 const char *zThis, /* Table name */
1022 int *pnCol, /* OUT: number of columns */
1023 const char **pzTab, /* OUT: Copy of zThis */
1024 const char ***pazCol, /* OUT: Array of column names for table */
1025 const char ***pazDflt, /* OUT: Array of default value expressions */
1026 u8 **pabPK, /* OUT: Array of booleans - true for PK col */
1027 int *pbRowid /* OUT: True if only PK is a rowid */
1029 char *zPragma;
1030 sqlite3_stmt *pStmt;
1031 int rc;
1032 sqlite3_int64 nByte;
1033 int nDbCol = 0;
1034 int nThis;
1035 int i;
1036 u8 *pAlloc = 0;
1037 char **azCol = 0;
1038 char **azDflt = 0;
1039 u8 *abPK = 0;
1040 int bRowid = 0; /* Set to true to use rowid as PK */
1042 assert( pazCol && pabPK );
1044 *pazCol = 0;
1045 *pabPK = 0;
1046 *pnCol = 0;
1047 if( pzTab ) *pzTab = 0;
1048 if( pazDflt ) *pazDflt = 0;
1050 nThis = sqlite3Strlen30(zThis);
1051 if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){
1052 rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0);
1053 if( rc==SQLITE_OK ){
1054 /* For sqlite_stat1, pretend that (tbl,idx) is the PRIMARY KEY. */
1055 zPragma = sqlite3_mprintf(
1056 "SELECT 0, 'tbl', '', 0, '', 1 UNION ALL "
1057 "SELECT 1, 'idx', '', 0, '', 2 UNION ALL "
1058 "SELECT 2, 'stat', '', 0, '', 0"
1060 }else if( rc==SQLITE_ERROR ){
1061 zPragma = sqlite3_mprintf("");
1062 }else{
1063 return rc;
1065 }else{
1066 zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
1068 if( !zPragma ){
1069 return SQLITE_NOMEM;
1072 rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0);
1073 sqlite3_free(zPragma);
1074 if( rc!=SQLITE_OK ){
1075 return rc;
1078 nByte = nThis + 1;
1079 bRowid = (pbRowid!=0);
1080 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1081 nByte += sqlite3_column_bytes(pStmt, 1); /* name */
1082 nByte += sqlite3_column_bytes(pStmt, 4); /* dflt_value */
1083 nDbCol++;
1084 if( sqlite3_column_int(pStmt, 5) ) bRowid = 0; /* pk */
1086 if( nDbCol==0 ) bRowid = 0;
1087 nDbCol += bRowid;
1088 nByte += strlen(SESSIONS_ROWID);
1089 rc = sqlite3_reset(pStmt);
1091 if( rc==SQLITE_OK ){
1092 nByte += nDbCol * (sizeof(const char *)*2 + sizeof(u8) + 1 + 1);
1093 pAlloc = sessionMalloc64(pSession, nByte);
1094 if( pAlloc==0 ){
1095 rc = SQLITE_NOMEM;
1098 if( rc==SQLITE_OK ){
1099 azCol = (char **)pAlloc;
1100 azDflt = (char**)&azCol[nDbCol];
1101 pAlloc = (u8 *)&azDflt[nDbCol];
1102 abPK = (u8 *)pAlloc;
1103 pAlloc = &abPK[nDbCol];
1104 if( pzTab ){
1105 memcpy(pAlloc, zThis, nThis+1);
1106 *pzTab = (char *)pAlloc;
1107 pAlloc += nThis+1;
1110 i = 0;
1111 if( bRowid ){
1112 size_t nName = strlen(SESSIONS_ROWID);
1113 memcpy(pAlloc, SESSIONS_ROWID, nName+1);
1114 azCol[i] = (char*)pAlloc;
1115 pAlloc += nName+1;
1116 abPK[i] = 1;
1117 i++;
1119 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1120 int nName = sqlite3_column_bytes(pStmt, 1);
1121 int nDflt = sqlite3_column_bytes(pStmt, 4);
1122 const unsigned char *zName = sqlite3_column_text(pStmt, 1);
1123 const unsigned char *zDflt = sqlite3_column_text(pStmt, 4);
1125 if( zName==0 ) break;
1126 memcpy(pAlloc, zName, nName+1);
1127 azCol[i] = (char *)pAlloc;
1128 pAlloc += nName+1;
1129 if( zDflt ){
1130 memcpy(pAlloc, zDflt, nDflt+1);
1131 azDflt[i] = (char *)pAlloc;
1132 pAlloc += nDflt+1;
1133 }else{
1134 azDflt[i] = 0;
1136 abPK[i] = sqlite3_column_int(pStmt, 5);
1137 i++;
1139 rc = sqlite3_reset(pStmt);
1142 /* If successful, populate the output variables. Otherwise, zero them and
1143 ** free any allocation made. An error code will be returned in this case.
1145 if( rc==SQLITE_OK ){
1146 *pazCol = (const char**)azCol;
1147 if( pazDflt ) *pazDflt = (const char**)azDflt;
1148 *pabPK = abPK;
1149 *pnCol = nDbCol;
1150 }else{
1151 sessionFree(pSession, azCol);
1153 if( pbRowid ) *pbRowid = bRowid;
1154 sqlite3_finalize(pStmt);
1155 return rc;
1159 ** This function is only called from within a pre-update handler for a
1160 ** write to table pTab, part of session pSession. If this is the first
1161 ** write to this table, initalize the SessionTable.nCol, azCol[] and
1162 ** abPK[] arrays accordingly.
1164 ** If an error occurs, an error code is stored in sqlite3_session.rc and
1165 ** non-zero returned. Or, if no error occurs but the table has no primary
1166 ** key, sqlite3_session.rc is left set to SQLITE_OK and non-zero returned to
1167 ** indicate that updates on this table should be ignored. SessionTable.abPK
1168 ** is set to NULL in this case.
1170 static int sessionInitTable(
1171 sqlite3_session *pSession,
1172 SessionTable *pTab,
1173 sqlite3 *db,
1174 const char *zDb
1176 int rc = SQLITE_OK;
1178 if( pTab->nCol==0 ){
1179 u8 *abPK;
1180 assert( pTab->azCol==0 || pTab->abPK==0 );
1181 rc = sessionTableInfo(pSession, db, zDb,
1182 pTab->zName, &pTab->nCol, 0, &pTab->azCol, &pTab->azDflt, &abPK,
1183 ((pSession==0 || pSession->bImplicitPK) ? &pTab->bRowid : 0)
1185 if( rc==SQLITE_OK ){
1186 int i;
1187 for(i=0; i<pTab->nCol; i++){
1188 if( abPK[i] ){
1189 pTab->abPK = abPK;
1190 break;
1193 if( 0==sqlite3_stricmp("sqlite_stat1", pTab->zName) ){
1194 pTab->bStat1 = 1;
1197 if( pSession && pSession->bEnableSize ){
1198 pSession->nMaxChangesetSize += (
1199 1 + sessionVarintLen(pTab->nCol) + pTab->nCol + strlen(pTab->zName)+1
1205 if( pSession ){
1206 pSession->rc = rc;
1207 return (rc || pTab->abPK==0);
1209 return rc;
1212 static int sessionReinitTable(sqlite3_session *pSession, SessionTable *pTab){
1213 int nCol = 0;
1214 const char **azCol = 0;
1215 const char **azDflt = 0;
1216 u8 *abPK = 0;
1217 int bRowid = 0;
1219 assert( pSession->rc==SQLITE_OK );
1221 pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb,
1222 pTab->zName, &nCol, 0, &azCol, &azDflt, &abPK,
1223 (pSession->bImplicitPK ? &bRowid : 0)
1225 if( pSession->rc==SQLITE_OK ){
1226 if( pTab->nCol>nCol || pTab->bRowid!=bRowid ){
1227 pSession->rc = SQLITE_SCHEMA;
1228 }else{
1229 int ii;
1230 int nOldCol = pTab->nCol;
1231 for(ii=0; ii<nCol; ii++){
1232 if( ii<pTab->nCol ){
1233 if( pTab->abPK[ii]!=abPK[ii] ){
1234 pSession->rc = SQLITE_SCHEMA;
1236 }else if( abPK[ii] ){
1237 pSession->rc = SQLITE_SCHEMA;
1241 if( pSession->rc==SQLITE_OK ){
1242 const char **a = pTab->azCol;
1243 pTab->azCol = azCol;
1244 pTab->nCol = nCol;
1245 pTab->azDflt = azDflt;
1246 pTab->abPK = abPK;
1247 azCol = a;
1249 if( pSession->bEnableSize ){
1250 pSession->nMaxChangesetSize += (nCol - nOldCol);
1251 pSession->nMaxChangesetSize += sessionVarintLen(nCol);
1252 pSession->nMaxChangesetSize -= sessionVarintLen(nOldCol);
1257 sqlite3_free(azCol);
1258 return pSession->rc;
1261 static void sessionUpdateOneChange(
1262 sqlite3_session *pSession,
1263 int *pRc,
1264 SessionChange **pp,
1265 int nCol,
1266 sqlite3_stmt *pDflt
1268 SessionChange *pOld = *pp;
1270 while( pOld->nRecordField<nCol ){
1271 SessionChange *pNew = 0;
1272 int nByte = 0;
1273 int nIncr = 0;
1274 int iField = pOld->nRecordField;
1275 int eType = sqlite3_column_type(pDflt, iField);
1276 switch( eType ){
1277 case SQLITE_NULL:
1278 nIncr = 1;
1279 break;
1280 case SQLITE_INTEGER:
1281 case SQLITE_FLOAT:
1282 nIncr = 9;
1283 break;
1284 default: {
1285 int n = sqlite3_column_bytes(pDflt, iField);
1286 nIncr = 1 + sessionVarintLen(n) + n;
1287 assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
1288 break;
1292 nByte = nIncr + (sizeof(SessionChange) + pOld->nRecord);
1293 pNew = sessionMalloc64(pSession, nByte);
1294 if( pNew==0 ){
1295 *pRc = SQLITE_NOMEM;
1296 return;
1297 }else{
1298 memcpy(pNew, pOld, sizeof(SessionChange));
1299 pNew->aRecord = (u8*)&pNew[1];
1300 memcpy(pNew->aRecord, pOld->aRecord, pOld->nRecord);
1301 pNew->aRecord[pNew->nRecord++] = (u8)eType;
1302 switch( eType ){
1303 case SQLITE_INTEGER: {
1304 i64 iVal = sqlite3_column_int64(pDflt, iField);
1305 sessionPutI64(&pNew->aRecord[pNew->nRecord], iVal);
1306 pNew->nRecord += 8;
1307 break;
1310 case SQLITE_FLOAT: {
1311 double rVal = sqlite3_column_double(pDflt, iField);
1312 i64 iVal = 0;
1313 memcpy(&iVal, &rVal, sizeof(rVal));
1314 sessionPutI64(&pNew->aRecord[pNew->nRecord], iVal);
1315 pNew->nRecord += 8;
1316 break;
1319 case SQLITE_TEXT: {
1320 int n = sqlite3_column_bytes(pDflt, iField);
1321 const char *z = (const char*)sqlite3_column_text(pDflt, iField);
1322 pNew->nRecord += sessionVarintPut(&pNew->aRecord[pNew->nRecord], n);
1323 memcpy(&pNew->aRecord[pNew->nRecord], z, n);
1324 pNew->nRecord += n;
1325 break;
1328 case SQLITE_BLOB: {
1329 int n = sqlite3_column_bytes(pDflt, iField);
1330 const u8 *z = (const u8*)sqlite3_column_blob(pDflt, iField);
1331 pNew->nRecord += sessionVarintPut(&pNew->aRecord[pNew->nRecord], n);
1332 memcpy(&pNew->aRecord[pNew->nRecord], z, n);
1333 pNew->nRecord += n;
1334 break;
1337 default:
1338 assert( eType==SQLITE_NULL );
1339 break;
1342 sessionFree(pSession, pOld);
1343 *pp = pOld = pNew;
1344 pNew->nRecordField++;
1345 pNew->nMaxSize += nIncr;
1346 if( pSession ){
1347 pSession->nMaxChangesetSize += nIncr;
1354 ** Ensure that there is room in the buffer to append nByte bytes of data.
1355 ** If not, use sqlite3_realloc() to grow the buffer so that there is.
1357 ** If successful, return zero. Otherwise, if an OOM condition is encountered,
1358 ** set *pRc to SQLITE_NOMEM and return non-zero.
1360 static int sessionBufferGrow(SessionBuffer *p, i64 nByte, int *pRc){
1361 #define SESSION_MAX_BUFFER_SZ (0x7FFFFF00 - 1)
1362 i64 nReq = p->nBuf + nByte;
1363 if( *pRc==SQLITE_OK && nReq>p->nAlloc ){
1364 u8 *aNew;
1365 i64 nNew = p->nAlloc ? p->nAlloc : 128;
1367 do {
1368 nNew = nNew*2;
1369 }while( nNew<nReq );
1371 /* The value of SESSION_MAX_BUFFER_SZ is copied from the implementation
1372 ** of sqlite3_realloc64(). Allocations greater than this size in bytes
1373 ** always fail. It is used here to ensure that this routine can always
1374 ** allocate up to this limit - instead of up to the largest power of
1375 ** two smaller than the limit. */
1376 if( nNew>SESSION_MAX_BUFFER_SZ ){
1377 nNew = SESSION_MAX_BUFFER_SZ;
1378 if( nNew<nReq ){
1379 *pRc = SQLITE_NOMEM;
1380 return 1;
1384 aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew);
1385 if( 0==aNew ){
1386 *pRc = SQLITE_NOMEM;
1387 }else{
1388 p->aBuf = aNew;
1389 p->nAlloc = nNew;
1392 return (*pRc!=SQLITE_OK);
1397 ** This function is a no-op if *pRc is other than SQLITE_OK when it is
1398 ** called. Otherwise, append a string to the buffer. All bytes in the string
1399 ** up to (but not including) the nul-terminator are written to the buffer.
1401 ** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
1402 ** returning.
1404 static void sessionAppendStr(
1405 SessionBuffer *p,
1406 const char *zStr,
1407 int *pRc
1409 int nStr = sqlite3Strlen30(zStr);
1410 if( 0==sessionBufferGrow(p, nStr+1, pRc) ){
1411 memcpy(&p->aBuf[p->nBuf], zStr, nStr);
1412 p->nBuf += nStr;
1413 p->aBuf[p->nBuf] = 0x00;
1417 static void sessionAppendPrintf(
1418 SessionBuffer *p, /* Buffer to append to */
1419 int *pRc,
1420 const char *zFmt,
1423 if( *pRc==SQLITE_OK ){
1424 char *zApp = 0;
1425 va_list ap;
1426 va_start(ap, zFmt);
1427 zApp = sqlite3_vmprintf(zFmt, ap);
1428 if( zApp==0 ){
1429 *pRc = SQLITE_NOMEM;
1430 }else{
1431 sessionAppendStr(p, zApp, pRc);
1433 va_end(ap);
1434 sqlite3_free(zApp);
1439 ** Prepare a statement against database handle db that SELECTs a single
1440 ** row containing the default values for each column in table pTab. For
1441 ** example, if pTab is declared as:
1443 ** CREATE TABLE pTab(a PRIMARY KEY, b DEFAULT 123, c DEFAULT 'abcd');
1445 ** Then this function prepares and returns the SQL statement:
1447 ** SELECT NULL, 123, 'abcd';
1449 static int sessionPrepareDfltStmt(
1450 sqlite3 *db, /* Database handle */
1451 SessionTable *pTab, /* Table to prepare statement for */
1452 sqlite3_stmt **ppStmt /* OUT: Statement handle */
1454 SessionBuffer sql = {0,0,0};
1455 int rc = SQLITE_OK;
1456 const char *zSep = " ";
1457 int ii = 0;
1459 *ppStmt = 0;
1460 sessionAppendPrintf(&sql, &rc, "SELECT");
1461 for(ii=0; ii<pTab->nCol; ii++){
1462 const char *zDflt = pTab->azDflt[ii] ? pTab->azDflt[ii] : "NULL";
1463 sessionAppendPrintf(&sql, &rc, "%s%s", zSep, zDflt);
1464 zSep = ", ";
1466 if( rc==SQLITE_OK ){
1467 rc = sqlite3_prepare_v2(db, (const char*)sql.aBuf, -1, ppStmt, 0);
1469 sqlite3_free(sql.aBuf);
1471 return rc;
1474 static int sessionUpdateChanges(sqlite3_session *pSession, SessionTable *pTab){
1475 sqlite3 *db = pSession->db;
1476 sqlite3_stmt *pStmt = 0;
1477 int ii = 0;
1478 int rc = pSession->rc;
1480 rc = sessionPrepareDfltStmt(pSession->db, pTab, &pStmt);
1481 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
1482 int ii = 0;
1483 SessionChange **pp = 0;
1484 for(ii=0; ii<pTab->nChange; ii++){
1485 for(pp=&pTab->apChange[ii]; *pp; pp=&((*pp)->pNext)){
1486 if( (*pp)->nRecordField!=pTab->nCol ){
1487 sessionUpdateOneChange(pSession, &rc, pp, pTab->nCol, pStmt);
1493 pSession->rc = rc;
1494 rc = sqlite3_finalize(pStmt);
1495 if( pSession->rc==SQLITE_OK ) pSession->rc = rc;
1496 return pSession->rc;
1500 ** Versions of the four methods in object SessionHook for use with the
1501 ** sqlite_stat1 table. The purpose of this is to substitute a zero-length
1502 ** blob each time a NULL value is read from the "idx" column of the
1503 ** sqlite_stat1 table.
1505 typedef struct SessionStat1Ctx SessionStat1Ctx;
1506 struct SessionStat1Ctx {
1507 SessionHook hook;
1508 sqlite3_session *pSession;
1510 static int sessionStat1Old(void *pCtx, int iCol, sqlite3_value **ppVal){
1511 SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
1512 sqlite3_value *pVal = 0;
1513 int rc = p->hook.xOld(p->hook.pCtx, iCol, &pVal);
1514 if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){
1515 pVal = p->pSession->pZeroBlob;
1517 *ppVal = pVal;
1518 return rc;
1520 static int sessionStat1New(void *pCtx, int iCol, sqlite3_value **ppVal){
1521 SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
1522 sqlite3_value *pVal = 0;
1523 int rc = p->hook.xNew(p->hook.pCtx, iCol, &pVal);
1524 if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){
1525 pVal = p->pSession->pZeroBlob;
1527 *ppVal = pVal;
1528 return rc;
1530 static int sessionStat1Count(void *pCtx){
1531 SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
1532 return p->hook.xCount(p->hook.pCtx);
1534 static int sessionStat1Depth(void *pCtx){
1535 SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
1536 return p->hook.xDepth(p->hook.pCtx);
1539 static int sessionUpdateMaxSize(
1540 int op,
1541 sqlite3_session *pSession, /* Session object pTab is attached to */
1542 SessionTable *pTab, /* Table that change applies to */
1543 SessionChange *pC /* Update pC->nMaxSize */
1545 i64 nNew = 2;
1546 if( pC->op==SQLITE_INSERT ){
1547 if( pTab->bRowid ) nNew += 9;
1548 if( op!=SQLITE_DELETE ){
1549 int ii;
1550 for(ii=0; ii<pTab->nCol; ii++){
1551 sqlite3_value *p = 0;
1552 pSession->hook.xNew(pSession->hook.pCtx, ii, &p);
1553 sessionSerializeValue(0, p, &nNew);
1556 }else if( op==SQLITE_DELETE ){
1557 nNew += pC->nRecord;
1558 if( sqlite3_preupdate_blobwrite(pSession->db)>=0 ){
1559 nNew += pC->nRecord;
1561 }else{
1562 int ii;
1563 u8 *pCsr = pC->aRecord;
1564 if( pTab->bRowid ){
1565 nNew += 9 + 1;
1566 pCsr += 9;
1568 for(ii=pTab->bRowid; ii<pTab->nCol; ii++){
1569 int bChanged = 1;
1570 int nOld = 0;
1571 int eType;
1572 sqlite3_value *p = 0;
1573 pSession->hook.xNew(pSession->hook.pCtx, ii-pTab->bRowid, &p);
1574 if( p==0 ){
1575 return SQLITE_NOMEM;
1578 eType = *pCsr++;
1579 switch( eType ){
1580 case SQLITE_NULL:
1581 bChanged = sqlite3_value_type(p)!=SQLITE_NULL;
1582 break;
1584 case SQLITE_FLOAT:
1585 case SQLITE_INTEGER: {
1586 if( eType==sqlite3_value_type(p) ){
1587 sqlite3_int64 iVal = sessionGetI64(pCsr);
1588 if( eType==SQLITE_INTEGER ){
1589 bChanged = (iVal!=sqlite3_value_int64(p));
1590 }else{
1591 double dVal;
1592 memcpy(&dVal, &iVal, 8);
1593 bChanged = (dVal!=sqlite3_value_double(p));
1596 nOld = 8;
1597 pCsr += 8;
1598 break;
1601 default: {
1602 int nByte;
1603 nOld = sessionVarintGet(pCsr, &nByte);
1604 pCsr += nOld;
1605 nOld += nByte;
1606 assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
1607 if( eType==sqlite3_value_type(p)
1608 && nByte==sqlite3_value_bytes(p)
1609 && (nByte==0 || 0==memcmp(pCsr, sqlite3_value_blob(p), nByte))
1611 bChanged = 0;
1613 pCsr += nByte;
1614 break;
1618 if( bChanged && pTab->abPK[ii] ){
1619 nNew = pC->nRecord + 2;
1620 break;
1623 if( bChanged ){
1624 nNew += 1 + nOld;
1625 sessionSerializeValue(0, p, &nNew);
1626 }else if( pTab->abPK[ii] ){
1627 nNew += 2 + nOld;
1628 }else{
1629 nNew += 2;
1634 if( nNew>pC->nMaxSize ){
1635 int nIncr = nNew - pC->nMaxSize;
1636 pC->nMaxSize = nNew;
1637 pSession->nMaxChangesetSize += nIncr;
1639 return SQLITE_OK;
1643 ** This function is only called from with a pre-update-hook reporting a
1644 ** change on table pTab (attached to session pSession). The type of change
1645 ** (UPDATE, INSERT, DELETE) is specified by the first argument.
1647 ** Unless one is already present or an error occurs, an entry is added
1648 ** to the changed-rows hash table associated with table pTab.
1650 static void sessionPreupdateOneChange(
1651 int op, /* One of SQLITE_UPDATE, INSERT, DELETE */
1652 i64 iRowid,
1653 sqlite3_session *pSession, /* Session object pTab is attached to */
1654 SessionTable *pTab /* Table that change applies to */
1656 int iHash;
1657 int bNull = 0;
1658 int rc = SQLITE_OK;
1659 int nExpect = 0;
1660 SessionStat1Ctx stat1 = {{0,0,0,0,0},0};
1662 if( pSession->rc ) return;
1664 /* Load table details if required */
1665 if( sessionInitTable(pSession, pTab, pSession->db, pSession->zDb) ) return;
1667 /* Check the number of columns in this xPreUpdate call matches the
1668 ** number of columns in the table. */
1669 nExpect = pSession->hook.xCount(pSession->hook.pCtx);
1670 if( (pTab->nCol-pTab->bRowid)<nExpect ){
1671 if( sessionReinitTable(pSession, pTab) ) return;
1672 if( sessionUpdateChanges(pSession, pTab) ) return;
1674 if( (pTab->nCol-pTab->bRowid)!=nExpect ){
1675 pSession->rc = SQLITE_SCHEMA;
1676 return;
1679 /* Grow the hash table if required */
1680 if( sessionGrowHash(pSession, 0, pTab) ){
1681 pSession->rc = SQLITE_NOMEM;
1682 return;
1685 if( pTab->bStat1 ){
1686 stat1.hook = pSession->hook;
1687 stat1.pSession = pSession;
1688 pSession->hook.pCtx = (void*)&stat1;
1689 pSession->hook.xNew = sessionStat1New;
1690 pSession->hook.xOld = sessionStat1Old;
1691 pSession->hook.xCount = sessionStat1Count;
1692 pSession->hook.xDepth = sessionStat1Depth;
1693 if( pSession->pZeroBlob==0 ){
1694 sqlite3_value *p = sqlite3ValueNew(0);
1695 if( p==0 ){
1696 rc = SQLITE_NOMEM;
1697 goto error_out;
1699 sqlite3ValueSetStr(p, 0, "", 0, SQLITE_STATIC);
1700 pSession->pZeroBlob = p;
1704 /* Calculate the hash-key for this change. If the primary key of the row
1705 ** includes a NULL value, exit early. Such changes are ignored by the
1706 ** session module. */
1707 rc = sessionPreupdateHash(
1708 pSession, iRowid, pTab, op==SQLITE_INSERT, &iHash, &bNull
1710 if( rc!=SQLITE_OK ) goto error_out;
1712 if( bNull==0 ){
1713 /* Search the hash table for an existing record for this row. */
1714 SessionChange *pC;
1715 for(pC=pTab->apChange[iHash]; pC; pC=pC->pNext){
1716 if( sessionPreupdateEqual(pSession, iRowid, pTab, pC, op) ) break;
1719 if( pC==0 ){
1720 /* Create a new change object containing all the old values (if
1721 ** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK
1722 ** values (if this is an INSERT). */
1723 sqlite3_int64 nByte; /* Number of bytes to allocate */
1724 int i; /* Used to iterate through columns */
1726 assert( rc==SQLITE_OK );
1727 pTab->nEntry++;
1729 /* Figure out how large an allocation is required */
1730 nByte = sizeof(SessionChange);
1731 for(i=0; i<(pTab->nCol-pTab->bRowid); i++){
1732 sqlite3_value *p = 0;
1733 if( op!=SQLITE_INSERT ){
1734 TESTONLY(int trc = ) pSession->hook.xOld(pSession->hook.pCtx, i, &p);
1735 assert( trc==SQLITE_OK );
1736 }else if( pTab->abPK[i] ){
1737 TESTONLY(int trc = ) pSession->hook.xNew(pSession->hook.pCtx, i, &p);
1738 assert( trc==SQLITE_OK );
1741 /* This may fail if SQLite value p contains a utf-16 string that must
1742 ** be converted to utf-8 and an OOM error occurs while doing so. */
1743 rc = sessionSerializeValue(0, p, &nByte);
1744 if( rc!=SQLITE_OK ) goto error_out;
1746 if( pTab->bRowid ){
1747 nByte += 9; /* Size of rowid field - an integer */
1750 /* Allocate the change object */
1751 pC = (SessionChange*)sessionMalloc64(pSession, nByte);
1752 if( !pC ){
1753 rc = SQLITE_NOMEM;
1754 goto error_out;
1755 }else{
1756 memset(pC, 0, sizeof(SessionChange));
1757 pC->aRecord = (u8 *)&pC[1];
1760 /* Populate the change object. None of the preupdate_old(),
1761 ** preupdate_new() or SerializeValue() calls below may fail as all
1762 ** required values and encodings have already been cached in memory.
1763 ** It is not possible for an OOM to occur in this block. */
1764 nByte = 0;
1765 if( pTab->bRowid ){
1766 pC->aRecord[0] = SQLITE_INTEGER;
1767 sessionPutI64(&pC->aRecord[1], iRowid);
1768 nByte = 9;
1770 for(i=0; i<(pTab->nCol-pTab->bRowid); i++){
1771 sqlite3_value *p = 0;
1772 if( op!=SQLITE_INSERT ){
1773 pSession->hook.xOld(pSession->hook.pCtx, i, &p);
1774 }else if( pTab->abPK[i] ){
1775 pSession->hook.xNew(pSession->hook.pCtx, i, &p);
1777 sessionSerializeValue(&pC->aRecord[nByte], p, &nByte);
1780 /* Add the change to the hash-table */
1781 if( pSession->bIndirect || pSession->hook.xDepth(pSession->hook.pCtx) ){
1782 pC->bIndirect = 1;
1784 pC->nRecordField = pTab->nCol;
1785 pC->nRecord = nByte;
1786 pC->op = op;
1787 pC->pNext = pTab->apChange[iHash];
1788 pTab->apChange[iHash] = pC;
1790 }else if( pC->bIndirect ){
1791 /* If the existing change is considered "indirect", but this current
1792 ** change is "direct", mark the change object as direct. */
1793 if( pSession->hook.xDepth(pSession->hook.pCtx)==0
1794 && pSession->bIndirect==0
1796 pC->bIndirect = 0;
1800 assert( rc==SQLITE_OK );
1801 if( pSession->bEnableSize ){
1802 rc = sessionUpdateMaxSize(op, pSession, pTab, pC);
1807 /* If an error has occurred, mark the session object as failed. */
1808 error_out:
1809 if( pTab->bStat1 ){
1810 pSession->hook = stat1.hook;
1812 if( rc!=SQLITE_OK ){
1813 pSession->rc = rc;
1817 static int sessionFindTable(
1818 sqlite3_session *pSession,
1819 const char *zName,
1820 SessionTable **ppTab
1822 int rc = SQLITE_OK;
1823 int nName = sqlite3Strlen30(zName);
1824 SessionTable *pRet;
1826 /* Search for an existing table */
1827 for(pRet=pSession->pTable; pRet; pRet=pRet->pNext){
1828 if( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) ) break;
1831 if( pRet==0 && pSession->bAutoAttach ){
1832 /* If there is a table-filter configured, invoke it. If it returns 0,
1833 ** do not automatically add the new table. */
1834 if( pSession->xTableFilter==0
1835 || pSession->xTableFilter(pSession->pFilterCtx, zName)
1837 rc = sqlite3session_attach(pSession, zName);
1838 if( rc==SQLITE_OK ){
1839 pRet = pSession->pTable;
1840 while( ALWAYS(pRet) && pRet->pNext ){
1841 pRet = pRet->pNext;
1843 assert( pRet!=0 );
1844 assert( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) );
1849 assert( rc==SQLITE_OK || pRet==0 );
1850 *ppTab = pRet;
1851 return rc;
1855 ** The 'pre-update' hook registered by this module with SQLite databases.
1857 static void xPreUpdate(
1858 void *pCtx, /* Copy of third arg to preupdate_hook() */
1859 sqlite3 *db, /* Database handle */
1860 int op, /* SQLITE_UPDATE, DELETE or INSERT */
1861 char const *zDb, /* Database name */
1862 char const *zName, /* Table name */
1863 sqlite3_int64 iKey1, /* Rowid of row about to be deleted/updated */
1864 sqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */
1866 sqlite3_session *pSession;
1867 int nDb = sqlite3Strlen30(zDb);
1869 assert( sqlite3_mutex_held(db->mutex) );
1870 (void)iKey1;
1871 (void)iKey2;
1873 for(pSession=(sqlite3_session *)pCtx; pSession; pSession=pSession->pNext){
1874 SessionTable *pTab;
1876 /* If this session is attached to a different database ("main", "temp"
1877 ** etc.), or if it is not currently enabled, there is nothing to do. Skip
1878 ** to the next session object attached to this database. */
1879 if( pSession->bEnable==0 ) continue;
1880 if( pSession->rc ) continue;
1881 if( sqlite3_strnicmp(zDb, pSession->zDb, nDb+1) ) continue;
1883 pSession->rc = sessionFindTable(pSession, zName, &pTab);
1884 if( pTab ){
1885 assert( pSession->rc==SQLITE_OK );
1886 assert( op==SQLITE_UPDATE || iKey1==iKey2 );
1887 sessionPreupdateOneChange(op, iKey1, pSession, pTab);
1888 if( op==SQLITE_UPDATE ){
1889 sessionPreupdateOneChange(SQLITE_INSERT, iKey2, pSession, pTab);
1896 ** The pre-update hook implementations.
1898 static int sessionPreupdateOld(void *pCtx, int iVal, sqlite3_value **ppVal){
1899 return sqlite3_preupdate_old((sqlite3*)pCtx, iVal, ppVal);
1901 static int sessionPreupdateNew(void *pCtx, int iVal, sqlite3_value **ppVal){
1902 return sqlite3_preupdate_new((sqlite3*)pCtx, iVal, ppVal);
1904 static int sessionPreupdateCount(void *pCtx){
1905 return sqlite3_preupdate_count((sqlite3*)pCtx);
1907 static int sessionPreupdateDepth(void *pCtx){
1908 return sqlite3_preupdate_depth((sqlite3*)pCtx);
1912 ** Install the pre-update hooks on the session object passed as the only
1913 ** argument.
1915 static void sessionPreupdateHooks(
1916 sqlite3_session *pSession
1918 pSession->hook.pCtx = (void*)pSession->db;
1919 pSession->hook.xOld = sessionPreupdateOld;
1920 pSession->hook.xNew = sessionPreupdateNew;
1921 pSession->hook.xCount = sessionPreupdateCount;
1922 pSession->hook.xDepth = sessionPreupdateDepth;
1925 typedef struct SessionDiffCtx SessionDiffCtx;
1926 struct SessionDiffCtx {
1927 sqlite3_stmt *pStmt;
1928 int bRowid;
1929 int nOldOff;
1933 ** The diff hook implementations.
1935 static int sessionDiffOld(void *pCtx, int iVal, sqlite3_value **ppVal){
1936 SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
1937 *ppVal = sqlite3_column_value(p->pStmt, iVal+p->nOldOff+p->bRowid);
1938 return SQLITE_OK;
1940 static int sessionDiffNew(void *pCtx, int iVal, sqlite3_value **ppVal){
1941 SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
1942 *ppVal = sqlite3_column_value(p->pStmt, iVal+p->bRowid);
1943 return SQLITE_OK;
1945 static int sessionDiffCount(void *pCtx){
1946 SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
1947 return (p->nOldOff ? p->nOldOff : sqlite3_column_count(p->pStmt)) - p->bRowid;
1949 static int sessionDiffDepth(void *pCtx){
1950 (void)pCtx;
1951 return 0;
1955 ** Install the diff hooks on the session object passed as the only
1956 ** argument.
1958 static void sessionDiffHooks(
1959 sqlite3_session *pSession,
1960 SessionDiffCtx *pDiffCtx
1962 pSession->hook.pCtx = (void*)pDiffCtx;
1963 pSession->hook.xOld = sessionDiffOld;
1964 pSession->hook.xNew = sessionDiffNew;
1965 pSession->hook.xCount = sessionDiffCount;
1966 pSession->hook.xDepth = sessionDiffDepth;
1969 static char *sessionExprComparePK(
1970 int nCol,
1971 const char *zDb1, const char *zDb2,
1972 const char *zTab,
1973 const char **azCol, u8 *abPK
1975 int i;
1976 const char *zSep = "";
1977 char *zRet = 0;
1979 for(i=0; i<nCol; i++){
1980 if( abPK[i] ){
1981 zRet = sqlite3_mprintf("%z%s\"%w\".\"%w\".\"%w\"=\"%w\".\"%w\".\"%w\"",
1982 zRet, zSep, zDb1, zTab, azCol[i], zDb2, zTab, azCol[i]
1984 zSep = " AND ";
1985 if( zRet==0 ) break;
1989 return zRet;
1992 static char *sessionExprCompareOther(
1993 int nCol,
1994 const char *zDb1, const char *zDb2,
1995 const char *zTab,
1996 const char **azCol, u8 *abPK
1998 int i;
1999 const char *zSep = "";
2000 char *zRet = 0;
2001 int bHave = 0;
2003 for(i=0; i<nCol; i++){
2004 if( abPK[i]==0 ){
2005 bHave = 1;
2006 zRet = sqlite3_mprintf(
2007 "%z%s\"%w\".\"%w\".\"%w\" IS NOT \"%w\".\"%w\".\"%w\"",
2008 zRet, zSep, zDb1, zTab, azCol[i], zDb2, zTab, azCol[i]
2010 zSep = " OR ";
2011 if( zRet==0 ) break;
2015 if( bHave==0 ){
2016 assert( zRet==0 );
2017 zRet = sqlite3_mprintf("0");
2020 return zRet;
2023 static char *sessionSelectFindNew(
2024 const char *zDb1, /* Pick rows in this db only */
2025 const char *zDb2, /* But not in this one */
2026 int bRowid,
2027 const char *zTbl, /* Table name */
2028 const char *zExpr
2030 const char *zSel = (bRowid ? SESSIONS_ROWID ", *" : "*");
2031 char *zRet = sqlite3_mprintf(
2032 "SELECT %s FROM \"%w\".\"%w\" WHERE NOT EXISTS ("
2033 " SELECT 1 FROM \"%w\".\"%w\" WHERE %s"
2034 ")",
2035 zSel, zDb1, zTbl, zDb2, zTbl, zExpr
2037 return zRet;
2040 static int sessionDiffFindNew(
2041 int op,
2042 sqlite3_session *pSession,
2043 SessionTable *pTab,
2044 const char *zDb1,
2045 const char *zDb2,
2046 char *zExpr
2048 int rc = SQLITE_OK;
2049 char *zStmt = sessionSelectFindNew(
2050 zDb1, zDb2, pTab->bRowid, pTab->zName, zExpr
2053 if( zStmt==0 ){
2054 rc = SQLITE_NOMEM;
2055 }else{
2056 sqlite3_stmt *pStmt;
2057 rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0);
2058 if( rc==SQLITE_OK ){
2059 SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx;
2060 pDiffCtx->pStmt = pStmt;
2061 pDiffCtx->nOldOff = 0;
2062 pDiffCtx->bRowid = pTab->bRowid;
2063 while( SQLITE_ROW==sqlite3_step(pStmt) ){
2064 i64 iRowid = (pTab->bRowid ? sqlite3_column_int64(pStmt, 0) : 0);
2065 sessionPreupdateOneChange(op, iRowid, pSession, pTab);
2067 rc = sqlite3_finalize(pStmt);
2069 sqlite3_free(zStmt);
2072 return rc;
2076 ** Return a comma-separated list of the fully-qualified (with both database
2077 ** and table name) column names from table pTab. e.g.
2079 ** "main"."t1"."a", "main"."t1"."b", "main"."t1"."c"
2081 static char *sessionAllCols(
2082 const char *zDb,
2083 SessionTable *pTab
2085 int ii;
2086 char *zRet = 0;
2087 for(ii=0; ii<pTab->nCol; ii++){
2088 zRet = sqlite3_mprintf("%z%s\"%w\".\"%w\".\"%w\"",
2089 zRet, (zRet ? ", " : ""), zDb, pTab->zName, pTab->azCol[ii]
2091 if( !zRet ) break;
2093 return zRet;
2096 static int sessionDiffFindModified(
2097 sqlite3_session *pSession,
2098 SessionTable *pTab,
2099 const char *zFrom,
2100 const char *zExpr
2102 int rc = SQLITE_OK;
2104 char *zExpr2 = sessionExprCompareOther(pTab->nCol,
2105 pSession->zDb, zFrom, pTab->zName, pTab->azCol, pTab->abPK
2107 if( zExpr2==0 ){
2108 rc = SQLITE_NOMEM;
2109 }else{
2110 char *z1 = sessionAllCols(pSession->zDb, pTab);
2111 char *z2 = sessionAllCols(zFrom, pTab);
2112 char *zStmt = sqlite3_mprintf(
2113 "SELECT %s,%s FROM \"%w\".\"%w\", \"%w\".\"%w\" WHERE %s AND (%z)",
2114 z1, z2, pSession->zDb, pTab->zName, zFrom, pTab->zName, zExpr, zExpr2
2116 if( zStmt==0 || z1==0 || z2==0 ){
2117 rc = SQLITE_NOMEM;
2118 }else{
2119 sqlite3_stmt *pStmt;
2120 rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0);
2122 if( rc==SQLITE_OK ){
2123 SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx;
2124 pDiffCtx->pStmt = pStmt;
2125 pDiffCtx->nOldOff = pTab->nCol;
2126 while( SQLITE_ROW==sqlite3_step(pStmt) ){
2127 i64 iRowid = (pTab->bRowid ? sqlite3_column_int64(pStmt, 0) : 0);
2128 sessionPreupdateOneChange(SQLITE_UPDATE, iRowid, pSession, pTab);
2130 rc = sqlite3_finalize(pStmt);
2133 sqlite3_free(zStmt);
2134 sqlite3_free(z1);
2135 sqlite3_free(z2);
2138 return rc;
2141 int sqlite3session_diff(
2142 sqlite3_session *pSession,
2143 const char *zFrom,
2144 const char *zTbl,
2145 char **pzErrMsg
2147 const char *zDb = pSession->zDb;
2148 int rc = pSession->rc;
2149 SessionDiffCtx d;
2151 memset(&d, 0, sizeof(d));
2152 sessionDiffHooks(pSession, &d);
2154 sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
2155 if( pzErrMsg ) *pzErrMsg = 0;
2156 if( rc==SQLITE_OK ){
2157 char *zExpr = 0;
2158 sqlite3 *db = pSession->db;
2159 SessionTable *pTo; /* Table zTbl */
2161 /* Locate and if necessary initialize the target table object */
2162 rc = sessionFindTable(pSession, zTbl, &pTo);
2163 if( pTo==0 ) goto diff_out;
2164 if( sessionInitTable(pSession, pTo, pSession->db, pSession->zDb) ){
2165 rc = pSession->rc;
2166 goto diff_out;
2169 /* Check the table schemas match */
2170 if( rc==SQLITE_OK ){
2171 int bHasPk = 0;
2172 int bMismatch = 0;
2173 int nCol; /* Columns in zFrom.zTbl */
2174 int bRowid = 0;
2175 u8 *abPK;
2176 const char **azCol = 0;
2177 rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, 0, &abPK,
2178 pSession->bImplicitPK ? &bRowid : 0
2180 if( rc==SQLITE_OK ){
2181 if( pTo->nCol!=nCol ){
2182 bMismatch = 1;
2183 }else{
2184 int i;
2185 for(i=0; i<nCol; i++){
2186 if( pTo->abPK[i]!=abPK[i] ) bMismatch = 1;
2187 if( sqlite3_stricmp(azCol[i], pTo->azCol[i]) ) bMismatch = 1;
2188 if( abPK[i] ) bHasPk = 1;
2192 sqlite3_free((char*)azCol);
2193 if( bMismatch ){
2194 if( pzErrMsg ){
2195 *pzErrMsg = sqlite3_mprintf("table schemas do not match");
2197 rc = SQLITE_SCHEMA;
2199 if( bHasPk==0 ){
2200 /* Ignore tables with no primary keys */
2201 goto diff_out;
2205 if( rc==SQLITE_OK ){
2206 zExpr = sessionExprComparePK(pTo->nCol,
2207 zDb, zFrom, pTo->zName, pTo->azCol, pTo->abPK
2211 /* Find new rows */
2212 if( rc==SQLITE_OK ){
2213 rc = sessionDiffFindNew(SQLITE_INSERT, pSession, pTo, zDb, zFrom, zExpr);
2216 /* Find old rows */
2217 if( rc==SQLITE_OK ){
2218 rc = sessionDiffFindNew(SQLITE_DELETE, pSession, pTo, zFrom, zDb, zExpr);
2221 /* Find modified rows */
2222 if( rc==SQLITE_OK ){
2223 rc = sessionDiffFindModified(pSession, pTo, zFrom, zExpr);
2226 sqlite3_free(zExpr);
2229 diff_out:
2230 sessionPreupdateHooks(pSession);
2231 sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
2232 return rc;
2236 ** Create a session object. This session object will record changes to
2237 ** database zDb attached to connection db.
2239 int sqlite3session_create(
2240 sqlite3 *db, /* Database handle */
2241 const char *zDb, /* Name of db (e.g. "main") */
2242 sqlite3_session **ppSession /* OUT: New session object */
2244 sqlite3_session *pNew; /* Newly allocated session object */
2245 sqlite3_session *pOld; /* Session object already attached to db */
2246 int nDb = sqlite3Strlen30(zDb); /* Length of zDb in bytes */
2248 /* Zero the output value in case an error occurs. */
2249 *ppSession = 0;
2251 /* Allocate and populate the new session object. */
2252 pNew = (sqlite3_session *)sqlite3_malloc64(sizeof(sqlite3_session) + nDb + 1);
2253 if( !pNew ) return SQLITE_NOMEM;
2254 memset(pNew, 0, sizeof(sqlite3_session));
2255 pNew->db = db;
2256 pNew->zDb = (char *)&pNew[1];
2257 pNew->bEnable = 1;
2258 memcpy(pNew->zDb, zDb, nDb+1);
2259 sessionPreupdateHooks(pNew);
2261 /* Add the new session object to the linked list of session objects
2262 ** attached to database handle $db. Do this under the cover of the db
2263 ** handle mutex. */
2264 sqlite3_mutex_enter(sqlite3_db_mutex(db));
2265 pOld = (sqlite3_session*)sqlite3_preupdate_hook(db, xPreUpdate, (void*)pNew);
2266 pNew->pNext = pOld;
2267 sqlite3_mutex_leave(sqlite3_db_mutex(db));
2269 *ppSession = pNew;
2270 return SQLITE_OK;
2274 ** Free the list of table objects passed as the first argument. The contents
2275 ** of the changed-rows hash tables are also deleted.
2277 static void sessionDeleteTable(sqlite3_session *pSession, SessionTable *pList){
2278 SessionTable *pNext;
2279 SessionTable *pTab;
2281 for(pTab=pList; pTab; pTab=pNext){
2282 int i;
2283 pNext = pTab->pNext;
2284 for(i=0; i<pTab->nChange; i++){
2285 SessionChange *p;
2286 SessionChange *pNextChange;
2287 for(p=pTab->apChange[i]; p; p=pNextChange){
2288 pNextChange = p->pNext;
2289 sessionFree(pSession, p);
2292 sessionFree(pSession, (char*)pTab->azCol); /* cast works around VC++ bug */
2293 sessionFree(pSession, pTab->apChange);
2294 sessionFree(pSession, pTab);
2299 ** Delete a session object previously allocated using sqlite3session_create().
2301 void sqlite3session_delete(sqlite3_session *pSession){
2302 sqlite3 *db = pSession->db;
2303 sqlite3_session *pHead;
2304 sqlite3_session **pp;
2306 /* Unlink the session from the linked list of sessions attached to the
2307 ** database handle. Hold the db mutex while doing so. */
2308 sqlite3_mutex_enter(sqlite3_db_mutex(db));
2309 pHead = (sqlite3_session*)sqlite3_preupdate_hook(db, 0, 0);
2310 for(pp=&pHead; ALWAYS((*pp)!=0); pp=&((*pp)->pNext)){
2311 if( (*pp)==pSession ){
2312 *pp = (*pp)->pNext;
2313 if( pHead ) sqlite3_preupdate_hook(db, xPreUpdate, (void*)pHead);
2314 break;
2317 sqlite3_mutex_leave(sqlite3_db_mutex(db));
2318 sqlite3ValueFree(pSession->pZeroBlob);
2320 /* Delete all attached table objects. And the contents of their
2321 ** associated hash-tables. */
2322 sessionDeleteTable(pSession, pSession->pTable);
2324 /* Assert that all allocations have been freed and then free the
2325 ** session object itself. */
2326 // assert( pSession->nMalloc==0 );
2327 sqlite3_free(pSession);
2331 ** Set a table filter on a Session Object.
2333 void sqlite3session_table_filter(
2334 sqlite3_session *pSession,
2335 int(*xFilter)(void*, const char*),
2336 void *pCtx /* First argument passed to xFilter */
2338 pSession->bAutoAttach = 1;
2339 pSession->pFilterCtx = pCtx;
2340 pSession->xTableFilter = xFilter;
2344 ** Attach a table to a session. All subsequent changes made to the table
2345 ** while the session object is enabled will be recorded.
2347 ** Only tables that have a PRIMARY KEY defined may be attached. It does
2348 ** not matter if the PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias)
2349 ** or not.
2351 int sqlite3session_attach(
2352 sqlite3_session *pSession, /* Session object */
2353 const char *zName /* Table name */
2355 int rc = SQLITE_OK;
2356 sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
2358 if( !zName ){
2359 pSession->bAutoAttach = 1;
2360 }else{
2361 SessionTable *pTab; /* New table object (if required) */
2362 int nName; /* Number of bytes in string zName */
2364 /* First search for an existing entry. If one is found, this call is
2365 ** a no-op. Return early. */
2366 nName = sqlite3Strlen30(zName);
2367 for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){
2368 if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ) break;
2371 if( !pTab ){
2372 /* Allocate new SessionTable object. */
2373 int nByte = sizeof(SessionTable) + nName + 1;
2374 pTab = (SessionTable*)sessionMalloc64(pSession, nByte);
2375 if( !pTab ){
2376 rc = SQLITE_NOMEM;
2377 }else{
2378 /* Populate the new SessionTable object and link it into the list.
2379 ** The new object must be linked onto the end of the list, not
2380 ** simply added to the start of it in order to ensure that tables
2381 ** appear in the correct order when a changeset or patchset is
2382 ** eventually generated. */
2383 SessionTable **ppTab;
2384 memset(pTab, 0, sizeof(SessionTable));
2385 pTab->zName = (char *)&pTab[1];
2386 memcpy(pTab->zName, zName, nName+1);
2387 for(ppTab=&pSession->pTable; *ppTab; ppTab=&(*ppTab)->pNext);
2388 *ppTab = pTab;
2393 sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
2394 return rc;
2398 ** Append the value passed as the second argument to the buffer passed
2399 ** as the first.
2401 ** This function is a no-op if *pRc is non-zero when it is called.
2402 ** Otherwise, if an error occurs, *pRc is set to an SQLite error code
2403 ** before returning.
2405 static void sessionAppendValue(SessionBuffer *p, sqlite3_value *pVal, int *pRc){
2406 int rc = *pRc;
2407 if( rc==SQLITE_OK ){
2408 sqlite3_int64 nByte = 0;
2409 rc = sessionSerializeValue(0, pVal, &nByte);
2410 sessionBufferGrow(p, nByte, &rc);
2411 if( rc==SQLITE_OK ){
2412 rc = sessionSerializeValue(&p->aBuf[p->nBuf], pVal, 0);
2413 p->nBuf += nByte;
2414 }else{
2415 *pRc = rc;
2421 ** This function is a no-op if *pRc is other than SQLITE_OK when it is
2422 ** called. Otherwise, append a single byte to the buffer.
2424 ** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
2425 ** returning.
2427 static void sessionAppendByte(SessionBuffer *p, u8 v, int *pRc){
2428 if( 0==sessionBufferGrow(p, 1, pRc) ){
2429 p->aBuf[p->nBuf++] = v;
2434 ** This function is a no-op if *pRc is other than SQLITE_OK when it is
2435 ** called. Otherwise, append a single varint to the buffer.
2437 ** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
2438 ** returning.
2440 static void sessionAppendVarint(SessionBuffer *p, int v, int *pRc){
2441 if( 0==sessionBufferGrow(p, 9, pRc) ){
2442 p->nBuf += sessionVarintPut(&p->aBuf[p->nBuf], v);
2447 ** This function is a no-op if *pRc is other than SQLITE_OK when it is
2448 ** called. Otherwise, append a blob of data to the buffer.
2450 ** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
2451 ** returning.
2453 static void sessionAppendBlob(
2454 SessionBuffer *p,
2455 const u8 *aBlob,
2456 int nBlob,
2457 int *pRc
2459 if( nBlob>0 && 0==sessionBufferGrow(p, nBlob, pRc) ){
2460 memcpy(&p->aBuf[p->nBuf], aBlob, nBlob);
2461 p->nBuf += nBlob;
2466 ** This function is a no-op if *pRc is other than SQLITE_OK when it is
2467 ** called. Otherwise, append the string representation of integer iVal
2468 ** to the buffer. No nul-terminator is written.
2470 ** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
2471 ** returning.
2473 static void sessionAppendInteger(
2474 SessionBuffer *p, /* Buffer to append to */
2475 int iVal, /* Value to write the string rep. of */
2476 int *pRc /* IN/OUT: Error code */
2478 char aBuf[24];
2479 sqlite3_snprintf(sizeof(aBuf)-1, aBuf, "%d", iVal);
2480 sessionAppendStr(p, aBuf, pRc);
2484 ** This function is a no-op if *pRc is other than SQLITE_OK when it is
2485 ** called. Otherwise, append the string zStr enclosed in quotes (") and
2486 ** with any embedded quote characters escaped to the buffer. No
2487 ** nul-terminator byte is written.
2489 ** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
2490 ** returning.
2492 static void sessionAppendIdent(
2493 SessionBuffer *p, /* Buffer to a append to */
2494 const char *zStr, /* String to quote, escape and append */
2495 int *pRc /* IN/OUT: Error code */
2497 int nStr = sqlite3Strlen30(zStr)*2 + 2 + 2;
2498 if( 0==sessionBufferGrow(p, nStr, pRc) ){
2499 char *zOut = (char *)&p->aBuf[p->nBuf];
2500 const char *zIn = zStr;
2501 *zOut++ = '"';
2502 while( *zIn ){
2503 if( *zIn=='"' ) *zOut++ = '"';
2504 *zOut++ = *(zIn++);
2506 *zOut++ = '"';
2507 p->nBuf = (int)((u8 *)zOut - p->aBuf);
2508 p->aBuf[p->nBuf] = 0x00;
2513 ** This function is a no-op if *pRc is other than SQLITE_OK when it is
2514 ** called. Otherwse, it appends the serialized version of the value stored
2515 ** in column iCol of the row that SQL statement pStmt currently points
2516 ** to to the buffer.
2518 static void sessionAppendCol(
2519 SessionBuffer *p, /* Buffer to append to */
2520 sqlite3_stmt *pStmt, /* Handle pointing to row containing value */
2521 int iCol, /* Column to read value from */
2522 int *pRc /* IN/OUT: Error code */
2524 if( *pRc==SQLITE_OK ){
2525 int eType = sqlite3_column_type(pStmt, iCol);
2526 sessionAppendByte(p, (u8)eType, pRc);
2527 if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
2528 sqlite3_int64 i;
2529 u8 aBuf[8];
2530 if( eType==SQLITE_INTEGER ){
2531 i = sqlite3_column_int64(pStmt, iCol);
2532 }else{
2533 double r = sqlite3_column_double(pStmt, iCol);
2534 memcpy(&i, &r, 8);
2536 sessionPutI64(aBuf, i);
2537 sessionAppendBlob(p, aBuf, 8, pRc);
2539 if( eType==SQLITE_BLOB || eType==SQLITE_TEXT ){
2540 u8 *z;
2541 int nByte;
2542 if( eType==SQLITE_BLOB ){
2543 z = (u8 *)sqlite3_column_blob(pStmt, iCol);
2544 }else{
2545 z = (u8 *)sqlite3_column_text(pStmt, iCol);
2547 nByte = sqlite3_column_bytes(pStmt, iCol);
2548 if( z || (eType==SQLITE_BLOB && nByte==0) ){
2549 sessionAppendVarint(p, nByte, pRc);
2550 sessionAppendBlob(p, z, nByte, pRc);
2551 }else{
2552 *pRc = SQLITE_NOMEM;
2560 ** This function appends an update change to the buffer (see the comments
2561 ** under "CHANGESET FORMAT" at the top of the file). An update change
2562 ** consists of:
2564 ** 1 byte: SQLITE_UPDATE (0x17)
2565 ** n bytes: old.* record (see RECORD FORMAT)
2566 ** m bytes: new.* record (see RECORD FORMAT)
2568 ** The SessionChange object passed as the third argument contains the
2569 ** values that were stored in the row when the session began (the old.*
2570 ** values). The statement handle passed as the second argument points
2571 ** at the current version of the row (the new.* values).
2573 ** If all of the old.* values are equal to their corresponding new.* value
2574 ** (i.e. nothing has changed), then no data at all is appended to the buffer.
2576 ** Otherwise, the old.* record contains all primary key values and the
2577 ** original values of any fields that have been modified. The new.* record
2578 ** contains the new values of only those fields that have been modified.
2580 static int sessionAppendUpdate(
2581 SessionBuffer *pBuf, /* Buffer to append to */
2582 int bPatchset, /* True for "patchset", 0 for "changeset" */
2583 sqlite3_stmt *pStmt, /* Statement handle pointing at new row */
2584 SessionChange *p, /* Object containing old values */
2585 u8 *abPK /* Boolean array - true for PK columns */
2587 int rc = SQLITE_OK;
2588 SessionBuffer buf2 = {0,0,0}; /* Buffer to accumulate new.* record in */
2589 int bNoop = 1; /* Set to zero if any values are modified */
2590 int nRewind = pBuf->nBuf; /* Set to zero if any values are modified */
2591 int i; /* Used to iterate through columns */
2592 u8 *pCsr = p->aRecord; /* Used to iterate through old.* values */
2594 assert( abPK!=0 );
2595 sessionAppendByte(pBuf, SQLITE_UPDATE, &rc);
2596 sessionAppendByte(pBuf, p->bIndirect, &rc);
2597 for(i=0; i<sqlite3_column_count(pStmt); i++){
2598 int bChanged = 0;
2599 int nAdvance;
2600 int eType = *pCsr;
2601 switch( eType ){
2602 case SQLITE_NULL:
2603 nAdvance = 1;
2604 if( sqlite3_column_type(pStmt, i)!=SQLITE_NULL ){
2605 bChanged = 1;
2607 break;
2609 case SQLITE_FLOAT:
2610 case SQLITE_INTEGER: {
2611 nAdvance = 9;
2612 if( eType==sqlite3_column_type(pStmt, i) ){
2613 sqlite3_int64 iVal = sessionGetI64(&pCsr[1]);
2614 if( eType==SQLITE_INTEGER ){
2615 if( iVal==sqlite3_column_int64(pStmt, i) ) break;
2616 }else{
2617 double dVal;
2618 memcpy(&dVal, &iVal, 8);
2619 if( dVal==sqlite3_column_double(pStmt, i) ) break;
2622 bChanged = 1;
2623 break;
2626 default: {
2627 int n;
2628 int nHdr = 1 + sessionVarintGet(&pCsr[1], &n);
2629 assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
2630 nAdvance = nHdr + n;
2631 if( eType==sqlite3_column_type(pStmt, i)
2632 && n==sqlite3_column_bytes(pStmt, i)
2633 && (n==0 || 0==memcmp(&pCsr[nHdr], sqlite3_column_blob(pStmt, i), n))
2635 break;
2637 bChanged = 1;
2641 /* If at least one field has been modified, this is not a no-op. */
2642 if( bChanged ) bNoop = 0;
2644 /* Add a field to the old.* record. This is omitted if this module is
2645 ** currently generating a patchset. */
2646 if( bPatchset==0 ){
2647 if( bChanged || abPK[i] ){
2648 sessionAppendBlob(pBuf, pCsr, nAdvance, &rc);
2649 }else{
2650 sessionAppendByte(pBuf, 0, &rc);
2654 /* Add a field to the new.* record. Or the only record if currently
2655 ** generating a patchset. */
2656 if( bChanged || (bPatchset && abPK[i]) ){
2657 sessionAppendCol(&buf2, pStmt, i, &rc);
2658 }else{
2659 sessionAppendByte(&buf2, 0, &rc);
2662 pCsr += nAdvance;
2665 if( bNoop ){
2666 pBuf->nBuf = nRewind;
2667 }else{
2668 sessionAppendBlob(pBuf, buf2.aBuf, buf2.nBuf, &rc);
2670 sqlite3_free(buf2.aBuf);
2672 return rc;
2676 ** Append a DELETE change to the buffer passed as the first argument. Use
2677 ** the changeset format if argument bPatchset is zero, or the patchset
2678 ** format otherwise.
2680 static int sessionAppendDelete(
2681 SessionBuffer *pBuf, /* Buffer to append to */
2682 int bPatchset, /* True for "patchset", 0 for "changeset" */
2683 SessionChange *p, /* Object containing old values */
2684 int nCol, /* Number of columns in table */
2685 u8 *abPK /* Boolean array - true for PK columns */
2687 int rc = SQLITE_OK;
2689 sessionAppendByte(pBuf, SQLITE_DELETE, &rc);
2690 sessionAppendByte(pBuf, p->bIndirect, &rc);
2692 if( bPatchset==0 ){
2693 sessionAppendBlob(pBuf, p->aRecord, p->nRecord, &rc);
2694 }else{
2695 int i;
2696 u8 *a = p->aRecord;
2697 for(i=0; i<nCol; i++){
2698 u8 *pStart = a;
2699 int eType = *a++;
2701 switch( eType ){
2702 case 0:
2703 case SQLITE_NULL:
2704 assert( abPK[i]==0 );
2705 break;
2707 case SQLITE_FLOAT:
2708 case SQLITE_INTEGER:
2709 a += 8;
2710 break;
2712 default: {
2713 int n;
2714 a += sessionVarintGet(a, &n);
2715 a += n;
2716 break;
2719 if( abPK[i] ){
2720 sessionAppendBlob(pBuf, pStart, (int)(a-pStart), &rc);
2723 assert( (a - p->aRecord)==p->nRecord );
2726 return rc;
2730 ** Formulate and prepare a SELECT statement to retrieve a row from table
2731 ** zTab in database zDb based on its primary key. i.e.
2733 ** SELECT *, <noop-test> FROM zDb.zTab WHERE (pk1, pk2,...) IS (?1, ?2,...)
2735 ** where <noop-test> is:
2737 ** 1 AND (?A OR ?1 IS <column>) AND ...
2739 ** for each non-pk <column>.
2741 static int sessionSelectStmt(
2742 sqlite3 *db, /* Database handle */
2743 int bIgnoreNoop,
2744 const char *zDb, /* Database name */
2745 const char *zTab, /* Table name */
2746 int bRowid,
2747 int nCol, /* Number of columns in table */
2748 const char **azCol, /* Names of table columns */
2749 u8 *abPK, /* PRIMARY KEY array */
2750 sqlite3_stmt **ppStmt /* OUT: Prepared SELECT statement */
2752 int rc = SQLITE_OK;
2753 char *zSql = 0;
2754 const char *zSep = "";
2755 const char *zCols = bRowid ? SESSIONS_ROWID ", *" : "*";
2756 int nSql = -1;
2757 int i;
2759 SessionBuffer nooptest = {0, 0, 0};
2760 SessionBuffer pkfield = {0, 0, 0};
2761 SessionBuffer pkvar = {0, 0, 0};
2763 sessionAppendStr(&nooptest, ", 1", &rc);
2765 if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){
2766 sessionAppendStr(&nooptest, " AND (?6 OR ?3 IS stat)", &rc);
2767 sessionAppendStr(&pkfield, "tbl, idx", &rc);
2768 sessionAppendStr(&pkvar,
2769 "?1, (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", &rc
2771 zCols = "tbl, ?2, stat";
2772 }else{
2773 for(i=0; i<nCol; i++){
2774 if( abPK[i] ){
2775 sessionAppendStr(&pkfield, zSep, &rc);
2776 sessionAppendStr(&pkvar, zSep, &rc);
2777 zSep = ", ";
2778 sessionAppendIdent(&pkfield, azCol[i], &rc);
2779 sessionAppendPrintf(&pkvar, &rc, "?%d", i+1);
2780 }else{
2781 sessionAppendPrintf(&nooptest, &rc,
2782 " AND (?%d OR ?%d IS %w.%w)", i+1+nCol, i+1, zTab, azCol[i]
2788 if( rc==SQLITE_OK ){
2789 zSql = sqlite3_mprintf(
2790 "SELECT %s%s FROM %Q.%Q WHERE (%s) IS (%s)",
2791 zCols, (bIgnoreNoop ? (char*)nooptest.aBuf : ""),
2792 zDb, zTab, (char*)pkfield.aBuf, (char*)pkvar.aBuf
2794 if( zSql==0 ) rc = SQLITE_NOMEM;
2797 #if 0
2798 if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){
2799 zSql = sqlite3_mprintf(
2800 "SELECT tbl, ?2, stat FROM %Q.sqlite_stat1 WHERE tbl IS ?1 AND "
2801 "idx IS (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", zDb
2803 if( zSql==0 ) rc = SQLITE_NOMEM;
2804 }else{
2805 const char *zSep = "";
2806 SessionBuffer buf = {0, 0, 0};
2808 sessionAppendStr(&buf, "SELECT * FROM ", &rc);
2809 sessionAppendIdent(&buf, zDb, &rc);
2810 sessionAppendStr(&buf, ".", &rc);
2811 sessionAppendIdent(&buf, zTab, &rc);
2812 sessionAppendStr(&buf, " WHERE ", &rc);
2813 for(i=0; i<nCol; i++){
2814 if( abPK[i] ){
2815 sessionAppendStr(&buf, zSep, &rc);
2816 sessionAppendIdent(&buf, azCol[i], &rc);
2817 sessionAppendStr(&buf, " IS ?", &rc);
2818 sessionAppendInteger(&buf, i+1, &rc);
2819 zSep = " AND ";
2822 zSql = (char*)buf.aBuf;
2823 nSql = buf.nBuf;
2825 #endif
2827 if( rc==SQLITE_OK ){
2828 rc = sqlite3_prepare_v2(db, zSql, nSql, ppStmt, 0);
2830 sqlite3_free(zSql);
2831 sqlite3_free(nooptest.aBuf);
2832 sqlite3_free(pkfield.aBuf);
2833 sqlite3_free(pkvar.aBuf);
2834 return rc;
2838 ** Bind the PRIMARY KEY values from the change passed in argument pChange
2839 ** to the SELECT statement passed as the first argument. The SELECT statement
2840 ** is as prepared by function sessionSelectStmt().
2842 ** Return SQLITE_OK if all PK values are successfully bound, or an SQLite
2843 ** error code (e.g. SQLITE_NOMEM) otherwise.
2845 static int sessionSelectBind(
2846 sqlite3_stmt *pSelect, /* SELECT from sessionSelectStmt() */
2847 int nCol, /* Number of columns in table */
2848 u8 *abPK, /* PRIMARY KEY array */
2849 SessionChange *pChange /* Change structure */
2851 int i;
2852 int rc = SQLITE_OK;
2853 u8 *a = pChange->aRecord;
2855 for(i=0; i<nCol && rc==SQLITE_OK; i++){
2856 int eType = *a++;
2858 switch( eType ){
2859 case 0:
2860 case SQLITE_NULL:
2861 assert( abPK[i]==0 );
2862 break;
2864 case SQLITE_INTEGER: {
2865 if( abPK[i] ){
2866 i64 iVal = sessionGetI64(a);
2867 rc = sqlite3_bind_int64(pSelect, i+1, iVal);
2869 a += 8;
2870 break;
2873 case SQLITE_FLOAT: {
2874 if( abPK[i] ){
2875 double rVal;
2876 i64 iVal = sessionGetI64(a);
2877 memcpy(&rVal, &iVal, 8);
2878 rc = sqlite3_bind_double(pSelect, i+1, rVal);
2880 a += 8;
2881 break;
2884 case SQLITE_TEXT: {
2885 int n;
2886 a += sessionVarintGet(a, &n);
2887 if( abPK[i] ){
2888 rc = sqlite3_bind_text(pSelect, i+1, (char *)a, n, SQLITE_TRANSIENT);
2890 a += n;
2891 break;
2894 default: {
2895 int n;
2896 assert( eType==SQLITE_BLOB );
2897 a += sessionVarintGet(a, &n);
2898 if( abPK[i] ){
2899 rc = sqlite3_bind_blob(pSelect, i+1, a, n, SQLITE_TRANSIENT);
2901 a += n;
2902 break;
2907 return rc;
2911 ** This function is a no-op if *pRc is set to other than SQLITE_OK when it
2912 ** is called. Otherwise, append a serialized table header (part of the binary
2913 ** changeset format) to buffer *pBuf. If an error occurs, set *pRc to an
2914 ** SQLite error code before returning.
2916 static void sessionAppendTableHdr(
2917 SessionBuffer *pBuf, /* Append header to this buffer */
2918 int bPatchset, /* Use the patchset format if true */
2919 SessionTable *pTab, /* Table object to append header for */
2920 int *pRc /* IN/OUT: Error code */
2922 /* Write a table header */
2923 sessionAppendByte(pBuf, (bPatchset ? 'P' : 'T'), pRc);
2924 sessionAppendVarint(pBuf, pTab->nCol, pRc);
2925 sessionAppendBlob(pBuf, pTab->abPK, pTab->nCol, pRc);
2926 sessionAppendBlob(pBuf, (u8 *)pTab->zName, (int)strlen(pTab->zName)+1, pRc);
2930 ** Generate either a changeset (if argument bPatchset is zero) or a patchset
2931 ** (if it is non-zero) based on the current contents of the session object
2932 ** passed as the first argument.
2934 ** If no error occurs, SQLITE_OK is returned and the new changeset/patchset
2935 ** stored in output variables *pnChangeset and *ppChangeset. Or, if an error
2936 ** occurs, an SQLite error code is returned and both output variables set
2937 ** to 0.
2939 static int sessionGenerateChangeset(
2940 sqlite3_session *pSession, /* Session object */
2941 int bPatchset, /* True for patchset, false for changeset */
2942 int (*xOutput)(void *pOut, const void *pData, int nData),
2943 void *pOut, /* First argument for xOutput */
2944 int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */
2945 void **ppChangeset /* OUT: Buffer containing changeset */
2947 sqlite3 *db = pSession->db; /* Source database handle */
2948 SessionTable *pTab; /* Used to iterate through attached tables */
2949 SessionBuffer buf = {0,0,0}; /* Buffer in which to accumlate changeset */
2950 int rc; /* Return code */
2952 assert( xOutput==0 || (pnChangeset==0 && ppChangeset==0) );
2953 assert( xOutput!=0 || (pnChangeset!=0 && ppChangeset!=0) );
2955 /* Zero the output variables in case an error occurs. If this session
2956 ** object is already in the error state (sqlite3_session.rc != SQLITE_OK),
2957 ** this call will be a no-op. */
2958 if( xOutput==0 ){
2959 assert( pnChangeset!=0 && ppChangeset!=0 );
2960 *pnChangeset = 0;
2961 *ppChangeset = 0;
2964 if( pSession->rc ) return pSession->rc;
2965 rc = sqlite3_exec(pSession->db, "SAVEPOINT changeset", 0, 0, 0);
2966 if( rc!=SQLITE_OK ) return rc;
2968 sqlite3_mutex_enter(sqlite3_db_mutex(db));
2970 for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
2971 if( pTab->nEntry ){
2972 const char *zName = pTab->zName;
2974 #if 0
2975 int nCol = 0; /* Number of columns in table */
2976 u8 *abPK = 0; /* Primary key array */
2977 int bRowid = 0;
2978 const char **azCol = 0; /* Table columns */
2979 #endif
2980 int i; /* Used to iterate through hash buckets */
2981 sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */
2982 int nRewind = buf.nBuf; /* Initial size of write buffer */
2983 int nNoop; /* Size of buffer after writing tbl header */
2984 int nOldCol = pTab->nCol;
2986 /* Check the table schema is still Ok. */
2987 rc = sessionReinitTable(pSession, pTab);
2988 if( rc==SQLITE_OK && pTab->nCol!=nOldCol ){
2989 rc = sessionUpdateChanges(pSession, pTab);
2992 /* Write a table header */
2993 sessionAppendTableHdr(&buf, bPatchset, pTab, &rc);
2995 /* Build and compile a statement to execute: */
2996 if( rc==SQLITE_OK ){
2997 rc = sessionSelectStmt(db, 0, pSession->zDb,
2998 zName, pTab->bRowid, pTab->nCol, pTab->azCol, pTab->abPK, &pSel
3002 nNoop = buf.nBuf;
3003 for(i=0; i<pTab->nChange && rc==SQLITE_OK; i++){
3004 SessionChange *p; /* Used to iterate through changes */
3006 for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){
3007 rc = sessionSelectBind(pSel, pTab->nCol, pTab->abPK, p);
3008 if( rc!=SQLITE_OK ) continue;
3009 if( sqlite3_step(pSel)==SQLITE_ROW ){
3010 if( p->op==SQLITE_INSERT ){
3011 int iCol;
3012 sessionAppendByte(&buf, SQLITE_INSERT, &rc);
3013 sessionAppendByte(&buf, p->bIndirect, &rc);
3014 for(iCol=0; iCol<pTab->nCol; iCol++){
3015 sessionAppendCol(&buf, pSel, iCol, &rc);
3017 }else{
3018 assert( pTab->abPK!=0 );
3019 rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, pTab->abPK);
3021 }else if( p->op!=SQLITE_INSERT ){
3022 rc = sessionAppendDelete(&buf, bPatchset, p, pTab->nCol,pTab->abPK);
3024 if( rc==SQLITE_OK ){
3025 rc = sqlite3_reset(pSel);
3028 /* If the buffer is now larger than sessions_strm_chunk_size, pass
3029 ** its contents to the xOutput() callback. */
3030 if( xOutput
3031 && rc==SQLITE_OK
3032 && buf.nBuf>nNoop
3033 && buf.nBuf>sessions_strm_chunk_size
3035 rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
3036 nNoop = -1;
3037 buf.nBuf = 0;
3043 sqlite3_finalize(pSel);
3044 if( buf.nBuf==nNoop ){
3045 buf.nBuf = nRewind;
3050 if( rc==SQLITE_OK ){
3051 if( xOutput==0 ){
3052 *pnChangeset = buf.nBuf;
3053 *ppChangeset = buf.aBuf;
3054 buf.aBuf = 0;
3055 }else if( buf.nBuf>0 ){
3056 rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
3060 sqlite3_free(buf.aBuf);
3061 sqlite3_exec(db, "RELEASE changeset", 0, 0, 0);
3062 sqlite3_mutex_leave(sqlite3_db_mutex(db));
3063 return rc;
3067 ** Obtain a changeset object containing all changes recorded by the
3068 ** session object passed as the first argument.
3070 ** It is the responsibility of the caller to eventually free the buffer
3071 ** using sqlite3_free().
3073 int sqlite3session_changeset(
3074 sqlite3_session *pSession, /* Session object */
3075 int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */
3076 void **ppChangeset /* OUT: Buffer containing changeset */
3078 int rc;
3080 if( pnChangeset==0 || ppChangeset==0 ) return SQLITE_MISUSE;
3081 rc = sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset, ppChangeset);
3082 assert( rc || pnChangeset==0
3083 || pSession->bEnableSize==0 || *pnChangeset<=pSession->nMaxChangesetSize
3085 return rc;
3089 ** Streaming version of sqlite3session_changeset().
3091 int sqlite3session_changeset_strm(
3092 sqlite3_session *pSession,
3093 int (*xOutput)(void *pOut, const void *pData, int nData),
3094 void *pOut
3096 if( xOutput==0 ) return SQLITE_MISUSE;
3097 return sessionGenerateChangeset(pSession, 0, xOutput, pOut, 0, 0);
3101 ** Streaming version of sqlite3session_patchset().
3103 int sqlite3session_patchset_strm(
3104 sqlite3_session *pSession,
3105 int (*xOutput)(void *pOut, const void *pData, int nData),
3106 void *pOut
3108 if( xOutput==0 ) return SQLITE_MISUSE;
3109 return sessionGenerateChangeset(pSession, 1, xOutput, pOut, 0, 0);
3113 ** Obtain a patchset object containing all changes recorded by the
3114 ** session object passed as the first argument.
3116 ** It is the responsibility of the caller to eventually free the buffer
3117 ** using sqlite3_free().
3119 int sqlite3session_patchset(
3120 sqlite3_session *pSession, /* Session object */
3121 int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */
3122 void **ppPatchset /* OUT: Buffer containing changeset */
3124 if( pnPatchset==0 || ppPatchset==0 ) return SQLITE_MISUSE;
3125 return sessionGenerateChangeset(pSession, 1, 0, 0, pnPatchset, ppPatchset);
3129 ** Enable or disable the session object passed as the first argument.
3131 int sqlite3session_enable(sqlite3_session *pSession, int bEnable){
3132 int ret;
3133 sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
3134 if( bEnable>=0 ){
3135 pSession->bEnable = bEnable;
3137 ret = pSession->bEnable;
3138 sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
3139 return ret;
3143 ** Enable or disable the session object passed as the first argument.
3145 int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect){
3146 int ret;
3147 sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
3148 if( bIndirect>=0 ){
3149 pSession->bIndirect = bIndirect;
3151 ret = pSession->bIndirect;
3152 sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
3153 return ret;
3157 ** Return true if there have been no changes to monitored tables recorded
3158 ** by the session object passed as the only argument.
3160 int sqlite3session_isempty(sqlite3_session *pSession){
3161 int ret = 0;
3162 SessionTable *pTab;
3164 sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
3165 for(pTab=pSession->pTable; pTab && ret==0; pTab=pTab->pNext){
3166 ret = (pTab->nEntry>0);
3168 sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
3170 return (ret==0);
3174 ** Return the amount of heap memory in use.
3176 sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession){
3177 return pSession->nMalloc;
3181 ** Configure the session object passed as the first argument.
3183 int sqlite3session_object_config(sqlite3_session *pSession, int op, void *pArg){
3184 int rc = SQLITE_OK;
3185 switch( op ){
3186 case SQLITE_SESSION_OBJCONFIG_SIZE: {
3187 int iArg = *(int*)pArg;
3188 if( iArg>=0 ){
3189 if( pSession->pTable ){
3190 rc = SQLITE_MISUSE;
3191 }else{
3192 pSession->bEnableSize = (iArg!=0);
3195 *(int*)pArg = pSession->bEnableSize;
3196 break;
3199 case SQLITE_SESSION_OBJCONFIG_ROWID: {
3200 int iArg = *(int*)pArg;
3201 if( iArg>=0 ){
3202 if( pSession->pTable ){
3203 rc = SQLITE_MISUSE;
3204 }else{
3205 pSession->bImplicitPK = (iArg!=0);
3208 *(int*)pArg = pSession->bImplicitPK;
3209 break;
3212 default:
3213 rc = SQLITE_MISUSE;
3216 return rc;
3220 ** Return the maximum size of sqlite3session_changeset() output.
3222 sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession){
3223 return pSession->nMaxChangesetSize;
3227 ** Do the work for either sqlite3changeset_start() or start_strm().
3229 static int sessionChangesetStart(
3230 sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
3231 int (*xInput)(void *pIn, void *pData, int *pnData),
3232 void *pIn,
3233 int nChangeset, /* Size of buffer pChangeset in bytes */
3234 void *pChangeset, /* Pointer to buffer containing changeset */
3235 int bInvert, /* True to invert changeset */
3236 int bSkipEmpty /* True to skip empty UPDATE changes */
3238 sqlite3_changeset_iter *pRet; /* Iterator to return */
3239 int nByte; /* Number of bytes to allocate for iterator */
3241 assert( xInput==0 || (pChangeset==0 && nChangeset==0) );
3243 /* Zero the output variable in case an error occurs. */
3244 *pp = 0;
3246 /* Allocate and initialize the iterator structure. */
3247 nByte = sizeof(sqlite3_changeset_iter);
3248 pRet = (sqlite3_changeset_iter *)sqlite3_malloc(nByte);
3249 if( !pRet ) return SQLITE_NOMEM;
3250 memset(pRet, 0, sizeof(sqlite3_changeset_iter));
3251 pRet->in.aData = (u8 *)pChangeset;
3252 pRet->in.nData = nChangeset;
3253 pRet->in.xInput = xInput;
3254 pRet->in.pIn = pIn;
3255 pRet->in.bEof = (xInput ? 0 : 1);
3256 pRet->bInvert = bInvert;
3257 pRet->bSkipEmpty = bSkipEmpty;
3259 /* Populate the output variable and return success. */
3260 *pp = pRet;
3261 return SQLITE_OK;
3265 ** Create an iterator used to iterate through the contents of a changeset.
3267 int sqlite3changeset_start(
3268 sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
3269 int nChangeset, /* Size of buffer pChangeset in bytes */
3270 void *pChangeset /* Pointer to buffer containing changeset */
3272 return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0, 0);
3274 int sqlite3changeset_start_v2(
3275 sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
3276 int nChangeset, /* Size of buffer pChangeset in bytes */
3277 void *pChangeset, /* Pointer to buffer containing changeset */
3278 int flags
3280 int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
3281 return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert, 0);
3285 ** Streaming version of sqlite3changeset_start().
3287 int sqlite3changeset_start_strm(
3288 sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
3289 int (*xInput)(void *pIn, void *pData, int *pnData),
3290 void *pIn
3292 return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0, 0);
3294 int sqlite3changeset_start_v2_strm(
3295 sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
3296 int (*xInput)(void *pIn, void *pData, int *pnData),
3297 void *pIn,
3298 int flags
3300 int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
3301 return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert, 0);
3305 ** If the SessionInput object passed as the only argument is a streaming
3306 ** object and the buffer is full, discard some data to free up space.
3308 static void sessionDiscardData(SessionInput *pIn){
3309 if( pIn->xInput && pIn->iNext>=sessions_strm_chunk_size ){
3310 int nMove = pIn->buf.nBuf - pIn->iNext;
3311 assert( nMove>=0 );
3312 if( nMove>0 ){
3313 memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove);
3315 pIn->buf.nBuf -= pIn->iNext;
3316 pIn->iNext = 0;
3317 pIn->nData = pIn->buf.nBuf;
3322 ** Ensure that there are at least nByte bytes available in the buffer. Or,
3323 ** if there are not nByte bytes remaining in the input, that all available
3324 ** data is in the buffer.
3326 ** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
3328 static int sessionInputBuffer(SessionInput *pIn, int nByte){
3329 int rc = SQLITE_OK;
3330 if( pIn->xInput ){
3331 while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){
3332 int nNew = sessions_strm_chunk_size;
3334 if( pIn->bNoDiscard==0 ) sessionDiscardData(pIn);
3335 if( SQLITE_OK==sessionBufferGrow(&pIn->buf, nNew, &rc) ){
3336 rc = pIn->xInput(pIn->pIn, &pIn->buf.aBuf[pIn->buf.nBuf], &nNew);
3337 if( nNew==0 ){
3338 pIn->bEof = 1;
3339 }else{
3340 pIn->buf.nBuf += nNew;
3344 pIn->aData = pIn->buf.aBuf;
3345 pIn->nData = pIn->buf.nBuf;
3348 return rc;
3352 ** When this function is called, *ppRec points to the start of a record
3353 ** that contains nCol values. This function advances the pointer *ppRec
3354 ** until it points to the byte immediately following that record.
3356 static void sessionSkipRecord(
3357 u8 **ppRec, /* IN/OUT: Record pointer */
3358 int nCol /* Number of values in record */
3360 u8 *aRec = *ppRec;
3361 int i;
3362 for(i=0; i<nCol; i++){
3363 int eType = *aRec++;
3364 if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
3365 int nByte;
3366 aRec += sessionVarintGet((u8*)aRec, &nByte);
3367 aRec += nByte;
3368 }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
3369 aRec += 8;
3373 *ppRec = aRec;
3377 ** This function sets the value of the sqlite3_value object passed as the
3378 ** first argument to a copy of the string or blob held in the aData[]
3379 ** buffer. SQLITE_OK is returned if successful, or SQLITE_NOMEM if an OOM
3380 ** error occurs.
3382 static int sessionValueSetStr(
3383 sqlite3_value *pVal, /* Set the value of this object */
3384 u8 *aData, /* Buffer containing string or blob data */
3385 int nData, /* Size of buffer aData[] in bytes */
3386 u8 enc /* String encoding (0 for blobs) */
3388 /* In theory this code could just pass SQLITE_TRANSIENT as the final
3389 ** argument to sqlite3ValueSetStr() and have the copy created
3390 ** automatically. But doing so makes it difficult to detect any OOM
3391 ** error. Hence the code to create the copy externally. */
3392 u8 *aCopy = sqlite3_malloc64((sqlite3_int64)nData+1);
3393 if( aCopy==0 ) return SQLITE_NOMEM;
3394 memcpy(aCopy, aData, nData);
3395 sqlite3ValueSetStr(pVal, nData, (char*)aCopy, enc, sqlite3_free);
3396 return SQLITE_OK;
3400 ** Deserialize a single record from a buffer in memory. See "RECORD FORMAT"
3401 ** for details.
3403 ** When this function is called, *paChange points to the start of the record
3404 ** to deserialize. Assuming no error occurs, *paChange is set to point to
3405 ** one byte after the end of the same record before this function returns.
3406 ** If the argument abPK is NULL, then the record contains nCol values. Or,
3407 ** if abPK is other than NULL, then the record contains only the PK fields
3408 ** (in other words, it is a patchset DELETE record).
3410 ** If successful, each element of the apOut[] array (allocated by the caller)
3411 ** is set to point to an sqlite3_value object containing the value read
3412 ** from the corresponding position in the record. If that value is not
3413 ** included in the record (i.e. because the record is part of an UPDATE change
3414 ** and the field was not modified), the corresponding element of apOut[] is
3415 ** set to NULL.
3417 ** It is the responsibility of the caller to free all sqlite_value structures
3418 ** using sqlite3_free().
3420 ** If an error occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
3421 ** The apOut[] array may have been partially populated in this case.
3423 static int sessionReadRecord(
3424 SessionInput *pIn, /* Input data */
3425 int nCol, /* Number of values in record */
3426 u8 *abPK, /* Array of primary key flags, or NULL */
3427 sqlite3_value **apOut, /* Write values to this array */
3428 int *pbEmpty
3430 int i; /* Used to iterate through columns */
3431 int rc = SQLITE_OK;
3433 assert( pbEmpty==0 || *pbEmpty==0 );
3434 if( pbEmpty ) *pbEmpty = 1;
3435 for(i=0; i<nCol && rc==SQLITE_OK; i++){
3436 int eType = 0; /* Type of value (SQLITE_NULL, TEXT etc.) */
3437 if( abPK && abPK[i]==0 ) continue;
3438 rc = sessionInputBuffer(pIn, 9);
3439 if( rc==SQLITE_OK ){
3440 if( pIn->iNext>=pIn->nData ){
3441 rc = SQLITE_CORRUPT_BKPT;
3442 }else{
3443 eType = pIn->aData[pIn->iNext++];
3444 assert( apOut[i]==0 );
3445 if( eType ){
3446 if( pbEmpty ) *pbEmpty = 0;
3447 apOut[i] = sqlite3ValueNew(0);
3448 if( !apOut[i] ) rc = SQLITE_NOMEM;
3453 if( rc==SQLITE_OK ){
3454 u8 *aVal = &pIn->aData[pIn->iNext];
3455 if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
3456 int nByte;
3457 pIn->iNext += sessionVarintGet(aVal, &nByte);
3458 rc = sessionInputBuffer(pIn, nByte);
3459 if( rc==SQLITE_OK ){
3460 if( nByte<0 || nByte>pIn->nData-pIn->iNext ){
3461 rc = SQLITE_CORRUPT_BKPT;
3462 }else{
3463 u8 enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0);
3464 rc = sessionValueSetStr(apOut[i],&pIn->aData[pIn->iNext],nByte,enc);
3465 pIn->iNext += nByte;
3469 if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
3470 if( (pIn->nData-pIn->iNext)<8 ){
3471 rc = SQLITE_CORRUPT_BKPT;
3472 }else{
3473 sqlite3_int64 v = sessionGetI64(aVal);
3474 if( eType==SQLITE_INTEGER ){
3475 sqlite3VdbeMemSetInt64(apOut[i], v);
3476 }else{
3477 double d;
3478 memcpy(&d, &v, 8);
3479 sqlite3VdbeMemSetDouble(apOut[i], d);
3481 pIn->iNext += 8;
3487 return rc;
3491 ** The input pointer currently points to the second byte of a table-header.
3492 ** Specifically, to the following:
3494 ** + number of columns in table (varint)
3495 ** + array of PK flags (1 byte per column),
3496 ** + table name (nul terminated).
3498 ** This function ensures that all of the above is present in the input
3499 ** buffer (i.e. that it can be accessed without any calls to xInput()).
3500 ** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code.
3501 ** The input pointer is not moved.
3503 static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){
3504 int rc = SQLITE_OK;
3505 int nCol = 0;
3506 int nRead = 0;
3508 rc = sessionInputBuffer(pIn, 9);
3509 if( rc==SQLITE_OK ){
3510 nRead += sessionVarintGet(&pIn->aData[pIn->iNext + nRead], &nCol);
3511 /* The hard upper limit for the number of columns in an SQLite
3512 ** database table is, according to sqliteLimit.h, 32676. So
3513 ** consider any table-header that purports to have more than 65536
3514 ** columns to be corrupt. This is convenient because otherwise,
3515 ** if the (nCol>65536) condition below were omitted, a sufficiently
3516 ** large value for nCol may cause nRead to wrap around and become
3517 ** negative. Leading to a crash. */
3518 if( nCol<0 || nCol>65536 ){
3519 rc = SQLITE_CORRUPT_BKPT;
3520 }else{
3521 rc = sessionInputBuffer(pIn, nRead+nCol+100);
3522 nRead += nCol;
3526 while( rc==SQLITE_OK ){
3527 while( (pIn->iNext + nRead)<pIn->nData && pIn->aData[pIn->iNext + nRead] ){
3528 nRead++;
3530 if( (pIn->iNext + nRead)<pIn->nData ) break;
3531 rc = sessionInputBuffer(pIn, nRead + 100);
3533 *pnByte = nRead+1;
3534 return rc;
3538 ** The input pointer currently points to the first byte of the first field
3539 ** of a record consisting of nCol columns. This function ensures the entire
3540 ** record is buffered. It does not move the input pointer.
3542 ** If successful, SQLITE_OK is returned and *pnByte is set to the size of
3543 ** the record in bytes. Otherwise, an SQLite error code is returned. The
3544 ** final value of *pnByte is undefined in this case.
3546 static int sessionChangesetBufferRecord(
3547 SessionInput *pIn, /* Input data */
3548 int nCol, /* Number of columns in record */
3549 int *pnByte /* OUT: Size of record in bytes */
3551 int rc = SQLITE_OK;
3552 int nByte = 0;
3553 int i;
3554 for(i=0; rc==SQLITE_OK && i<nCol; i++){
3555 int eType;
3556 rc = sessionInputBuffer(pIn, nByte + 10);
3557 if( rc==SQLITE_OK ){
3558 eType = pIn->aData[pIn->iNext + nByte++];
3559 if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
3560 int n;
3561 nByte += sessionVarintGet(&pIn->aData[pIn->iNext+nByte], &n);
3562 nByte += n;
3563 rc = sessionInputBuffer(pIn, nByte);
3564 }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
3565 nByte += 8;
3569 *pnByte = nByte;
3570 return rc;
3574 ** The input pointer currently points to the second byte of a table-header.
3575 ** Specifically, to the following:
3577 ** + number of columns in table (varint)
3578 ** + array of PK flags (1 byte per column),
3579 ** + table name (nul terminated).
3581 ** This function decodes the table-header and populates the p->nCol,
3582 ** p->zTab and p->abPK[] variables accordingly. The p->apValue[] array is
3583 ** also allocated or resized according to the new value of p->nCol. The
3584 ** input pointer is left pointing to the byte following the table header.
3586 ** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code
3587 ** is returned and the final values of the various fields enumerated above
3588 ** are undefined.
3590 static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){
3591 int rc;
3592 int nCopy;
3593 assert( p->rc==SQLITE_OK );
3595 rc = sessionChangesetBufferTblhdr(&p->in, &nCopy);
3596 if( rc==SQLITE_OK ){
3597 int nByte;
3598 int nVarint;
3599 nVarint = sessionVarintGet(&p->in.aData[p->in.iNext], &p->nCol);
3600 if( p->nCol>0 ){
3601 nCopy -= nVarint;
3602 p->in.iNext += nVarint;
3603 nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy;
3604 p->tblhdr.nBuf = 0;
3605 sessionBufferGrow(&p->tblhdr, nByte, &rc);
3606 }else{
3607 rc = SQLITE_CORRUPT_BKPT;
3611 if( rc==SQLITE_OK ){
3612 size_t iPK = sizeof(sqlite3_value*)*p->nCol*2;
3613 memset(p->tblhdr.aBuf, 0, iPK);
3614 memcpy(&p->tblhdr.aBuf[iPK], &p->in.aData[p->in.iNext], nCopy);
3615 p->in.iNext += nCopy;
3618 p->apValue = (sqlite3_value**)p->tblhdr.aBuf;
3619 if( p->apValue==0 ){
3620 p->abPK = 0;
3621 p->zTab = 0;
3622 }else{
3623 p->abPK = (u8*)&p->apValue[p->nCol*2];
3624 p->zTab = p->abPK ? (char*)&p->abPK[p->nCol] : 0;
3626 return (p->rc = rc);
3630 ** Advance the changeset iterator to the next change. The differences between
3631 ** this function and sessionChangesetNext() are that
3633 ** * If pbEmpty is not NULL and the change is a no-op UPDATE (an UPDATE
3634 ** that modifies no columns), this function sets (*pbEmpty) to 1.
3636 ** * If the iterator is configured to skip no-op UPDATEs,
3637 ** sessionChangesetNext() does that. This function does not.
3639 static int sessionChangesetNextOne(
3640 sqlite3_changeset_iter *p, /* Changeset iterator */
3641 u8 **paRec, /* If non-NULL, store record pointer here */
3642 int *pnRec, /* If non-NULL, store size of record here */
3643 int *pbNew, /* If non-NULL, true if new table */
3644 int *pbEmpty
3646 int i;
3647 u8 op;
3649 assert( (paRec==0 && pnRec==0) || (paRec && pnRec) );
3650 assert( pbEmpty==0 || *pbEmpty==0 );
3652 /* If the iterator is in the error-state, return immediately. */
3653 if( p->rc!=SQLITE_OK ) return p->rc;
3655 /* Free the current contents of p->apValue[], if any. */
3656 if( p->apValue ){
3657 for(i=0; i<p->nCol*2; i++){
3658 sqlite3ValueFree(p->apValue[i]);
3660 memset(p->apValue, 0, sizeof(sqlite3_value*)*p->nCol*2);
3663 /* Make sure the buffer contains at least 10 bytes of input data, or all
3664 ** remaining data if there are less than 10 bytes available. This is
3665 ** sufficient either for the 'T' or 'P' byte and the varint that follows
3666 ** it, or for the two single byte values otherwise. */
3667 p->rc = sessionInputBuffer(&p->in, 2);
3668 if( p->rc!=SQLITE_OK ) return p->rc;
3670 /* If the iterator is already at the end of the changeset, return DONE. */
3671 if( p->in.iNext>=p->in.nData ){
3672 return SQLITE_DONE;
3675 sessionDiscardData(&p->in);
3676 p->in.iCurrent = p->in.iNext;
3678 op = p->in.aData[p->in.iNext++];
3679 while( op=='T' || op=='P' ){
3680 if( pbNew ) *pbNew = 1;
3681 p->bPatchset = (op=='P');
3682 if( sessionChangesetReadTblhdr(p) ) return p->rc;
3683 if( (p->rc = sessionInputBuffer(&p->in, 2)) ) return p->rc;
3684 p->in.iCurrent = p->in.iNext;
3685 if( p->in.iNext>=p->in.nData ) return SQLITE_DONE;
3686 op = p->in.aData[p->in.iNext++];
3689 if( p->zTab==0 || (p->bPatchset && p->bInvert) ){
3690 /* The first record in the changeset is not a table header. Must be a
3691 ** corrupt changeset. */
3692 assert( p->in.iNext==1 || p->zTab );
3693 return (p->rc = SQLITE_CORRUPT_BKPT);
3696 p->op = op;
3697 p->bIndirect = p->in.aData[p->in.iNext++];
3698 if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){
3699 return (p->rc = SQLITE_CORRUPT_BKPT);
3702 if( paRec ){
3703 int nVal; /* Number of values to buffer */
3704 if( p->bPatchset==0 && op==SQLITE_UPDATE ){
3705 nVal = p->nCol * 2;
3706 }else if( p->bPatchset && op==SQLITE_DELETE ){
3707 nVal = 0;
3708 for(i=0; i<p->nCol; i++) if( p->abPK[i] ) nVal++;
3709 }else{
3710 nVal = p->nCol;
3712 p->rc = sessionChangesetBufferRecord(&p->in, nVal, pnRec);
3713 if( p->rc!=SQLITE_OK ) return p->rc;
3714 *paRec = &p->in.aData[p->in.iNext];
3715 p->in.iNext += *pnRec;
3716 }else{
3717 sqlite3_value **apOld = (p->bInvert ? &p->apValue[p->nCol] : p->apValue);
3718 sqlite3_value **apNew = (p->bInvert ? p->apValue : &p->apValue[p->nCol]);
3720 /* If this is an UPDATE or DELETE, read the old.* record. */
3721 if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){
3722 u8 *abPK = p->bPatchset ? p->abPK : 0;
3723 p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld, 0);
3724 if( p->rc!=SQLITE_OK ) return p->rc;
3727 /* If this is an INSERT or UPDATE, read the new.* record. */
3728 if( p->op!=SQLITE_DELETE ){
3729 p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew, pbEmpty);
3730 if( p->rc!=SQLITE_OK ) return p->rc;
3733 if( (p->bPatchset || p->bInvert) && p->op==SQLITE_UPDATE ){
3734 /* If this is an UPDATE that is part of a patchset, then all PK and
3735 ** modified fields are present in the new.* record. The old.* record
3736 ** is currently completely empty. This block shifts the PK fields from
3737 ** new.* to old.*, to accommodate the code that reads these arrays. */
3738 for(i=0; i<p->nCol; i++){
3739 assert( p->bPatchset==0 || p->apValue[i]==0 );
3740 if( p->abPK[i] ){
3741 assert( p->apValue[i]==0 );
3742 p->apValue[i] = p->apValue[i+p->nCol];
3743 if( p->apValue[i]==0 ) return (p->rc = SQLITE_CORRUPT_BKPT);
3744 p->apValue[i+p->nCol] = 0;
3747 }else if( p->bInvert ){
3748 if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE;
3749 else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT;
3752 /* If this is an UPDATE that is part of a changeset, then check that
3753 ** there are no fields in the old.* record that are not (a) PK fields,
3754 ** or (b) also present in the new.* record.
3756 ** Such records are technically corrupt, but the rebaser was at one
3757 ** point generating them. Under most circumstances this is benign, but
3758 ** can cause spurious SQLITE_RANGE errors when applying the changeset. */
3759 if( p->bPatchset==0 && p->op==SQLITE_UPDATE){
3760 for(i=0; i<p->nCol; i++){
3761 if( p->abPK[i]==0 && p->apValue[i+p->nCol]==0 ){
3762 sqlite3ValueFree(p->apValue[i]);
3763 p->apValue[i] = 0;
3769 return SQLITE_ROW;
3773 ** Advance the changeset iterator to the next change.
3775 ** If both paRec and pnRec are NULL, then this function works like the public
3776 ** API sqlite3changeset_next(). If SQLITE_ROW is returned, then the
3777 ** sqlite3changeset_new() and old() APIs may be used to query for values.
3779 ** Otherwise, if paRec and pnRec are not NULL, then a pointer to the change
3780 ** record is written to *paRec before returning and the number of bytes in
3781 ** the record to *pnRec.
3783 ** Either way, this function returns SQLITE_ROW if the iterator is
3784 ** successfully advanced to the next change in the changeset, an SQLite
3785 ** error code if an error occurs, or SQLITE_DONE if there are no further
3786 ** changes in the changeset.
3788 static int sessionChangesetNext(
3789 sqlite3_changeset_iter *p, /* Changeset iterator */
3790 u8 **paRec, /* If non-NULL, store record pointer here */
3791 int *pnRec, /* If non-NULL, store size of record here */
3792 int *pbNew /* If non-NULL, true if new table */
3794 int bEmpty;
3795 int rc;
3796 do {
3797 bEmpty = 0;
3798 rc = sessionChangesetNextOne(p, paRec, pnRec, pbNew, &bEmpty);
3799 }while( rc==SQLITE_ROW && p->bSkipEmpty && bEmpty);
3800 return rc;
3804 ** Advance an iterator created by sqlite3changeset_start() to the next
3805 ** change in the changeset. This function may return SQLITE_ROW, SQLITE_DONE
3806 ** or SQLITE_CORRUPT.
3808 ** This function may not be called on iterators passed to a conflict handler
3809 ** callback by changeset_apply().
3811 int sqlite3changeset_next(sqlite3_changeset_iter *p){
3812 return sessionChangesetNext(p, 0, 0, 0);
3816 ** The following function extracts information on the current change
3817 ** from a changeset iterator. It may only be called after changeset_next()
3818 ** has returned SQLITE_ROW.
3820 int sqlite3changeset_op(
3821 sqlite3_changeset_iter *pIter, /* Iterator handle */
3822 const char **pzTab, /* OUT: Pointer to table name */
3823 int *pnCol, /* OUT: Number of columns in table */
3824 int *pOp, /* OUT: SQLITE_INSERT, DELETE or UPDATE */
3825 int *pbIndirect /* OUT: True if change is indirect */
3827 *pOp = pIter->op;
3828 *pnCol = pIter->nCol;
3829 *pzTab = pIter->zTab;
3830 if( pbIndirect ) *pbIndirect = pIter->bIndirect;
3831 return SQLITE_OK;
3835 ** Return information regarding the PRIMARY KEY and number of columns in
3836 ** the database table affected by the change that pIter currently points
3837 ** to. This function may only be called after changeset_next() returns
3838 ** SQLITE_ROW.
3840 int sqlite3changeset_pk(
3841 sqlite3_changeset_iter *pIter, /* Iterator object */
3842 unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */
3843 int *pnCol /* OUT: Number of entries in output array */
3845 *pabPK = pIter->abPK;
3846 if( pnCol ) *pnCol = pIter->nCol;
3847 return SQLITE_OK;
3851 ** This function may only be called while the iterator is pointing to an
3852 ** SQLITE_UPDATE or SQLITE_DELETE change (see sqlite3changeset_op()).
3853 ** Otherwise, SQLITE_MISUSE is returned.
3855 ** It sets *ppValue to point to an sqlite3_value structure containing the
3856 ** iVal'th value in the old.* record. Or, if that particular value is not
3857 ** included in the record (because the change is an UPDATE and the field
3858 ** was not modified and is not a PK column), set *ppValue to NULL.
3860 ** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is
3861 ** not modified. Otherwise, SQLITE_OK.
3863 int sqlite3changeset_old(
3864 sqlite3_changeset_iter *pIter, /* Changeset iterator */
3865 int iVal, /* Index of old.* value to retrieve */
3866 sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */
3868 if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_DELETE ){
3869 return SQLITE_MISUSE;
3871 if( iVal<0 || iVal>=pIter->nCol ){
3872 return SQLITE_RANGE;
3874 *ppValue = pIter->apValue[iVal];
3875 return SQLITE_OK;
3879 ** This function may only be called while the iterator is pointing to an
3880 ** SQLITE_UPDATE or SQLITE_INSERT change (see sqlite3changeset_op()).
3881 ** Otherwise, SQLITE_MISUSE is returned.
3883 ** It sets *ppValue to point to an sqlite3_value structure containing the
3884 ** iVal'th value in the new.* record. Or, if that particular value is not
3885 ** included in the record (because the change is an UPDATE and the field
3886 ** was not modified), set *ppValue to NULL.
3888 ** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is
3889 ** not modified. Otherwise, SQLITE_OK.
3891 int sqlite3changeset_new(
3892 sqlite3_changeset_iter *pIter, /* Changeset iterator */
3893 int iVal, /* Index of new.* value to retrieve */
3894 sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */
3896 if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_INSERT ){
3897 return SQLITE_MISUSE;
3899 if( iVal<0 || iVal>=pIter->nCol ){
3900 return SQLITE_RANGE;
3902 *ppValue = pIter->apValue[pIter->nCol+iVal];
3903 return SQLITE_OK;
3907 ** The following two macros are used internally. They are similar to the
3908 ** sqlite3changeset_new() and sqlite3changeset_old() functions, except that
3909 ** they omit all error checking and return a pointer to the requested value.
3911 #define sessionChangesetNew(pIter, iVal) (pIter)->apValue[(pIter)->nCol+(iVal)]
3912 #define sessionChangesetOld(pIter, iVal) (pIter)->apValue[(iVal)]
3915 ** This function may only be called with a changeset iterator that has been
3916 ** passed to an SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT
3917 ** conflict-handler function. Otherwise, SQLITE_MISUSE is returned.
3919 ** If successful, *ppValue is set to point to an sqlite3_value structure
3920 ** containing the iVal'th value of the conflicting record.
3922 ** If value iVal is out-of-range or some other error occurs, an SQLite error
3923 ** code is returned. Otherwise, SQLITE_OK.
3925 int sqlite3changeset_conflict(
3926 sqlite3_changeset_iter *pIter, /* Changeset iterator */
3927 int iVal, /* Index of conflict record value to fetch */
3928 sqlite3_value **ppValue /* OUT: Value from conflicting row */
3930 if( !pIter->pConflict ){
3931 return SQLITE_MISUSE;
3933 if( iVal<0 || iVal>=pIter->nCol ){
3934 return SQLITE_RANGE;
3936 *ppValue = sqlite3_column_value(pIter->pConflict, iVal);
3937 return SQLITE_OK;
3941 ** This function may only be called with an iterator passed to an
3942 ** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
3943 ** it sets the output variable to the total number of known foreign key
3944 ** violations in the destination database and returns SQLITE_OK.
3946 ** In all other cases this function returns SQLITE_MISUSE.
3948 int sqlite3changeset_fk_conflicts(
3949 sqlite3_changeset_iter *pIter, /* Changeset iterator */
3950 int *pnOut /* OUT: Number of FK violations */
3952 if( pIter->pConflict || pIter->apValue ){
3953 return SQLITE_MISUSE;
3955 *pnOut = pIter->nCol;
3956 return SQLITE_OK;
3961 ** Finalize an iterator allocated with sqlite3changeset_start().
3963 ** This function may not be called on iterators passed to a conflict handler
3964 ** callback by changeset_apply().
3966 int sqlite3changeset_finalize(sqlite3_changeset_iter *p){
3967 int rc = SQLITE_OK;
3968 if( p ){
3969 int i; /* Used to iterate through p->apValue[] */
3970 rc = p->rc;
3971 if( p->apValue ){
3972 for(i=0; i<p->nCol*2; i++) sqlite3ValueFree(p->apValue[i]);
3974 sqlite3_free(p->tblhdr.aBuf);
3975 sqlite3_free(p->in.buf.aBuf);
3976 sqlite3_free(p);
3978 return rc;
3981 static int sessionChangesetInvert(
3982 SessionInput *pInput, /* Input changeset */
3983 int (*xOutput)(void *pOut, const void *pData, int nData),
3984 void *pOut,
3985 int *pnInverted, /* OUT: Number of bytes in output changeset */
3986 void **ppInverted /* OUT: Inverse of pChangeset */
3988 int rc = SQLITE_OK; /* Return value */
3989 SessionBuffer sOut; /* Output buffer */
3990 int nCol = 0; /* Number of cols in current table */
3991 u8 *abPK = 0; /* PK array for current table */
3992 sqlite3_value **apVal = 0; /* Space for values for UPDATE inversion */
3993 SessionBuffer sPK = {0, 0, 0}; /* PK array for current table */
3995 /* Initialize the output buffer */
3996 memset(&sOut, 0, sizeof(SessionBuffer));
3998 /* Zero the output variables in case an error occurs. */
3999 if( ppInverted ){
4000 *ppInverted = 0;
4001 *pnInverted = 0;
4004 while( 1 ){
4005 u8 eType;
4007 /* Test for EOF. */
4008 if( (rc = sessionInputBuffer(pInput, 2)) ) goto finished_invert;
4009 if( pInput->iNext>=pInput->nData ) break;
4010 eType = pInput->aData[pInput->iNext];
4012 switch( eType ){
4013 case 'T': {
4014 /* A 'table' record consists of:
4016 ** * A constant 'T' character,
4017 ** * Number of columns in said table (a varint),
4018 ** * An array of nCol bytes (sPK),
4019 ** * A nul-terminated table name.
4021 int nByte;
4022 int nVar;
4023 pInput->iNext++;
4024 if( (rc = sessionChangesetBufferTblhdr(pInput, &nByte)) ){
4025 goto finished_invert;
4027 nVar = sessionVarintGet(&pInput->aData[pInput->iNext], &nCol);
4028 sPK.nBuf = 0;
4029 sessionAppendBlob(&sPK, &pInput->aData[pInput->iNext+nVar], nCol, &rc);
4030 sessionAppendByte(&sOut, eType, &rc);
4031 sessionAppendBlob(&sOut, &pInput->aData[pInput->iNext], nByte, &rc);
4032 if( rc ) goto finished_invert;
4034 pInput->iNext += nByte;
4035 sqlite3_free(apVal);
4036 apVal = 0;
4037 abPK = sPK.aBuf;
4038 break;
4041 case SQLITE_INSERT:
4042 case SQLITE_DELETE: {
4043 int nByte;
4044 int bIndirect = pInput->aData[pInput->iNext+1];
4045 int eType2 = (eType==SQLITE_DELETE ? SQLITE_INSERT : SQLITE_DELETE);
4046 pInput->iNext += 2;
4047 assert( rc==SQLITE_OK );
4048 rc = sessionChangesetBufferRecord(pInput, nCol, &nByte);
4049 sessionAppendByte(&sOut, eType2, &rc);
4050 sessionAppendByte(&sOut, bIndirect, &rc);
4051 sessionAppendBlob(&sOut, &pInput->aData[pInput->iNext], nByte, &rc);
4052 pInput->iNext += nByte;
4053 if( rc ) goto finished_invert;
4054 break;
4057 case SQLITE_UPDATE: {
4058 int iCol;
4060 if( 0==apVal ){
4061 apVal = (sqlite3_value **)sqlite3_malloc64(sizeof(apVal[0])*nCol*2);
4062 if( 0==apVal ){
4063 rc = SQLITE_NOMEM;
4064 goto finished_invert;
4066 memset(apVal, 0, sizeof(apVal[0])*nCol*2);
4069 /* Write the header for the new UPDATE change. Same as the original. */
4070 sessionAppendByte(&sOut, eType, &rc);
4071 sessionAppendByte(&sOut, pInput->aData[pInput->iNext+1], &rc);
4073 /* Read the old.* and new.* records for the update change. */
4074 pInput->iNext += 2;
4075 rc = sessionReadRecord(pInput, nCol, 0, &apVal[0], 0);
4076 if( rc==SQLITE_OK ){
4077 rc = sessionReadRecord(pInput, nCol, 0, &apVal[nCol], 0);
4080 /* Write the new old.* record. Consists of the PK columns from the
4081 ** original old.* record, and the other values from the original
4082 ** new.* record. */
4083 for(iCol=0; iCol<nCol; iCol++){
4084 sqlite3_value *pVal = apVal[iCol + (abPK[iCol] ? 0 : nCol)];
4085 sessionAppendValue(&sOut, pVal, &rc);
4088 /* Write the new new.* record. Consists of a copy of all values
4089 ** from the original old.* record, except for the PK columns, which
4090 ** are set to "undefined". */
4091 for(iCol=0; iCol<nCol; iCol++){
4092 sqlite3_value *pVal = (abPK[iCol] ? 0 : apVal[iCol]);
4093 sessionAppendValue(&sOut, pVal, &rc);
4096 for(iCol=0; iCol<nCol*2; iCol++){
4097 sqlite3ValueFree(apVal[iCol]);
4099 memset(apVal, 0, sizeof(apVal[0])*nCol*2);
4100 if( rc!=SQLITE_OK ){
4101 goto finished_invert;
4104 break;
4107 default:
4108 rc = SQLITE_CORRUPT_BKPT;
4109 goto finished_invert;
4112 assert( rc==SQLITE_OK );
4113 if( xOutput && sOut.nBuf>=sessions_strm_chunk_size ){
4114 rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
4115 sOut.nBuf = 0;
4116 if( rc!=SQLITE_OK ) goto finished_invert;
4120 assert( rc==SQLITE_OK );
4121 if( pnInverted && ALWAYS(ppInverted) ){
4122 *pnInverted = sOut.nBuf;
4123 *ppInverted = sOut.aBuf;
4124 sOut.aBuf = 0;
4125 }else if( sOut.nBuf>0 && ALWAYS(xOutput!=0) ){
4126 rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
4129 finished_invert:
4130 sqlite3_free(sOut.aBuf);
4131 sqlite3_free(apVal);
4132 sqlite3_free(sPK.aBuf);
4133 return rc;
4138 ** Invert a changeset object.
4140 int sqlite3changeset_invert(
4141 int nChangeset, /* Number of bytes in input */
4142 const void *pChangeset, /* Input changeset */
4143 int *pnInverted, /* OUT: Number of bytes in output changeset */
4144 void **ppInverted /* OUT: Inverse of pChangeset */
4146 SessionInput sInput;
4148 /* Set up the input stream */
4149 memset(&sInput, 0, sizeof(SessionInput));
4150 sInput.nData = nChangeset;
4151 sInput.aData = (u8*)pChangeset;
4153 return sessionChangesetInvert(&sInput, 0, 0, pnInverted, ppInverted);
4157 ** Streaming version of sqlite3changeset_invert().
4159 int sqlite3changeset_invert_strm(
4160 int (*xInput)(void *pIn, void *pData, int *pnData),
4161 void *pIn,
4162 int (*xOutput)(void *pOut, const void *pData, int nData),
4163 void *pOut
4165 SessionInput sInput;
4166 int rc;
4168 /* Set up the input stream */
4169 memset(&sInput, 0, sizeof(SessionInput));
4170 sInput.xInput = xInput;
4171 sInput.pIn = pIn;
4173 rc = sessionChangesetInvert(&sInput, xOutput, pOut, 0, 0);
4174 sqlite3_free(sInput.buf.aBuf);
4175 return rc;
4179 typedef struct SessionUpdate SessionUpdate;
4180 struct SessionUpdate {
4181 sqlite3_stmt *pStmt;
4182 u32 *aMask;
4183 SessionUpdate *pNext;
4186 typedef struct SessionApplyCtx SessionApplyCtx;
4187 struct SessionApplyCtx {
4188 sqlite3 *db;
4189 sqlite3_stmt *pDelete; /* DELETE statement */
4190 sqlite3_stmt *pInsert; /* INSERT statement */
4191 sqlite3_stmt *pSelect; /* SELECT statement */
4192 int nCol; /* Size of azCol[] and abPK[] arrays */
4193 const char **azCol; /* Array of column names */
4194 u8 *abPK; /* Boolean array - true if column is in PK */
4195 u32 *aUpdateMask; /* Used by sessionUpdateFind */
4196 SessionUpdate *pUp;
4197 int bStat1; /* True if table is sqlite_stat1 */
4198 int bDeferConstraints; /* True to defer constraints */
4199 int bInvertConstraints; /* Invert when iterating constraints buffer */
4200 SessionBuffer constraints; /* Deferred constraints are stored here */
4201 SessionBuffer rebase; /* Rebase information (if any) here */
4202 u8 bRebaseStarted; /* If table header is already in rebase */
4203 u8 bRebase; /* True to collect rebase information */
4204 u8 bIgnoreNoop; /* True to ignore no-op conflicts */
4205 int bRowid;
4208 /* Number of prepared UPDATE statements to cache. */
4209 #define SESSION_UPDATE_CACHE_SZ 12
4212 ** Find a prepared UPDATE statement suitable for the UPDATE step currently
4213 ** being visited by the iterator. The UPDATE is of the form:
4215 ** UPDATE tbl SET col = ?, col2 = ? WHERE pk1 IS ? AND pk2 IS ?
4217 static int sessionUpdateFind(
4218 sqlite3_changeset_iter *pIter,
4219 SessionApplyCtx *p,
4220 int bPatchset,
4221 sqlite3_stmt **ppStmt
4223 int rc = SQLITE_OK;
4224 SessionUpdate *pUp = 0;
4225 int nCol = pIter->nCol;
4226 int nU32 = (pIter->nCol+33)/32;
4227 int ii;
4229 if( p->aUpdateMask==0 ){
4230 p->aUpdateMask = sqlite3_malloc(nU32*sizeof(u32));
4231 if( p->aUpdateMask==0 ){
4232 rc = SQLITE_NOMEM;
4236 if( rc==SQLITE_OK ){
4237 memset(p->aUpdateMask, 0, nU32*sizeof(u32));
4238 rc = SQLITE_CORRUPT;
4239 for(ii=0; ii<pIter->nCol; ii++){
4240 if( sessionChangesetNew(pIter, ii) ){
4241 p->aUpdateMask[ii/32] |= (1<<(ii%32));
4242 rc = SQLITE_OK;
4247 if( rc==SQLITE_OK ){
4248 if( bPatchset ) p->aUpdateMask[nCol/32] |= (1<<(nCol%32));
4250 if( p->pUp ){
4251 int nUp = 0;
4252 SessionUpdate **pp = &p->pUp;
4253 while( 1 ){
4254 nUp++;
4255 if( 0==memcmp(p->aUpdateMask, (*pp)->aMask, nU32*sizeof(u32)) ){
4256 pUp = *pp;
4257 *pp = pUp->pNext;
4258 pUp->pNext = p->pUp;
4259 p->pUp = pUp;
4260 break;
4263 if( (*pp)->pNext ){
4264 pp = &(*pp)->pNext;
4265 }else{
4266 if( nUp>=SESSION_UPDATE_CACHE_SZ ){
4267 sqlite3_finalize((*pp)->pStmt);
4268 sqlite3_free(*pp);
4269 *pp = 0;
4271 break;
4276 if( pUp==0 ){
4277 int nByte = sizeof(SessionUpdate) * nU32*sizeof(u32);
4278 int bStat1 = (sqlite3_stricmp(pIter->zTab, "sqlite_stat1")==0);
4279 pUp = (SessionUpdate*)sqlite3_malloc(nByte);
4280 if( pUp==0 ){
4281 rc = SQLITE_NOMEM;
4282 }else{
4283 const char *zSep = "";
4284 SessionBuffer buf;
4286 memset(&buf, 0, sizeof(buf));
4287 pUp->aMask = (u32*)&pUp[1];
4288 memcpy(pUp->aMask, p->aUpdateMask, nU32*sizeof(u32));
4290 sessionAppendStr(&buf, "UPDATE main.", &rc);
4291 sessionAppendIdent(&buf, pIter->zTab, &rc);
4292 sessionAppendStr(&buf, " SET ", &rc);
4294 /* Create the assignments part of the UPDATE */
4295 for(ii=0; ii<pIter->nCol; ii++){
4296 if( p->abPK[ii]==0 && sessionChangesetNew(pIter, ii) ){
4297 sessionAppendStr(&buf, zSep, &rc);
4298 sessionAppendIdent(&buf, p->azCol[ii], &rc);
4299 sessionAppendStr(&buf, " = ?", &rc);
4300 sessionAppendInteger(&buf, ii*2+1, &rc);
4301 zSep = ", ";
4305 /* Create the WHERE clause part of the UPDATE */
4306 zSep = "";
4307 sessionAppendStr(&buf, " WHERE ", &rc);
4308 for(ii=0; ii<pIter->nCol; ii++){
4309 if( p->abPK[ii] || (bPatchset==0 && sessionChangesetOld(pIter, ii)) ){
4310 sessionAppendStr(&buf, zSep, &rc);
4311 if( bStat1 && ii==1 ){
4312 assert( sqlite3_stricmp(p->azCol[ii], "idx")==0 );
4313 sessionAppendStr(&buf,
4314 "idx IS CASE "
4315 "WHEN length(?4)=0 AND typeof(?4)='blob' THEN NULL "
4316 "ELSE ?4 END ", &rc
4318 }else{
4319 sessionAppendIdent(&buf, p->azCol[ii], &rc);
4320 sessionAppendStr(&buf, " IS ?", &rc);
4321 sessionAppendInteger(&buf, ii*2+2, &rc);
4323 zSep = " AND ";
4327 if( rc==SQLITE_OK ){
4328 char *zSql = (char*)buf.aBuf;
4329 rc = sqlite3_prepare_v2(p->db, zSql, buf.nBuf, &pUp->pStmt, 0);
4332 if( rc!=SQLITE_OK ){
4333 sqlite3_free(pUp);
4334 pUp = 0;
4335 }else{
4336 pUp->pNext = p->pUp;
4337 p->pUp = pUp;
4339 sqlite3_free(buf.aBuf);
4344 assert( (rc==SQLITE_OK)==(pUp!=0) );
4345 if( pUp ){
4346 *ppStmt = pUp->pStmt;
4347 }else{
4348 *ppStmt = 0;
4350 return rc;
4354 ** Free all cached UPDATE statements.
4356 static void sessionUpdateFree(SessionApplyCtx *p){
4357 SessionUpdate *pUp;
4358 SessionUpdate *pNext;
4359 for(pUp=p->pUp; pUp; pUp=pNext){
4360 pNext = pUp->pNext;
4361 sqlite3_finalize(pUp->pStmt);
4362 sqlite3_free(pUp);
4364 p->pUp = 0;
4365 sqlite3_free(p->aUpdateMask);
4366 p->aUpdateMask = 0;
4370 ** Formulate a statement to DELETE a row from database db. Assuming a table
4371 ** structure like this:
4373 ** CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
4375 ** The DELETE statement looks like this:
4377 ** DELETE FROM x WHERE a = :1 AND c = :3 AND (:5 OR b IS :2 AND d IS :4)
4379 ** Variable :5 (nCol+1) is a boolean. It should be set to 0 if we require
4380 ** matching b and d values, or 1 otherwise. The second case comes up if the
4381 ** conflict handler is invoked with NOTFOUND and returns CHANGESET_REPLACE.
4383 ** If successful, SQLITE_OK is returned and SessionApplyCtx.pDelete is left
4384 ** pointing to the prepared version of the SQL statement.
4386 static int sessionDeleteRow(
4387 sqlite3 *db, /* Database handle */
4388 const char *zTab, /* Table name */
4389 SessionApplyCtx *p /* Session changeset-apply context */
4391 int i;
4392 const char *zSep = "";
4393 int rc = SQLITE_OK;
4394 SessionBuffer buf = {0, 0, 0};
4395 int nPk = 0;
4397 sessionAppendStr(&buf, "DELETE FROM main.", &rc);
4398 sessionAppendIdent(&buf, zTab, &rc);
4399 sessionAppendStr(&buf, " WHERE ", &rc);
4401 for(i=0; i<p->nCol; i++){
4402 if( p->abPK[i] ){
4403 nPk++;
4404 sessionAppendStr(&buf, zSep, &rc);
4405 sessionAppendIdent(&buf, p->azCol[i], &rc);
4406 sessionAppendStr(&buf, " = ?", &rc);
4407 sessionAppendInteger(&buf, i+1, &rc);
4408 zSep = " AND ";
4412 if( nPk<p->nCol ){
4413 sessionAppendStr(&buf, " AND (?", &rc);
4414 sessionAppendInteger(&buf, p->nCol+1, &rc);
4415 sessionAppendStr(&buf, " OR ", &rc);
4417 zSep = "";
4418 for(i=0; i<p->nCol; i++){
4419 if( !p->abPK[i] ){
4420 sessionAppendStr(&buf, zSep, &rc);
4421 sessionAppendIdent(&buf, p->azCol[i], &rc);
4422 sessionAppendStr(&buf, " IS ?", &rc);
4423 sessionAppendInteger(&buf, i+1, &rc);
4424 zSep = "AND ";
4427 sessionAppendStr(&buf, ")", &rc);
4430 if( rc==SQLITE_OK ){
4431 rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pDelete, 0);
4433 sqlite3_free(buf.aBuf);
4435 return rc;
4439 ** Formulate and prepare an SQL statement to query table zTab by primary
4440 ** key. Assuming the following table structure:
4442 ** CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
4444 ** The SELECT statement looks like this:
4446 ** SELECT * FROM x WHERE a = ?1 AND c = ?3
4448 ** If successful, SQLITE_OK is returned and SessionApplyCtx.pSelect is left
4449 ** pointing to the prepared version of the SQL statement.
4451 static int sessionSelectRow(
4452 sqlite3 *db, /* Database handle */
4453 const char *zTab, /* Table name */
4454 SessionApplyCtx *p /* Session changeset-apply context */
4456 /* TODO */
4457 return sessionSelectStmt(db, p->bIgnoreNoop,
4458 "main", zTab, p->bRowid, p->nCol, p->azCol, p->abPK, &p->pSelect
4463 ** Formulate and prepare an INSERT statement to add a record to table zTab.
4464 ** For example:
4466 ** INSERT INTO main."zTab" VALUES(?1, ?2, ?3 ...);
4468 ** If successful, SQLITE_OK is returned and SessionApplyCtx.pInsert is left
4469 ** pointing to the prepared version of the SQL statement.
4471 static int sessionInsertRow(
4472 sqlite3 *db, /* Database handle */
4473 const char *zTab, /* Table name */
4474 SessionApplyCtx *p /* Session changeset-apply context */
4476 int rc = SQLITE_OK;
4477 int i;
4478 SessionBuffer buf = {0, 0, 0};
4480 sessionAppendStr(&buf, "INSERT INTO main.", &rc);
4481 sessionAppendIdent(&buf, zTab, &rc);
4482 sessionAppendStr(&buf, "(", &rc);
4483 for(i=0; i<p->nCol; i++){
4484 if( i!=0 ) sessionAppendStr(&buf, ", ", &rc);
4485 sessionAppendIdent(&buf, p->azCol[i], &rc);
4488 sessionAppendStr(&buf, ") VALUES(?", &rc);
4489 for(i=1; i<p->nCol; i++){
4490 sessionAppendStr(&buf, ", ?", &rc);
4492 sessionAppendStr(&buf, ")", &rc);
4494 if( rc==SQLITE_OK ){
4495 rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pInsert, 0);
4497 sqlite3_free(buf.aBuf);
4498 return rc;
4501 static int sessionPrepare(sqlite3 *db, sqlite3_stmt **pp, const char *zSql){
4502 return sqlite3_prepare_v2(db, zSql, -1, pp, 0);
4506 ** Prepare statements for applying changes to the sqlite_stat1 table.
4507 ** These are similar to those created by sessionSelectRow(),
4508 ** sessionInsertRow(), sessionUpdateRow() and sessionDeleteRow() for
4509 ** other tables.
4511 static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){
4512 int rc = sessionSelectRow(db, "sqlite_stat1", p);
4513 if( rc==SQLITE_OK ){
4514 rc = sessionPrepare(db, &p->pInsert,
4515 "INSERT INTO main.sqlite_stat1 VALUES(?1, "
4516 "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END, "
4517 "?3)"
4520 if( rc==SQLITE_OK ){
4521 rc = sessionPrepare(db, &p->pDelete,
4522 "DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS "
4523 "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END "
4524 "AND (?4 OR stat IS ?3)"
4527 return rc;
4531 ** A wrapper around sqlite3_bind_value() that detects an extra problem.
4532 ** See comments in the body of this function for details.
4534 static int sessionBindValue(
4535 sqlite3_stmt *pStmt, /* Statement to bind value to */
4536 int i, /* Parameter number to bind to */
4537 sqlite3_value *pVal /* Value to bind */
4539 int eType = sqlite3_value_type(pVal);
4540 /* COVERAGE: The (pVal->z==0) branch is never true using current versions
4541 ** of SQLite. If a malloc fails in an sqlite3_value_xxx() function, either
4542 ** the (pVal->z) variable remains as it was or the type of the value is
4543 ** set to SQLITE_NULL. */
4544 if( (eType==SQLITE_TEXT || eType==SQLITE_BLOB) && pVal->z==0 ){
4545 /* This condition occurs when an earlier OOM in a call to
4546 ** sqlite3_value_text() or sqlite3_value_blob() (perhaps from within
4547 ** a conflict-handler) has zeroed the pVal->z pointer. Return NOMEM. */
4548 return SQLITE_NOMEM;
4550 return sqlite3_bind_value(pStmt, i, pVal);
4554 ** Iterator pIter must point to an SQLITE_INSERT entry. This function
4555 ** transfers new.* values from the current iterator entry to statement
4556 ** pStmt. The table being inserted into has nCol columns.
4558 ** New.* value $i from the iterator is bound to variable ($i+1) of
4559 ** statement pStmt. If parameter abPK is NULL, all values from 0 to (nCol-1)
4560 ** are transfered to the statement. Otherwise, if abPK is not NULL, it points
4561 ** to an array nCol elements in size. In this case only those values for
4562 ** which abPK[$i] is true are read from the iterator and bound to the
4563 ** statement.
4565 ** An SQLite error code is returned if an error occurs. Otherwise, SQLITE_OK.
4567 static int sessionBindRow(
4568 sqlite3_changeset_iter *pIter, /* Iterator to read values from */
4569 int(*xValue)(sqlite3_changeset_iter *, int, sqlite3_value **),
4570 int nCol, /* Number of columns */
4571 u8 *abPK, /* If not NULL, bind only if true */
4572 sqlite3_stmt *pStmt /* Bind values to this statement */
4574 int i;
4575 int rc = SQLITE_OK;
4577 /* Neither sqlite3changeset_old or sqlite3changeset_new can fail if the
4578 ** argument iterator points to a suitable entry. Make sure that xValue
4579 ** is one of these to guarantee that it is safe to ignore the return
4580 ** in the code below. */
4581 assert( xValue==sqlite3changeset_old || xValue==sqlite3changeset_new );
4583 for(i=0; rc==SQLITE_OK && i<nCol; i++){
4584 if( !abPK || abPK[i] ){
4585 sqlite3_value *pVal = 0;
4586 (void)xValue(pIter, i, &pVal);
4587 if( pVal==0 ){
4588 /* The value in the changeset was "undefined". This indicates a
4589 ** corrupt changeset blob. */
4590 rc = SQLITE_CORRUPT_BKPT;
4591 }else{
4592 rc = sessionBindValue(pStmt, i+1, pVal);
4596 return rc;
4600 ** SQL statement pSelect is as generated by the sessionSelectRow() function.
4601 ** This function binds the primary key values from the change that changeset
4602 ** iterator pIter points to to the SELECT and attempts to seek to the table
4603 ** entry. If a row is found, the SELECT statement left pointing at the row
4604 ** and SQLITE_ROW is returned. Otherwise, if no row is found and no error
4605 ** has occured, the statement is reset and SQLITE_OK is returned. If an
4606 ** error occurs, the statement is reset and an SQLite error code is returned.
4608 ** If this function returns SQLITE_ROW, the caller must eventually reset()
4609 ** statement pSelect. If any other value is returned, the statement does
4610 ** not require a reset().
4612 ** If the iterator currently points to an INSERT record, bind values from the
4613 ** new.* record to the SELECT statement. Or, if it points to a DELETE or
4614 ** UPDATE, bind values from the old.* record.
4616 static int sessionSeekToRow(
4617 sqlite3_changeset_iter *pIter, /* Changeset iterator */
4618 SessionApplyCtx *p
4620 sqlite3_stmt *pSelect = p->pSelect;
4621 int rc; /* Return code */
4622 int nCol; /* Number of columns in table */
4623 int op; /* Changset operation (SQLITE_UPDATE etc.) */
4624 const char *zDummy; /* Unused */
4626 sqlite3_clear_bindings(pSelect);
4627 sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);
4628 rc = sessionBindRow(pIter,
4629 op==SQLITE_INSERT ? sqlite3changeset_new : sqlite3changeset_old,
4630 nCol, p->abPK, pSelect
4633 if( op!=SQLITE_DELETE && p->bIgnoreNoop ){
4634 int ii;
4635 for(ii=0; rc==SQLITE_OK && ii<nCol; ii++){
4636 if( p->abPK[ii]==0 ){
4637 sqlite3_value *pVal = 0;
4638 sqlite3changeset_new(pIter, ii, &pVal);
4639 sqlite3_bind_int(pSelect, ii+1+nCol, (pVal==0));
4640 if( pVal ) rc = sessionBindValue(pSelect, ii+1, pVal);
4645 if( rc==SQLITE_OK ){
4646 rc = sqlite3_step(pSelect);
4647 if( rc!=SQLITE_ROW ) rc = sqlite3_reset(pSelect);
4650 return rc;
4654 ** This function is called from within sqlite3changeset_apply_v2() when
4655 ** a conflict is encountered and resolved using conflict resolution
4656 ** mode eType (either SQLITE_CHANGESET_OMIT or SQLITE_CHANGESET_REPLACE)..
4657 ** It adds a conflict resolution record to the buffer in
4658 ** SessionApplyCtx.rebase, which will eventually be returned to the caller
4659 ** of apply_v2() as the "rebase" buffer.
4661 ** Return SQLITE_OK if successful, or an SQLite error code otherwise.
4663 static int sessionRebaseAdd(
4664 SessionApplyCtx *p, /* Apply context */
4665 int eType, /* Conflict resolution (OMIT or REPLACE) */
4666 sqlite3_changeset_iter *pIter /* Iterator pointing at current change */
4668 int rc = SQLITE_OK;
4669 if( p->bRebase ){
4670 int i;
4671 int eOp = pIter->op;
4672 if( p->bRebaseStarted==0 ){
4673 /* Append a table-header to the rebase buffer */
4674 const char *zTab = pIter->zTab;
4675 sessionAppendByte(&p->rebase, 'T', &rc);
4676 sessionAppendVarint(&p->rebase, p->nCol, &rc);
4677 sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc);
4678 sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc);
4679 p->bRebaseStarted = 1;
4682 assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT );
4683 assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE );
4685 sessionAppendByte(&p->rebase,
4686 (eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc
4688 sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc);
4689 for(i=0; i<p->nCol; i++){
4690 sqlite3_value *pVal = 0;
4691 if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){
4692 sqlite3changeset_old(pIter, i, &pVal);
4693 }else{
4694 sqlite3changeset_new(pIter, i, &pVal);
4696 sessionAppendValue(&p->rebase, pVal, &rc);
4699 return rc;
4703 ** Invoke the conflict handler for the change that the changeset iterator
4704 ** currently points to.
4706 ** Argument eType must be either CHANGESET_DATA or CHANGESET_CONFLICT.
4707 ** If argument pbReplace is NULL, then the type of conflict handler invoked
4708 ** depends solely on eType, as follows:
4710 ** eType value Value passed to xConflict
4711 ** -------------------------------------------------
4712 ** CHANGESET_DATA CHANGESET_NOTFOUND
4713 ** CHANGESET_CONFLICT CHANGESET_CONSTRAINT
4715 ** Or, if pbReplace is not NULL, then an attempt is made to find an existing
4716 ** record with the same primary key as the record about to be deleted, updated
4717 ** or inserted. If such a record can be found, it is available to the conflict
4718 ** handler as the "conflicting" record. In this case the type of conflict
4719 ** handler invoked is as follows:
4721 ** eType value PK Record found? Value passed to xConflict
4722 ** ----------------------------------------------------------------
4723 ** CHANGESET_DATA Yes CHANGESET_DATA
4724 ** CHANGESET_DATA No CHANGESET_NOTFOUND
4725 ** CHANGESET_CONFLICT Yes CHANGESET_CONFLICT
4726 ** CHANGESET_CONFLICT No CHANGESET_CONSTRAINT
4728 ** If pbReplace is not NULL, and a record with a matching PK is found, and
4729 ** the conflict handler function returns SQLITE_CHANGESET_REPLACE, *pbReplace
4730 ** is set to non-zero before returning SQLITE_OK.
4732 ** If the conflict handler returns SQLITE_CHANGESET_ABORT, SQLITE_ABORT is
4733 ** returned. Or, if the conflict handler returns an invalid value,
4734 ** SQLITE_MISUSE. If the conflict handler returns SQLITE_CHANGESET_OMIT,
4735 ** this function returns SQLITE_OK.
4737 static int sessionConflictHandler(
4738 int eType, /* Either CHANGESET_DATA or CONFLICT */
4739 SessionApplyCtx *p, /* changeset_apply() context */
4740 sqlite3_changeset_iter *pIter, /* Changeset iterator */
4741 int(*xConflict)(void *, int, sqlite3_changeset_iter*),
4742 void *pCtx, /* First argument for conflict handler */
4743 int *pbReplace /* OUT: Set to true if PK row is found */
4745 int res = 0; /* Value returned by conflict handler */
4746 int rc;
4747 int nCol;
4748 int op;
4749 const char *zDummy;
4751 sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);
4753 assert( eType==SQLITE_CHANGESET_CONFLICT || eType==SQLITE_CHANGESET_DATA );
4754 assert( SQLITE_CHANGESET_CONFLICT+1==SQLITE_CHANGESET_CONSTRAINT );
4755 assert( SQLITE_CHANGESET_DATA+1==SQLITE_CHANGESET_NOTFOUND );
4757 /* Bind the new.* PRIMARY KEY values to the SELECT statement. */
4758 if( pbReplace ){
4759 rc = sessionSeekToRow(pIter, p);
4760 }else{
4761 rc = SQLITE_OK;
4764 if( rc==SQLITE_ROW ){
4765 /* There exists another row with the new.* primary key. */
4766 if( p->bIgnoreNoop
4767 && sqlite3_column_int(p->pSelect, sqlite3_column_count(p->pSelect)-1)
4769 res = SQLITE_CHANGESET_OMIT;
4770 }else{
4771 pIter->pConflict = p->pSelect;
4772 res = xConflict(pCtx, eType, pIter);
4773 pIter->pConflict = 0;
4775 rc = sqlite3_reset(p->pSelect);
4776 }else if( rc==SQLITE_OK ){
4777 if( p->bDeferConstraints && eType==SQLITE_CHANGESET_CONFLICT ){
4778 /* Instead of invoking the conflict handler, append the change blob
4779 ** to the SessionApplyCtx.constraints buffer. */
4780 u8 *aBlob = &pIter->in.aData[pIter->in.iCurrent];
4781 int nBlob = pIter->in.iNext - pIter->in.iCurrent;
4782 sessionAppendBlob(&p->constraints, aBlob, nBlob, &rc);
4783 return SQLITE_OK;
4784 }else{
4785 /* No other row with the new.* primary key. */
4786 res = xConflict(pCtx, eType+1, pIter);
4787 if( res==SQLITE_CHANGESET_REPLACE ) rc = SQLITE_MISUSE;
4791 if( rc==SQLITE_OK ){
4792 switch( res ){
4793 case SQLITE_CHANGESET_REPLACE:
4794 assert( pbReplace );
4795 *pbReplace = 1;
4796 break;
4798 case SQLITE_CHANGESET_OMIT:
4799 break;
4801 case SQLITE_CHANGESET_ABORT:
4802 rc = SQLITE_ABORT;
4803 break;
4805 default:
4806 rc = SQLITE_MISUSE;
4807 break;
4809 if( rc==SQLITE_OK ){
4810 rc = sessionRebaseAdd(p, res, pIter);
4814 return rc;
4818 ** Attempt to apply the change that the iterator passed as the first argument
4819 ** currently points to to the database. If a conflict is encountered, invoke
4820 ** the conflict handler callback.
4822 ** If argument pbRetry is NULL, then ignore any CHANGESET_DATA conflict. If
4823 ** one is encountered, update or delete the row with the matching primary key
4824 ** instead. Or, if pbRetry is not NULL and a CHANGESET_DATA conflict occurs,
4825 ** invoke the conflict handler. If it returns CHANGESET_REPLACE, set *pbRetry
4826 ** to true before returning. In this case the caller will invoke this function
4827 ** again, this time with pbRetry set to NULL.
4829 ** If argument pbReplace is NULL and a CHANGESET_CONFLICT conflict is
4830 ** encountered invoke the conflict handler with CHANGESET_CONSTRAINT instead.
4831 ** Or, if pbReplace is not NULL, invoke it with CHANGESET_CONFLICT. If such
4832 ** an invocation returns SQLITE_CHANGESET_REPLACE, set *pbReplace to true
4833 ** before retrying. In this case the caller attempts to remove the conflicting
4834 ** row before invoking this function again, this time with pbReplace set
4835 ** to NULL.
4837 ** If any conflict handler returns SQLITE_CHANGESET_ABORT, this function
4838 ** returns SQLITE_ABORT. Otherwise, if no error occurs, SQLITE_OK is
4839 ** returned.
4841 static int sessionApplyOneOp(
4842 sqlite3_changeset_iter *pIter, /* Changeset iterator */
4843 SessionApplyCtx *p, /* changeset_apply() context */
4844 int(*xConflict)(void *, int, sqlite3_changeset_iter *),
4845 void *pCtx, /* First argument for the conflict handler */
4846 int *pbReplace, /* OUT: True to remove PK row and retry */
4847 int *pbRetry /* OUT: True to retry. */
4849 const char *zDummy;
4850 int op;
4851 int nCol;
4852 int rc = SQLITE_OK;
4854 assert( p->pDelete && p->pInsert && p->pSelect );
4855 assert( p->azCol && p->abPK );
4856 assert( !pbReplace || *pbReplace==0 );
4858 sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);
4860 if( op==SQLITE_DELETE ){
4862 /* Bind values to the DELETE statement. If conflict handling is required,
4863 ** bind values for all columns and set bound variable (nCol+1) to true.
4864 ** Or, if conflict handling is not required, bind just the PK column
4865 ** values and, if it exists, set (nCol+1) to false. Conflict handling
4866 ** is not required if:
4868 ** * this is a patchset, or
4869 ** * (pbRetry==0), or
4870 ** * all columns of the table are PK columns (in this case there is
4871 ** no (nCol+1) variable to bind to).
4873 u8 *abPK = (pIter->bPatchset ? p->abPK : 0);
4874 rc = sessionBindRow(pIter, sqlite3changeset_old, nCol, abPK, p->pDelete);
4875 if( rc==SQLITE_OK && sqlite3_bind_parameter_count(p->pDelete)>nCol ){
4876 rc = sqlite3_bind_int(p->pDelete, nCol+1, (pbRetry==0 || abPK));
4878 if( rc!=SQLITE_OK ) return rc;
4880 sqlite3_step(p->pDelete);
4881 rc = sqlite3_reset(p->pDelete);
4882 if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 && p->bIgnoreNoop==0 ){
4883 rc = sessionConflictHandler(
4884 SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry
4886 }else if( (rc&0xff)==SQLITE_CONSTRAINT ){
4887 rc = sessionConflictHandler(
4888 SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0
4892 }else if( op==SQLITE_UPDATE ){
4893 int i;
4894 sqlite3_stmt *pUp = 0;
4895 int bPatchset = (pbRetry==0 || pIter->bPatchset);
4897 rc = sessionUpdateFind(pIter, p, bPatchset, &pUp);
4899 /* Bind values to the UPDATE statement. */
4900 for(i=0; rc==SQLITE_OK && i<nCol; i++){
4901 sqlite3_value *pOld = sessionChangesetOld(pIter, i);
4902 sqlite3_value *pNew = sessionChangesetNew(pIter, i);
4903 if( p->abPK[i] || (bPatchset==0 && pOld) ){
4904 rc = sessionBindValue(pUp, i*2+2, pOld);
4906 if( rc==SQLITE_OK && pNew ){
4907 rc = sessionBindValue(pUp, i*2+1, pNew);
4910 if( rc!=SQLITE_OK ) return rc;
4912 /* Attempt the UPDATE. In the case of a NOTFOUND or DATA conflict,
4913 ** the result will be SQLITE_OK with 0 rows modified. */
4914 sqlite3_step(pUp);
4915 rc = sqlite3_reset(pUp);
4917 if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){
4918 /* A NOTFOUND or DATA error. Search the table to see if it contains
4919 ** a row with a matching primary key. If so, this is a DATA conflict.
4920 ** Otherwise, if there is no primary key match, it is a NOTFOUND. */
4922 rc = sessionConflictHandler(
4923 SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry
4926 }else if( (rc&0xff)==SQLITE_CONSTRAINT ){
4927 /* This is always a CONSTRAINT conflict. */
4928 rc = sessionConflictHandler(
4929 SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0
4933 }else{
4934 assert( op==SQLITE_INSERT );
4935 if( p->bStat1 ){
4936 /* Check if there is a conflicting row. For sqlite_stat1, this needs
4937 ** to be done using a SELECT, as there is no PRIMARY KEY in the
4938 ** database schema to throw an exception if a duplicate is inserted. */
4939 rc = sessionSeekToRow(pIter, p);
4940 if( rc==SQLITE_ROW ){
4941 rc = SQLITE_CONSTRAINT;
4942 sqlite3_reset(p->pSelect);
4946 if( rc==SQLITE_OK ){
4947 rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
4948 if( rc!=SQLITE_OK ) return rc;
4950 sqlite3_step(p->pInsert);
4951 rc = sqlite3_reset(p->pInsert);
4954 if( (rc&0xff)==SQLITE_CONSTRAINT ){
4955 rc = sessionConflictHandler(
4956 SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace
4961 return rc;
4965 ** Attempt to apply the change that the iterator passed as the first argument
4966 ** currently points to to the database. If a conflict is encountered, invoke
4967 ** the conflict handler callback.
4969 ** The difference between this function and sessionApplyOne() is that this
4970 ** function handles the case where the conflict-handler is invoked and
4971 ** returns SQLITE_CHANGESET_REPLACE - indicating that the change should be
4972 ** retried in some manner.
4974 static int sessionApplyOneWithRetry(
4975 sqlite3 *db, /* Apply change to "main" db of this handle */
4976 sqlite3_changeset_iter *pIter, /* Changeset iterator to read change from */
4977 SessionApplyCtx *pApply, /* Apply context */
4978 int(*xConflict)(void*, int, sqlite3_changeset_iter*),
4979 void *pCtx /* First argument passed to xConflict */
4981 int bReplace = 0;
4982 int bRetry = 0;
4983 int rc;
4985 rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, &bReplace, &bRetry);
4986 if( rc==SQLITE_OK ){
4987 /* If the bRetry flag is set, the change has not been applied due to an
4988 ** SQLITE_CHANGESET_DATA problem (i.e. this is an UPDATE or DELETE and
4989 ** a row with the correct PK is present in the db, but one or more other
4990 ** fields do not contain the expected values) and the conflict handler
4991 ** returned SQLITE_CHANGESET_REPLACE. In this case retry the operation,
4992 ** but pass NULL as the final argument so that sessionApplyOneOp() ignores
4993 ** the SQLITE_CHANGESET_DATA problem. */
4994 if( bRetry ){
4995 assert( pIter->op==SQLITE_UPDATE || pIter->op==SQLITE_DELETE );
4996 rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0);
4999 /* If the bReplace flag is set, the change is an INSERT that has not
5000 ** been performed because the database already contains a row with the
5001 ** specified primary key and the conflict handler returned
5002 ** SQLITE_CHANGESET_REPLACE. In this case remove the conflicting row
5003 ** before reattempting the INSERT. */
5004 else if( bReplace ){
5005 assert( pIter->op==SQLITE_INSERT );
5006 rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0);
5007 if( rc==SQLITE_OK ){
5008 rc = sessionBindRow(pIter,
5009 sqlite3changeset_new, pApply->nCol, pApply->abPK, pApply->pDelete);
5010 sqlite3_bind_int(pApply->pDelete, pApply->nCol+1, 1);
5012 if( rc==SQLITE_OK ){
5013 sqlite3_step(pApply->pDelete);
5014 rc = sqlite3_reset(pApply->pDelete);
5016 if( rc==SQLITE_OK ){
5017 rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0);
5019 if( rc==SQLITE_OK ){
5020 rc = sqlite3_exec(db, "RELEASE replace_op", 0, 0, 0);
5025 return rc;
5029 ** Retry the changes accumulated in the pApply->constraints buffer.
5031 static int sessionRetryConstraints(
5032 sqlite3 *db,
5033 int bPatchset,
5034 const char *zTab,
5035 SessionApplyCtx *pApply,
5036 int(*xConflict)(void*, int, sqlite3_changeset_iter*),
5037 void *pCtx /* First argument passed to xConflict */
5039 int rc = SQLITE_OK;
5041 while( pApply->constraints.nBuf ){
5042 sqlite3_changeset_iter *pIter2 = 0;
5043 SessionBuffer cons = pApply->constraints;
5044 memset(&pApply->constraints, 0, sizeof(SessionBuffer));
5046 rc = sessionChangesetStart(
5047 &pIter2, 0, 0, cons.nBuf, cons.aBuf, pApply->bInvertConstraints, 1
5049 if( rc==SQLITE_OK ){
5050 size_t nByte = 2*pApply->nCol*sizeof(sqlite3_value*);
5051 int rc2;
5052 pIter2->bPatchset = bPatchset;
5053 pIter2->zTab = (char*)zTab;
5054 pIter2->nCol = pApply->nCol;
5055 pIter2->abPK = pApply->abPK;
5056 sessionBufferGrow(&pIter2->tblhdr, nByte, &rc);
5057 pIter2->apValue = (sqlite3_value**)pIter2->tblhdr.aBuf;
5058 if( rc==SQLITE_OK ) memset(pIter2->apValue, 0, nByte);
5060 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter2) ){
5061 rc = sessionApplyOneWithRetry(db, pIter2, pApply, xConflict, pCtx);
5064 rc2 = sqlite3changeset_finalize(pIter2);
5065 if( rc==SQLITE_OK ) rc = rc2;
5067 assert( pApply->bDeferConstraints || pApply->constraints.nBuf==0 );
5069 sqlite3_free(cons.aBuf);
5070 if( rc!=SQLITE_OK ) break;
5071 if( pApply->constraints.nBuf>=cons.nBuf ){
5072 /* No progress was made on the last round. */
5073 pApply->bDeferConstraints = 0;
5077 return rc;
5081 ** Argument pIter is a changeset iterator that has been initialized, but
5082 ** not yet passed to sqlite3changeset_next(). This function applies the
5083 ** changeset to the main database attached to handle "db". The supplied
5084 ** conflict handler callback is invoked to resolve any conflicts encountered
5085 ** while applying the change.
5087 static int sessionChangesetApply(
5088 sqlite3 *db, /* Apply change to "main" db of this handle */
5089 sqlite3_changeset_iter *pIter, /* Changeset to apply */
5090 int(*xFilter)(
5091 void *pCtx, /* Copy of sixth arg to _apply() */
5092 const char *zTab /* Table name */
5094 int(*xConflict)(
5095 void *pCtx, /* Copy of fifth arg to _apply() */
5096 int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
5097 sqlite3_changeset_iter *p /* Handle describing change and conflict */
5099 void *pCtx, /* First argument passed to xConflict */
5100 void **ppRebase, int *pnRebase, /* OUT: Rebase information */
5101 int flags /* SESSION_APPLY_XXX flags */
5103 int schemaMismatch = 0;
5104 int rc = SQLITE_OK; /* Return code */
5105 const char *zTab = 0; /* Name of current table */
5106 int nTab = 0; /* Result of sqlite3Strlen30(zTab) */
5107 SessionApplyCtx sApply; /* changeset_apply() context object */
5108 int bPatchset;
5110 assert( xConflict!=0 );
5112 pIter->in.bNoDiscard = 1;
5113 memset(&sApply, 0, sizeof(sApply));
5114 sApply.bRebase = (ppRebase && pnRebase);
5115 sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
5116 sApply.bIgnoreNoop = !!(flags & SQLITE_CHANGESETAPPLY_IGNORENOOP);
5117 sqlite3_mutex_enter(sqlite3_db_mutex(db));
5118 if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
5119 rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
5121 if( rc==SQLITE_OK ){
5122 rc = sqlite3_exec(db, "PRAGMA defer_foreign_keys = 1", 0, 0, 0);
5124 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter) ){
5125 int nCol;
5126 int op;
5127 const char *zNew;
5129 sqlite3changeset_op(pIter, &zNew, &nCol, &op, 0);
5131 if( zTab==0 || sqlite3_strnicmp(zNew, zTab, nTab+1) ){
5132 u8 *abPK;
5134 rc = sessionRetryConstraints(
5135 db, pIter->bPatchset, zTab, &sApply, xConflict, pCtx
5137 if( rc!=SQLITE_OK ) break;
5139 sessionUpdateFree(&sApply);
5140 sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */
5141 sqlite3_finalize(sApply.pDelete);
5142 sqlite3_finalize(sApply.pInsert);
5143 sqlite3_finalize(sApply.pSelect);
5144 sApply.db = db;
5145 sApply.pDelete = 0;
5146 sApply.pInsert = 0;
5147 sApply.pSelect = 0;
5148 sApply.nCol = 0;
5149 sApply.azCol = 0;
5150 sApply.abPK = 0;
5151 sApply.bStat1 = 0;
5152 sApply.bDeferConstraints = 1;
5153 sApply.bRebaseStarted = 0;
5154 sApply.bRowid = 0;
5155 memset(&sApply.constraints, 0, sizeof(SessionBuffer));
5157 /* If an xFilter() callback was specified, invoke it now. If the
5158 ** xFilter callback returns zero, skip this table. If it returns
5159 ** non-zero, proceed. */
5160 schemaMismatch = (xFilter && (0==xFilter(pCtx, zNew)));
5161 if( schemaMismatch ){
5162 zTab = sqlite3_mprintf("%s", zNew);
5163 if( zTab==0 ){
5164 rc = SQLITE_NOMEM;
5165 break;
5167 nTab = (int)strlen(zTab);
5168 sApply.azCol = (const char **)zTab;
5169 }else{
5170 int nMinCol = 0;
5171 int i;
5173 sqlite3changeset_pk(pIter, &abPK, 0);
5174 rc = sessionTableInfo(0, db, "main", zNew,
5175 &sApply.nCol, &zTab, &sApply.azCol, 0, &sApply.abPK, &sApply.bRowid
5177 if( rc!=SQLITE_OK ) break;
5178 for(i=0; i<sApply.nCol; i++){
5179 if( sApply.abPK[i] ) nMinCol = i+1;
5182 if( sApply.nCol==0 ){
5183 schemaMismatch = 1;
5184 sqlite3_log(SQLITE_SCHEMA,
5185 "sqlite3changeset_apply(): no such table: %s", zTab
5188 else if( sApply.nCol<nCol ){
5189 schemaMismatch = 1;
5190 sqlite3_log(SQLITE_SCHEMA,
5191 "sqlite3changeset_apply(): table %s has %d columns, "
5192 "expected %d or more",
5193 zTab, sApply.nCol, nCol
5196 else if( nCol<nMinCol || memcmp(sApply.abPK, abPK, nCol)!=0 ){
5197 schemaMismatch = 1;
5198 sqlite3_log(SQLITE_SCHEMA, "sqlite3changeset_apply(): "
5199 "primary key mismatch for table %s", zTab
5202 else{
5203 sApply.nCol = nCol;
5204 if( 0==sqlite3_stricmp(zTab, "sqlite_stat1") ){
5205 if( (rc = sessionStat1Sql(db, &sApply) ) ){
5206 break;
5208 sApply.bStat1 = 1;
5209 }else{
5210 if( (rc = sessionSelectRow(db, zTab, &sApply))
5211 || (rc = sessionDeleteRow(db, zTab, &sApply))
5212 || (rc = sessionInsertRow(db, zTab, &sApply))
5214 break;
5216 sApply.bStat1 = 0;
5219 nTab = sqlite3Strlen30(zTab);
5223 /* If there is a schema mismatch on the current table, proceed to the
5224 ** next change. A log message has already been issued. */
5225 if( schemaMismatch ) continue;
5227 rc = sessionApplyOneWithRetry(db, pIter, &sApply, xConflict, pCtx);
5230 bPatchset = pIter->bPatchset;
5231 if( rc==SQLITE_OK ){
5232 rc = sqlite3changeset_finalize(pIter);
5233 }else{
5234 sqlite3changeset_finalize(pIter);
5237 if( rc==SQLITE_OK ){
5238 rc = sessionRetryConstraints(db, bPatchset, zTab, &sApply, xConflict, pCtx);
5241 if( rc==SQLITE_OK ){
5242 int nFk, notUsed;
5243 sqlite3_db_status(db, SQLITE_DBSTATUS_DEFERRED_FKS, &nFk, &notUsed, 0);
5244 if( nFk!=0 ){
5245 int res = SQLITE_CHANGESET_ABORT;
5246 sqlite3_changeset_iter sIter;
5247 memset(&sIter, 0, sizeof(sIter));
5248 sIter.nCol = nFk;
5249 res = xConflict(pCtx, SQLITE_CHANGESET_FOREIGN_KEY, &sIter);
5250 if( res!=SQLITE_CHANGESET_OMIT ){
5251 rc = SQLITE_CONSTRAINT;
5255 sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0);
5257 if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
5258 if( rc==SQLITE_OK ){
5259 rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
5260 }else{
5261 sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0);
5262 sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
5266 assert( sApply.bRebase || sApply.rebase.nBuf==0 );
5267 if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){
5268 *ppRebase = (void*)sApply.rebase.aBuf;
5269 *pnRebase = sApply.rebase.nBuf;
5270 sApply.rebase.aBuf = 0;
5272 sessionUpdateFree(&sApply);
5273 sqlite3_finalize(sApply.pInsert);
5274 sqlite3_finalize(sApply.pDelete);
5275 sqlite3_finalize(sApply.pSelect);
5276 sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */
5277 sqlite3_free((char*)sApply.constraints.aBuf);
5278 sqlite3_free((char*)sApply.rebase.aBuf);
5279 sqlite3_mutex_leave(sqlite3_db_mutex(db));
5280 return rc;
5284 ** Apply the changeset passed via pChangeset/nChangeset to the main
5285 ** database attached to handle "db".
5287 int sqlite3changeset_apply_v2(
5288 sqlite3 *db, /* Apply change to "main" db of this handle */
5289 int nChangeset, /* Size of changeset in bytes */
5290 void *pChangeset, /* Changeset blob */
5291 int(*xFilter)(
5292 void *pCtx, /* Copy of sixth arg to _apply() */
5293 const char *zTab /* Table name */
5295 int(*xConflict)(
5296 void *pCtx, /* Copy of sixth arg to _apply() */
5297 int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
5298 sqlite3_changeset_iter *p /* Handle describing change and conflict */
5300 void *pCtx, /* First argument passed to xConflict */
5301 void **ppRebase, int *pnRebase,
5302 int flags
5304 sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
5305 int bInv = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
5306 int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset, bInv, 1);
5307 if( rc==SQLITE_OK ){
5308 rc = sessionChangesetApply(
5309 db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
5312 return rc;
5316 ** Apply the changeset passed via pChangeset/nChangeset to the main database
5317 ** attached to handle "db". Invoke the supplied conflict handler callback
5318 ** to resolve any conflicts encountered while applying the change.
5320 int sqlite3changeset_apply(
5321 sqlite3 *db, /* Apply change to "main" db of this handle */
5322 int nChangeset, /* Size of changeset in bytes */
5323 void *pChangeset, /* Changeset blob */
5324 int(*xFilter)(
5325 void *pCtx, /* Copy of sixth arg to _apply() */
5326 const char *zTab /* Table name */
5328 int(*xConflict)(
5329 void *pCtx, /* Copy of fifth arg to _apply() */
5330 int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
5331 sqlite3_changeset_iter *p /* Handle describing change and conflict */
5333 void *pCtx /* First argument passed to xConflict */
5335 return sqlite3changeset_apply_v2(
5336 db, nChangeset, pChangeset, xFilter, xConflict, pCtx, 0, 0, 0
5341 ** Apply the changeset passed via xInput/pIn to the main database
5342 ** attached to handle "db". Invoke the supplied conflict handler callback
5343 ** to resolve any conflicts encountered while applying the change.
5345 int sqlite3changeset_apply_v2_strm(
5346 sqlite3 *db, /* Apply change to "main" db of this handle */
5347 int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
5348 void *pIn, /* First arg for xInput */
5349 int(*xFilter)(
5350 void *pCtx, /* Copy of sixth arg to _apply() */
5351 const char *zTab /* Table name */
5353 int(*xConflict)(
5354 void *pCtx, /* Copy of sixth arg to _apply() */
5355 int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
5356 sqlite3_changeset_iter *p /* Handle describing change and conflict */
5358 void *pCtx, /* First argument passed to xConflict */
5359 void **ppRebase, int *pnRebase,
5360 int flags
5362 sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
5363 int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
5364 int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse, 1);
5365 if( rc==SQLITE_OK ){
5366 rc = sessionChangesetApply(
5367 db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
5370 return rc;
5372 int sqlite3changeset_apply_strm(
5373 sqlite3 *db, /* Apply change to "main" db of this handle */
5374 int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
5375 void *pIn, /* First arg for xInput */
5376 int(*xFilter)(
5377 void *pCtx, /* Copy of sixth arg to _apply() */
5378 const char *zTab /* Table name */
5380 int(*xConflict)(
5381 void *pCtx, /* Copy of sixth arg to _apply() */
5382 int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
5383 sqlite3_changeset_iter *p /* Handle describing change and conflict */
5385 void *pCtx /* First argument passed to xConflict */
5387 return sqlite3changeset_apply_v2_strm(
5388 db, xInput, pIn, xFilter, xConflict, pCtx, 0, 0, 0
5393 ** sqlite3_changegroup handle.
5395 struct sqlite3_changegroup {
5396 int rc; /* Error code */
5397 int bPatch; /* True to accumulate patchsets */
5398 SessionTable *pList; /* List of tables in current patch */
5400 sqlite3 *db; /* Configured by changegroup_schema() */
5401 const char *zDb; /* Configured by changegroup_schema() */
5405 ** This function is called to merge two changes to the same row together as
5406 ** part of an sqlite3changeset_concat() operation. A new change object is
5407 ** allocated and a pointer to it stored in *ppNew.
5409 static int sessionChangeMerge(
5410 SessionTable *pTab, /* Table structure */
5411 int bRebase, /* True for a rebase hash-table */
5412 int bPatchset, /* True for patchsets */
5413 SessionChange *pExist, /* Existing change */
5414 int op2, /* Second change operation */
5415 int bIndirect, /* True if second change is indirect */
5416 u8 *aRec, /* Second change record */
5417 int nRec, /* Number of bytes in aRec */
5418 SessionChange **ppNew /* OUT: Merged change */
5420 SessionChange *pNew = 0;
5421 int rc = SQLITE_OK;
5423 if( !pExist ){
5424 pNew = (SessionChange *)sqlite3_malloc64(sizeof(SessionChange) + nRec);
5425 if( !pNew ){
5426 return SQLITE_NOMEM;
5428 memset(pNew, 0, sizeof(SessionChange));
5429 pNew->op = op2;
5430 pNew->bIndirect = bIndirect;
5431 pNew->aRecord = (u8*)&pNew[1];
5432 if( bIndirect==0 || bRebase==0 ){
5433 pNew->nRecord = nRec;
5434 memcpy(pNew->aRecord, aRec, nRec);
5435 }else{
5436 int i;
5437 u8 *pIn = aRec;
5438 u8 *pOut = pNew->aRecord;
5439 for(i=0; i<pTab->nCol; i++){
5440 int nIn = sessionSerialLen(pIn);
5441 if( *pIn==0 ){
5442 *pOut++ = 0;
5443 }else if( pTab->abPK[i]==0 ){
5444 *pOut++ = 0xFF;
5445 }else{
5446 memcpy(pOut, pIn, nIn);
5447 pOut += nIn;
5449 pIn += nIn;
5451 pNew->nRecord = pOut - pNew->aRecord;
5453 }else if( bRebase ){
5454 if( pExist->op==SQLITE_DELETE && pExist->bIndirect ){
5455 *ppNew = pExist;
5456 }else{
5457 sqlite3_int64 nByte = nRec + pExist->nRecord + sizeof(SessionChange);
5458 pNew = (SessionChange*)sqlite3_malloc64(nByte);
5459 if( pNew==0 ){
5460 rc = SQLITE_NOMEM;
5461 }else{
5462 int i;
5463 u8 *a1 = pExist->aRecord;
5464 u8 *a2 = aRec;
5465 u8 *pOut;
5467 memset(pNew, 0, nByte);
5468 pNew->bIndirect = bIndirect || pExist->bIndirect;
5469 pNew->op = op2;
5470 pOut = pNew->aRecord = (u8*)&pNew[1];
5472 for(i=0; i<pTab->nCol; i++){
5473 int n1 = sessionSerialLen(a1);
5474 int n2 = sessionSerialLen(a2);
5475 if( *a1==0xFF || (pTab->abPK[i]==0 && bIndirect) ){
5476 *pOut++ = 0xFF;
5477 }else if( *a2==0 ){
5478 memcpy(pOut, a1, n1);
5479 pOut += n1;
5480 }else{
5481 memcpy(pOut, a2, n2);
5482 pOut += n2;
5484 a1 += n1;
5485 a2 += n2;
5487 pNew->nRecord = pOut - pNew->aRecord;
5489 sqlite3_free(pExist);
5491 }else{
5492 int op1 = pExist->op;
5495 ** op1=INSERT, op2=INSERT -> Unsupported. Discard op2.
5496 ** op1=INSERT, op2=UPDATE -> INSERT.
5497 ** op1=INSERT, op2=DELETE -> (none)
5499 ** op1=UPDATE, op2=INSERT -> Unsupported. Discard op2.
5500 ** op1=UPDATE, op2=UPDATE -> UPDATE.
5501 ** op1=UPDATE, op2=DELETE -> DELETE.
5503 ** op1=DELETE, op2=INSERT -> UPDATE.
5504 ** op1=DELETE, op2=UPDATE -> Unsupported. Discard op2.
5505 ** op1=DELETE, op2=DELETE -> Unsupported. Discard op2.
5507 if( (op1==SQLITE_INSERT && op2==SQLITE_INSERT)
5508 || (op1==SQLITE_UPDATE && op2==SQLITE_INSERT)
5509 || (op1==SQLITE_DELETE && op2==SQLITE_UPDATE)
5510 || (op1==SQLITE_DELETE && op2==SQLITE_DELETE)
5512 pNew = pExist;
5513 }else if( op1==SQLITE_INSERT && op2==SQLITE_DELETE ){
5514 sqlite3_free(pExist);
5515 assert( pNew==0 );
5516 }else{
5517 u8 *aExist = pExist->aRecord;
5518 sqlite3_int64 nByte;
5519 u8 *aCsr;
5521 /* Allocate a new SessionChange object. Ensure that the aRecord[]
5522 ** buffer of the new object is large enough to hold any record that
5523 ** may be generated by combining the input records. */
5524 nByte = sizeof(SessionChange) + pExist->nRecord + nRec;
5525 pNew = (SessionChange *)sqlite3_malloc64(nByte);
5526 if( !pNew ){
5527 sqlite3_free(pExist);
5528 return SQLITE_NOMEM;
5530 memset(pNew, 0, sizeof(SessionChange));
5531 pNew->bIndirect = (bIndirect && pExist->bIndirect);
5532 aCsr = pNew->aRecord = (u8 *)&pNew[1];
5534 if( op1==SQLITE_INSERT ){ /* INSERT + UPDATE */
5535 u8 *a1 = aRec;
5536 assert( op2==SQLITE_UPDATE );
5537 pNew->op = SQLITE_INSERT;
5538 if( bPatchset==0 ) sessionSkipRecord(&a1, pTab->nCol);
5539 sessionMergeRecord(&aCsr, pTab->nCol, aExist, a1);
5540 }else if( op1==SQLITE_DELETE ){ /* DELETE + INSERT */
5541 assert( op2==SQLITE_INSERT );
5542 pNew->op = SQLITE_UPDATE;
5543 if( bPatchset ){
5544 memcpy(aCsr, aRec, nRec);
5545 aCsr += nRec;
5546 }else{
5547 if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aExist, 0,aRec,0) ){
5548 sqlite3_free(pNew);
5549 pNew = 0;
5552 }else if( op2==SQLITE_UPDATE ){ /* UPDATE + UPDATE */
5553 u8 *a1 = aExist;
5554 u8 *a2 = aRec;
5555 assert( op1==SQLITE_UPDATE );
5556 if( bPatchset==0 ){
5557 sessionSkipRecord(&a1, pTab->nCol);
5558 sessionSkipRecord(&a2, pTab->nCol);
5560 pNew->op = SQLITE_UPDATE;
5561 if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aRec, aExist,a1,a2) ){
5562 sqlite3_free(pNew);
5563 pNew = 0;
5565 }else{ /* UPDATE + DELETE */
5566 assert( op1==SQLITE_UPDATE && op2==SQLITE_DELETE );
5567 pNew->op = SQLITE_DELETE;
5568 if( bPatchset ){
5569 memcpy(aCsr, aRec, nRec);
5570 aCsr += nRec;
5571 }else{
5572 sessionMergeRecord(&aCsr, pTab->nCol, aRec, aExist);
5576 if( pNew ){
5577 pNew->nRecord = (int)(aCsr - pNew->aRecord);
5579 sqlite3_free(pExist);
5583 *ppNew = pNew;
5584 return rc;
5588 ** Check if a changeset entry with nCol columns and the PK array passed
5589 ** as the final argument to this function is compatible with SessionTable
5590 ** pTab. If so, return 1. Otherwise, if they are incompatible in some way,
5591 ** return 0.
5593 static int sessionChangesetCheckCompat(
5594 SessionTable *pTab,
5595 int nCol,
5596 u8 *abPK
5598 if( pTab->azCol && nCol<pTab->nCol ){
5599 int ii;
5600 for(ii=0; ii<pTab->nCol; ii++){
5601 u8 bPK = (ii < nCol) ? abPK[ii] : 0;
5602 if( pTab->abPK[ii]!=bPK ) return 0;
5604 return 1;
5606 return (pTab->nCol==nCol && 0==memcmp(abPK, pTab->abPK, nCol));
5609 static int sessionChangesetExtendRecord(
5610 sqlite3_changegroup *pGrp,
5611 SessionTable *pTab,
5612 int nCol,
5613 int op,
5614 const u8 *aRec,
5615 int nRec,
5616 SessionBuffer *pOut
5618 int rc = SQLITE_OK;
5619 int ii = 0;
5621 assert( pTab->azCol );
5622 assert( nCol<pTab->nCol );
5624 pOut->nBuf = 0;
5625 if( op==SQLITE_INSERT || (op==SQLITE_DELETE && pGrp->bPatch==0) ){
5626 /* Append the missing default column values to the record. */
5627 sessionAppendBlob(pOut, aRec, nRec, &rc);
5628 if( pTab->pDfltStmt==0 ){
5629 rc = sessionPrepareDfltStmt(pGrp->db, pTab, &pTab->pDfltStmt);
5631 for(ii=nCol; rc==SQLITE_OK && ii<pTab->nCol; ii++){
5632 int eType = sqlite3_column_type(pTab->pDfltStmt, ii);
5633 sessionAppendByte(pOut, eType, &rc);
5634 switch( eType ){
5635 case SQLITE_FLOAT:
5636 case SQLITE_INTEGER: {
5637 i64 iVal;
5638 if( eType==SQLITE_INTEGER ){
5639 iVal = sqlite3_column_int64(pTab->pDfltStmt, ii);
5640 }else{
5641 double rVal = sqlite3_column_int64(pTab->pDfltStmt, ii);
5642 memcpy(&iVal, &rVal, sizeof(i64));
5644 if( SQLITE_OK==sessionBufferGrow(pOut, 8, &rc) ){
5645 sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal);
5647 break;
5650 case SQLITE_BLOB:
5651 case SQLITE_TEXT: {
5652 int n = sqlite3_column_bytes(pTab->pDfltStmt, ii);
5653 sessionAppendVarint(pOut, n, &rc);
5654 if( eType==SQLITE_TEXT ){
5655 const u8 *z = (const u8*)sqlite3_column_text(pTab->pDfltStmt, ii);
5656 sessionAppendBlob(pOut, z, n, &rc);
5657 }else{
5658 const u8 *z = (const u8*)sqlite3_column_blob(pTab->pDfltStmt, ii);
5659 sessionAppendBlob(pOut, z, n, &rc);
5661 break;
5664 default:
5665 assert( eType==SQLITE_NULL );
5666 break;
5669 }else{
5670 /* Append missing "undefined" entries to the old.* record. And, if this
5671 ** is an UPDATE, to the new.* record as well. */
5672 int iOff = 0;
5673 if( op==SQLITE_UPDATE ){
5674 for(ii=0; ii<nCol; ii++){
5675 iOff += sessionSerialLen(&aRec[iOff]);
5677 sessionAppendBlob(pOut, aRec, iOff, &rc);
5678 for(ii=0; ii<(pTab->nCol-nCol); ii++){
5679 sessionAppendByte(pOut, 0x00, &rc);
5683 sessionAppendBlob(pOut, &aRec[iOff], nRec-iOff, &rc);
5684 for(ii=0; ii<(pTab->nCol-nCol); ii++){
5685 sessionAppendByte(pOut, 0x00, &rc);
5689 return rc;
5693 ** Add all changes in the changeset traversed by the iterator passed as
5694 ** the first argument to the changegroup hash tables.
5696 static int sessionChangesetToHash(
5697 sqlite3_changeset_iter *pIter, /* Iterator to read from */
5698 sqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */
5699 int bRebase /* True if hash table is for rebasing */
5701 u8 *aRec;
5702 int nRec;
5703 int rc = SQLITE_OK;
5704 SessionTable *pTab = 0;
5705 SessionBuffer rec = {0, 0, 0};
5707 while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, 0) ){
5708 const char *zNew;
5709 int nCol;
5710 int op;
5711 int iHash;
5712 int bIndirect;
5713 SessionChange *pChange;
5714 SessionChange *pExist = 0;
5715 SessionChange **pp;
5717 /* Ensure that only changesets, or only patchsets, but not a mixture
5718 ** of both, are being combined. It is an error to try to combine a
5719 ** changeset and a patchset. */
5720 if( pGrp->pList==0 ){
5721 pGrp->bPatch = pIter->bPatchset;
5722 }else if( pIter->bPatchset!=pGrp->bPatch ){
5723 rc = SQLITE_ERROR;
5724 break;
5727 sqlite3changeset_op(pIter, &zNew, &nCol, &op, &bIndirect);
5728 if( !pTab || sqlite3_stricmp(zNew, pTab->zName) ){
5729 /* Search the list for a matching table */
5730 int nNew = (int)strlen(zNew);
5731 u8 *abPK;
5733 sqlite3changeset_pk(pIter, &abPK, 0);
5734 for(pTab = pGrp->pList; pTab; pTab=pTab->pNext){
5735 if( 0==sqlite3_strnicmp(pTab->zName, zNew, nNew+1) ) break;
5737 if( !pTab ){
5738 SessionTable **ppTab;
5740 pTab = sqlite3_malloc64(sizeof(SessionTable) + nCol + nNew+1);
5741 if( !pTab ){
5742 rc = SQLITE_NOMEM;
5743 break;
5745 memset(pTab, 0, sizeof(SessionTable));
5746 pTab->nCol = nCol;
5747 pTab->abPK = (u8*)&pTab[1];
5748 memcpy(pTab->abPK, abPK, nCol);
5749 pTab->zName = (char*)&pTab->abPK[nCol];
5750 memcpy(pTab->zName, zNew, nNew+1);
5752 if( pGrp->db ){
5753 pTab->nCol = 0;
5754 rc = sessionInitTable(0, pTab, pGrp->db, pGrp->zDb);
5757 /* The new object must be linked on to the end of the list, not
5758 ** simply added to the start of it. This is to ensure that the
5759 ** tables within the output of sqlite3changegroup_output() are in
5760 ** the right order. */
5761 for(ppTab=&pGrp->pList; *ppTab; ppTab=&(*ppTab)->pNext);
5762 *ppTab = pTab;
5765 if( !sessionChangesetCheckCompat(pTab, nCol, abPK) ){
5766 rc = SQLITE_SCHEMA;
5767 break;
5771 if( nCol<pTab->nCol ){
5772 assert( pGrp->db );
5773 rc = sessionChangesetExtendRecord(pGrp, pTab, nCol, op, aRec, nRec, &rec);
5774 if( rc ) break;
5775 aRec = rec.aBuf;
5776 nRec = rec.nBuf;
5779 if( sessionGrowHash(0, pIter->bPatchset, pTab) ){
5780 rc = SQLITE_NOMEM;
5781 break;
5783 iHash = sessionChangeHash(
5784 pTab, (pIter->bPatchset && op==SQLITE_DELETE), aRec, pTab->nChange
5787 /* Search for existing entry. If found, remove it from the hash table.
5788 ** Code below may link it back in.
5790 for(pp=&pTab->apChange[iHash]; *pp; pp=&(*pp)->pNext){
5791 int bPkOnly1 = 0;
5792 int bPkOnly2 = 0;
5793 if( pIter->bPatchset ){
5794 bPkOnly1 = (*pp)->op==SQLITE_DELETE;
5795 bPkOnly2 = op==SQLITE_DELETE;
5797 if( sessionChangeEqual(pTab, bPkOnly1, (*pp)->aRecord, bPkOnly2, aRec) ){
5798 pExist = *pp;
5799 *pp = (*pp)->pNext;
5800 pTab->nEntry--;
5801 break;
5805 rc = sessionChangeMerge(pTab, bRebase,
5806 pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange
5808 if( rc ) break;
5809 if( pChange ){
5810 pChange->pNext = pTab->apChange[iHash];
5811 pTab->apChange[iHash] = pChange;
5812 pTab->nEntry++;
5816 sqlite3_free(rec.aBuf);
5817 if( rc==SQLITE_OK ) rc = pIter->rc;
5818 return rc;
5822 ** Serialize a changeset (or patchset) based on all changesets (or patchsets)
5823 ** added to the changegroup object passed as the first argument.
5825 ** If xOutput is not NULL, then the changeset/patchset is returned to the
5826 ** user via one or more calls to xOutput, as with the other streaming
5827 ** interfaces.
5829 ** Or, if xOutput is NULL, then (*ppOut) is populated with a pointer to a
5830 ** buffer containing the output changeset before this function returns. In
5831 ** this case (*pnOut) is set to the size of the output buffer in bytes. It
5832 ** is the responsibility of the caller to free the output buffer using
5833 ** sqlite3_free() when it is no longer required.
5835 ** If successful, SQLITE_OK is returned. Or, if an error occurs, an SQLite
5836 ** error code. If an error occurs and xOutput is NULL, (*ppOut) and (*pnOut)
5837 ** are both set to 0 before returning.
5839 static int sessionChangegroupOutput(
5840 sqlite3_changegroup *pGrp,
5841 int (*xOutput)(void *pOut, const void *pData, int nData),
5842 void *pOut,
5843 int *pnOut,
5844 void **ppOut
5846 int rc = SQLITE_OK;
5847 SessionBuffer buf = {0, 0, 0};
5848 SessionTable *pTab;
5849 assert( xOutput==0 || (ppOut==0 && pnOut==0) );
5851 /* Create the serialized output changeset based on the contents of the
5852 ** hash tables attached to the SessionTable objects in list p->pList.
5854 for(pTab=pGrp->pList; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
5855 int i;
5856 if( pTab->nEntry==0 ) continue;
5858 sessionAppendTableHdr(&buf, pGrp->bPatch, pTab, &rc);
5859 for(i=0; i<pTab->nChange; i++){
5860 SessionChange *p;
5861 for(p=pTab->apChange[i]; p; p=p->pNext){
5862 sessionAppendByte(&buf, p->op, &rc);
5863 sessionAppendByte(&buf, p->bIndirect, &rc);
5864 sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc);
5865 if( rc==SQLITE_OK && xOutput && buf.nBuf>=sessions_strm_chunk_size ){
5866 rc = xOutput(pOut, buf.aBuf, buf.nBuf);
5867 buf.nBuf = 0;
5873 if( rc==SQLITE_OK ){
5874 if( xOutput ){
5875 if( buf.nBuf>0 ) rc = xOutput(pOut, buf.aBuf, buf.nBuf);
5876 }else if( ppOut ){
5877 *ppOut = buf.aBuf;
5878 if( pnOut ) *pnOut = buf.nBuf;
5879 buf.aBuf = 0;
5882 sqlite3_free(buf.aBuf);
5884 return rc;
5888 ** Allocate a new, empty, sqlite3_changegroup.
5890 int sqlite3changegroup_new(sqlite3_changegroup **pp){
5891 int rc = SQLITE_OK; /* Return code */
5892 sqlite3_changegroup *p; /* New object */
5893 p = (sqlite3_changegroup*)sqlite3_malloc(sizeof(sqlite3_changegroup));
5894 if( p==0 ){
5895 rc = SQLITE_NOMEM;
5896 }else{
5897 memset(p, 0, sizeof(sqlite3_changegroup));
5899 *pp = p;
5900 return rc;
5903 int sqlite3changegroup_schema(
5904 sqlite3_changegroup *pGrp,
5905 sqlite3 *db,
5906 const char *zDb
5908 int rc = SQLITE_OK;
5910 if( pGrp->pList || pGrp->db ){
5911 /* Cannot add a schema after one or more calls to sqlite3changegroup_add(),
5912 ** or after sqlite3changegroup_schema() has already been called. */
5913 rc = SQLITE_MISUSE;
5914 }else{
5915 pGrp->zDb = sqlite3_mprintf("%s", zDb);
5916 if( pGrp->zDb==0 ){
5917 rc = SQLITE_NOMEM;
5918 }else{
5919 pGrp->db = db;
5922 return rc;
5926 ** Add the changeset currently stored in buffer pData, size nData bytes,
5927 ** to changeset-group p.
5929 int sqlite3changegroup_add(sqlite3_changegroup *pGrp, int nData, void *pData){
5930 sqlite3_changeset_iter *pIter; /* Iterator opened on pData/nData */
5931 int rc; /* Return code */
5933 rc = sqlite3changeset_start(&pIter, nData, pData);
5934 if( rc==SQLITE_OK ){
5935 rc = sessionChangesetToHash(pIter, pGrp, 0);
5937 sqlite3changeset_finalize(pIter);
5938 return rc;
5942 ** Obtain a buffer containing a changeset representing the concatenation
5943 ** of all changesets added to the group so far.
5945 int sqlite3changegroup_output(
5946 sqlite3_changegroup *pGrp,
5947 int *pnData,
5948 void **ppData
5950 return sessionChangegroupOutput(pGrp, 0, 0, pnData, ppData);
5954 ** Streaming versions of changegroup_add().
5956 int sqlite3changegroup_add_strm(
5957 sqlite3_changegroup *pGrp,
5958 int (*xInput)(void *pIn, void *pData, int *pnData),
5959 void *pIn
5961 sqlite3_changeset_iter *pIter; /* Iterator opened on pData/nData */
5962 int rc; /* Return code */
5964 rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
5965 if( rc==SQLITE_OK ){
5966 rc = sessionChangesetToHash(pIter, pGrp, 0);
5968 sqlite3changeset_finalize(pIter);
5969 return rc;
5973 ** Streaming versions of changegroup_output().
5975 int sqlite3changegroup_output_strm(
5976 sqlite3_changegroup *pGrp,
5977 int (*xOutput)(void *pOut, const void *pData, int nData),
5978 void *pOut
5980 return sessionChangegroupOutput(pGrp, xOutput, pOut, 0, 0);
5984 ** Delete a changegroup object.
5986 void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){
5987 if( pGrp ){
5988 sessionDeleteTable(0, pGrp->pList);
5989 sqlite3_free(pGrp);
5994 ** Combine two changesets together.
5996 int sqlite3changeset_concat(
5997 int nLeft, /* Number of bytes in lhs input */
5998 void *pLeft, /* Lhs input changeset */
5999 int nRight /* Number of bytes in rhs input */,
6000 void *pRight, /* Rhs input changeset */
6001 int *pnOut, /* OUT: Number of bytes in output changeset */
6002 void **ppOut /* OUT: changeset (left <concat> right) */
6004 sqlite3_changegroup *pGrp;
6005 int rc;
6007 rc = sqlite3changegroup_new(&pGrp);
6008 if( rc==SQLITE_OK ){
6009 rc = sqlite3changegroup_add(pGrp, nLeft, pLeft);
6011 if( rc==SQLITE_OK ){
6012 rc = sqlite3changegroup_add(pGrp, nRight, pRight);
6014 if( rc==SQLITE_OK ){
6015 rc = sqlite3changegroup_output(pGrp, pnOut, ppOut);
6017 sqlite3changegroup_delete(pGrp);
6019 return rc;
6023 ** Streaming version of sqlite3changeset_concat().
6025 int sqlite3changeset_concat_strm(
6026 int (*xInputA)(void *pIn, void *pData, int *pnData),
6027 void *pInA,
6028 int (*xInputB)(void *pIn, void *pData, int *pnData),
6029 void *pInB,
6030 int (*xOutput)(void *pOut, const void *pData, int nData),
6031 void *pOut
6033 sqlite3_changegroup *pGrp;
6034 int rc;
6036 rc = sqlite3changegroup_new(&pGrp);
6037 if( rc==SQLITE_OK ){
6038 rc = sqlite3changegroup_add_strm(pGrp, xInputA, pInA);
6040 if( rc==SQLITE_OK ){
6041 rc = sqlite3changegroup_add_strm(pGrp, xInputB, pInB);
6043 if( rc==SQLITE_OK ){
6044 rc = sqlite3changegroup_output_strm(pGrp, xOutput, pOut);
6046 sqlite3changegroup_delete(pGrp);
6048 return rc;
6052 ** Changeset rebaser handle.
6054 struct sqlite3_rebaser {
6055 sqlite3_changegroup grp; /* Hash table */
6059 ** Buffers a1 and a2 must both contain a sessions module record nCol
6060 ** fields in size. This function appends an nCol sessions module
6061 ** record to buffer pBuf that is a copy of a1, except that for
6062 ** each field that is undefined in a1[], swap in the field from a2[].
6064 static void sessionAppendRecordMerge(
6065 SessionBuffer *pBuf, /* Buffer to append to */
6066 int nCol, /* Number of columns in each record */
6067 u8 *a1, int n1, /* Record 1 */
6068 u8 *a2, int n2, /* Record 2 */
6069 int *pRc /* IN/OUT: error code */
6071 sessionBufferGrow(pBuf, n1+n2, pRc);
6072 if( *pRc==SQLITE_OK ){
6073 int i;
6074 u8 *pOut = &pBuf->aBuf[pBuf->nBuf];
6075 for(i=0; i<nCol; i++){
6076 int nn1 = sessionSerialLen(a1);
6077 int nn2 = sessionSerialLen(a2);
6078 if( *a1==0 || *a1==0xFF ){
6079 memcpy(pOut, a2, nn2);
6080 pOut += nn2;
6081 }else{
6082 memcpy(pOut, a1, nn1);
6083 pOut += nn1;
6085 a1 += nn1;
6086 a2 += nn2;
6089 pBuf->nBuf = pOut-pBuf->aBuf;
6090 assert( pBuf->nBuf<=pBuf->nAlloc );
6095 ** This function is called when rebasing a local UPDATE change against one
6096 ** or more remote UPDATE changes. The aRec/nRec buffer contains the current
6097 ** old.* and new.* records for the change. The rebase buffer (a single
6098 ** record) is in aChange/nChange. The rebased change is appended to buffer
6099 ** pBuf.
6101 ** Rebasing the UPDATE involves:
6103 ** * Removing any changes to fields for which the corresponding field
6104 ** in the rebase buffer is set to "replaced" (type 0xFF). If this
6105 ** means the UPDATE change updates no fields, nothing is appended
6106 ** to the output buffer.
6108 ** * For each field modified by the local change for which the
6109 ** corresponding field in the rebase buffer is not "undefined" (0x00)
6110 ** or "replaced" (0xFF), the old.* value is replaced by the value
6111 ** in the rebase buffer.
6113 static void sessionAppendPartialUpdate(
6114 SessionBuffer *pBuf, /* Append record here */
6115 sqlite3_changeset_iter *pIter, /* Iterator pointed at local change */
6116 u8 *aRec, int nRec, /* Local change */
6117 u8 *aChange, int nChange, /* Record to rebase against */
6118 int *pRc /* IN/OUT: Return Code */
6120 sessionBufferGrow(pBuf, 2+nRec+nChange, pRc);
6121 if( *pRc==SQLITE_OK ){
6122 int bData = 0;
6123 u8 *pOut = &pBuf->aBuf[pBuf->nBuf];
6124 int i;
6125 u8 *a1 = aRec;
6126 u8 *a2 = aChange;
6128 *pOut++ = SQLITE_UPDATE;
6129 *pOut++ = pIter->bIndirect;
6130 for(i=0; i<pIter->nCol; i++){
6131 int n1 = sessionSerialLen(a1);
6132 int n2 = sessionSerialLen(a2);
6133 if( pIter->abPK[i] || a2[0]==0 ){
6134 if( !pIter->abPK[i] && a1[0] ) bData = 1;
6135 memcpy(pOut, a1, n1);
6136 pOut += n1;
6137 }else if( a2[0]!=0xFF && a1[0] ){
6138 bData = 1;
6139 memcpy(pOut, a2, n2);
6140 pOut += n2;
6141 }else{
6142 *pOut++ = '\0';
6144 a1 += n1;
6145 a2 += n2;
6147 if( bData ){
6148 a2 = aChange;
6149 for(i=0; i<pIter->nCol; i++){
6150 int n1 = sessionSerialLen(a1);
6151 int n2 = sessionSerialLen(a2);
6152 if( pIter->abPK[i] || a2[0]!=0xFF ){
6153 memcpy(pOut, a1, n1);
6154 pOut += n1;
6155 }else{
6156 *pOut++ = '\0';
6158 a1 += n1;
6159 a2 += n2;
6161 pBuf->nBuf = (pOut - pBuf->aBuf);
6167 ** pIter is configured to iterate through a changeset. This function rebases
6168 ** that changeset according to the current configuration of the rebaser
6169 ** object passed as the first argument. If no error occurs and argument xOutput
6170 ** is not NULL, then the changeset is returned to the caller by invoking
6171 ** xOutput zero or more times and SQLITE_OK returned. Or, if xOutput is NULL,
6172 ** then (*ppOut) is set to point to a buffer containing the rebased changeset
6173 ** before this function returns. In this case (*pnOut) is set to the size of
6174 ** the buffer in bytes. It is the responsibility of the caller to eventually
6175 ** free the (*ppOut) buffer using sqlite3_free().
6177 ** If an error occurs, an SQLite error code is returned. If ppOut and
6178 ** pnOut are not NULL, then the two output parameters are set to 0 before
6179 ** returning.
6181 static int sessionRebase(
6182 sqlite3_rebaser *p, /* Rebaser hash table */
6183 sqlite3_changeset_iter *pIter, /* Input data */
6184 int (*xOutput)(void *pOut, const void *pData, int nData),
6185 void *pOut, /* Context for xOutput callback */
6186 int *pnOut, /* OUT: Number of bytes in output changeset */
6187 void **ppOut /* OUT: Inverse of pChangeset */
6189 int rc = SQLITE_OK;
6190 u8 *aRec = 0;
6191 int nRec = 0;
6192 int bNew = 0;
6193 SessionTable *pTab = 0;
6194 SessionBuffer sOut = {0,0,0};
6196 while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, &bNew) ){
6197 SessionChange *pChange = 0;
6198 int bDone = 0;
6200 if( bNew ){
6201 const char *zTab = pIter->zTab;
6202 for(pTab=p->grp.pList; pTab; pTab=pTab->pNext){
6203 if( 0==sqlite3_stricmp(pTab->zName, zTab) ) break;
6205 bNew = 0;
6207 /* A patchset may not be rebased */
6208 if( pIter->bPatchset ){
6209 rc = SQLITE_ERROR;
6212 /* Append a table header to the output for this new table */
6213 sessionAppendByte(&sOut, pIter->bPatchset ? 'P' : 'T', &rc);
6214 sessionAppendVarint(&sOut, pIter->nCol, &rc);
6215 sessionAppendBlob(&sOut, pIter->abPK, pIter->nCol, &rc);
6216 sessionAppendBlob(&sOut,(u8*)pIter->zTab,(int)strlen(pIter->zTab)+1,&rc);
6219 if( pTab && rc==SQLITE_OK ){
6220 int iHash = sessionChangeHash(pTab, 0, aRec, pTab->nChange);
6222 for(pChange=pTab->apChange[iHash]; pChange; pChange=pChange->pNext){
6223 if( sessionChangeEqual(pTab, 0, aRec, 0, pChange->aRecord) ){
6224 break;
6229 if( pChange ){
6230 assert( pChange->op==SQLITE_DELETE || pChange->op==SQLITE_INSERT );
6231 switch( pIter->op ){
6232 case SQLITE_INSERT:
6233 if( pChange->op==SQLITE_INSERT ){
6234 bDone = 1;
6235 if( pChange->bIndirect==0 ){
6236 sessionAppendByte(&sOut, SQLITE_UPDATE, &rc);
6237 sessionAppendByte(&sOut, pIter->bIndirect, &rc);
6238 sessionAppendBlob(&sOut, pChange->aRecord, pChange->nRecord, &rc);
6239 sessionAppendBlob(&sOut, aRec, nRec, &rc);
6242 break;
6244 case SQLITE_UPDATE:
6245 bDone = 1;
6246 if( pChange->op==SQLITE_DELETE ){
6247 if( pChange->bIndirect==0 ){
6248 u8 *pCsr = aRec;
6249 sessionSkipRecord(&pCsr, pIter->nCol);
6250 sessionAppendByte(&sOut, SQLITE_INSERT, &rc);
6251 sessionAppendByte(&sOut, pIter->bIndirect, &rc);
6252 sessionAppendRecordMerge(&sOut, pIter->nCol,
6253 pCsr, nRec-(pCsr-aRec),
6254 pChange->aRecord, pChange->nRecord, &rc
6257 }else{
6258 sessionAppendPartialUpdate(&sOut, pIter,
6259 aRec, nRec, pChange->aRecord, pChange->nRecord, &rc
6262 break;
6264 default:
6265 assert( pIter->op==SQLITE_DELETE );
6266 bDone = 1;
6267 if( pChange->op==SQLITE_INSERT ){
6268 sessionAppendByte(&sOut, SQLITE_DELETE, &rc);
6269 sessionAppendByte(&sOut, pIter->bIndirect, &rc);
6270 sessionAppendRecordMerge(&sOut, pIter->nCol,
6271 pChange->aRecord, pChange->nRecord, aRec, nRec, &rc
6274 break;
6278 if( bDone==0 ){
6279 sessionAppendByte(&sOut, pIter->op, &rc);
6280 sessionAppendByte(&sOut, pIter->bIndirect, &rc);
6281 sessionAppendBlob(&sOut, aRec, nRec, &rc);
6283 if( rc==SQLITE_OK && xOutput && sOut.nBuf>sessions_strm_chunk_size ){
6284 rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
6285 sOut.nBuf = 0;
6287 if( rc ) break;
6290 if( rc!=SQLITE_OK ){
6291 sqlite3_free(sOut.aBuf);
6292 memset(&sOut, 0, sizeof(sOut));
6295 if( rc==SQLITE_OK ){
6296 if( xOutput ){
6297 if( sOut.nBuf>0 ){
6298 rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
6300 }else if( ppOut ){
6301 *ppOut = (void*)sOut.aBuf;
6302 *pnOut = sOut.nBuf;
6303 sOut.aBuf = 0;
6306 sqlite3_free(sOut.aBuf);
6307 return rc;
6311 ** Create a new rebaser object.
6313 int sqlite3rebaser_create(sqlite3_rebaser **ppNew){
6314 int rc = SQLITE_OK;
6315 sqlite3_rebaser *pNew;
6317 pNew = sqlite3_malloc(sizeof(sqlite3_rebaser));
6318 if( pNew==0 ){
6319 rc = SQLITE_NOMEM;
6320 }else{
6321 memset(pNew, 0, sizeof(sqlite3_rebaser));
6323 *ppNew = pNew;
6324 return rc;
6328 ** Call this one or more times to configure a rebaser.
6330 int sqlite3rebaser_configure(
6331 sqlite3_rebaser *p,
6332 int nRebase, const void *pRebase
6334 sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */
6335 int rc; /* Return code */
6336 rc = sqlite3changeset_start(&pIter, nRebase, (void*)pRebase);
6337 if( rc==SQLITE_OK ){
6338 rc = sessionChangesetToHash(pIter, &p->grp, 1);
6340 sqlite3changeset_finalize(pIter);
6341 return rc;
6345 ** Rebase a changeset according to current rebaser configuration
6347 int sqlite3rebaser_rebase(
6348 sqlite3_rebaser *p,
6349 int nIn, const void *pIn,
6350 int *pnOut, void **ppOut
6352 sqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */
6353 int rc = sqlite3changeset_start(&pIter, nIn, (void*)pIn);
6355 if( rc==SQLITE_OK ){
6356 rc = sessionRebase(p, pIter, 0, 0, pnOut, ppOut);
6357 sqlite3changeset_finalize(pIter);
6360 return rc;
6364 ** Rebase a changeset according to current rebaser configuration
6366 int sqlite3rebaser_rebase_strm(
6367 sqlite3_rebaser *p,
6368 int (*xInput)(void *pIn, void *pData, int *pnData),
6369 void *pIn,
6370 int (*xOutput)(void *pOut, const void *pData, int nData),
6371 void *pOut
6373 sqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */
6374 int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
6376 if( rc==SQLITE_OK ){
6377 rc = sessionRebase(p, pIter, xOutput, pOut, 0, 0);
6378 sqlite3changeset_finalize(pIter);
6381 return rc;
6385 ** Destroy a rebaser object
6387 void sqlite3rebaser_delete(sqlite3_rebaser *p){
6388 if( p ){
6389 sessionDeleteTable(0, p->grp.pList);
6390 sqlite3_free(p);
6395 ** Global configuration
6397 int sqlite3session_config(int op, void *pArg){
6398 int rc = SQLITE_OK;
6399 switch( op ){
6400 case SQLITE_SESSION_CONFIG_STRMSIZE: {
6401 int *pInt = (int*)pArg;
6402 if( *pInt>0 ){
6403 sessions_strm_chunk_size = *pInt;
6405 *pInt = sessions_strm_chunk_size;
6406 break;
6408 default:
6409 rc = SQLITE_MISUSE;
6410 break;
6412 return rc;
6415 #endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */