Merge sqlite-release(3.45.1) into prerelease-integration
[sqlcipher.git] / ext / session / sqlite3session.c
blobacb945194daeb2fd19f994db4345b26567e41ef4
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. It is a SELECT statement that
126 ** selects the default value for each table column. For example,
127 ** if the table is
129 ** CREATE TABLE xx(a DEFAULT 1, b, c DEFAULT 'abc')
131 ** then this variable is the compiled version of:
133 ** SELECT 1, NULL, 'abc'
135 struct SessionTable {
136 SessionTable *pNext;
137 char *zName; /* Local name of table */
138 int nCol; /* Number of columns in table zName */
139 int bStat1; /* True if this is sqlite_stat1 */
140 int bRowid; /* True if this table uses rowid for PK */
141 const char **azCol; /* Column names */
142 const char **azDflt; /* Default value expressions */
143 u8 *abPK; /* Array of primary key flags */
144 int nEntry; /* Total number of entries in hash table */
145 int nChange; /* Size of apChange[] array */
146 SessionChange **apChange; /* Hash table buckets */
147 sqlite3_stmt *pDfltStmt;
151 ** RECORD FORMAT:
153 ** The following record format is similar to (but not compatible with) that
154 ** used in SQLite database files. This format is used as part of the
155 ** change-set binary format, and so must be architecture independent.
157 ** Unlike the SQLite database record format, each field is self-contained -
158 ** there is no separation of header and data. Each field begins with a
159 ** single byte describing its type, as follows:
161 ** 0x00: Undefined value.
162 ** 0x01: Integer value.
163 ** 0x02: Real value.
164 ** 0x03: Text value.
165 ** 0x04: Blob value.
166 ** 0x05: SQL NULL value.
168 ** Note that the above match the definitions of SQLITE_INTEGER, SQLITE_TEXT
169 ** and so on in sqlite3.h. For undefined and NULL values, the field consists
170 ** only of the single type byte. For other types of values, the type byte
171 ** is followed by:
173 ** Text values:
174 ** A varint containing the number of bytes in the value (encoded using
175 ** UTF-8). Followed by a buffer containing the UTF-8 representation
176 ** of the text value. There is no nul terminator.
178 ** Blob values:
179 ** A varint containing the number of bytes in the value, followed by
180 ** a buffer containing the value itself.
182 ** Integer values:
183 ** An 8-byte big-endian integer value.
185 ** Real values:
186 ** An 8-byte big-endian IEEE 754-2008 real value.
188 ** Varint values are encoded in the same way as varints in the SQLite
189 ** record format.
191 ** CHANGESET FORMAT:
193 ** A changeset is a collection of DELETE, UPDATE and INSERT operations on
194 ** one or more tables. Operations on a single table are grouped together,
195 ** but may occur in any order (i.e. deletes, updates and inserts are all
196 ** mixed together).
198 ** Each group of changes begins with a table header:
200 ** 1 byte: Constant 0x54 (capital 'T')
201 ** Varint: Number of columns in the table.
202 ** nCol bytes: 0x01 for PK columns, 0x00 otherwise.
203 ** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
205 ** Followed by one or more changes to the table.
207 ** 1 byte: Either SQLITE_INSERT (0x12), UPDATE (0x17) or DELETE (0x09).
208 ** 1 byte: The "indirect-change" flag.
209 ** old.* record: (delete and update only)
210 ** new.* record: (insert and update only)
212 ** The "old.*" and "new.*" records, if present, are N field records in the
213 ** format described above under "RECORD FORMAT", where N is the number of
214 ** columns in the table. The i'th field of each record is associated with
215 ** the i'th column of the table, counting from left to right in the order
216 ** in which columns were declared in the CREATE TABLE statement.
218 ** The new.* record that is part of each INSERT change contains the values
219 ** that make up the new row. Similarly, the old.* record that is part of each
220 ** DELETE change contains the values that made up the row that was deleted
221 ** from the database. In the changeset format, the records that are part
222 ** of INSERT or DELETE changes never contain any undefined (type byte 0x00)
223 ** fields.
225 ** Within the old.* record associated with an UPDATE change, all fields
226 ** associated with table columns that are not PRIMARY KEY columns and are
227 ** not modified by the UPDATE change are set to "undefined". Other fields
228 ** are set to the values that made up the row before the UPDATE that the
229 ** change records took place. Within the new.* record, fields associated
230 ** with table columns modified by the UPDATE change contain the new
231 ** values. Fields associated with table columns that are not modified
232 ** are set to "undefined".
234 ** PATCHSET FORMAT:
236 ** A patchset is also a collection of changes. It is similar to a changeset,
237 ** but leaves undefined those fields that are not useful if no conflict
238 ** resolution is required when applying the changeset.
240 ** Each group of changes begins with a table header:
242 ** 1 byte: Constant 0x50 (capital 'P')
243 ** Varint: Number of columns in the table.
244 ** nCol bytes: 0x01 for PK columns, 0x00 otherwise.
245 ** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
247 ** Followed by one or more changes to the table.
249 ** 1 byte: Either SQLITE_INSERT (0x12), UPDATE (0x17) or DELETE (0x09).
250 ** 1 byte: The "indirect-change" flag.
251 ** single record: (PK fields for DELETE, PK and modified fields for UPDATE,
252 ** full record for INSERT).
254 ** As in the changeset format, each field of the single record that is part
255 ** of a patchset change is associated with the correspondingly positioned
256 ** table column, counting from left to right within the CREATE TABLE
257 ** statement.
259 ** For a DELETE change, all fields within the record except those associated
260 ** with PRIMARY KEY columns are omitted. The PRIMARY KEY fields contain the
261 ** values identifying the row to delete.
263 ** For an UPDATE change, all fields except those associated with PRIMARY KEY
264 ** columns and columns that are modified by the UPDATE are set to "undefined".
265 ** PRIMARY KEY fields contain the values identifying the table row to update,
266 ** and fields associated with modified columns contain the new column values.
268 ** The records associated with INSERT changes are in the same format as for
269 ** changesets. It is not possible for a record associated with an INSERT
270 ** change to contain a field set to "undefined".
272 ** REBASE BLOB FORMAT:
274 ** A rebase blob may be output by sqlite3changeset_apply_v2() and its
275 ** streaming equivalent for use with the sqlite3_rebaser APIs to rebase
276 ** existing changesets. A rebase blob contains one entry for each conflict
277 ** resolved using either the OMIT or REPLACE strategies within the apply_v2()
278 ** call.
280 ** The format used for a rebase blob is very similar to that used for
281 ** changesets. All entries related to a single table are grouped together.
283 ** Each group of entries begins with a table header in changeset format:
285 ** 1 byte: Constant 0x54 (capital 'T')
286 ** Varint: Number of columns in the table.
287 ** nCol bytes: 0x01 for PK columns, 0x00 otherwise.
288 ** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
290 ** Followed by one or more entries associated with the table.
292 ** 1 byte: Either SQLITE_INSERT (0x12), DELETE (0x09).
293 ** 1 byte: Flag. 0x01 for REPLACE, 0x00 for OMIT.
294 ** record: (in the record format defined above).
296 ** In a rebase blob, the first field is set to SQLITE_INSERT if the change
297 ** that caused the conflict was an INSERT or UPDATE, or to SQLITE_DELETE if
298 ** it was a DELETE. The second field is set to 0x01 if the conflict
299 ** resolution strategy was REPLACE, or 0x00 if it was OMIT.
301 ** If the change that caused the conflict was a DELETE, then the single
302 ** record is a copy of the old.* record from the original changeset. If it
303 ** was an INSERT, then the single record is a copy of the new.* record. If
304 ** the conflicting change was an UPDATE, then the single record is a copy
305 ** of the new.* record with the PK fields filled in based on the original
306 ** old.* record.
310 ** For each row modified during a session, there exists a single instance of
311 ** this structure stored in a SessionTable.aChange[] hash table.
313 struct SessionChange {
314 u8 op; /* One of UPDATE, DELETE, INSERT */
315 u8 bIndirect; /* True if this change is "indirect" */
316 u16 nRecordField; /* Number of fields in aRecord[] */
317 int nMaxSize; /* Max size of eventual changeset record */
318 int nRecord; /* Number of bytes in buffer aRecord[] */
319 u8 *aRecord; /* Buffer containing old.* record */
320 SessionChange *pNext; /* For hash-table collisions */
324 ** Write a varint with value iVal into the buffer at aBuf. Return the
325 ** number of bytes written.
327 static int sessionVarintPut(u8 *aBuf, int iVal){
328 return putVarint32(aBuf, iVal);
332 ** Return the number of bytes required to store value iVal as a varint.
334 static int sessionVarintLen(int iVal){
335 return sqlite3VarintLen(iVal);
339 ** Read a varint value from aBuf[] into *piVal. Return the number of
340 ** bytes read.
342 static int sessionVarintGet(const u8 *aBuf, int *piVal){
343 return getVarint32(aBuf, *piVal);
346 /* Load an unaligned and unsigned 32-bit integer */
347 #define SESSION_UINT32(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
350 ** Read a 64-bit big-endian integer value from buffer aRec[]. Return
351 ** the value read.
353 static sqlite3_int64 sessionGetI64(u8 *aRec){
354 u64 x = SESSION_UINT32(aRec);
355 u32 y = SESSION_UINT32(aRec+4);
356 x = (x<<32) + y;
357 return (sqlite3_int64)x;
361 ** Write a 64-bit big-endian integer value to the buffer aBuf[].
363 static void sessionPutI64(u8 *aBuf, sqlite3_int64 i){
364 aBuf[0] = (i>>56) & 0xFF;
365 aBuf[1] = (i>>48) & 0xFF;
366 aBuf[2] = (i>>40) & 0xFF;
367 aBuf[3] = (i>>32) & 0xFF;
368 aBuf[4] = (i>>24) & 0xFF;
369 aBuf[5] = (i>>16) & 0xFF;
370 aBuf[6] = (i>> 8) & 0xFF;
371 aBuf[7] = (i>> 0) & 0xFF;
375 ** This function is used to serialize the contents of value pValue (see
376 ** comment titled "RECORD FORMAT" above).
378 ** If it is non-NULL, the serialized form of the value is written to
379 ** buffer aBuf. *pnWrite is set to the number of bytes written before
380 ** returning. Or, if aBuf is NULL, the only thing this function does is
381 ** set *pnWrite.
383 ** If no error occurs, SQLITE_OK is returned. Or, if an OOM error occurs
384 ** within a call to sqlite3_value_text() (may fail if the db is utf-16))
385 ** SQLITE_NOMEM is returned.
387 static int sessionSerializeValue(
388 u8 *aBuf, /* If non-NULL, write serialized value here */
389 sqlite3_value *pValue, /* Value to serialize */
390 sqlite3_int64 *pnWrite /* IN/OUT: Increment by bytes written */
392 int nByte; /* Size of serialized value in bytes */
394 if( pValue ){
395 int eType; /* Value type (SQLITE_NULL, TEXT etc.) */
397 eType = sqlite3_value_type(pValue);
398 if( aBuf ) aBuf[0] = eType;
400 switch( eType ){
401 case SQLITE_NULL:
402 nByte = 1;
403 break;
405 case SQLITE_INTEGER:
406 case SQLITE_FLOAT:
407 if( aBuf ){
408 /* TODO: SQLite does something special to deal with mixed-endian
409 ** floating point values (e.g. ARM7). This code probably should
410 ** too. */
411 u64 i;
412 if( eType==SQLITE_INTEGER ){
413 i = (u64)sqlite3_value_int64(pValue);
414 }else{
415 double r;
416 assert( sizeof(double)==8 && sizeof(u64)==8 );
417 r = sqlite3_value_double(pValue);
418 memcpy(&i, &r, 8);
420 sessionPutI64(&aBuf[1], i);
422 nByte = 9;
423 break;
425 default: {
426 u8 *z;
427 int n;
428 int nVarint;
430 assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
431 if( eType==SQLITE_TEXT ){
432 z = (u8 *)sqlite3_value_text(pValue);
433 }else{
434 z = (u8 *)sqlite3_value_blob(pValue);
436 n = sqlite3_value_bytes(pValue);
437 if( z==0 && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM;
438 nVarint = sessionVarintLen(n);
440 if( aBuf ){
441 sessionVarintPut(&aBuf[1], n);
442 if( n>0 ) memcpy(&aBuf[nVarint + 1], z, n);
445 nByte = 1 + nVarint + n;
446 break;
449 }else{
450 nByte = 1;
451 if( aBuf ) aBuf[0] = '\0';
454 if( pnWrite ) *pnWrite += nByte;
455 return SQLITE_OK;
459 ** Allocate and return a pointer to a buffer nByte bytes in size. If
460 ** pSession is not NULL, increase the sqlite3_session.nMalloc variable
461 ** by the number of bytes allocated.
463 static void *sessionMalloc64(sqlite3_session *pSession, i64 nByte){
464 void *pRet = sqlite3_malloc64(nByte);
465 if( pSession ) pSession->nMalloc += sqlite3_msize(pRet);
466 return pRet;
470 ** Free buffer pFree, which must have been allocated by an earlier
471 ** call to sessionMalloc64(). If pSession is not NULL, decrease the
472 ** sqlite3_session.nMalloc counter by the number of bytes freed.
474 static void sessionFree(sqlite3_session *pSession, void *pFree){
475 if( pSession ) pSession->nMalloc -= sqlite3_msize(pFree);
476 sqlite3_free(pFree);
480 ** This macro is used to calculate hash key values for data structures. In
481 ** order to use this macro, the entire data structure must be represented
482 ** as a series of unsigned integers. In order to calculate a hash-key value
483 ** for a data structure represented as three such integers, the macro may
484 ** then be used as follows:
486 ** int hash_key_value;
487 ** hash_key_value = HASH_APPEND(0, <value 1>);
488 ** hash_key_value = HASH_APPEND(hash_key_value, <value 2>);
489 ** hash_key_value = HASH_APPEND(hash_key_value, <value 3>);
491 ** In practice, the data structures this macro is used for are the primary
492 ** key values of modified rows.
494 #define HASH_APPEND(hash, add) ((hash) << 3) ^ (hash) ^ (unsigned int)(add)
497 ** Append the hash of the 64-bit integer passed as the second argument to the
498 ** hash-key value passed as the first. Return the new hash-key value.
500 static unsigned int sessionHashAppendI64(unsigned int h, i64 i){
501 h = HASH_APPEND(h, i & 0xFFFFFFFF);
502 return HASH_APPEND(h, (i>>32)&0xFFFFFFFF);
506 ** Append the hash of the blob passed via the second and third arguments to
507 ** the hash-key value passed as the first. Return the new hash-key value.
509 static unsigned int sessionHashAppendBlob(unsigned int h, int n, const u8 *z){
510 int i;
511 for(i=0; i<n; i++) h = HASH_APPEND(h, z[i]);
512 return h;
516 ** Append the hash of the data type passed as the second argument to the
517 ** hash-key value passed as the first. Return the new hash-key value.
519 static unsigned int sessionHashAppendType(unsigned int h, int eType){
520 return HASH_APPEND(h, eType);
524 ** This function may only be called from within a pre-update callback.
525 ** It calculates a hash based on the primary key values of the old.* or
526 ** new.* row currently available and, assuming no error occurs, writes it to
527 ** *piHash before returning. If the primary key contains one or more NULL
528 ** values, *pbNullPK is set to true before returning.
530 ** If an error occurs, an SQLite error code is returned and the final values
531 ** of *piHash asn *pbNullPK are undefined. Otherwise, SQLITE_OK is returned
532 ** and the output variables are set as described above.
534 static int sessionPreupdateHash(
535 sqlite3_session *pSession, /* Session object that owns pTab */
536 i64 iRowid,
537 SessionTable *pTab, /* Session table handle */
538 int bNew, /* True to hash the new.* PK */
539 int *piHash, /* OUT: Hash value */
540 int *pbNullPK /* OUT: True if there are NULL values in PK */
542 unsigned int h = 0; /* Hash value to return */
543 int i; /* Used to iterate through columns */
545 if( pTab->bRowid ){
546 assert( pTab->nCol-1==pSession->hook.xCount(pSession->hook.pCtx) );
547 h = sessionHashAppendI64(h, iRowid);
548 }else{
549 assert( *pbNullPK==0 );
550 assert( pTab->nCol==pSession->hook.xCount(pSession->hook.pCtx) );
551 for(i=0; i<pTab->nCol; i++){
552 if( pTab->abPK[i] ){
553 int rc;
554 int eType;
555 sqlite3_value *pVal;
557 if( bNew ){
558 rc = pSession->hook.xNew(pSession->hook.pCtx, i, &pVal);
559 }else{
560 rc = pSession->hook.xOld(pSession->hook.pCtx, i, &pVal);
562 if( rc!=SQLITE_OK ) return rc;
564 eType = sqlite3_value_type(pVal);
565 h = sessionHashAppendType(h, eType);
566 if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
567 i64 iVal;
568 if( eType==SQLITE_INTEGER ){
569 iVal = sqlite3_value_int64(pVal);
570 }else{
571 double rVal = sqlite3_value_double(pVal);
572 assert( sizeof(iVal)==8 && sizeof(rVal)==8 );
573 memcpy(&iVal, &rVal, 8);
575 h = sessionHashAppendI64(h, iVal);
576 }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
577 const u8 *z;
578 int n;
579 if( eType==SQLITE_TEXT ){
580 z = (const u8 *)sqlite3_value_text(pVal);
581 }else{
582 z = (const u8 *)sqlite3_value_blob(pVal);
584 n = sqlite3_value_bytes(pVal);
585 if( !z && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM;
586 h = sessionHashAppendBlob(h, n, z);
587 }else{
588 assert( eType==SQLITE_NULL );
589 assert( pTab->bStat1==0 || i!=1 );
590 *pbNullPK = 1;
596 *piHash = (h % pTab->nChange);
597 return SQLITE_OK;
601 ** The buffer that the argument points to contains a serialized SQL value.
602 ** Return the number of bytes of space occupied by the value (including
603 ** the type byte).
605 static int sessionSerialLen(const u8 *a){
606 int e;
607 int n;
608 assert( a!=0 );
609 e = *a;
610 if( e==0 || e==0xFF ) return 1;
611 if( e==SQLITE_NULL ) return 1;
612 if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9;
613 return sessionVarintGet(&a[1], &n) + 1 + n;
617 ** Based on the primary key values stored in change aRecord, calculate a
618 ** hash key. Assume the has table has nBucket buckets. The hash keys
619 ** calculated by this function are compatible with those calculated by
620 ** sessionPreupdateHash().
622 ** The bPkOnly argument is non-zero if the record at aRecord[] is from
623 ** a patchset DELETE. In this case the non-PK fields are omitted entirely.
625 static unsigned int sessionChangeHash(
626 SessionTable *pTab, /* Table handle */
627 int bPkOnly, /* Record consists of PK fields only */
628 u8 *aRecord, /* Change record */
629 int nBucket /* Assume this many buckets in hash table */
631 unsigned int h = 0; /* Value to return */
632 int i; /* Used to iterate through columns */
633 u8 *a = aRecord; /* Used to iterate through change record */
635 for(i=0; i<pTab->nCol; i++){
636 int eType = *a;
637 int isPK = pTab->abPK[i];
638 if( bPkOnly && isPK==0 ) continue;
640 /* It is not possible for eType to be SQLITE_NULL here. The session
641 ** module does not record changes for rows with NULL values stored in
642 ** primary key columns. */
643 assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT
644 || eType==SQLITE_TEXT || eType==SQLITE_BLOB
645 || eType==SQLITE_NULL || eType==0
647 assert( !isPK || (eType!=0 && eType!=SQLITE_NULL) );
649 if( isPK ){
650 a++;
651 h = sessionHashAppendType(h, eType);
652 if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
653 h = sessionHashAppendI64(h, sessionGetI64(a));
654 a += 8;
655 }else{
656 int n;
657 a += sessionVarintGet(a, &n);
658 h = sessionHashAppendBlob(h, n, a);
659 a += n;
661 }else{
662 a += sessionSerialLen(a);
665 return (h % nBucket);
669 ** Arguments aLeft and aRight are pointers to change records for table pTab.
670 ** This function returns true if the two records apply to the same row (i.e.
671 ** have the same values stored in the primary key columns), or false
672 ** otherwise.
674 static int sessionChangeEqual(
675 SessionTable *pTab, /* Table used for PK definition */
676 int bLeftPkOnly, /* True if aLeft[] contains PK fields only */
677 u8 *aLeft, /* Change record */
678 int bRightPkOnly, /* True if aRight[] contains PK fields only */
679 u8 *aRight /* Change record */
681 u8 *a1 = aLeft; /* Cursor to iterate through aLeft */
682 u8 *a2 = aRight; /* Cursor to iterate through aRight */
683 int iCol; /* Used to iterate through table columns */
685 for(iCol=0; iCol<pTab->nCol; iCol++){
686 if( pTab->abPK[iCol] ){
687 int n1 = sessionSerialLen(a1);
688 int n2 = sessionSerialLen(a2);
690 if( n1!=n2 || memcmp(a1, a2, n1) ){
691 return 0;
693 a1 += n1;
694 a2 += n2;
695 }else{
696 if( bLeftPkOnly==0 ) a1 += sessionSerialLen(a1);
697 if( bRightPkOnly==0 ) a2 += sessionSerialLen(a2);
701 return 1;
705 ** Arguments aLeft and aRight both point to buffers containing change
706 ** records with nCol columns. This function "merges" the two records into
707 ** a single records which is written to the buffer at *paOut. *paOut is
708 ** then set to point to one byte after the last byte written before
709 ** returning.
711 ** The merging of records is done as follows: For each column, if the
712 ** aRight record contains a value for the column, copy the value from
713 ** their. Otherwise, if aLeft contains a value, copy it. If neither
714 ** record contains a value for a given column, then neither does the
715 ** output record.
717 static void sessionMergeRecord(
718 u8 **paOut,
719 int nCol,
720 u8 *aLeft,
721 u8 *aRight
723 u8 *a1 = aLeft; /* Cursor used to iterate through aLeft */
724 u8 *a2 = aRight; /* Cursor used to iterate through aRight */
725 u8 *aOut = *paOut; /* Output cursor */
726 int iCol; /* Used to iterate from 0 to nCol */
728 for(iCol=0; iCol<nCol; iCol++){
729 int n1 = sessionSerialLen(a1);
730 int n2 = sessionSerialLen(a2);
731 if( *a2 ){
732 memcpy(aOut, a2, n2);
733 aOut += n2;
734 }else{
735 memcpy(aOut, a1, n1);
736 aOut += n1;
738 a1 += n1;
739 a2 += n2;
742 *paOut = aOut;
746 ** This is a helper function used by sessionMergeUpdate().
748 ** When this function is called, both *paOne and *paTwo point to a value
749 ** within a change record. Before it returns, both have been advanced so
750 ** as to point to the next value in the record.
752 ** If, when this function is called, *paTwo points to a valid value (i.e.
753 ** *paTwo[0] is not 0x00 - the "no value" placeholder), a copy of the *paTwo
754 ** pointer is returned and *pnVal is set to the number of bytes in the
755 ** serialized value. Otherwise, a copy of *paOne is returned and *pnVal
756 ** set to the number of bytes in the value at *paOne. If *paOne points
757 ** to the "no value" placeholder, *pnVal is set to 1. In other words:
759 ** if( *paTwo is valid ) return *paTwo;
760 ** return *paOne;
763 static u8 *sessionMergeValue(
764 u8 **paOne, /* IN/OUT: Left-hand buffer pointer */
765 u8 **paTwo, /* IN/OUT: Right-hand buffer pointer */
766 int *pnVal /* OUT: Bytes in returned value */
768 u8 *a1 = *paOne;
769 u8 *a2 = *paTwo;
770 u8 *pRet = 0;
771 int n1;
773 assert( a1 );
774 if( a2 ){
775 int n2 = sessionSerialLen(a2);
776 if( *a2 ){
777 *pnVal = n2;
778 pRet = a2;
780 *paTwo = &a2[n2];
783 n1 = sessionSerialLen(a1);
784 if( pRet==0 ){
785 *pnVal = n1;
786 pRet = a1;
788 *paOne = &a1[n1];
790 return pRet;
794 ** This function is used by changeset_concat() to merge two UPDATE changes
795 ** on the same row.
797 static int sessionMergeUpdate(
798 u8 **paOut, /* IN/OUT: Pointer to output buffer */
799 SessionTable *pTab, /* Table change pertains to */
800 int bPatchset, /* True if records are patchset records */
801 u8 *aOldRecord1, /* old.* record for first change */
802 u8 *aOldRecord2, /* old.* record for second change */
803 u8 *aNewRecord1, /* new.* record for first change */
804 u8 *aNewRecord2 /* new.* record for second change */
806 u8 *aOld1 = aOldRecord1;
807 u8 *aOld2 = aOldRecord2;
808 u8 *aNew1 = aNewRecord1;
809 u8 *aNew2 = aNewRecord2;
811 u8 *aOut = *paOut;
812 int i;
814 if( bPatchset==0 ){
815 int bRequired = 0;
817 assert( aOldRecord1 && aNewRecord1 );
819 /* Write the old.* vector first. */
820 for(i=0; i<pTab->nCol; i++){
821 int nOld;
822 u8 *aOld;
823 int nNew;
824 u8 *aNew;
826 aOld = sessionMergeValue(&aOld1, &aOld2, &nOld);
827 aNew = sessionMergeValue(&aNew1, &aNew2, &nNew);
828 if( pTab->abPK[i] || nOld!=nNew || memcmp(aOld, aNew, nNew) ){
829 if( pTab->abPK[i]==0 ) bRequired = 1;
830 memcpy(aOut, aOld, nOld);
831 aOut += nOld;
832 }else{
833 *(aOut++) = '\0';
837 if( !bRequired ) return 0;
840 /* Write the new.* vector */
841 aOld1 = aOldRecord1;
842 aOld2 = aOldRecord2;
843 aNew1 = aNewRecord1;
844 aNew2 = aNewRecord2;
845 for(i=0; i<pTab->nCol; i++){
846 int nOld;
847 u8 *aOld;
848 int nNew;
849 u8 *aNew;
851 aOld = sessionMergeValue(&aOld1, &aOld2, &nOld);
852 aNew = sessionMergeValue(&aNew1, &aNew2, &nNew);
853 if( bPatchset==0
854 && (pTab->abPK[i] || (nOld==nNew && 0==memcmp(aOld, aNew, nNew)))
856 *(aOut++) = '\0';
857 }else{
858 memcpy(aOut, aNew, nNew);
859 aOut += nNew;
863 *paOut = aOut;
864 return 1;
868 ** This function is only called from within a pre-update-hook callback.
869 ** It determines if the current pre-update-hook change affects the same row
870 ** as the change stored in argument pChange. If so, it returns true. Otherwise
871 ** if the pre-update-hook does not affect the same row as pChange, it returns
872 ** false.
874 static int sessionPreupdateEqual(
875 sqlite3_session *pSession, /* Session object that owns SessionTable */
876 i64 iRowid, /* Rowid value if pTab->bRowid */
877 SessionTable *pTab, /* Table associated with change */
878 SessionChange *pChange, /* Change to compare to */
879 int op /* Current pre-update operation */
881 int iCol; /* Used to iterate through columns */
882 u8 *a = pChange->aRecord; /* Cursor used to scan change record */
884 if( pTab->bRowid ){
885 if( a[0]!=SQLITE_INTEGER ) return 0;
886 return sessionGetI64(&a[1])==iRowid;
889 assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
890 for(iCol=0; iCol<pTab->nCol; iCol++){
891 if( !pTab->abPK[iCol] ){
892 a += sessionSerialLen(a);
893 }else{
894 sqlite3_value *pVal; /* Value returned by preupdate_new/old */
895 int rc; /* Error code from preupdate_new/old */
896 int eType = *a++; /* Type of value from change record */
898 /* The following calls to preupdate_new() and preupdate_old() can not
899 ** fail. This is because they cache their return values, and by the
900 ** time control flows to here they have already been called once from
901 ** within sessionPreupdateHash(). The first two asserts below verify
902 ** this (that the method has already been called). */
903 if( op==SQLITE_INSERT ){
904 /* assert( db->pPreUpdate->pNewUnpacked || db->pPreUpdate->aNew ); */
905 rc = pSession->hook.xNew(pSession->hook.pCtx, iCol, &pVal);
906 }else{
907 /* assert( db->pPreUpdate->pUnpacked ); */
908 rc = pSession->hook.xOld(pSession->hook.pCtx, iCol, &pVal);
910 assert( rc==SQLITE_OK );
911 (void)rc; /* Suppress warning about unused variable */
912 if( sqlite3_value_type(pVal)!=eType ) return 0;
914 /* A SessionChange object never has a NULL value in a PK column */
915 assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT
916 || eType==SQLITE_BLOB || eType==SQLITE_TEXT
919 if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
920 i64 iVal = sessionGetI64(a);
921 a += 8;
922 if( eType==SQLITE_INTEGER ){
923 if( sqlite3_value_int64(pVal)!=iVal ) return 0;
924 }else{
925 double rVal;
926 assert( sizeof(iVal)==8 && sizeof(rVal)==8 );
927 memcpy(&rVal, &iVal, 8);
928 if( sqlite3_value_double(pVal)!=rVal ) return 0;
930 }else{
931 int n;
932 const u8 *z;
933 a += sessionVarintGet(a, &n);
934 if( sqlite3_value_bytes(pVal)!=n ) return 0;
935 if( eType==SQLITE_TEXT ){
936 z = sqlite3_value_text(pVal);
937 }else{
938 z = sqlite3_value_blob(pVal);
940 if( n>0 && memcmp(a, z, n) ) return 0;
941 a += n;
946 return 1;
950 ** If required, grow the hash table used to store changes on table pTab
951 ** (part of the session pSession). If a fatal OOM error occurs, set the
952 ** session object to failed and return SQLITE_ERROR. Otherwise, return
953 ** SQLITE_OK.
955 ** It is possible that a non-fatal OOM error occurs in this function. In
956 ** that case the hash-table does not grow, but SQLITE_OK is returned anyway.
957 ** Growing the hash table in this case is a performance optimization only,
958 ** it is not required for correct operation.
960 static int sessionGrowHash(
961 sqlite3_session *pSession, /* For memory accounting. May be NULL */
962 int bPatchset,
963 SessionTable *pTab
965 if( pTab->nChange==0 || pTab->nEntry>=(pTab->nChange/2) ){
966 int i;
967 SessionChange **apNew;
968 sqlite3_int64 nNew = 2*(sqlite3_int64)(pTab->nChange ? pTab->nChange : 128);
970 apNew = (SessionChange**)sessionMalloc64(
971 pSession, sizeof(SessionChange*) * nNew
973 if( apNew==0 ){
974 if( pTab->nChange==0 ){
975 return SQLITE_ERROR;
977 return SQLITE_OK;
979 memset(apNew, 0, sizeof(SessionChange *) * nNew);
981 for(i=0; i<pTab->nChange; i++){
982 SessionChange *p;
983 SessionChange *pNext;
984 for(p=pTab->apChange[i]; p; p=pNext){
985 int bPkOnly = (p->op==SQLITE_DELETE && bPatchset);
986 int iHash = sessionChangeHash(pTab, bPkOnly, p->aRecord, nNew);
987 pNext = p->pNext;
988 p->pNext = apNew[iHash];
989 apNew[iHash] = p;
993 sessionFree(pSession, pTab->apChange);
994 pTab->nChange = nNew;
995 pTab->apChange = apNew;
998 return SQLITE_OK;
1002 ** This function queries the database for the names of the columns of table
1003 ** zThis, in schema zDb.
1005 ** Otherwise, if they are not NULL, variable *pnCol is set to the number
1006 ** of columns in the database table and variable *pzTab is set to point to a
1007 ** nul-terminated copy of the table name. *pazCol (if not NULL) is set to
1008 ** point to an array of pointers to column names. And *pabPK (again, if not
1009 ** NULL) is set to point to an array of booleans - true if the corresponding
1010 ** column is part of the primary key.
1012 ** For example, if the table is declared as:
1014 ** CREATE TABLE tbl1(w, x DEFAULT 'abc', y, z, PRIMARY KEY(w, z));
1016 ** Then the five output variables are populated as follows:
1018 ** *pnCol = 4
1019 ** *pzTab = "tbl1"
1020 ** *pazCol = {"w", "x", "y", "z"}
1021 ** *pazDflt = {NULL, 'abc', NULL, NULL}
1022 ** *pabPK = {1, 0, 0, 1}
1024 ** All returned buffers are part of the same single allocation, which must
1025 ** be freed using sqlite3_free() by the caller
1027 static int sessionTableInfo(
1028 sqlite3_session *pSession, /* For memory accounting. May be NULL */
1029 sqlite3 *db, /* Database connection */
1030 const char *zDb, /* Name of attached database (e.g. "main") */
1031 const char *zThis, /* Table name */
1032 int *pnCol, /* OUT: number of columns */
1033 const char **pzTab, /* OUT: Copy of zThis */
1034 const char ***pazCol, /* OUT: Array of column names for table */
1035 const char ***pazDflt, /* OUT: Array of default value expressions */
1036 u8 **pabPK, /* OUT: Array of booleans - true for PK col */
1037 int *pbRowid /* OUT: True if only PK is a rowid */
1039 char *zPragma;
1040 sqlite3_stmt *pStmt;
1041 int rc;
1042 sqlite3_int64 nByte;
1043 int nDbCol = 0;
1044 int nThis;
1045 int i;
1046 u8 *pAlloc = 0;
1047 char **azCol = 0;
1048 char **azDflt = 0;
1049 u8 *abPK = 0;
1050 int bRowid = 0; /* Set to true to use rowid as PK */
1052 assert( pazCol && pabPK );
1054 *pazCol = 0;
1055 *pabPK = 0;
1056 *pnCol = 0;
1057 if( pzTab ) *pzTab = 0;
1058 if( pazDflt ) *pazDflt = 0;
1060 nThis = sqlite3Strlen30(zThis);
1061 if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){
1062 rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0);
1063 if( rc==SQLITE_OK ){
1064 /* For sqlite_stat1, pretend that (tbl,idx) is the PRIMARY KEY. */
1065 zPragma = sqlite3_mprintf(
1066 "SELECT 0, 'tbl', '', 0, '', 1 UNION ALL "
1067 "SELECT 1, 'idx', '', 0, '', 2 UNION ALL "
1068 "SELECT 2, 'stat', '', 0, '', 0"
1070 }else if( rc==SQLITE_ERROR ){
1071 zPragma = sqlite3_mprintf("");
1072 }else{
1073 return rc;
1075 }else{
1076 zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
1078 if( !zPragma ){
1079 return SQLITE_NOMEM;
1082 rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0);
1083 sqlite3_free(zPragma);
1084 if( rc!=SQLITE_OK ){
1085 return rc;
1088 nByte = nThis + 1;
1089 bRowid = (pbRowid!=0);
1090 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1091 nByte += sqlite3_column_bytes(pStmt, 1); /* name */
1092 nByte += sqlite3_column_bytes(pStmt, 4); /* dflt_value */
1093 nDbCol++;
1094 if( sqlite3_column_int(pStmt, 5) ) bRowid = 0; /* pk */
1096 if( nDbCol==0 ) bRowid = 0;
1097 nDbCol += bRowid;
1098 nByte += strlen(SESSIONS_ROWID);
1099 rc = sqlite3_reset(pStmt);
1101 if( rc==SQLITE_OK ){
1102 nByte += nDbCol * (sizeof(const char *)*2 + sizeof(u8) + 1 + 1);
1103 pAlloc = sessionMalloc64(pSession, nByte);
1104 if( pAlloc==0 ){
1105 rc = SQLITE_NOMEM;
1106 }else{
1107 memset(pAlloc, 0, nByte);
1110 if( rc==SQLITE_OK ){
1111 azCol = (char **)pAlloc;
1112 azDflt = (char**)&azCol[nDbCol];
1113 pAlloc = (u8 *)&azDflt[nDbCol];
1114 abPK = (u8 *)pAlloc;
1115 pAlloc = &abPK[nDbCol];
1116 if( pzTab ){
1117 memcpy(pAlloc, zThis, nThis+1);
1118 *pzTab = (char *)pAlloc;
1119 pAlloc += nThis+1;
1122 i = 0;
1123 if( bRowid ){
1124 size_t nName = strlen(SESSIONS_ROWID);
1125 memcpy(pAlloc, SESSIONS_ROWID, nName+1);
1126 azCol[i] = (char*)pAlloc;
1127 pAlloc += nName+1;
1128 abPK[i] = 1;
1129 i++;
1131 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1132 int nName = sqlite3_column_bytes(pStmt, 1);
1133 int nDflt = sqlite3_column_bytes(pStmt, 4);
1134 const unsigned char *zName = sqlite3_column_text(pStmt, 1);
1135 const unsigned char *zDflt = sqlite3_column_text(pStmt, 4);
1137 if( zName==0 ) break;
1138 memcpy(pAlloc, zName, nName+1);
1139 azCol[i] = (char *)pAlloc;
1140 pAlloc += nName+1;
1141 if( zDflt ){
1142 memcpy(pAlloc, zDflt, nDflt+1);
1143 azDflt[i] = (char *)pAlloc;
1144 pAlloc += nDflt+1;
1145 }else{
1146 azDflt[i] = 0;
1148 abPK[i] = sqlite3_column_int(pStmt, 5);
1149 i++;
1151 rc = sqlite3_reset(pStmt);
1154 /* If successful, populate the output variables. Otherwise, zero them and
1155 ** free any allocation made. An error code will be returned in this case.
1157 if( rc==SQLITE_OK ){
1158 *pazCol = (const char**)azCol;
1159 if( pazDflt ) *pazDflt = (const char**)azDflt;
1160 *pabPK = abPK;
1161 *pnCol = nDbCol;
1162 }else{
1163 sessionFree(pSession, azCol);
1165 if( pbRowid ) *pbRowid = bRowid;
1166 sqlite3_finalize(pStmt);
1167 return rc;
1171 ** This function is called to initialize the SessionTable.nCol, azCol[]
1172 ** abPK[] and azDflt[] members of SessionTable object pTab. If these
1173 ** fields are already initilialized, this function is a no-op.
1175 ** If an error occurs, an error code is stored in sqlite3_session.rc and
1176 ** non-zero returned. Or, if no error occurs but the table has no primary
1177 ** key, sqlite3_session.rc is left set to SQLITE_OK and non-zero returned to
1178 ** indicate that updates on this table should be ignored. SessionTable.abPK
1179 ** is set to NULL in this case.
1181 static int sessionInitTable(
1182 sqlite3_session *pSession, /* Optional session handle */
1183 SessionTable *pTab, /* Table object to initialize */
1184 sqlite3 *db, /* Database handle to read schema from */
1185 const char *zDb /* Name of db - "main", "temp" etc. */
1187 int rc = SQLITE_OK;
1189 if( pTab->nCol==0 ){
1190 u8 *abPK;
1191 assert( pTab->azCol==0 || pTab->abPK==0 );
1192 rc = sessionTableInfo(pSession, db, zDb,
1193 pTab->zName, &pTab->nCol, 0, &pTab->azCol, &pTab->azDflt, &abPK,
1194 ((pSession==0 || pSession->bImplicitPK) ? &pTab->bRowid : 0)
1196 if( rc==SQLITE_OK ){
1197 int i;
1198 for(i=0; i<pTab->nCol; i++){
1199 if( abPK[i] ){
1200 pTab->abPK = abPK;
1201 break;
1204 if( 0==sqlite3_stricmp("sqlite_stat1", pTab->zName) ){
1205 pTab->bStat1 = 1;
1208 if( pSession && pSession->bEnableSize ){
1209 pSession->nMaxChangesetSize += (
1210 1 + sessionVarintLen(pTab->nCol) + pTab->nCol + strlen(pTab->zName)+1
1216 if( pSession ){
1217 pSession->rc = rc;
1218 return (rc || pTab->abPK==0);
1220 return rc;
1224 ** Re-initialize table object pTab.
1226 static int sessionReinitTable(sqlite3_session *pSession, SessionTable *pTab){
1227 int nCol = 0;
1228 const char **azCol = 0;
1229 const char **azDflt = 0;
1230 u8 *abPK = 0;
1231 int bRowid = 0;
1233 assert( pSession->rc==SQLITE_OK );
1235 pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb,
1236 pTab->zName, &nCol, 0, &azCol, &azDflt, &abPK,
1237 (pSession->bImplicitPK ? &bRowid : 0)
1239 if( pSession->rc==SQLITE_OK ){
1240 if( pTab->nCol>nCol || pTab->bRowid!=bRowid ){
1241 pSession->rc = SQLITE_SCHEMA;
1242 }else{
1243 int ii;
1244 int nOldCol = pTab->nCol;
1245 for(ii=0; ii<nCol; ii++){
1246 if( ii<pTab->nCol ){
1247 if( pTab->abPK[ii]!=abPK[ii] ){
1248 pSession->rc = SQLITE_SCHEMA;
1250 }else if( abPK[ii] ){
1251 pSession->rc = SQLITE_SCHEMA;
1255 if( pSession->rc==SQLITE_OK ){
1256 const char **a = pTab->azCol;
1257 pTab->azCol = azCol;
1258 pTab->nCol = nCol;
1259 pTab->azDflt = azDflt;
1260 pTab->abPK = abPK;
1261 azCol = a;
1263 if( pSession->bEnableSize ){
1264 pSession->nMaxChangesetSize += (nCol - nOldCol);
1265 pSession->nMaxChangesetSize += sessionVarintLen(nCol);
1266 pSession->nMaxChangesetSize -= sessionVarintLen(nOldCol);
1271 sqlite3_free((char*)azCol);
1272 return pSession->rc;
1276 ** Session-change object (*pp) contains an old.* record with fewer than
1277 ** nCol fields. This function updates it with the default values for
1278 ** the missing fields.
1280 static void sessionUpdateOneChange(
1281 sqlite3_session *pSession, /* For memory accounting */
1282 int *pRc, /* IN/OUT: Error code */
1283 SessionChange **pp, /* IN/OUT: Change object to update */
1284 int nCol, /* Number of columns now in table */
1285 sqlite3_stmt *pDflt /* SELECT <default-values...> */
1287 SessionChange *pOld = *pp;
1289 while( pOld->nRecordField<nCol ){
1290 SessionChange *pNew = 0;
1291 int nByte = 0;
1292 int nIncr = 0;
1293 int iField = pOld->nRecordField;
1294 int eType = sqlite3_column_type(pDflt, iField);
1295 switch( eType ){
1296 case SQLITE_NULL:
1297 nIncr = 1;
1298 break;
1299 case SQLITE_INTEGER:
1300 case SQLITE_FLOAT:
1301 nIncr = 9;
1302 break;
1303 default: {
1304 int n = sqlite3_column_bytes(pDflt, iField);
1305 nIncr = 1 + sessionVarintLen(n) + n;
1306 assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
1307 break;
1311 nByte = nIncr + (sizeof(SessionChange) + pOld->nRecord);
1312 pNew = sessionMalloc64(pSession, nByte);
1313 if( pNew==0 ){
1314 *pRc = SQLITE_NOMEM;
1315 return;
1316 }else{
1317 memcpy(pNew, pOld, sizeof(SessionChange));
1318 pNew->aRecord = (u8*)&pNew[1];
1319 memcpy(pNew->aRecord, pOld->aRecord, pOld->nRecord);
1320 pNew->aRecord[pNew->nRecord++] = (u8)eType;
1321 switch( eType ){
1322 case SQLITE_INTEGER: {
1323 i64 iVal = sqlite3_column_int64(pDflt, iField);
1324 sessionPutI64(&pNew->aRecord[pNew->nRecord], iVal);
1325 pNew->nRecord += 8;
1326 break;
1329 case SQLITE_FLOAT: {
1330 double rVal = sqlite3_column_double(pDflt, iField);
1331 i64 iVal = 0;
1332 memcpy(&iVal, &rVal, sizeof(rVal));
1333 sessionPutI64(&pNew->aRecord[pNew->nRecord], iVal);
1334 pNew->nRecord += 8;
1335 break;
1338 case SQLITE_TEXT: {
1339 int n = sqlite3_column_bytes(pDflt, iField);
1340 const char *z = (const char*)sqlite3_column_text(pDflt, iField);
1341 pNew->nRecord += sessionVarintPut(&pNew->aRecord[pNew->nRecord], n);
1342 memcpy(&pNew->aRecord[pNew->nRecord], z, n);
1343 pNew->nRecord += n;
1344 break;
1347 case SQLITE_BLOB: {
1348 int n = sqlite3_column_bytes(pDflt, iField);
1349 const u8 *z = (const u8*)sqlite3_column_blob(pDflt, iField);
1350 pNew->nRecord += sessionVarintPut(&pNew->aRecord[pNew->nRecord], n);
1351 memcpy(&pNew->aRecord[pNew->nRecord], z, n);
1352 pNew->nRecord += n;
1353 break;
1356 default:
1357 assert( eType==SQLITE_NULL );
1358 break;
1361 sessionFree(pSession, pOld);
1362 *pp = pOld = pNew;
1363 pNew->nRecordField++;
1364 pNew->nMaxSize += nIncr;
1365 if( pSession ){
1366 pSession->nMaxChangesetSize += nIncr;
1373 ** Ensure that there is room in the buffer to append nByte bytes of data.
1374 ** If not, use sqlite3_realloc() to grow the buffer so that there is.
1376 ** If successful, return zero. Otherwise, if an OOM condition is encountered,
1377 ** set *pRc to SQLITE_NOMEM and return non-zero.
1379 static int sessionBufferGrow(SessionBuffer *p, i64 nByte, int *pRc){
1380 #define SESSION_MAX_BUFFER_SZ (0x7FFFFF00 - 1)
1381 i64 nReq = p->nBuf + nByte;
1382 if( *pRc==SQLITE_OK && nReq>p->nAlloc ){
1383 u8 *aNew;
1384 i64 nNew = p->nAlloc ? p->nAlloc : 128;
1386 do {
1387 nNew = nNew*2;
1388 }while( nNew<nReq );
1390 /* The value of SESSION_MAX_BUFFER_SZ is copied from the implementation
1391 ** of sqlite3_realloc64(). Allocations greater than this size in bytes
1392 ** always fail. It is used here to ensure that this routine can always
1393 ** allocate up to this limit - instead of up to the largest power of
1394 ** two smaller than the limit. */
1395 if( nNew>SESSION_MAX_BUFFER_SZ ){
1396 nNew = SESSION_MAX_BUFFER_SZ;
1397 if( nNew<nReq ){
1398 *pRc = SQLITE_NOMEM;
1399 return 1;
1403 aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew);
1404 if( 0==aNew ){
1405 *pRc = SQLITE_NOMEM;
1406 }else{
1407 p->aBuf = aNew;
1408 p->nAlloc = nNew;
1411 return (*pRc!=SQLITE_OK);
1416 ** This function is a no-op if *pRc is other than SQLITE_OK when it is
1417 ** called. Otherwise, append a string to the buffer. All bytes in the string
1418 ** up to (but not including) the nul-terminator are written to the buffer.
1420 ** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
1421 ** returning.
1423 static void sessionAppendStr(
1424 SessionBuffer *p,
1425 const char *zStr,
1426 int *pRc
1428 int nStr = sqlite3Strlen30(zStr);
1429 if( 0==sessionBufferGrow(p, nStr+1, pRc) ){
1430 memcpy(&p->aBuf[p->nBuf], zStr, nStr);
1431 p->nBuf += nStr;
1432 p->aBuf[p->nBuf] = 0x00;
1437 ** Format a string using printf() style formatting and then append it to the
1438 ** buffer using sessionAppendString().
1440 static void sessionAppendPrintf(
1441 SessionBuffer *p, /* Buffer to append to */
1442 int *pRc,
1443 const char *zFmt,
1446 if( *pRc==SQLITE_OK ){
1447 char *zApp = 0;
1448 va_list ap;
1449 va_start(ap, zFmt);
1450 zApp = sqlite3_vmprintf(zFmt, ap);
1451 if( zApp==0 ){
1452 *pRc = SQLITE_NOMEM;
1453 }else{
1454 sessionAppendStr(p, zApp, pRc);
1456 va_end(ap);
1457 sqlite3_free(zApp);
1462 ** Prepare a statement against database handle db that SELECTs a single
1463 ** row containing the default values for each column in table pTab. For
1464 ** example, if pTab is declared as:
1466 ** CREATE TABLE pTab(a PRIMARY KEY, b DEFAULT 123, c DEFAULT 'abcd');
1468 ** Then this function prepares and returns the SQL statement:
1470 ** SELECT NULL, 123, 'abcd';
1472 static int sessionPrepareDfltStmt(
1473 sqlite3 *db, /* Database handle */
1474 SessionTable *pTab, /* Table to prepare statement for */
1475 sqlite3_stmt **ppStmt /* OUT: Statement handle */
1477 SessionBuffer sql = {0,0,0};
1478 int rc = SQLITE_OK;
1479 const char *zSep = " ";
1480 int ii = 0;
1482 *ppStmt = 0;
1483 sessionAppendPrintf(&sql, &rc, "SELECT");
1484 for(ii=0; ii<pTab->nCol; ii++){
1485 const char *zDflt = pTab->azDflt[ii] ? pTab->azDflt[ii] : "NULL";
1486 sessionAppendPrintf(&sql, &rc, "%s%s", zSep, zDflt);
1487 zSep = ", ";
1489 if( rc==SQLITE_OK ){
1490 rc = sqlite3_prepare_v2(db, (const char*)sql.aBuf, -1, ppStmt, 0);
1492 sqlite3_free(sql.aBuf);
1494 return rc;
1498 ** Table pTab has one or more existing change-records with old.* records
1499 ** with fewer than pTab->nCol columns. This function updates all such
1500 ** change-records with the default values for the missing columns.
1502 static int sessionUpdateChanges(sqlite3_session *pSession, SessionTable *pTab){
1503 sqlite3_stmt *pStmt = 0;
1504 int rc = pSession->rc;
1506 rc = sessionPrepareDfltStmt(pSession->db, pTab, &pStmt);
1507 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
1508 int ii = 0;
1509 SessionChange **pp = 0;
1510 for(ii=0; ii<pTab->nChange; ii++){
1511 for(pp=&pTab->apChange[ii]; *pp; pp=&((*pp)->pNext)){
1512 if( (*pp)->nRecordField!=pTab->nCol ){
1513 sessionUpdateOneChange(pSession, &rc, pp, pTab->nCol, pStmt);
1519 pSession->rc = rc;
1520 rc = sqlite3_finalize(pStmt);
1521 if( pSession->rc==SQLITE_OK ) pSession->rc = rc;
1522 return pSession->rc;
1526 ** Versions of the four methods in object SessionHook for use with the
1527 ** sqlite_stat1 table. The purpose of this is to substitute a zero-length
1528 ** blob each time a NULL value is read from the "idx" column of the
1529 ** sqlite_stat1 table.
1531 typedef struct SessionStat1Ctx SessionStat1Ctx;
1532 struct SessionStat1Ctx {
1533 SessionHook hook;
1534 sqlite3_session *pSession;
1536 static int sessionStat1Old(void *pCtx, int iCol, sqlite3_value **ppVal){
1537 SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
1538 sqlite3_value *pVal = 0;
1539 int rc = p->hook.xOld(p->hook.pCtx, iCol, &pVal);
1540 if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){
1541 pVal = p->pSession->pZeroBlob;
1543 *ppVal = pVal;
1544 return rc;
1546 static int sessionStat1New(void *pCtx, int iCol, sqlite3_value **ppVal){
1547 SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
1548 sqlite3_value *pVal = 0;
1549 int rc = p->hook.xNew(p->hook.pCtx, iCol, &pVal);
1550 if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){
1551 pVal = p->pSession->pZeroBlob;
1553 *ppVal = pVal;
1554 return rc;
1556 static int sessionStat1Count(void *pCtx){
1557 SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
1558 return p->hook.xCount(p->hook.pCtx);
1560 static int sessionStat1Depth(void *pCtx){
1561 SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
1562 return p->hook.xDepth(p->hook.pCtx);
1565 static int sessionUpdateMaxSize(
1566 int op,
1567 sqlite3_session *pSession, /* Session object pTab is attached to */
1568 SessionTable *pTab, /* Table that change applies to */
1569 SessionChange *pC /* Update pC->nMaxSize */
1571 i64 nNew = 2;
1572 if( pC->op==SQLITE_INSERT ){
1573 if( pTab->bRowid ) nNew += 9;
1574 if( op!=SQLITE_DELETE ){
1575 int ii;
1576 for(ii=0; ii<pTab->nCol; ii++){
1577 sqlite3_value *p = 0;
1578 pSession->hook.xNew(pSession->hook.pCtx, ii, &p);
1579 sessionSerializeValue(0, p, &nNew);
1582 }else if( op==SQLITE_DELETE ){
1583 nNew += pC->nRecord;
1584 if( sqlite3_preupdate_blobwrite(pSession->db)>=0 ){
1585 nNew += pC->nRecord;
1587 }else{
1588 int ii;
1589 u8 *pCsr = pC->aRecord;
1590 if( pTab->bRowid ){
1591 nNew += 9 + 1;
1592 pCsr += 9;
1594 for(ii=pTab->bRowid; ii<pTab->nCol; ii++){
1595 int bChanged = 1;
1596 int nOld = 0;
1597 int eType;
1598 sqlite3_value *p = 0;
1599 pSession->hook.xNew(pSession->hook.pCtx, ii-pTab->bRowid, &p);
1600 if( p==0 ){
1601 return SQLITE_NOMEM;
1604 eType = *pCsr++;
1605 switch( eType ){
1606 case SQLITE_NULL:
1607 bChanged = sqlite3_value_type(p)!=SQLITE_NULL;
1608 break;
1610 case SQLITE_FLOAT:
1611 case SQLITE_INTEGER: {
1612 if( eType==sqlite3_value_type(p) ){
1613 sqlite3_int64 iVal = sessionGetI64(pCsr);
1614 if( eType==SQLITE_INTEGER ){
1615 bChanged = (iVal!=sqlite3_value_int64(p));
1616 }else{
1617 double dVal;
1618 memcpy(&dVal, &iVal, 8);
1619 bChanged = (dVal!=sqlite3_value_double(p));
1622 nOld = 8;
1623 pCsr += 8;
1624 break;
1627 default: {
1628 int nByte;
1629 nOld = sessionVarintGet(pCsr, &nByte);
1630 pCsr += nOld;
1631 nOld += nByte;
1632 assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
1633 if( eType==sqlite3_value_type(p)
1634 && nByte==sqlite3_value_bytes(p)
1635 && (nByte==0 || 0==memcmp(pCsr, sqlite3_value_blob(p), nByte))
1637 bChanged = 0;
1639 pCsr += nByte;
1640 break;
1644 if( bChanged && pTab->abPK[ii] ){
1645 nNew = pC->nRecord + 2;
1646 break;
1649 if( bChanged ){
1650 nNew += 1 + nOld;
1651 sessionSerializeValue(0, p, &nNew);
1652 }else if( pTab->abPK[ii] ){
1653 nNew += 2 + nOld;
1654 }else{
1655 nNew += 2;
1660 if( nNew>pC->nMaxSize ){
1661 int nIncr = nNew - pC->nMaxSize;
1662 pC->nMaxSize = nNew;
1663 pSession->nMaxChangesetSize += nIncr;
1665 return SQLITE_OK;
1669 ** This function is only called from with a pre-update-hook reporting a
1670 ** change on table pTab (attached to session pSession). The type of change
1671 ** (UPDATE, INSERT, DELETE) is specified by the first argument.
1673 ** Unless one is already present or an error occurs, an entry is added
1674 ** to the changed-rows hash table associated with table pTab.
1676 static void sessionPreupdateOneChange(
1677 int op, /* One of SQLITE_UPDATE, INSERT, DELETE */
1678 i64 iRowid,
1679 sqlite3_session *pSession, /* Session object pTab is attached to */
1680 SessionTable *pTab /* Table that change applies to */
1682 int iHash;
1683 int bNull = 0;
1684 int rc = SQLITE_OK;
1685 int nExpect = 0;
1686 SessionStat1Ctx stat1 = {{0,0,0,0,0},0};
1688 if( pSession->rc ) return;
1690 /* Load table details if required */
1691 if( sessionInitTable(pSession, pTab, pSession->db, pSession->zDb) ) return;
1693 /* Check the number of columns in this xPreUpdate call matches the
1694 ** number of columns in the table. */
1695 nExpect = pSession->hook.xCount(pSession->hook.pCtx);
1696 if( (pTab->nCol-pTab->bRowid)<nExpect ){
1697 if( sessionReinitTable(pSession, pTab) ) return;
1698 if( sessionUpdateChanges(pSession, pTab) ) return;
1700 if( (pTab->nCol-pTab->bRowid)!=nExpect ){
1701 pSession->rc = SQLITE_SCHEMA;
1702 return;
1705 /* Grow the hash table if required */
1706 if( sessionGrowHash(pSession, 0, pTab) ){
1707 pSession->rc = SQLITE_NOMEM;
1708 return;
1711 if( pTab->bStat1 ){
1712 stat1.hook = pSession->hook;
1713 stat1.pSession = pSession;
1714 pSession->hook.pCtx = (void*)&stat1;
1715 pSession->hook.xNew = sessionStat1New;
1716 pSession->hook.xOld = sessionStat1Old;
1717 pSession->hook.xCount = sessionStat1Count;
1718 pSession->hook.xDepth = sessionStat1Depth;
1719 if( pSession->pZeroBlob==0 ){
1720 sqlite3_value *p = sqlite3ValueNew(0);
1721 if( p==0 ){
1722 rc = SQLITE_NOMEM;
1723 goto error_out;
1725 sqlite3ValueSetStr(p, 0, "", 0, SQLITE_STATIC);
1726 pSession->pZeroBlob = p;
1730 /* Calculate the hash-key for this change. If the primary key of the row
1731 ** includes a NULL value, exit early. Such changes are ignored by the
1732 ** session module. */
1733 rc = sessionPreupdateHash(
1734 pSession, iRowid, pTab, op==SQLITE_INSERT, &iHash, &bNull
1736 if( rc!=SQLITE_OK ) goto error_out;
1738 if( bNull==0 ){
1739 /* Search the hash table for an existing record for this row. */
1740 SessionChange *pC;
1741 for(pC=pTab->apChange[iHash]; pC; pC=pC->pNext){
1742 if( sessionPreupdateEqual(pSession, iRowid, pTab, pC, op) ) break;
1745 if( pC==0 ){
1746 /* Create a new change object containing all the old values (if
1747 ** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK
1748 ** values (if this is an INSERT). */
1749 sqlite3_int64 nByte; /* Number of bytes to allocate */
1750 int i; /* Used to iterate through columns */
1752 assert( rc==SQLITE_OK );
1753 pTab->nEntry++;
1755 /* Figure out how large an allocation is required */
1756 nByte = sizeof(SessionChange);
1757 for(i=0; i<(pTab->nCol-pTab->bRowid); i++){
1758 sqlite3_value *p = 0;
1759 if( op!=SQLITE_INSERT ){
1760 TESTONLY(int trc = ) pSession->hook.xOld(pSession->hook.pCtx, i, &p);
1761 assert( trc==SQLITE_OK );
1762 }else if( pTab->abPK[i] ){
1763 TESTONLY(int trc = ) pSession->hook.xNew(pSession->hook.pCtx, i, &p);
1764 assert( trc==SQLITE_OK );
1767 /* This may fail if SQLite value p contains a utf-16 string that must
1768 ** be converted to utf-8 and an OOM error occurs while doing so. */
1769 rc = sessionSerializeValue(0, p, &nByte);
1770 if( rc!=SQLITE_OK ) goto error_out;
1772 if( pTab->bRowid ){
1773 nByte += 9; /* Size of rowid field - an integer */
1776 /* Allocate the change object */
1777 pC = (SessionChange*)sessionMalloc64(pSession, nByte);
1778 if( !pC ){
1779 rc = SQLITE_NOMEM;
1780 goto error_out;
1781 }else{
1782 memset(pC, 0, sizeof(SessionChange));
1783 pC->aRecord = (u8 *)&pC[1];
1786 /* Populate the change object. None of the preupdate_old(),
1787 ** preupdate_new() or SerializeValue() calls below may fail as all
1788 ** required values and encodings have already been cached in memory.
1789 ** It is not possible for an OOM to occur in this block. */
1790 nByte = 0;
1791 if( pTab->bRowid ){
1792 pC->aRecord[0] = SQLITE_INTEGER;
1793 sessionPutI64(&pC->aRecord[1], iRowid);
1794 nByte = 9;
1796 for(i=0; i<(pTab->nCol-pTab->bRowid); i++){
1797 sqlite3_value *p = 0;
1798 if( op!=SQLITE_INSERT ){
1799 pSession->hook.xOld(pSession->hook.pCtx, i, &p);
1800 }else if( pTab->abPK[i] ){
1801 pSession->hook.xNew(pSession->hook.pCtx, i, &p);
1803 sessionSerializeValue(&pC->aRecord[nByte], p, &nByte);
1806 /* Add the change to the hash-table */
1807 if( pSession->bIndirect || pSession->hook.xDepth(pSession->hook.pCtx) ){
1808 pC->bIndirect = 1;
1810 pC->nRecordField = pTab->nCol;
1811 pC->nRecord = nByte;
1812 pC->op = op;
1813 pC->pNext = pTab->apChange[iHash];
1814 pTab->apChange[iHash] = pC;
1816 }else if( pC->bIndirect ){
1817 /* If the existing change is considered "indirect", but this current
1818 ** change is "direct", mark the change object as direct. */
1819 if( pSession->hook.xDepth(pSession->hook.pCtx)==0
1820 && pSession->bIndirect==0
1822 pC->bIndirect = 0;
1826 assert( rc==SQLITE_OK );
1827 if( pSession->bEnableSize ){
1828 rc = sessionUpdateMaxSize(op, pSession, pTab, pC);
1833 /* If an error has occurred, mark the session object as failed. */
1834 error_out:
1835 if( pTab->bStat1 ){
1836 pSession->hook = stat1.hook;
1838 if( rc!=SQLITE_OK ){
1839 pSession->rc = rc;
1843 static int sessionFindTable(
1844 sqlite3_session *pSession,
1845 const char *zName,
1846 SessionTable **ppTab
1848 int rc = SQLITE_OK;
1849 int nName = sqlite3Strlen30(zName);
1850 SessionTable *pRet;
1852 /* Search for an existing table */
1853 for(pRet=pSession->pTable; pRet; pRet=pRet->pNext){
1854 if( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) ) break;
1857 if( pRet==0 && pSession->bAutoAttach ){
1858 /* If there is a table-filter configured, invoke it. If it returns 0,
1859 ** do not automatically add the new table. */
1860 if( pSession->xTableFilter==0
1861 || pSession->xTableFilter(pSession->pFilterCtx, zName)
1863 rc = sqlite3session_attach(pSession, zName);
1864 if( rc==SQLITE_OK ){
1865 pRet = pSession->pTable;
1866 while( ALWAYS(pRet) && pRet->pNext ){
1867 pRet = pRet->pNext;
1869 assert( pRet!=0 );
1870 assert( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) );
1875 assert( rc==SQLITE_OK || pRet==0 );
1876 *ppTab = pRet;
1877 return rc;
1881 ** The 'pre-update' hook registered by this module with SQLite databases.
1883 static void xPreUpdate(
1884 void *pCtx, /* Copy of third arg to preupdate_hook() */
1885 sqlite3 *db, /* Database handle */
1886 int op, /* SQLITE_UPDATE, DELETE or INSERT */
1887 char const *zDb, /* Database name */
1888 char const *zName, /* Table name */
1889 sqlite3_int64 iKey1, /* Rowid of row about to be deleted/updated */
1890 sqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */
1892 sqlite3_session *pSession;
1893 int nDb = sqlite3Strlen30(zDb);
1895 assert( sqlite3_mutex_held(db->mutex) );
1896 (void)iKey1;
1897 (void)iKey2;
1899 for(pSession=(sqlite3_session *)pCtx; pSession; pSession=pSession->pNext){
1900 SessionTable *pTab;
1902 /* If this session is attached to a different database ("main", "temp"
1903 ** etc.), or if it is not currently enabled, there is nothing to do. Skip
1904 ** to the next session object attached to this database. */
1905 if( pSession->bEnable==0 ) continue;
1906 if( pSession->rc ) continue;
1907 if( sqlite3_strnicmp(zDb, pSession->zDb, nDb+1) ) continue;
1909 pSession->rc = sessionFindTable(pSession, zName, &pTab);
1910 if( pTab ){
1911 assert( pSession->rc==SQLITE_OK );
1912 assert( op==SQLITE_UPDATE || iKey1==iKey2 );
1913 sessionPreupdateOneChange(op, iKey1, pSession, pTab);
1914 if( op==SQLITE_UPDATE ){
1915 sessionPreupdateOneChange(SQLITE_INSERT, iKey2, pSession, pTab);
1922 ** The pre-update hook implementations.
1924 static int sessionPreupdateOld(void *pCtx, int iVal, sqlite3_value **ppVal){
1925 return sqlite3_preupdate_old((sqlite3*)pCtx, iVal, ppVal);
1927 static int sessionPreupdateNew(void *pCtx, int iVal, sqlite3_value **ppVal){
1928 return sqlite3_preupdate_new((sqlite3*)pCtx, iVal, ppVal);
1930 static int sessionPreupdateCount(void *pCtx){
1931 return sqlite3_preupdate_count((sqlite3*)pCtx);
1933 static int sessionPreupdateDepth(void *pCtx){
1934 return sqlite3_preupdate_depth((sqlite3*)pCtx);
1938 ** Install the pre-update hooks on the session object passed as the only
1939 ** argument.
1941 static void sessionPreupdateHooks(
1942 sqlite3_session *pSession
1944 pSession->hook.pCtx = (void*)pSession->db;
1945 pSession->hook.xOld = sessionPreupdateOld;
1946 pSession->hook.xNew = sessionPreupdateNew;
1947 pSession->hook.xCount = sessionPreupdateCount;
1948 pSession->hook.xDepth = sessionPreupdateDepth;
1951 typedef struct SessionDiffCtx SessionDiffCtx;
1952 struct SessionDiffCtx {
1953 sqlite3_stmt *pStmt;
1954 int bRowid;
1955 int nOldOff;
1959 ** The diff hook implementations.
1961 static int sessionDiffOld(void *pCtx, int iVal, sqlite3_value **ppVal){
1962 SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
1963 *ppVal = sqlite3_column_value(p->pStmt, iVal+p->nOldOff+p->bRowid);
1964 return SQLITE_OK;
1966 static int sessionDiffNew(void *pCtx, int iVal, sqlite3_value **ppVal){
1967 SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
1968 *ppVal = sqlite3_column_value(p->pStmt, iVal+p->bRowid);
1969 return SQLITE_OK;
1971 static int sessionDiffCount(void *pCtx){
1972 SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
1973 return (p->nOldOff ? p->nOldOff : sqlite3_column_count(p->pStmt)) - p->bRowid;
1975 static int sessionDiffDepth(void *pCtx){
1976 (void)pCtx;
1977 return 0;
1981 ** Install the diff hooks on the session object passed as the only
1982 ** argument.
1984 static void sessionDiffHooks(
1985 sqlite3_session *pSession,
1986 SessionDiffCtx *pDiffCtx
1988 pSession->hook.pCtx = (void*)pDiffCtx;
1989 pSession->hook.xOld = sessionDiffOld;
1990 pSession->hook.xNew = sessionDiffNew;
1991 pSession->hook.xCount = sessionDiffCount;
1992 pSession->hook.xDepth = sessionDiffDepth;
1995 static char *sessionExprComparePK(
1996 int nCol,
1997 const char *zDb1, const char *zDb2,
1998 const char *zTab,
1999 const char **azCol, u8 *abPK
2001 int i;
2002 const char *zSep = "";
2003 char *zRet = 0;
2005 for(i=0; i<nCol; i++){
2006 if( abPK[i] ){
2007 zRet = sqlite3_mprintf("%z%s\"%w\".\"%w\".\"%w\"=\"%w\".\"%w\".\"%w\"",
2008 zRet, zSep, zDb1, zTab, azCol[i], zDb2, zTab, azCol[i]
2010 zSep = " AND ";
2011 if( zRet==0 ) break;
2015 return zRet;
2018 static char *sessionExprCompareOther(
2019 int nCol,
2020 const char *zDb1, const char *zDb2,
2021 const char *zTab,
2022 const char **azCol, u8 *abPK
2024 int i;
2025 const char *zSep = "";
2026 char *zRet = 0;
2027 int bHave = 0;
2029 for(i=0; i<nCol; i++){
2030 if( abPK[i]==0 ){
2031 bHave = 1;
2032 zRet = sqlite3_mprintf(
2033 "%z%s\"%w\".\"%w\".\"%w\" IS NOT \"%w\".\"%w\".\"%w\"",
2034 zRet, zSep, zDb1, zTab, azCol[i], zDb2, zTab, azCol[i]
2036 zSep = " OR ";
2037 if( zRet==0 ) break;
2041 if( bHave==0 ){
2042 assert( zRet==0 );
2043 zRet = sqlite3_mprintf("0");
2046 return zRet;
2049 static char *sessionSelectFindNew(
2050 const char *zDb1, /* Pick rows in this db only */
2051 const char *zDb2, /* But not in this one */
2052 int bRowid,
2053 const char *zTbl, /* Table name */
2054 const char *zExpr
2056 const char *zSel = (bRowid ? SESSIONS_ROWID ", *" : "*");
2057 char *zRet = sqlite3_mprintf(
2058 "SELECT %s FROM \"%w\".\"%w\" WHERE NOT EXISTS ("
2059 " SELECT 1 FROM \"%w\".\"%w\" WHERE %s"
2060 ")",
2061 zSel, zDb1, zTbl, zDb2, zTbl, zExpr
2063 return zRet;
2066 static int sessionDiffFindNew(
2067 int op,
2068 sqlite3_session *pSession,
2069 SessionTable *pTab,
2070 const char *zDb1,
2071 const char *zDb2,
2072 char *zExpr
2074 int rc = SQLITE_OK;
2075 char *zStmt = sessionSelectFindNew(
2076 zDb1, zDb2, pTab->bRowid, pTab->zName, zExpr
2079 if( zStmt==0 ){
2080 rc = SQLITE_NOMEM;
2081 }else{
2082 sqlite3_stmt *pStmt;
2083 rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0);
2084 if( rc==SQLITE_OK ){
2085 SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx;
2086 pDiffCtx->pStmt = pStmt;
2087 pDiffCtx->nOldOff = 0;
2088 pDiffCtx->bRowid = pTab->bRowid;
2089 while( SQLITE_ROW==sqlite3_step(pStmt) ){
2090 i64 iRowid = (pTab->bRowid ? sqlite3_column_int64(pStmt, 0) : 0);
2091 sessionPreupdateOneChange(op, iRowid, pSession, pTab);
2093 rc = sqlite3_finalize(pStmt);
2095 sqlite3_free(zStmt);
2098 return rc;
2102 ** Return a comma-separated list of the fully-qualified (with both database
2103 ** and table name) column names from table pTab. e.g.
2105 ** "main"."t1"."a", "main"."t1"."b", "main"."t1"."c"
2107 static char *sessionAllCols(
2108 const char *zDb,
2109 SessionTable *pTab
2111 int ii;
2112 char *zRet = 0;
2113 for(ii=0; ii<pTab->nCol; ii++){
2114 zRet = sqlite3_mprintf("%z%s\"%w\".\"%w\".\"%w\"",
2115 zRet, (zRet ? ", " : ""), zDb, pTab->zName, pTab->azCol[ii]
2117 if( !zRet ) break;
2119 return zRet;
2122 static int sessionDiffFindModified(
2123 sqlite3_session *pSession,
2124 SessionTable *pTab,
2125 const char *zFrom,
2126 const char *zExpr
2128 int rc = SQLITE_OK;
2130 char *zExpr2 = sessionExprCompareOther(pTab->nCol,
2131 pSession->zDb, zFrom, pTab->zName, pTab->azCol, pTab->abPK
2133 if( zExpr2==0 ){
2134 rc = SQLITE_NOMEM;
2135 }else{
2136 char *z1 = sessionAllCols(pSession->zDb, pTab);
2137 char *z2 = sessionAllCols(zFrom, pTab);
2138 char *zStmt = sqlite3_mprintf(
2139 "SELECT %s,%s FROM \"%w\".\"%w\", \"%w\".\"%w\" WHERE %s AND (%z)",
2140 z1, z2, pSession->zDb, pTab->zName, zFrom, pTab->zName, zExpr, zExpr2
2142 if( zStmt==0 || z1==0 || z2==0 ){
2143 rc = SQLITE_NOMEM;
2144 }else{
2145 sqlite3_stmt *pStmt;
2146 rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0);
2148 if( rc==SQLITE_OK ){
2149 SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx;
2150 pDiffCtx->pStmt = pStmt;
2151 pDiffCtx->nOldOff = pTab->nCol;
2152 while( SQLITE_ROW==sqlite3_step(pStmt) ){
2153 i64 iRowid = (pTab->bRowid ? sqlite3_column_int64(pStmt, 0) : 0);
2154 sessionPreupdateOneChange(SQLITE_UPDATE, iRowid, pSession, pTab);
2156 rc = sqlite3_finalize(pStmt);
2159 sqlite3_free(zStmt);
2160 sqlite3_free(z1);
2161 sqlite3_free(z2);
2164 return rc;
2167 int sqlite3session_diff(
2168 sqlite3_session *pSession,
2169 const char *zFrom,
2170 const char *zTbl,
2171 char **pzErrMsg
2173 const char *zDb = pSession->zDb;
2174 int rc = pSession->rc;
2175 SessionDiffCtx d;
2177 memset(&d, 0, sizeof(d));
2178 sessionDiffHooks(pSession, &d);
2180 sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
2181 if( pzErrMsg ) *pzErrMsg = 0;
2182 if( rc==SQLITE_OK ){
2183 char *zExpr = 0;
2184 sqlite3 *db = pSession->db;
2185 SessionTable *pTo; /* Table zTbl */
2187 /* Locate and if necessary initialize the target table object */
2188 rc = sessionFindTable(pSession, zTbl, &pTo);
2189 if( pTo==0 ) goto diff_out;
2190 if( sessionInitTable(pSession, pTo, pSession->db, pSession->zDb) ){
2191 rc = pSession->rc;
2192 goto diff_out;
2195 /* Check the table schemas match */
2196 if( rc==SQLITE_OK ){
2197 int bHasPk = 0;
2198 int bMismatch = 0;
2199 int nCol; /* Columns in zFrom.zTbl */
2200 int bRowid = 0;
2201 u8 *abPK;
2202 const char **azCol = 0;
2203 rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, 0, &abPK,
2204 pSession->bImplicitPK ? &bRowid : 0
2206 if( rc==SQLITE_OK ){
2207 if( pTo->nCol!=nCol ){
2208 bMismatch = 1;
2209 }else{
2210 int i;
2211 for(i=0; i<nCol; i++){
2212 if( pTo->abPK[i]!=abPK[i] ) bMismatch = 1;
2213 if( sqlite3_stricmp(azCol[i], pTo->azCol[i]) ) bMismatch = 1;
2214 if( abPK[i] ) bHasPk = 1;
2218 sqlite3_free((char*)azCol);
2219 if( bMismatch ){
2220 if( pzErrMsg ){
2221 *pzErrMsg = sqlite3_mprintf("table schemas do not match");
2223 rc = SQLITE_SCHEMA;
2225 if( bHasPk==0 ){
2226 /* Ignore tables with no primary keys */
2227 goto diff_out;
2231 if( rc==SQLITE_OK ){
2232 zExpr = sessionExprComparePK(pTo->nCol,
2233 zDb, zFrom, pTo->zName, pTo->azCol, pTo->abPK
2237 /* Find new rows */
2238 if( rc==SQLITE_OK ){
2239 rc = sessionDiffFindNew(SQLITE_INSERT, pSession, pTo, zDb, zFrom, zExpr);
2242 /* Find old rows */
2243 if( rc==SQLITE_OK ){
2244 rc = sessionDiffFindNew(SQLITE_DELETE, pSession, pTo, zFrom, zDb, zExpr);
2247 /* Find modified rows */
2248 if( rc==SQLITE_OK ){
2249 rc = sessionDiffFindModified(pSession, pTo, zFrom, zExpr);
2252 sqlite3_free(zExpr);
2255 diff_out:
2256 sessionPreupdateHooks(pSession);
2257 sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
2258 return rc;
2262 ** Create a session object. This session object will record changes to
2263 ** database zDb attached to connection db.
2265 int sqlite3session_create(
2266 sqlite3 *db, /* Database handle */
2267 const char *zDb, /* Name of db (e.g. "main") */
2268 sqlite3_session **ppSession /* OUT: New session object */
2270 sqlite3_session *pNew; /* Newly allocated session object */
2271 sqlite3_session *pOld; /* Session object already attached to db */
2272 int nDb = sqlite3Strlen30(zDb); /* Length of zDb in bytes */
2274 /* Zero the output value in case an error occurs. */
2275 *ppSession = 0;
2277 /* Allocate and populate the new session object. */
2278 pNew = (sqlite3_session *)sqlite3_malloc64(sizeof(sqlite3_session) + nDb + 1);
2279 if( !pNew ) return SQLITE_NOMEM;
2280 memset(pNew, 0, sizeof(sqlite3_session));
2281 pNew->db = db;
2282 pNew->zDb = (char *)&pNew[1];
2283 pNew->bEnable = 1;
2284 memcpy(pNew->zDb, zDb, nDb+1);
2285 sessionPreupdateHooks(pNew);
2287 /* Add the new session object to the linked list of session objects
2288 ** attached to database handle $db. Do this under the cover of the db
2289 ** handle mutex. */
2290 sqlite3_mutex_enter(sqlite3_db_mutex(db));
2291 pOld = (sqlite3_session*)sqlite3_preupdate_hook(db, xPreUpdate, (void*)pNew);
2292 pNew->pNext = pOld;
2293 sqlite3_mutex_leave(sqlite3_db_mutex(db));
2295 *ppSession = pNew;
2296 return SQLITE_OK;
2300 ** Free the list of table objects passed as the first argument. The contents
2301 ** of the changed-rows hash tables are also deleted.
2303 static void sessionDeleteTable(sqlite3_session *pSession, SessionTable *pList){
2304 SessionTable *pNext;
2305 SessionTable *pTab;
2307 for(pTab=pList; pTab; pTab=pNext){
2308 int i;
2309 pNext = pTab->pNext;
2310 for(i=0; i<pTab->nChange; i++){
2311 SessionChange *p;
2312 SessionChange *pNextChange;
2313 for(p=pTab->apChange[i]; p; p=pNextChange){
2314 pNextChange = p->pNext;
2315 sessionFree(pSession, p);
2318 sqlite3_finalize(pTab->pDfltStmt);
2319 sessionFree(pSession, (char*)pTab->azCol); /* cast works around VC++ bug */
2320 sessionFree(pSession, pTab->apChange);
2321 sessionFree(pSession, pTab);
2326 ** Delete a session object previously allocated using sqlite3session_create().
2328 void sqlite3session_delete(sqlite3_session *pSession){
2329 sqlite3 *db = pSession->db;
2330 sqlite3_session *pHead;
2331 sqlite3_session **pp;
2333 /* Unlink the session from the linked list of sessions attached to the
2334 ** database handle. Hold the db mutex while doing so. */
2335 sqlite3_mutex_enter(sqlite3_db_mutex(db));
2336 pHead = (sqlite3_session*)sqlite3_preupdate_hook(db, 0, 0);
2337 for(pp=&pHead; ALWAYS((*pp)!=0); pp=&((*pp)->pNext)){
2338 if( (*pp)==pSession ){
2339 *pp = (*pp)->pNext;
2340 if( pHead ) sqlite3_preupdate_hook(db, xPreUpdate, (void*)pHead);
2341 break;
2344 sqlite3_mutex_leave(sqlite3_db_mutex(db));
2345 sqlite3ValueFree(pSession->pZeroBlob);
2347 /* Delete all attached table objects. And the contents of their
2348 ** associated hash-tables. */
2349 sessionDeleteTable(pSession, pSession->pTable);
2351 /* Free the session object. */
2352 sqlite3_free(pSession);
2356 ** Set a table filter on a Session Object.
2358 void sqlite3session_table_filter(
2359 sqlite3_session *pSession,
2360 int(*xFilter)(void*, const char*),
2361 void *pCtx /* First argument passed to xFilter */
2363 pSession->bAutoAttach = 1;
2364 pSession->pFilterCtx = pCtx;
2365 pSession->xTableFilter = xFilter;
2369 ** Attach a table to a session. All subsequent changes made to the table
2370 ** while the session object is enabled will be recorded.
2372 ** Only tables that have a PRIMARY KEY defined may be attached. It does
2373 ** not matter if the PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias)
2374 ** or not.
2376 int sqlite3session_attach(
2377 sqlite3_session *pSession, /* Session object */
2378 const char *zName /* Table name */
2380 int rc = SQLITE_OK;
2381 sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
2383 if( !zName ){
2384 pSession->bAutoAttach = 1;
2385 }else{
2386 SessionTable *pTab; /* New table object (if required) */
2387 int nName; /* Number of bytes in string zName */
2389 /* First search for an existing entry. If one is found, this call is
2390 ** a no-op. Return early. */
2391 nName = sqlite3Strlen30(zName);
2392 for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){
2393 if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ) break;
2396 if( !pTab ){
2397 /* Allocate new SessionTable object. */
2398 int nByte = sizeof(SessionTable) + nName + 1;
2399 pTab = (SessionTable*)sessionMalloc64(pSession, nByte);
2400 if( !pTab ){
2401 rc = SQLITE_NOMEM;
2402 }else{
2403 /* Populate the new SessionTable object and link it into the list.
2404 ** The new object must be linked onto the end of the list, not
2405 ** simply added to the start of it in order to ensure that tables
2406 ** appear in the correct order when a changeset or patchset is
2407 ** eventually generated. */
2408 SessionTable **ppTab;
2409 memset(pTab, 0, sizeof(SessionTable));
2410 pTab->zName = (char *)&pTab[1];
2411 memcpy(pTab->zName, zName, nName+1);
2412 for(ppTab=&pSession->pTable; *ppTab; ppTab=&(*ppTab)->pNext);
2413 *ppTab = pTab;
2418 sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
2419 return rc;
2423 ** Append the value passed as the second argument to the buffer passed
2424 ** as the first.
2426 ** This function is a no-op if *pRc is non-zero when it is called.
2427 ** Otherwise, if an error occurs, *pRc is set to an SQLite error code
2428 ** before returning.
2430 static void sessionAppendValue(SessionBuffer *p, sqlite3_value *pVal, int *pRc){
2431 int rc = *pRc;
2432 if( rc==SQLITE_OK ){
2433 sqlite3_int64 nByte = 0;
2434 rc = sessionSerializeValue(0, pVal, &nByte);
2435 sessionBufferGrow(p, nByte, &rc);
2436 if( rc==SQLITE_OK ){
2437 rc = sessionSerializeValue(&p->aBuf[p->nBuf], pVal, 0);
2438 p->nBuf += nByte;
2439 }else{
2440 *pRc = rc;
2446 ** This function is a no-op if *pRc is other than SQLITE_OK when it is
2447 ** called. Otherwise, append a single byte to the buffer.
2449 ** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
2450 ** returning.
2452 static void sessionAppendByte(SessionBuffer *p, u8 v, int *pRc){
2453 if( 0==sessionBufferGrow(p, 1, pRc) ){
2454 p->aBuf[p->nBuf++] = v;
2459 ** This function is a no-op if *pRc is other than SQLITE_OK when it is
2460 ** called. Otherwise, append a single varint to the buffer.
2462 ** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
2463 ** returning.
2465 static void sessionAppendVarint(SessionBuffer *p, int v, int *pRc){
2466 if( 0==sessionBufferGrow(p, 9, pRc) ){
2467 p->nBuf += sessionVarintPut(&p->aBuf[p->nBuf], v);
2472 ** This function is a no-op if *pRc is other than SQLITE_OK when it is
2473 ** called. Otherwise, append a blob of data to the buffer.
2475 ** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
2476 ** returning.
2478 static void sessionAppendBlob(
2479 SessionBuffer *p,
2480 const u8 *aBlob,
2481 int nBlob,
2482 int *pRc
2484 if( nBlob>0 && 0==sessionBufferGrow(p, nBlob, pRc) ){
2485 memcpy(&p->aBuf[p->nBuf], aBlob, nBlob);
2486 p->nBuf += nBlob;
2491 ** This function is a no-op if *pRc is other than SQLITE_OK when it is
2492 ** called. Otherwise, append the string representation of integer iVal
2493 ** to the buffer. No nul-terminator is written.
2495 ** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
2496 ** returning.
2498 static void sessionAppendInteger(
2499 SessionBuffer *p, /* Buffer to append to */
2500 int iVal, /* Value to write the string rep. of */
2501 int *pRc /* IN/OUT: Error code */
2503 char aBuf[24];
2504 sqlite3_snprintf(sizeof(aBuf)-1, aBuf, "%d", iVal);
2505 sessionAppendStr(p, aBuf, pRc);
2509 ** This function is a no-op if *pRc is other than SQLITE_OK when it is
2510 ** called. Otherwise, append the string zStr enclosed in quotes (") and
2511 ** with any embedded quote characters escaped to the buffer. No
2512 ** nul-terminator byte is written.
2514 ** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
2515 ** returning.
2517 static void sessionAppendIdent(
2518 SessionBuffer *p, /* Buffer to a append to */
2519 const char *zStr, /* String to quote, escape and append */
2520 int *pRc /* IN/OUT: Error code */
2522 int nStr = sqlite3Strlen30(zStr)*2 + 2 + 2;
2523 if( 0==sessionBufferGrow(p, nStr, pRc) ){
2524 char *zOut = (char *)&p->aBuf[p->nBuf];
2525 const char *zIn = zStr;
2526 *zOut++ = '"';
2527 while( *zIn ){
2528 if( *zIn=='"' ) *zOut++ = '"';
2529 *zOut++ = *(zIn++);
2531 *zOut++ = '"';
2532 p->nBuf = (int)((u8 *)zOut - p->aBuf);
2533 p->aBuf[p->nBuf] = 0x00;
2538 ** This function is a no-op if *pRc is other than SQLITE_OK when it is
2539 ** called. Otherwse, it appends the serialized version of the value stored
2540 ** in column iCol of the row that SQL statement pStmt currently points
2541 ** to to the buffer.
2543 static void sessionAppendCol(
2544 SessionBuffer *p, /* Buffer to append to */
2545 sqlite3_stmt *pStmt, /* Handle pointing to row containing value */
2546 int iCol, /* Column to read value from */
2547 int *pRc /* IN/OUT: Error code */
2549 if( *pRc==SQLITE_OK ){
2550 int eType = sqlite3_column_type(pStmt, iCol);
2551 sessionAppendByte(p, (u8)eType, pRc);
2552 if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
2553 sqlite3_int64 i;
2554 u8 aBuf[8];
2555 if( eType==SQLITE_INTEGER ){
2556 i = sqlite3_column_int64(pStmt, iCol);
2557 }else{
2558 double r = sqlite3_column_double(pStmt, iCol);
2559 memcpy(&i, &r, 8);
2561 sessionPutI64(aBuf, i);
2562 sessionAppendBlob(p, aBuf, 8, pRc);
2564 if( eType==SQLITE_BLOB || eType==SQLITE_TEXT ){
2565 u8 *z;
2566 int nByte;
2567 if( eType==SQLITE_BLOB ){
2568 z = (u8 *)sqlite3_column_blob(pStmt, iCol);
2569 }else{
2570 z = (u8 *)sqlite3_column_text(pStmt, iCol);
2572 nByte = sqlite3_column_bytes(pStmt, iCol);
2573 if( z || (eType==SQLITE_BLOB && nByte==0) ){
2574 sessionAppendVarint(p, nByte, pRc);
2575 sessionAppendBlob(p, z, nByte, pRc);
2576 }else{
2577 *pRc = SQLITE_NOMEM;
2585 ** This function appends an update change to the buffer (see the comments
2586 ** under "CHANGESET FORMAT" at the top of the file). An update change
2587 ** consists of:
2589 ** 1 byte: SQLITE_UPDATE (0x17)
2590 ** n bytes: old.* record (see RECORD FORMAT)
2591 ** m bytes: new.* record (see RECORD FORMAT)
2593 ** The SessionChange object passed as the third argument contains the
2594 ** values that were stored in the row when the session began (the old.*
2595 ** values). The statement handle passed as the second argument points
2596 ** at the current version of the row (the new.* values).
2598 ** If all of the old.* values are equal to their corresponding new.* value
2599 ** (i.e. nothing has changed), then no data at all is appended to the buffer.
2601 ** Otherwise, the old.* record contains all primary key values and the
2602 ** original values of any fields that have been modified. The new.* record
2603 ** contains the new values of only those fields that have been modified.
2605 static int sessionAppendUpdate(
2606 SessionBuffer *pBuf, /* Buffer to append to */
2607 int bPatchset, /* True for "patchset", 0 for "changeset" */
2608 sqlite3_stmt *pStmt, /* Statement handle pointing at new row */
2609 SessionChange *p, /* Object containing old values */
2610 u8 *abPK /* Boolean array - true for PK columns */
2612 int rc = SQLITE_OK;
2613 SessionBuffer buf2 = {0,0,0}; /* Buffer to accumulate new.* record in */
2614 int bNoop = 1; /* Set to zero if any values are modified */
2615 int nRewind = pBuf->nBuf; /* Set to zero if any values are modified */
2616 int i; /* Used to iterate through columns */
2617 u8 *pCsr = p->aRecord; /* Used to iterate through old.* values */
2619 assert( abPK!=0 );
2620 sessionAppendByte(pBuf, SQLITE_UPDATE, &rc);
2621 sessionAppendByte(pBuf, p->bIndirect, &rc);
2622 for(i=0; i<sqlite3_column_count(pStmt); i++){
2623 int bChanged = 0;
2624 int nAdvance;
2625 int eType = *pCsr;
2626 switch( eType ){
2627 case SQLITE_NULL:
2628 nAdvance = 1;
2629 if( sqlite3_column_type(pStmt, i)!=SQLITE_NULL ){
2630 bChanged = 1;
2632 break;
2634 case SQLITE_FLOAT:
2635 case SQLITE_INTEGER: {
2636 nAdvance = 9;
2637 if( eType==sqlite3_column_type(pStmt, i) ){
2638 sqlite3_int64 iVal = sessionGetI64(&pCsr[1]);
2639 if( eType==SQLITE_INTEGER ){
2640 if( iVal==sqlite3_column_int64(pStmt, i) ) break;
2641 }else{
2642 double dVal;
2643 memcpy(&dVal, &iVal, 8);
2644 if( dVal==sqlite3_column_double(pStmt, i) ) break;
2647 bChanged = 1;
2648 break;
2651 default: {
2652 int n;
2653 int nHdr = 1 + sessionVarintGet(&pCsr[1], &n);
2654 assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
2655 nAdvance = nHdr + n;
2656 if( eType==sqlite3_column_type(pStmt, i)
2657 && n==sqlite3_column_bytes(pStmt, i)
2658 && (n==0 || 0==memcmp(&pCsr[nHdr], sqlite3_column_blob(pStmt, i), n))
2660 break;
2662 bChanged = 1;
2666 /* If at least one field has been modified, this is not a no-op. */
2667 if( bChanged ) bNoop = 0;
2669 /* Add a field to the old.* record. This is omitted if this module is
2670 ** currently generating a patchset. */
2671 if( bPatchset==0 ){
2672 if( bChanged || abPK[i] ){
2673 sessionAppendBlob(pBuf, pCsr, nAdvance, &rc);
2674 }else{
2675 sessionAppendByte(pBuf, 0, &rc);
2679 /* Add a field to the new.* record. Or the only record if currently
2680 ** generating a patchset. */
2681 if( bChanged || (bPatchset && abPK[i]) ){
2682 sessionAppendCol(&buf2, pStmt, i, &rc);
2683 }else{
2684 sessionAppendByte(&buf2, 0, &rc);
2687 pCsr += nAdvance;
2690 if( bNoop ){
2691 pBuf->nBuf = nRewind;
2692 }else{
2693 sessionAppendBlob(pBuf, buf2.aBuf, buf2.nBuf, &rc);
2695 sqlite3_free(buf2.aBuf);
2697 return rc;
2701 ** Append a DELETE change to the buffer passed as the first argument. Use
2702 ** the changeset format if argument bPatchset is zero, or the patchset
2703 ** format otherwise.
2705 static int sessionAppendDelete(
2706 SessionBuffer *pBuf, /* Buffer to append to */
2707 int bPatchset, /* True for "patchset", 0 for "changeset" */
2708 SessionChange *p, /* Object containing old values */
2709 int nCol, /* Number of columns in table */
2710 u8 *abPK /* Boolean array - true for PK columns */
2712 int rc = SQLITE_OK;
2714 sessionAppendByte(pBuf, SQLITE_DELETE, &rc);
2715 sessionAppendByte(pBuf, p->bIndirect, &rc);
2717 if( bPatchset==0 ){
2718 sessionAppendBlob(pBuf, p->aRecord, p->nRecord, &rc);
2719 }else{
2720 int i;
2721 u8 *a = p->aRecord;
2722 for(i=0; i<nCol; i++){
2723 u8 *pStart = a;
2724 int eType = *a++;
2726 switch( eType ){
2727 case 0:
2728 case SQLITE_NULL:
2729 assert( abPK[i]==0 );
2730 break;
2732 case SQLITE_FLOAT:
2733 case SQLITE_INTEGER:
2734 a += 8;
2735 break;
2737 default: {
2738 int n;
2739 a += sessionVarintGet(a, &n);
2740 a += n;
2741 break;
2744 if( abPK[i] ){
2745 sessionAppendBlob(pBuf, pStart, (int)(a-pStart), &rc);
2748 assert( (a - p->aRecord)==p->nRecord );
2751 return rc;
2755 ** Formulate and prepare a SELECT statement to retrieve a row from table
2756 ** zTab in database zDb based on its primary key. i.e.
2758 ** SELECT *, <noop-test> FROM zDb.zTab WHERE (pk1, pk2,...) IS (?1, ?2,...)
2760 ** where <noop-test> is:
2762 ** 1 AND (?A OR ?1 IS <column>) AND ...
2764 ** for each non-pk <column>.
2766 static int sessionSelectStmt(
2767 sqlite3 *db, /* Database handle */
2768 int bIgnoreNoop,
2769 const char *zDb, /* Database name */
2770 const char *zTab, /* Table name */
2771 int bRowid,
2772 int nCol, /* Number of columns in table */
2773 const char **azCol, /* Names of table columns */
2774 u8 *abPK, /* PRIMARY KEY array */
2775 sqlite3_stmt **ppStmt /* OUT: Prepared SELECT statement */
2777 int rc = SQLITE_OK;
2778 char *zSql = 0;
2779 const char *zSep = "";
2780 const char *zCols = bRowid ? SESSIONS_ROWID ", *" : "*";
2781 int nSql = -1;
2782 int i;
2784 SessionBuffer nooptest = {0, 0, 0};
2785 SessionBuffer pkfield = {0, 0, 0};
2786 SessionBuffer pkvar = {0, 0, 0};
2788 sessionAppendStr(&nooptest, ", 1", &rc);
2790 if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){
2791 sessionAppendStr(&nooptest, " AND (?6 OR ?3 IS stat)", &rc);
2792 sessionAppendStr(&pkfield, "tbl, idx", &rc);
2793 sessionAppendStr(&pkvar,
2794 "?1, (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", &rc
2796 zCols = "tbl, ?2, stat";
2797 }else{
2798 for(i=0; i<nCol; i++){
2799 if( abPK[i] ){
2800 sessionAppendStr(&pkfield, zSep, &rc);
2801 sessionAppendStr(&pkvar, zSep, &rc);
2802 zSep = ", ";
2803 sessionAppendIdent(&pkfield, azCol[i], &rc);
2804 sessionAppendPrintf(&pkvar, &rc, "?%d", i+1);
2805 }else{
2806 sessionAppendPrintf(&nooptest, &rc,
2807 " AND (?%d OR ?%d IS %w.%w)", i+1+nCol, i+1, zTab, azCol[i]
2813 if( rc==SQLITE_OK ){
2814 zSql = sqlite3_mprintf(
2815 "SELECT %s%s FROM %Q.%Q WHERE (%s) IS (%s)",
2816 zCols, (bIgnoreNoop ? (char*)nooptest.aBuf : ""),
2817 zDb, zTab, (char*)pkfield.aBuf, (char*)pkvar.aBuf
2819 if( zSql==0 ) rc = SQLITE_NOMEM;
2822 #if 0
2823 if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){
2824 zSql = sqlite3_mprintf(
2825 "SELECT tbl, ?2, stat FROM %Q.sqlite_stat1 WHERE tbl IS ?1 AND "
2826 "idx IS (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", zDb
2828 if( zSql==0 ) rc = SQLITE_NOMEM;
2829 }else{
2830 const char *zSep = "";
2831 SessionBuffer buf = {0, 0, 0};
2833 sessionAppendStr(&buf, "SELECT * FROM ", &rc);
2834 sessionAppendIdent(&buf, zDb, &rc);
2835 sessionAppendStr(&buf, ".", &rc);
2836 sessionAppendIdent(&buf, zTab, &rc);
2837 sessionAppendStr(&buf, " WHERE ", &rc);
2838 for(i=0; i<nCol; i++){
2839 if( abPK[i] ){
2840 sessionAppendStr(&buf, zSep, &rc);
2841 sessionAppendIdent(&buf, azCol[i], &rc);
2842 sessionAppendStr(&buf, " IS ?", &rc);
2843 sessionAppendInteger(&buf, i+1, &rc);
2844 zSep = " AND ";
2847 zSql = (char*)buf.aBuf;
2848 nSql = buf.nBuf;
2850 #endif
2852 if( rc==SQLITE_OK ){
2853 rc = sqlite3_prepare_v2(db, zSql, nSql, ppStmt, 0);
2855 sqlite3_free(zSql);
2856 sqlite3_free(nooptest.aBuf);
2857 sqlite3_free(pkfield.aBuf);
2858 sqlite3_free(pkvar.aBuf);
2859 return rc;
2863 ** Bind the PRIMARY KEY values from the change passed in argument pChange
2864 ** to the SELECT statement passed as the first argument. The SELECT statement
2865 ** is as prepared by function sessionSelectStmt().
2867 ** Return SQLITE_OK if all PK values are successfully bound, or an SQLite
2868 ** error code (e.g. SQLITE_NOMEM) otherwise.
2870 static int sessionSelectBind(
2871 sqlite3_stmt *pSelect, /* SELECT from sessionSelectStmt() */
2872 int nCol, /* Number of columns in table */
2873 u8 *abPK, /* PRIMARY KEY array */
2874 SessionChange *pChange /* Change structure */
2876 int i;
2877 int rc = SQLITE_OK;
2878 u8 *a = pChange->aRecord;
2880 for(i=0; i<nCol && rc==SQLITE_OK; i++){
2881 int eType = *a++;
2883 switch( eType ){
2884 case 0:
2885 case SQLITE_NULL:
2886 assert( abPK[i]==0 );
2887 break;
2889 case SQLITE_INTEGER: {
2890 if( abPK[i] ){
2891 i64 iVal = sessionGetI64(a);
2892 rc = sqlite3_bind_int64(pSelect, i+1, iVal);
2894 a += 8;
2895 break;
2898 case SQLITE_FLOAT: {
2899 if( abPK[i] ){
2900 double rVal;
2901 i64 iVal = sessionGetI64(a);
2902 memcpy(&rVal, &iVal, 8);
2903 rc = sqlite3_bind_double(pSelect, i+1, rVal);
2905 a += 8;
2906 break;
2909 case SQLITE_TEXT: {
2910 int n;
2911 a += sessionVarintGet(a, &n);
2912 if( abPK[i] ){
2913 rc = sqlite3_bind_text(pSelect, i+1, (char *)a, n, SQLITE_TRANSIENT);
2915 a += n;
2916 break;
2919 default: {
2920 int n;
2921 assert( eType==SQLITE_BLOB );
2922 a += sessionVarintGet(a, &n);
2923 if( abPK[i] ){
2924 rc = sqlite3_bind_blob(pSelect, i+1, a, n, SQLITE_TRANSIENT);
2926 a += n;
2927 break;
2932 return rc;
2936 ** This function is a no-op if *pRc is set to other than SQLITE_OK when it
2937 ** is called. Otherwise, append a serialized table header (part of the binary
2938 ** changeset format) to buffer *pBuf. If an error occurs, set *pRc to an
2939 ** SQLite error code before returning.
2941 static void sessionAppendTableHdr(
2942 SessionBuffer *pBuf, /* Append header to this buffer */
2943 int bPatchset, /* Use the patchset format if true */
2944 SessionTable *pTab, /* Table object to append header for */
2945 int *pRc /* IN/OUT: Error code */
2947 /* Write a table header */
2948 sessionAppendByte(pBuf, (bPatchset ? 'P' : 'T'), pRc);
2949 sessionAppendVarint(pBuf, pTab->nCol, pRc);
2950 sessionAppendBlob(pBuf, pTab->abPK, pTab->nCol, pRc);
2951 sessionAppendBlob(pBuf, (u8 *)pTab->zName, (int)strlen(pTab->zName)+1, pRc);
2955 ** Generate either a changeset (if argument bPatchset is zero) or a patchset
2956 ** (if it is non-zero) based on the current contents of the session object
2957 ** passed as the first argument.
2959 ** If no error occurs, SQLITE_OK is returned and the new changeset/patchset
2960 ** stored in output variables *pnChangeset and *ppChangeset. Or, if an error
2961 ** occurs, an SQLite error code is returned and both output variables set
2962 ** to 0.
2964 static int sessionGenerateChangeset(
2965 sqlite3_session *pSession, /* Session object */
2966 int bPatchset, /* True for patchset, false for changeset */
2967 int (*xOutput)(void *pOut, const void *pData, int nData),
2968 void *pOut, /* First argument for xOutput */
2969 int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */
2970 void **ppChangeset /* OUT: Buffer containing changeset */
2972 sqlite3 *db = pSession->db; /* Source database handle */
2973 SessionTable *pTab; /* Used to iterate through attached tables */
2974 SessionBuffer buf = {0,0,0}; /* Buffer in which to accumlate changeset */
2975 int rc; /* Return code */
2977 assert( xOutput==0 || (pnChangeset==0 && ppChangeset==0) );
2978 assert( xOutput!=0 || (pnChangeset!=0 && ppChangeset!=0) );
2980 /* Zero the output variables in case an error occurs. If this session
2981 ** object is already in the error state (sqlite3_session.rc != SQLITE_OK),
2982 ** this call will be a no-op. */
2983 if( xOutput==0 ){
2984 assert( pnChangeset!=0 && ppChangeset!=0 );
2985 *pnChangeset = 0;
2986 *ppChangeset = 0;
2989 if( pSession->rc ) return pSession->rc;
2990 rc = sqlite3_exec(pSession->db, "SAVEPOINT changeset", 0, 0, 0);
2991 if( rc!=SQLITE_OK ) return rc;
2993 sqlite3_mutex_enter(sqlite3_db_mutex(db));
2995 for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
2996 if( pTab->nEntry ){
2997 const char *zName = pTab->zName;
2998 int i; /* Used to iterate through hash buckets */
2999 sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */
3000 int nRewind = buf.nBuf; /* Initial size of write buffer */
3001 int nNoop; /* Size of buffer after writing tbl header */
3002 int nOldCol = pTab->nCol;
3004 /* Check the table schema is still Ok. */
3005 rc = sessionReinitTable(pSession, pTab);
3006 if( rc==SQLITE_OK && pTab->nCol!=nOldCol ){
3007 rc = sessionUpdateChanges(pSession, pTab);
3010 /* Write a table header */
3011 sessionAppendTableHdr(&buf, bPatchset, pTab, &rc);
3013 /* Build and compile a statement to execute: */
3014 if( rc==SQLITE_OK ){
3015 rc = sessionSelectStmt(db, 0, pSession->zDb,
3016 zName, pTab->bRowid, pTab->nCol, pTab->azCol, pTab->abPK, &pSel
3020 nNoop = buf.nBuf;
3021 for(i=0; i<pTab->nChange && rc==SQLITE_OK; i++){
3022 SessionChange *p; /* Used to iterate through changes */
3024 for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){
3025 rc = sessionSelectBind(pSel, pTab->nCol, pTab->abPK, p);
3026 if( rc!=SQLITE_OK ) continue;
3027 if( sqlite3_step(pSel)==SQLITE_ROW ){
3028 if( p->op==SQLITE_INSERT ){
3029 int iCol;
3030 sessionAppendByte(&buf, SQLITE_INSERT, &rc);
3031 sessionAppendByte(&buf, p->bIndirect, &rc);
3032 for(iCol=0; iCol<pTab->nCol; iCol++){
3033 sessionAppendCol(&buf, pSel, iCol, &rc);
3035 }else{
3036 assert( pTab->abPK!=0 );
3037 rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, pTab->abPK);
3039 }else if( p->op!=SQLITE_INSERT ){
3040 rc = sessionAppendDelete(&buf, bPatchset, p, pTab->nCol,pTab->abPK);
3042 if( rc==SQLITE_OK ){
3043 rc = sqlite3_reset(pSel);
3046 /* If the buffer is now larger than sessions_strm_chunk_size, pass
3047 ** its contents to the xOutput() callback. */
3048 if( xOutput
3049 && rc==SQLITE_OK
3050 && buf.nBuf>nNoop
3051 && buf.nBuf>sessions_strm_chunk_size
3053 rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
3054 nNoop = -1;
3055 buf.nBuf = 0;
3061 sqlite3_finalize(pSel);
3062 if( buf.nBuf==nNoop ){
3063 buf.nBuf = nRewind;
3068 if( rc==SQLITE_OK ){
3069 if( xOutput==0 ){
3070 *pnChangeset = buf.nBuf;
3071 *ppChangeset = buf.aBuf;
3072 buf.aBuf = 0;
3073 }else if( buf.nBuf>0 ){
3074 rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
3078 sqlite3_free(buf.aBuf);
3079 sqlite3_exec(db, "RELEASE changeset", 0, 0, 0);
3080 sqlite3_mutex_leave(sqlite3_db_mutex(db));
3081 return rc;
3085 ** Obtain a changeset object containing all changes recorded by the
3086 ** session object passed as the first argument.
3088 ** It is the responsibility of the caller to eventually free the buffer
3089 ** using sqlite3_free().
3091 int sqlite3session_changeset(
3092 sqlite3_session *pSession, /* Session object */
3093 int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */
3094 void **ppChangeset /* OUT: Buffer containing changeset */
3096 int rc;
3098 if( pnChangeset==0 || ppChangeset==0 ) return SQLITE_MISUSE;
3099 rc = sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset, ppChangeset);
3100 assert( rc || pnChangeset==0
3101 || pSession->bEnableSize==0 || *pnChangeset<=pSession->nMaxChangesetSize
3103 return rc;
3107 ** Streaming version of sqlite3session_changeset().
3109 int sqlite3session_changeset_strm(
3110 sqlite3_session *pSession,
3111 int (*xOutput)(void *pOut, const void *pData, int nData),
3112 void *pOut
3114 if( xOutput==0 ) return SQLITE_MISUSE;
3115 return sessionGenerateChangeset(pSession, 0, xOutput, pOut, 0, 0);
3119 ** Streaming version of sqlite3session_patchset().
3121 int sqlite3session_patchset_strm(
3122 sqlite3_session *pSession,
3123 int (*xOutput)(void *pOut, const void *pData, int nData),
3124 void *pOut
3126 if( xOutput==0 ) return SQLITE_MISUSE;
3127 return sessionGenerateChangeset(pSession, 1, xOutput, pOut, 0, 0);
3131 ** Obtain a patchset object containing all changes recorded by the
3132 ** session object passed as the first argument.
3134 ** It is the responsibility of the caller to eventually free the buffer
3135 ** using sqlite3_free().
3137 int sqlite3session_patchset(
3138 sqlite3_session *pSession, /* Session object */
3139 int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */
3140 void **ppPatchset /* OUT: Buffer containing changeset */
3142 if( pnPatchset==0 || ppPatchset==0 ) return SQLITE_MISUSE;
3143 return sessionGenerateChangeset(pSession, 1, 0, 0, pnPatchset, ppPatchset);
3147 ** Enable or disable the session object passed as the first argument.
3149 int sqlite3session_enable(sqlite3_session *pSession, int bEnable){
3150 int ret;
3151 sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
3152 if( bEnable>=0 ){
3153 pSession->bEnable = bEnable;
3155 ret = pSession->bEnable;
3156 sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
3157 return ret;
3161 ** Enable or disable the session object passed as the first argument.
3163 int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect){
3164 int ret;
3165 sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
3166 if( bIndirect>=0 ){
3167 pSession->bIndirect = bIndirect;
3169 ret = pSession->bIndirect;
3170 sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
3171 return ret;
3175 ** Return true if there have been no changes to monitored tables recorded
3176 ** by the session object passed as the only argument.
3178 int sqlite3session_isempty(sqlite3_session *pSession){
3179 int ret = 0;
3180 SessionTable *pTab;
3182 sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
3183 for(pTab=pSession->pTable; pTab && ret==0; pTab=pTab->pNext){
3184 ret = (pTab->nEntry>0);
3186 sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));
3188 return (ret==0);
3192 ** Return the amount of heap memory in use.
3194 sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession){
3195 return pSession->nMalloc;
3199 ** Configure the session object passed as the first argument.
3201 int sqlite3session_object_config(sqlite3_session *pSession, int op, void *pArg){
3202 int rc = SQLITE_OK;
3203 switch( op ){
3204 case SQLITE_SESSION_OBJCONFIG_SIZE: {
3205 int iArg = *(int*)pArg;
3206 if( iArg>=0 ){
3207 if( pSession->pTable ){
3208 rc = SQLITE_MISUSE;
3209 }else{
3210 pSession->bEnableSize = (iArg!=0);
3213 *(int*)pArg = pSession->bEnableSize;
3214 break;
3217 case SQLITE_SESSION_OBJCONFIG_ROWID: {
3218 int iArg = *(int*)pArg;
3219 if( iArg>=0 ){
3220 if( pSession->pTable ){
3221 rc = SQLITE_MISUSE;
3222 }else{
3223 pSession->bImplicitPK = (iArg!=0);
3226 *(int*)pArg = pSession->bImplicitPK;
3227 break;
3230 default:
3231 rc = SQLITE_MISUSE;
3234 return rc;
3238 ** Return the maximum size of sqlite3session_changeset() output.
3240 sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession){
3241 return pSession->nMaxChangesetSize;
3245 ** Do the work for either sqlite3changeset_start() or start_strm().
3247 static int sessionChangesetStart(
3248 sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
3249 int (*xInput)(void *pIn, void *pData, int *pnData),
3250 void *pIn,
3251 int nChangeset, /* Size of buffer pChangeset in bytes */
3252 void *pChangeset, /* Pointer to buffer containing changeset */
3253 int bInvert, /* True to invert changeset */
3254 int bSkipEmpty /* True to skip empty UPDATE changes */
3256 sqlite3_changeset_iter *pRet; /* Iterator to return */
3257 int nByte; /* Number of bytes to allocate for iterator */
3259 assert( xInput==0 || (pChangeset==0 && nChangeset==0) );
3261 /* Zero the output variable in case an error occurs. */
3262 *pp = 0;
3264 /* Allocate and initialize the iterator structure. */
3265 nByte = sizeof(sqlite3_changeset_iter);
3266 pRet = (sqlite3_changeset_iter *)sqlite3_malloc(nByte);
3267 if( !pRet ) return SQLITE_NOMEM;
3268 memset(pRet, 0, sizeof(sqlite3_changeset_iter));
3269 pRet->in.aData = (u8 *)pChangeset;
3270 pRet->in.nData = nChangeset;
3271 pRet->in.xInput = xInput;
3272 pRet->in.pIn = pIn;
3273 pRet->in.bEof = (xInput ? 0 : 1);
3274 pRet->bInvert = bInvert;
3275 pRet->bSkipEmpty = bSkipEmpty;
3277 /* Populate the output variable and return success. */
3278 *pp = pRet;
3279 return SQLITE_OK;
3283 ** Create an iterator used to iterate through the contents of a changeset.
3285 int sqlite3changeset_start(
3286 sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
3287 int nChangeset, /* Size of buffer pChangeset in bytes */
3288 void *pChangeset /* Pointer to buffer containing changeset */
3290 return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0, 0);
3292 int sqlite3changeset_start_v2(
3293 sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
3294 int nChangeset, /* Size of buffer pChangeset in bytes */
3295 void *pChangeset, /* Pointer to buffer containing changeset */
3296 int flags
3298 int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
3299 return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert, 0);
3303 ** Streaming version of sqlite3changeset_start().
3305 int sqlite3changeset_start_strm(
3306 sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
3307 int (*xInput)(void *pIn, void *pData, int *pnData),
3308 void *pIn
3310 return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0, 0);
3312 int sqlite3changeset_start_v2_strm(
3313 sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
3314 int (*xInput)(void *pIn, void *pData, int *pnData),
3315 void *pIn,
3316 int flags
3318 int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
3319 return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert, 0);
3323 ** If the SessionInput object passed as the only argument is a streaming
3324 ** object and the buffer is full, discard some data to free up space.
3326 static void sessionDiscardData(SessionInput *pIn){
3327 if( pIn->xInput && pIn->iNext>=sessions_strm_chunk_size ){
3328 int nMove = pIn->buf.nBuf - pIn->iNext;
3329 assert( nMove>=0 );
3330 if( nMove>0 ){
3331 memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove);
3333 pIn->buf.nBuf -= pIn->iNext;
3334 pIn->iNext = 0;
3335 pIn->nData = pIn->buf.nBuf;
3340 ** Ensure that there are at least nByte bytes available in the buffer. Or,
3341 ** if there are not nByte bytes remaining in the input, that all available
3342 ** data is in the buffer.
3344 ** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
3346 static int sessionInputBuffer(SessionInput *pIn, int nByte){
3347 int rc = SQLITE_OK;
3348 if( pIn->xInput ){
3349 while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){
3350 int nNew = sessions_strm_chunk_size;
3352 if( pIn->bNoDiscard==0 ) sessionDiscardData(pIn);
3353 if( SQLITE_OK==sessionBufferGrow(&pIn->buf, nNew, &rc) ){
3354 rc = pIn->xInput(pIn->pIn, &pIn->buf.aBuf[pIn->buf.nBuf], &nNew);
3355 if( nNew==0 ){
3356 pIn->bEof = 1;
3357 }else{
3358 pIn->buf.nBuf += nNew;
3362 pIn->aData = pIn->buf.aBuf;
3363 pIn->nData = pIn->buf.nBuf;
3366 return rc;
3370 ** When this function is called, *ppRec points to the start of a record
3371 ** that contains nCol values. This function advances the pointer *ppRec
3372 ** until it points to the byte immediately following that record.
3374 static void sessionSkipRecord(
3375 u8 **ppRec, /* IN/OUT: Record pointer */
3376 int nCol /* Number of values in record */
3378 u8 *aRec = *ppRec;
3379 int i;
3380 for(i=0; i<nCol; i++){
3381 int eType = *aRec++;
3382 if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
3383 int nByte;
3384 aRec += sessionVarintGet((u8*)aRec, &nByte);
3385 aRec += nByte;
3386 }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
3387 aRec += 8;
3391 *ppRec = aRec;
3395 ** This function sets the value of the sqlite3_value object passed as the
3396 ** first argument to a copy of the string or blob held in the aData[]
3397 ** buffer. SQLITE_OK is returned if successful, or SQLITE_NOMEM if an OOM
3398 ** error occurs.
3400 static int sessionValueSetStr(
3401 sqlite3_value *pVal, /* Set the value of this object */
3402 u8 *aData, /* Buffer containing string or blob data */
3403 int nData, /* Size of buffer aData[] in bytes */
3404 u8 enc /* String encoding (0 for blobs) */
3406 /* In theory this code could just pass SQLITE_TRANSIENT as the final
3407 ** argument to sqlite3ValueSetStr() and have the copy created
3408 ** automatically. But doing so makes it difficult to detect any OOM
3409 ** error. Hence the code to create the copy externally. */
3410 u8 *aCopy = sqlite3_malloc64((sqlite3_int64)nData+1);
3411 if( aCopy==0 ) return SQLITE_NOMEM;
3412 memcpy(aCopy, aData, nData);
3413 sqlite3ValueSetStr(pVal, nData, (char*)aCopy, enc, sqlite3_free);
3414 return SQLITE_OK;
3418 ** Deserialize a single record from a buffer in memory. See "RECORD FORMAT"
3419 ** for details.
3421 ** When this function is called, *paChange points to the start of the record
3422 ** to deserialize. Assuming no error occurs, *paChange is set to point to
3423 ** one byte after the end of the same record before this function returns.
3424 ** If the argument abPK is NULL, then the record contains nCol values. Or,
3425 ** if abPK is other than NULL, then the record contains only the PK fields
3426 ** (in other words, it is a patchset DELETE record).
3428 ** If successful, each element of the apOut[] array (allocated by the caller)
3429 ** is set to point to an sqlite3_value object containing the value read
3430 ** from the corresponding position in the record. If that value is not
3431 ** included in the record (i.e. because the record is part of an UPDATE change
3432 ** and the field was not modified), the corresponding element of apOut[] is
3433 ** set to NULL.
3435 ** It is the responsibility of the caller to free all sqlite_value structures
3436 ** using sqlite3_free().
3438 ** If an error occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
3439 ** The apOut[] array may have been partially populated in this case.
3441 static int sessionReadRecord(
3442 SessionInput *pIn, /* Input data */
3443 int nCol, /* Number of values in record */
3444 u8 *abPK, /* Array of primary key flags, or NULL */
3445 sqlite3_value **apOut, /* Write values to this array */
3446 int *pbEmpty
3448 int i; /* Used to iterate through columns */
3449 int rc = SQLITE_OK;
3451 assert( pbEmpty==0 || *pbEmpty==0 );
3452 if( pbEmpty ) *pbEmpty = 1;
3453 for(i=0; i<nCol && rc==SQLITE_OK; i++){
3454 int eType = 0; /* Type of value (SQLITE_NULL, TEXT etc.) */
3455 if( abPK && abPK[i]==0 ) continue;
3456 rc = sessionInputBuffer(pIn, 9);
3457 if( rc==SQLITE_OK ){
3458 if( pIn->iNext>=pIn->nData ){
3459 rc = SQLITE_CORRUPT_BKPT;
3460 }else{
3461 eType = pIn->aData[pIn->iNext++];
3462 assert( apOut[i]==0 );
3463 if( eType ){
3464 if( pbEmpty ) *pbEmpty = 0;
3465 apOut[i] = sqlite3ValueNew(0);
3466 if( !apOut[i] ) rc = SQLITE_NOMEM;
3471 if( rc==SQLITE_OK ){
3472 u8 *aVal = &pIn->aData[pIn->iNext];
3473 if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
3474 int nByte;
3475 pIn->iNext += sessionVarintGet(aVal, &nByte);
3476 rc = sessionInputBuffer(pIn, nByte);
3477 if( rc==SQLITE_OK ){
3478 if( nByte<0 || nByte>pIn->nData-pIn->iNext ){
3479 rc = SQLITE_CORRUPT_BKPT;
3480 }else{
3481 u8 enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0);
3482 rc = sessionValueSetStr(apOut[i],&pIn->aData[pIn->iNext],nByte,enc);
3483 pIn->iNext += nByte;
3487 if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
3488 if( (pIn->nData-pIn->iNext)<8 ){
3489 rc = SQLITE_CORRUPT_BKPT;
3490 }else{
3491 sqlite3_int64 v = sessionGetI64(aVal);
3492 if( eType==SQLITE_INTEGER ){
3493 sqlite3VdbeMemSetInt64(apOut[i], v);
3494 }else{
3495 double d;
3496 memcpy(&d, &v, 8);
3497 sqlite3VdbeMemSetDouble(apOut[i], d);
3499 pIn->iNext += 8;
3505 return rc;
3509 ** The input pointer currently points to the second byte of a table-header.
3510 ** Specifically, to the following:
3512 ** + number of columns in table (varint)
3513 ** + array of PK flags (1 byte per column),
3514 ** + table name (nul terminated).
3516 ** This function ensures that all of the above is present in the input
3517 ** buffer (i.e. that it can be accessed without any calls to xInput()).
3518 ** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code.
3519 ** The input pointer is not moved.
3521 static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){
3522 int rc = SQLITE_OK;
3523 int nCol = 0;
3524 int nRead = 0;
3526 rc = sessionInputBuffer(pIn, 9);
3527 if( rc==SQLITE_OK ){
3528 nRead += sessionVarintGet(&pIn->aData[pIn->iNext + nRead], &nCol);
3529 /* The hard upper limit for the number of columns in an SQLite
3530 ** database table is, according to sqliteLimit.h, 32676. So
3531 ** consider any table-header that purports to have more than 65536
3532 ** columns to be corrupt. This is convenient because otherwise,
3533 ** if the (nCol>65536) condition below were omitted, a sufficiently
3534 ** large value for nCol may cause nRead to wrap around and become
3535 ** negative. Leading to a crash. */
3536 if( nCol<0 || nCol>65536 ){
3537 rc = SQLITE_CORRUPT_BKPT;
3538 }else{
3539 rc = sessionInputBuffer(pIn, nRead+nCol+100);
3540 nRead += nCol;
3544 while( rc==SQLITE_OK ){
3545 while( (pIn->iNext + nRead)<pIn->nData && pIn->aData[pIn->iNext + nRead] ){
3546 nRead++;
3548 if( (pIn->iNext + nRead)<pIn->nData ) break;
3549 rc = sessionInputBuffer(pIn, nRead + 100);
3551 *pnByte = nRead+1;
3552 return rc;
3556 ** The input pointer currently points to the first byte of the first field
3557 ** of a record consisting of nCol columns. This function ensures the entire
3558 ** record is buffered. It does not move the input pointer.
3560 ** If successful, SQLITE_OK is returned and *pnByte is set to the size of
3561 ** the record in bytes. Otherwise, an SQLite error code is returned. The
3562 ** final value of *pnByte is undefined in this case.
3564 static int sessionChangesetBufferRecord(
3565 SessionInput *pIn, /* Input data */
3566 int nCol, /* Number of columns in record */
3567 int *pnByte /* OUT: Size of record in bytes */
3569 int rc = SQLITE_OK;
3570 int nByte = 0;
3571 int i;
3572 for(i=0; rc==SQLITE_OK && i<nCol; i++){
3573 int eType;
3574 rc = sessionInputBuffer(pIn, nByte + 10);
3575 if( rc==SQLITE_OK ){
3576 eType = pIn->aData[pIn->iNext + nByte++];
3577 if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
3578 int n;
3579 nByte += sessionVarintGet(&pIn->aData[pIn->iNext+nByte], &n);
3580 nByte += n;
3581 rc = sessionInputBuffer(pIn, nByte);
3582 }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
3583 nByte += 8;
3587 *pnByte = nByte;
3588 return rc;
3592 ** The input pointer currently points to the second byte of a table-header.
3593 ** Specifically, to the following:
3595 ** + number of columns in table (varint)
3596 ** + array of PK flags (1 byte per column),
3597 ** + table name (nul terminated).
3599 ** This function decodes the table-header and populates the p->nCol,
3600 ** p->zTab and p->abPK[] variables accordingly. The p->apValue[] array is
3601 ** also allocated or resized according to the new value of p->nCol. The
3602 ** input pointer is left pointing to the byte following the table header.
3604 ** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code
3605 ** is returned and the final values of the various fields enumerated above
3606 ** are undefined.
3608 static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){
3609 int rc;
3610 int nCopy;
3611 assert( p->rc==SQLITE_OK );
3613 rc = sessionChangesetBufferTblhdr(&p->in, &nCopy);
3614 if( rc==SQLITE_OK ){
3615 int nByte;
3616 int nVarint;
3617 nVarint = sessionVarintGet(&p->in.aData[p->in.iNext], &p->nCol);
3618 if( p->nCol>0 ){
3619 nCopy -= nVarint;
3620 p->in.iNext += nVarint;
3621 nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy;
3622 p->tblhdr.nBuf = 0;
3623 sessionBufferGrow(&p->tblhdr, nByte, &rc);
3624 }else{
3625 rc = SQLITE_CORRUPT_BKPT;
3629 if( rc==SQLITE_OK ){
3630 size_t iPK = sizeof(sqlite3_value*)*p->nCol*2;
3631 memset(p->tblhdr.aBuf, 0, iPK);
3632 memcpy(&p->tblhdr.aBuf[iPK], &p->in.aData[p->in.iNext], nCopy);
3633 p->in.iNext += nCopy;
3636 p->apValue = (sqlite3_value**)p->tblhdr.aBuf;
3637 if( p->apValue==0 ){
3638 p->abPK = 0;
3639 p->zTab = 0;
3640 }else{
3641 p->abPK = (u8*)&p->apValue[p->nCol*2];
3642 p->zTab = p->abPK ? (char*)&p->abPK[p->nCol] : 0;
3644 return (p->rc = rc);
3648 ** Advance the changeset iterator to the next change. The differences between
3649 ** this function and sessionChangesetNext() are that
3651 ** * If pbEmpty is not NULL and the change is a no-op UPDATE (an UPDATE
3652 ** that modifies no columns), this function sets (*pbEmpty) to 1.
3654 ** * If the iterator is configured to skip no-op UPDATEs,
3655 ** sessionChangesetNext() does that. This function does not.
3657 static int sessionChangesetNextOne(
3658 sqlite3_changeset_iter *p, /* Changeset iterator */
3659 u8 **paRec, /* If non-NULL, store record pointer here */
3660 int *pnRec, /* If non-NULL, store size of record here */
3661 int *pbNew, /* If non-NULL, true if new table */
3662 int *pbEmpty
3664 int i;
3665 u8 op;
3667 assert( (paRec==0 && pnRec==0) || (paRec && pnRec) );
3668 assert( pbEmpty==0 || *pbEmpty==0 );
3670 /* If the iterator is in the error-state, return immediately. */
3671 if( p->rc!=SQLITE_OK ) return p->rc;
3673 /* Free the current contents of p->apValue[], if any. */
3674 if( p->apValue ){
3675 for(i=0; i<p->nCol*2; i++){
3676 sqlite3ValueFree(p->apValue[i]);
3678 memset(p->apValue, 0, sizeof(sqlite3_value*)*p->nCol*2);
3681 /* Make sure the buffer contains at least 10 bytes of input data, or all
3682 ** remaining data if there are less than 10 bytes available. This is
3683 ** sufficient either for the 'T' or 'P' byte and the varint that follows
3684 ** it, or for the two single byte values otherwise. */
3685 p->rc = sessionInputBuffer(&p->in, 2);
3686 if( p->rc!=SQLITE_OK ) return p->rc;
3688 /* If the iterator is already at the end of the changeset, return DONE. */
3689 if( p->in.iNext>=p->in.nData ){
3690 return SQLITE_DONE;
3693 sessionDiscardData(&p->in);
3694 p->in.iCurrent = p->in.iNext;
3696 op = p->in.aData[p->in.iNext++];
3697 while( op=='T' || op=='P' ){
3698 if( pbNew ) *pbNew = 1;
3699 p->bPatchset = (op=='P');
3700 if( sessionChangesetReadTblhdr(p) ) return p->rc;
3701 if( (p->rc = sessionInputBuffer(&p->in, 2)) ) return p->rc;
3702 p->in.iCurrent = p->in.iNext;
3703 if( p->in.iNext>=p->in.nData ) return SQLITE_DONE;
3704 op = p->in.aData[p->in.iNext++];
3707 if( p->zTab==0 || (p->bPatchset && p->bInvert) ){
3708 /* The first record in the changeset is not a table header. Must be a
3709 ** corrupt changeset. */
3710 assert( p->in.iNext==1 || p->zTab );
3711 return (p->rc = SQLITE_CORRUPT_BKPT);
3714 p->op = op;
3715 p->bIndirect = p->in.aData[p->in.iNext++];
3716 if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){
3717 return (p->rc = SQLITE_CORRUPT_BKPT);
3720 if( paRec ){
3721 int nVal; /* Number of values to buffer */
3722 if( p->bPatchset==0 && op==SQLITE_UPDATE ){
3723 nVal = p->nCol * 2;
3724 }else if( p->bPatchset && op==SQLITE_DELETE ){
3725 nVal = 0;
3726 for(i=0; i<p->nCol; i++) if( p->abPK[i] ) nVal++;
3727 }else{
3728 nVal = p->nCol;
3730 p->rc = sessionChangesetBufferRecord(&p->in, nVal, pnRec);
3731 if( p->rc!=SQLITE_OK ) return p->rc;
3732 *paRec = &p->in.aData[p->in.iNext];
3733 p->in.iNext += *pnRec;
3734 }else{
3735 sqlite3_value **apOld = (p->bInvert ? &p->apValue[p->nCol] : p->apValue);
3736 sqlite3_value **apNew = (p->bInvert ? p->apValue : &p->apValue[p->nCol]);
3738 /* If this is an UPDATE or DELETE, read the old.* record. */
3739 if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){
3740 u8 *abPK = p->bPatchset ? p->abPK : 0;
3741 p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld, 0);
3742 if( p->rc!=SQLITE_OK ) return p->rc;
3745 /* If this is an INSERT or UPDATE, read the new.* record. */
3746 if( p->op!=SQLITE_DELETE ){
3747 p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew, pbEmpty);
3748 if( p->rc!=SQLITE_OK ) return p->rc;
3751 if( (p->bPatchset || p->bInvert) && p->op==SQLITE_UPDATE ){
3752 /* If this is an UPDATE that is part of a patchset, then all PK and
3753 ** modified fields are present in the new.* record. The old.* record
3754 ** is currently completely empty. This block shifts the PK fields from
3755 ** new.* to old.*, to accommodate the code that reads these arrays. */
3756 for(i=0; i<p->nCol; i++){
3757 assert( p->bPatchset==0 || p->apValue[i]==0 );
3758 if( p->abPK[i] ){
3759 assert( p->apValue[i]==0 );
3760 p->apValue[i] = p->apValue[i+p->nCol];
3761 if( p->apValue[i]==0 ) return (p->rc = SQLITE_CORRUPT_BKPT);
3762 p->apValue[i+p->nCol] = 0;
3765 }else if( p->bInvert ){
3766 if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE;
3767 else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT;
3770 /* If this is an UPDATE that is part of a changeset, then check that
3771 ** there are no fields in the old.* record that are not (a) PK fields,
3772 ** or (b) also present in the new.* record.
3774 ** Such records are technically corrupt, but the rebaser was at one
3775 ** point generating them. Under most circumstances this is benign, but
3776 ** can cause spurious SQLITE_RANGE errors when applying the changeset. */
3777 if( p->bPatchset==0 && p->op==SQLITE_UPDATE){
3778 for(i=0; i<p->nCol; i++){
3779 if( p->abPK[i]==0 && p->apValue[i+p->nCol]==0 ){
3780 sqlite3ValueFree(p->apValue[i]);
3781 p->apValue[i] = 0;
3787 return SQLITE_ROW;
3791 ** Advance the changeset iterator to the next change.
3793 ** If both paRec and pnRec are NULL, then this function works like the public
3794 ** API sqlite3changeset_next(). If SQLITE_ROW is returned, then the
3795 ** sqlite3changeset_new() and old() APIs may be used to query for values.
3797 ** Otherwise, if paRec and pnRec are not NULL, then a pointer to the change
3798 ** record is written to *paRec before returning and the number of bytes in
3799 ** the record to *pnRec.
3801 ** Either way, this function returns SQLITE_ROW if the iterator is
3802 ** successfully advanced to the next change in the changeset, an SQLite
3803 ** error code if an error occurs, or SQLITE_DONE if there are no further
3804 ** changes in the changeset.
3806 static int sessionChangesetNext(
3807 sqlite3_changeset_iter *p, /* Changeset iterator */
3808 u8 **paRec, /* If non-NULL, store record pointer here */
3809 int *pnRec, /* If non-NULL, store size of record here */
3810 int *pbNew /* If non-NULL, true if new table */
3812 int bEmpty;
3813 int rc;
3814 do {
3815 bEmpty = 0;
3816 rc = sessionChangesetNextOne(p, paRec, pnRec, pbNew, &bEmpty);
3817 }while( rc==SQLITE_ROW && p->bSkipEmpty && bEmpty);
3818 return rc;
3822 ** Advance an iterator created by sqlite3changeset_start() to the next
3823 ** change in the changeset. This function may return SQLITE_ROW, SQLITE_DONE
3824 ** or SQLITE_CORRUPT.
3826 ** This function may not be called on iterators passed to a conflict handler
3827 ** callback by changeset_apply().
3829 int sqlite3changeset_next(sqlite3_changeset_iter *p){
3830 return sessionChangesetNext(p, 0, 0, 0);
3834 ** The following function extracts information on the current change
3835 ** from a changeset iterator. It may only be called after changeset_next()
3836 ** has returned SQLITE_ROW.
3838 int sqlite3changeset_op(
3839 sqlite3_changeset_iter *pIter, /* Iterator handle */
3840 const char **pzTab, /* OUT: Pointer to table name */
3841 int *pnCol, /* OUT: Number of columns in table */
3842 int *pOp, /* OUT: SQLITE_INSERT, DELETE or UPDATE */
3843 int *pbIndirect /* OUT: True if change is indirect */
3845 *pOp = pIter->op;
3846 *pnCol = pIter->nCol;
3847 *pzTab = pIter->zTab;
3848 if( pbIndirect ) *pbIndirect = pIter->bIndirect;
3849 return SQLITE_OK;
3853 ** Return information regarding the PRIMARY KEY and number of columns in
3854 ** the database table affected by the change that pIter currently points
3855 ** to. This function may only be called after changeset_next() returns
3856 ** SQLITE_ROW.
3858 int sqlite3changeset_pk(
3859 sqlite3_changeset_iter *pIter, /* Iterator object */
3860 unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */
3861 int *pnCol /* OUT: Number of entries in output array */
3863 *pabPK = pIter->abPK;
3864 if( pnCol ) *pnCol = pIter->nCol;
3865 return SQLITE_OK;
3869 ** This function may only be called while the iterator is pointing to an
3870 ** SQLITE_UPDATE or SQLITE_DELETE change (see sqlite3changeset_op()).
3871 ** Otherwise, SQLITE_MISUSE is returned.
3873 ** It sets *ppValue to point to an sqlite3_value structure containing the
3874 ** iVal'th value in the old.* record. Or, if that particular value is not
3875 ** included in the record (because the change is an UPDATE and the field
3876 ** was not modified and is not a PK column), set *ppValue to NULL.
3878 ** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is
3879 ** not modified. Otherwise, SQLITE_OK.
3881 int sqlite3changeset_old(
3882 sqlite3_changeset_iter *pIter, /* Changeset iterator */
3883 int iVal, /* Index of old.* value to retrieve */
3884 sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */
3886 if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_DELETE ){
3887 return SQLITE_MISUSE;
3889 if( iVal<0 || iVal>=pIter->nCol ){
3890 return SQLITE_RANGE;
3892 *ppValue = pIter->apValue[iVal];
3893 return SQLITE_OK;
3897 ** This function may only be called while the iterator is pointing to an
3898 ** SQLITE_UPDATE or SQLITE_INSERT change (see sqlite3changeset_op()).
3899 ** Otherwise, SQLITE_MISUSE is returned.
3901 ** It sets *ppValue to point to an sqlite3_value structure containing the
3902 ** iVal'th value in the new.* record. Or, if that particular value is not
3903 ** included in the record (because the change is an UPDATE and the field
3904 ** was not modified), set *ppValue to NULL.
3906 ** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is
3907 ** not modified. Otherwise, SQLITE_OK.
3909 int sqlite3changeset_new(
3910 sqlite3_changeset_iter *pIter, /* Changeset iterator */
3911 int iVal, /* Index of new.* value to retrieve */
3912 sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */
3914 if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_INSERT ){
3915 return SQLITE_MISUSE;
3917 if( iVal<0 || iVal>=pIter->nCol ){
3918 return SQLITE_RANGE;
3920 *ppValue = pIter->apValue[pIter->nCol+iVal];
3921 return SQLITE_OK;
3925 ** The following two macros are used internally. They are similar to the
3926 ** sqlite3changeset_new() and sqlite3changeset_old() functions, except that
3927 ** they omit all error checking and return a pointer to the requested value.
3929 #define sessionChangesetNew(pIter, iVal) (pIter)->apValue[(pIter)->nCol+(iVal)]
3930 #define sessionChangesetOld(pIter, iVal) (pIter)->apValue[(iVal)]
3933 ** This function may only be called with a changeset iterator that has been
3934 ** passed to an SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT
3935 ** conflict-handler function. Otherwise, SQLITE_MISUSE is returned.
3937 ** If successful, *ppValue is set to point to an sqlite3_value structure
3938 ** containing the iVal'th value of the conflicting record.
3940 ** If value iVal is out-of-range or some other error occurs, an SQLite error
3941 ** code is returned. Otherwise, SQLITE_OK.
3943 int sqlite3changeset_conflict(
3944 sqlite3_changeset_iter *pIter, /* Changeset iterator */
3945 int iVal, /* Index of conflict record value to fetch */
3946 sqlite3_value **ppValue /* OUT: Value from conflicting row */
3948 if( !pIter->pConflict ){
3949 return SQLITE_MISUSE;
3951 if( iVal<0 || iVal>=pIter->nCol ){
3952 return SQLITE_RANGE;
3954 *ppValue = sqlite3_column_value(pIter->pConflict, iVal);
3955 return SQLITE_OK;
3959 ** This function may only be called with an iterator passed to an
3960 ** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
3961 ** it sets the output variable to the total number of known foreign key
3962 ** violations in the destination database and returns SQLITE_OK.
3964 ** In all other cases this function returns SQLITE_MISUSE.
3966 int sqlite3changeset_fk_conflicts(
3967 sqlite3_changeset_iter *pIter, /* Changeset iterator */
3968 int *pnOut /* OUT: Number of FK violations */
3970 if( pIter->pConflict || pIter->apValue ){
3971 return SQLITE_MISUSE;
3973 *pnOut = pIter->nCol;
3974 return SQLITE_OK;
3979 ** Finalize an iterator allocated with sqlite3changeset_start().
3981 ** This function may not be called on iterators passed to a conflict handler
3982 ** callback by changeset_apply().
3984 int sqlite3changeset_finalize(sqlite3_changeset_iter *p){
3985 int rc = SQLITE_OK;
3986 if( p ){
3987 int i; /* Used to iterate through p->apValue[] */
3988 rc = p->rc;
3989 if( p->apValue ){
3990 for(i=0; i<p->nCol*2; i++) sqlite3ValueFree(p->apValue[i]);
3992 sqlite3_free(p->tblhdr.aBuf);
3993 sqlite3_free(p->in.buf.aBuf);
3994 sqlite3_free(p);
3996 return rc;
3999 static int sessionChangesetInvert(
4000 SessionInput *pInput, /* Input changeset */
4001 int (*xOutput)(void *pOut, const void *pData, int nData),
4002 void *pOut,
4003 int *pnInverted, /* OUT: Number of bytes in output changeset */
4004 void **ppInverted /* OUT: Inverse of pChangeset */
4006 int rc = SQLITE_OK; /* Return value */
4007 SessionBuffer sOut; /* Output buffer */
4008 int nCol = 0; /* Number of cols in current table */
4009 u8 *abPK = 0; /* PK array for current table */
4010 sqlite3_value **apVal = 0; /* Space for values for UPDATE inversion */
4011 SessionBuffer sPK = {0, 0, 0}; /* PK array for current table */
4013 /* Initialize the output buffer */
4014 memset(&sOut, 0, sizeof(SessionBuffer));
4016 /* Zero the output variables in case an error occurs. */
4017 if( ppInverted ){
4018 *ppInverted = 0;
4019 *pnInverted = 0;
4022 while( 1 ){
4023 u8 eType;
4025 /* Test for EOF. */
4026 if( (rc = sessionInputBuffer(pInput, 2)) ) goto finished_invert;
4027 if( pInput->iNext>=pInput->nData ) break;
4028 eType = pInput->aData[pInput->iNext];
4030 switch( eType ){
4031 case 'T': {
4032 /* A 'table' record consists of:
4034 ** * A constant 'T' character,
4035 ** * Number of columns in said table (a varint),
4036 ** * An array of nCol bytes (sPK),
4037 ** * A nul-terminated table name.
4039 int nByte;
4040 int nVar;
4041 pInput->iNext++;
4042 if( (rc = sessionChangesetBufferTblhdr(pInput, &nByte)) ){
4043 goto finished_invert;
4045 nVar = sessionVarintGet(&pInput->aData[pInput->iNext], &nCol);
4046 sPK.nBuf = 0;
4047 sessionAppendBlob(&sPK, &pInput->aData[pInput->iNext+nVar], nCol, &rc);
4048 sessionAppendByte(&sOut, eType, &rc);
4049 sessionAppendBlob(&sOut, &pInput->aData[pInput->iNext], nByte, &rc);
4050 if( rc ) goto finished_invert;
4052 pInput->iNext += nByte;
4053 sqlite3_free(apVal);
4054 apVal = 0;
4055 abPK = sPK.aBuf;
4056 break;
4059 case SQLITE_INSERT:
4060 case SQLITE_DELETE: {
4061 int nByte;
4062 int bIndirect = pInput->aData[pInput->iNext+1];
4063 int eType2 = (eType==SQLITE_DELETE ? SQLITE_INSERT : SQLITE_DELETE);
4064 pInput->iNext += 2;
4065 assert( rc==SQLITE_OK );
4066 rc = sessionChangesetBufferRecord(pInput, nCol, &nByte);
4067 sessionAppendByte(&sOut, eType2, &rc);
4068 sessionAppendByte(&sOut, bIndirect, &rc);
4069 sessionAppendBlob(&sOut, &pInput->aData[pInput->iNext], nByte, &rc);
4070 pInput->iNext += nByte;
4071 if( rc ) goto finished_invert;
4072 break;
4075 case SQLITE_UPDATE: {
4076 int iCol;
4078 if( 0==apVal ){
4079 apVal = (sqlite3_value **)sqlite3_malloc64(sizeof(apVal[0])*nCol*2);
4080 if( 0==apVal ){
4081 rc = SQLITE_NOMEM;
4082 goto finished_invert;
4084 memset(apVal, 0, sizeof(apVal[0])*nCol*2);
4087 /* Write the header for the new UPDATE change. Same as the original. */
4088 sessionAppendByte(&sOut, eType, &rc);
4089 sessionAppendByte(&sOut, pInput->aData[pInput->iNext+1], &rc);
4091 /* Read the old.* and new.* records for the update change. */
4092 pInput->iNext += 2;
4093 rc = sessionReadRecord(pInput, nCol, 0, &apVal[0], 0);
4094 if( rc==SQLITE_OK ){
4095 rc = sessionReadRecord(pInput, nCol, 0, &apVal[nCol], 0);
4098 /* Write the new old.* record. Consists of the PK columns from the
4099 ** original old.* record, and the other values from the original
4100 ** new.* record. */
4101 for(iCol=0; iCol<nCol; iCol++){
4102 sqlite3_value *pVal = apVal[iCol + (abPK[iCol] ? 0 : nCol)];
4103 sessionAppendValue(&sOut, pVal, &rc);
4106 /* Write the new new.* record. Consists of a copy of all values
4107 ** from the original old.* record, except for the PK columns, which
4108 ** are set to "undefined". */
4109 for(iCol=0; iCol<nCol; iCol++){
4110 sqlite3_value *pVal = (abPK[iCol] ? 0 : apVal[iCol]);
4111 sessionAppendValue(&sOut, pVal, &rc);
4114 for(iCol=0; iCol<nCol*2; iCol++){
4115 sqlite3ValueFree(apVal[iCol]);
4117 memset(apVal, 0, sizeof(apVal[0])*nCol*2);
4118 if( rc!=SQLITE_OK ){
4119 goto finished_invert;
4122 break;
4125 default:
4126 rc = SQLITE_CORRUPT_BKPT;
4127 goto finished_invert;
4130 assert( rc==SQLITE_OK );
4131 if( xOutput && sOut.nBuf>=sessions_strm_chunk_size ){
4132 rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
4133 sOut.nBuf = 0;
4134 if( rc!=SQLITE_OK ) goto finished_invert;
4138 assert( rc==SQLITE_OK );
4139 if( pnInverted && ALWAYS(ppInverted) ){
4140 *pnInverted = sOut.nBuf;
4141 *ppInverted = sOut.aBuf;
4142 sOut.aBuf = 0;
4143 }else if( sOut.nBuf>0 && ALWAYS(xOutput!=0) ){
4144 rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
4147 finished_invert:
4148 sqlite3_free(sOut.aBuf);
4149 sqlite3_free(apVal);
4150 sqlite3_free(sPK.aBuf);
4151 return rc;
4156 ** Invert a changeset object.
4158 int sqlite3changeset_invert(
4159 int nChangeset, /* Number of bytes in input */
4160 const void *pChangeset, /* Input changeset */
4161 int *pnInverted, /* OUT: Number of bytes in output changeset */
4162 void **ppInverted /* OUT: Inverse of pChangeset */
4164 SessionInput sInput;
4166 /* Set up the input stream */
4167 memset(&sInput, 0, sizeof(SessionInput));
4168 sInput.nData = nChangeset;
4169 sInput.aData = (u8*)pChangeset;
4171 return sessionChangesetInvert(&sInput, 0, 0, pnInverted, ppInverted);
4175 ** Streaming version of sqlite3changeset_invert().
4177 int sqlite3changeset_invert_strm(
4178 int (*xInput)(void *pIn, void *pData, int *pnData),
4179 void *pIn,
4180 int (*xOutput)(void *pOut, const void *pData, int nData),
4181 void *pOut
4183 SessionInput sInput;
4184 int rc;
4186 /* Set up the input stream */
4187 memset(&sInput, 0, sizeof(SessionInput));
4188 sInput.xInput = xInput;
4189 sInput.pIn = pIn;
4191 rc = sessionChangesetInvert(&sInput, xOutput, pOut, 0, 0);
4192 sqlite3_free(sInput.buf.aBuf);
4193 return rc;
4197 typedef struct SessionUpdate SessionUpdate;
4198 struct SessionUpdate {
4199 sqlite3_stmt *pStmt;
4200 u32 *aMask;
4201 SessionUpdate *pNext;
4204 typedef struct SessionApplyCtx SessionApplyCtx;
4205 struct SessionApplyCtx {
4206 sqlite3 *db;
4207 sqlite3_stmt *pDelete; /* DELETE statement */
4208 sqlite3_stmt *pInsert; /* INSERT statement */
4209 sqlite3_stmt *pSelect; /* SELECT statement */
4210 int nCol; /* Size of azCol[] and abPK[] arrays */
4211 const char **azCol; /* Array of column names */
4212 u8 *abPK; /* Boolean array - true if column is in PK */
4213 u32 *aUpdateMask; /* Used by sessionUpdateFind */
4214 SessionUpdate *pUp;
4215 int bStat1; /* True if table is sqlite_stat1 */
4216 int bDeferConstraints; /* True to defer constraints */
4217 int bInvertConstraints; /* Invert when iterating constraints buffer */
4218 SessionBuffer constraints; /* Deferred constraints are stored here */
4219 SessionBuffer rebase; /* Rebase information (if any) here */
4220 u8 bRebaseStarted; /* If table header is already in rebase */
4221 u8 bRebase; /* True to collect rebase information */
4222 u8 bIgnoreNoop; /* True to ignore no-op conflicts */
4223 int bRowid;
4226 /* Number of prepared UPDATE statements to cache. */
4227 #define SESSION_UPDATE_CACHE_SZ 12
4230 ** Find a prepared UPDATE statement suitable for the UPDATE step currently
4231 ** being visited by the iterator. The UPDATE is of the form:
4233 ** UPDATE tbl SET col = ?, col2 = ? WHERE pk1 IS ? AND pk2 IS ?
4235 static int sessionUpdateFind(
4236 sqlite3_changeset_iter *pIter,
4237 SessionApplyCtx *p,
4238 int bPatchset,
4239 sqlite3_stmt **ppStmt
4241 int rc = SQLITE_OK;
4242 SessionUpdate *pUp = 0;
4243 int nCol = pIter->nCol;
4244 int nU32 = (pIter->nCol+33)/32;
4245 int ii;
4247 if( p->aUpdateMask==0 ){
4248 p->aUpdateMask = sqlite3_malloc(nU32*sizeof(u32));
4249 if( p->aUpdateMask==0 ){
4250 rc = SQLITE_NOMEM;
4254 if( rc==SQLITE_OK ){
4255 memset(p->aUpdateMask, 0, nU32*sizeof(u32));
4256 rc = SQLITE_CORRUPT;
4257 for(ii=0; ii<pIter->nCol; ii++){
4258 if( sessionChangesetNew(pIter, ii) ){
4259 p->aUpdateMask[ii/32] |= (1<<(ii%32));
4260 rc = SQLITE_OK;
4265 if( rc==SQLITE_OK ){
4266 if( bPatchset ) p->aUpdateMask[nCol/32] |= (1<<(nCol%32));
4268 if( p->pUp ){
4269 int nUp = 0;
4270 SessionUpdate **pp = &p->pUp;
4271 while( 1 ){
4272 nUp++;
4273 if( 0==memcmp(p->aUpdateMask, (*pp)->aMask, nU32*sizeof(u32)) ){
4274 pUp = *pp;
4275 *pp = pUp->pNext;
4276 pUp->pNext = p->pUp;
4277 p->pUp = pUp;
4278 break;
4281 if( (*pp)->pNext ){
4282 pp = &(*pp)->pNext;
4283 }else{
4284 if( nUp>=SESSION_UPDATE_CACHE_SZ ){
4285 sqlite3_finalize((*pp)->pStmt);
4286 sqlite3_free(*pp);
4287 *pp = 0;
4289 break;
4294 if( pUp==0 ){
4295 int nByte = sizeof(SessionUpdate) * nU32*sizeof(u32);
4296 int bStat1 = (sqlite3_stricmp(pIter->zTab, "sqlite_stat1")==0);
4297 pUp = (SessionUpdate*)sqlite3_malloc(nByte);
4298 if( pUp==0 ){
4299 rc = SQLITE_NOMEM;
4300 }else{
4301 const char *zSep = "";
4302 SessionBuffer buf;
4304 memset(&buf, 0, sizeof(buf));
4305 pUp->aMask = (u32*)&pUp[1];
4306 memcpy(pUp->aMask, p->aUpdateMask, nU32*sizeof(u32));
4308 sessionAppendStr(&buf, "UPDATE main.", &rc);
4309 sessionAppendIdent(&buf, pIter->zTab, &rc);
4310 sessionAppendStr(&buf, " SET ", &rc);
4312 /* Create the assignments part of the UPDATE */
4313 for(ii=0; ii<pIter->nCol; ii++){
4314 if( p->abPK[ii]==0 && sessionChangesetNew(pIter, ii) ){
4315 sessionAppendStr(&buf, zSep, &rc);
4316 sessionAppendIdent(&buf, p->azCol[ii], &rc);
4317 sessionAppendStr(&buf, " = ?", &rc);
4318 sessionAppendInteger(&buf, ii*2+1, &rc);
4319 zSep = ", ";
4323 /* Create the WHERE clause part of the UPDATE */
4324 zSep = "";
4325 sessionAppendStr(&buf, " WHERE ", &rc);
4326 for(ii=0; ii<pIter->nCol; ii++){
4327 if( p->abPK[ii] || (bPatchset==0 && sessionChangesetOld(pIter, ii)) ){
4328 sessionAppendStr(&buf, zSep, &rc);
4329 if( bStat1 && ii==1 ){
4330 assert( sqlite3_stricmp(p->azCol[ii], "idx")==0 );
4331 sessionAppendStr(&buf,
4332 "idx IS CASE "
4333 "WHEN length(?4)=0 AND typeof(?4)='blob' THEN NULL "
4334 "ELSE ?4 END ", &rc
4336 }else{
4337 sessionAppendIdent(&buf, p->azCol[ii], &rc);
4338 sessionAppendStr(&buf, " IS ?", &rc);
4339 sessionAppendInteger(&buf, ii*2+2, &rc);
4341 zSep = " AND ";
4345 if( rc==SQLITE_OK ){
4346 char *zSql = (char*)buf.aBuf;
4347 rc = sqlite3_prepare_v2(p->db, zSql, buf.nBuf, &pUp->pStmt, 0);
4350 if( rc!=SQLITE_OK ){
4351 sqlite3_free(pUp);
4352 pUp = 0;
4353 }else{
4354 pUp->pNext = p->pUp;
4355 p->pUp = pUp;
4357 sqlite3_free(buf.aBuf);
4362 assert( (rc==SQLITE_OK)==(pUp!=0) );
4363 if( pUp ){
4364 *ppStmt = pUp->pStmt;
4365 }else{
4366 *ppStmt = 0;
4368 return rc;
4372 ** Free all cached UPDATE statements.
4374 static void sessionUpdateFree(SessionApplyCtx *p){
4375 SessionUpdate *pUp;
4376 SessionUpdate *pNext;
4377 for(pUp=p->pUp; pUp; pUp=pNext){
4378 pNext = pUp->pNext;
4379 sqlite3_finalize(pUp->pStmt);
4380 sqlite3_free(pUp);
4382 p->pUp = 0;
4383 sqlite3_free(p->aUpdateMask);
4384 p->aUpdateMask = 0;
4388 ** Formulate a statement to DELETE a row from database db. Assuming a table
4389 ** structure like this:
4391 ** CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
4393 ** The DELETE statement looks like this:
4395 ** DELETE FROM x WHERE a = :1 AND c = :3 AND (:5 OR b IS :2 AND d IS :4)
4397 ** Variable :5 (nCol+1) is a boolean. It should be set to 0 if we require
4398 ** matching b and d values, or 1 otherwise. The second case comes up if the
4399 ** conflict handler is invoked with NOTFOUND and returns CHANGESET_REPLACE.
4401 ** If successful, SQLITE_OK is returned and SessionApplyCtx.pDelete is left
4402 ** pointing to the prepared version of the SQL statement.
4404 static int sessionDeleteRow(
4405 sqlite3 *db, /* Database handle */
4406 const char *zTab, /* Table name */
4407 SessionApplyCtx *p /* Session changeset-apply context */
4409 int i;
4410 const char *zSep = "";
4411 int rc = SQLITE_OK;
4412 SessionBuffer buf = {0, 0, 0};
4413 int nPk = 0;
4415 sessionAppendStr(&buf, "DELETE FROM main.", &rc);
4416 sessionAppendIdent(&buf, zTab, &rc);
4417 sessionAppendStr(&buf, " WHERE ", &rc);
4419 for(i=0; i<p->nCol; i++){
4420 if( p->abPK[i] ){
4421 nPk++;
4422 sessionAppendStr(&buf, zSep, &rc);
4423 sessionAppendIdent(&buf, p->azCol[i], &rc);
4424 sessionAppendStr(&buf, " = ?", &rc);
4425 sessionAppendInteger(&buf, i+1, &rc);
4426 zSep = " AND ";
4430 if( nPk<p->nCol ){
4431 sessionAppendStr(&buf, " AND (?", &rc);
4432 sessionAppendInteger(&buf, p->nCol+1, &rc);
4433 sessionAppendStr(&buf, " OR ", &rc);
4435 zSep = "";
4436 for(i=0; i<p->nCol; i++){
4437 if( !p->abPK[i] ){
4438 sessionAppendStr(&buf, zSep, &rc);
4439 sessionAppendIdent(&buf, p->azCol[i], &rc);
4440 sessionAppendStr(&buf, " IS ?", &rc);
4441 sessionAppendInteger(&buf, i+1, &rc);
4442 zSep = "AND ";
4445 sessionAppendStr(&buf, ")", &rc);
4448 if( rc==SQLITE_OK ){
4449 rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pDelete, 0);
4451 sqlite3_free(buf.aBuf);
4453 return rc;
4457 ** Formulate and prepare an SQL statement to query table zTab by primary
4458 ** key. Assuming the following table structure:
4460 ** CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
4462 ** The SELECT statement looks like this:
4464 ** SELECT * FROM x WHERE a = ?1 AND c = ?3
4466 ** If successful, SQLITE_OK is returned and SessionApplyCtx.pSelect is left
4467 ** pointing to the prepared version of the SQL statement.
4469 static int sessionSelectRow(
4470 sqlite3 *db, /* Database handle */
4471 const char *zTab, /* Table name */
4472 SessionApplyCtx *p /* Session changeset-apply context */
4474 /* TODO */
4475 return sessionSelectStmt(db, p->bIgnoreNoop,
4476 "main", zTab, p->bRowid, p->nCol, p->azCol, p->abPK, &p->pSelect
4481 ** Formulate and prepare an INSERT statement to add a record to table zTab.
4482 ** For example:
4484 ** INSERT INTO main."zTab" VALUES(?1, ?2, ?3 ...);
4486 ** If successful, SQLITE_OK is returned and SessionApplyCtx.pInsert is left
4487 ** pointing to the prepared version of the SQL statement.
4489 static int sessionInsertRow(
4490 sqlite3 *db, /* Database handle */
4491 const char *zTab, /* Table name */
4492 SessionApplyCtx *p /* Session changeset-apply context */
4494 int rc = SQLITE_OK;
4495 int i;
4496 SessionBuffer buf = {0, 0, 0};
4498 sessionAppendStr(&buf, "INSERT INTO main.", &rc);
4499 sessionAppendIdent(&buf, zTab, &rc);
4500 sessionAppendStr(&buf, "(", &rc);
4501 for(i=0; i<p->nCol; i++){
4502 if( i!=0 ) sessionAppendStr(&buf, ", ", &rc);
4503 sessionAppendIdent(&buf, p->azCol[i], &rc);
4506 sessionAppendStr(&buf, ") VALUES(?", &rc);
4507 for(i=1; i<p->nCol; i++){
4508 sessionAppendStr(&buf, ", ?", &rc);
4510 sessionAppendStr(&buf, ")", &rc);
4512 if( rc==SQLITE_OK ){
4513 rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pInsert, 0);
4515 sqlite3_free(buf.aBuf);
4516 return rc;
4519 static int sessionPrepare(sqlite3 *db, sqlite3_stmt **pp, const char *zSql){
4520 return sqlite3_prepare_v2(db, zSql, -1, pp, 0);
4524 ** Prepare statements for applying changes to the sqlite_stat1 table.
4525 ** These are similar to those created by sessionSelectRow(),
4526 ** sessionInsertRow(), sessionUpdateRow() and sessionDeleteRow() for
4527 ** other tables.
4529 static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){
4530 int rc = sessionSelectRow(db, "sqlite_stat1", p);
4531 if( rc==SQLITE_OK ){
4532 rc = sessionPrepare(db, &p->pInsert,
4533 "INSERT INTO main.sqlite_stat1 VALUES(?1, "
4534 "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END, "
4535 "?3)"
4538 if( rc==SQLITE_OK ){
4539 rc = sessionPrepare(db, &p->pDelete,
4540 "DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS "
4541 "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END "
4542 "AND (?4 OR stat IS ?3)"
4545 return rc;
4549 ** A wrapper around sqlite3_bind_value() that detects an extra problem.
4550 ** See comments in the body of this function for details.
4552 static int sessionBindValue(
4553 sqlite3_stmt *pStmt, /* Statement to bind value to */
4554 int i, /* Parameter number to bind to */
4555 sqlite3_value *pVal /* Value to bind */
4557 int eType = sqlite3_value_type(pVal);
4558 /* COVERAGE: The (pVal->z==0) branch is never true using current versions
4559 ** of SQLite. If a malloc fails in an sqlite3_value_xxx() function, either
4560 ** the (pVal->z) variable remains as it was or the type of the value is
4561 ** set to SQLITE_NULL. */
4562 if( (eType==SQLITE_TEXT || eType==SQLITE_BLOB) && pVal->z==0 ){
4563 /* This condition occurs when an earlier OOM in a call to
4564 ** sqlite3_value_text() or sqlite3_value_blob() (perhaps from within
4565 ** a conflict-handler) has zeroed the pVal->z pointer. Return NOMEM. */
4566 return SQLITE_NOMEM;
4568 return sqlite3_bind_value(pStmt, i, pVal);
4572 ** Iterator pIter must point to an SQLITE_INSERT entry. This function
4573 ** transfers new.* values from the current iterator entry to statement
4574 ** pStmt. The table being inserted into has nCol columns.
4576 ** New.* value $i from the iterator is bound to variable ($i+1) of
4577 ** statement pStmt. If parameter abPK is NULL, all values from 0 to (nCol-1)
4578 ** are transfered to the statement. Otherwise, if abPK is not NULL, it points
4579 ** to an array nCol elements in size. In this case only those values for
4580 ** which abPK[$i] is true are read from the iterator and bound to the
4581 ** statement.
4583 ** An SQLite error code is returned if an error occurs. Otherwise, SQLITE_OK.
4585 static int sessionBindRow(
4586 sqlite3_changeset_iter *pIter, /* Iterator to read values from */
4587 int(*xValue)(sqlite3_changeset_iter *, int, sqlite3_value **),
4588 int nCol, /* Number of columns */
4589 u8 *abPK, /* If not NULL, bind only if true */
4590 sqlite3_stmt *pStmt /* Bind values to this statement */
4592 int i;
4593 int rc = SQLITE_OK;
4595 /* Neither sqlite3changeset_old or sqlite3changeset_new can fail if the
4596 ** argument iterator points to a suitable entry. Make sure that xValue
4597 ** is one of these to guarantee that it is safe to ignore the return
4598 ** in the code below. */
4599 assert( xValue==sqlite3changeset_old || xValue==sqlite3changeset_new );
4601 for(i=0; rc==SQLITE_OK && i<nCol; i++){
4602 if( !abPK || abPK[i] ){
4603 sqlite3_value *pVal = 0;
4604 (void)xValue(pIter, i, &pVal);
4605 if( pVal==0 ){
4606 /* The value in the changeset was "undefined". This indicates a
4607 ** corrupt changeset blob. */
4608 rc = SQLITE_CORRUPT_BKPT;
4609 }else{
4610 rc = sessionBindValue(pStmt, i+1, pVal);
4614 return rc;
4618 ** SQL statement pSelect is as generated by the sessionSelectRow() function.
4619 ** This function binds the primary key values from the change that changeset
4620 ** iterator pIter points to to the SELECT and attempts to seek to the table
4621 ** entry. If a row is found, the SELECT statement left pointing at the row
4622 ** and SQLITE_ROW is returned. Otherwise, if no row is found and no error
4623 ** has occured, the statement is reset and SQLITE_OK is returned. If an
4624 ** error occurs, the statement is reset and an SQLite error code is returned.
4626 ** If this function returns SQLITE_ROW, the caller must eventually reset()
4627 ** statement pSelect. If any other value is returned, the statement does
4628 ** not require a reset().
4630 ** If the iterator currently points to an INSERT record, bind values from the
4631 ** new.* record to the SELECT statement. Or, if it points to a DELETE or
4632 ** UPDATE, bind values from the old.* record.
4634 static int sessionSeekToRow(
4635 sqlite3_changeset_iter *pIter, /* Changeset iterator */
4636 SessionApplyCtx *p
4638 sqlite3_stmt *pSelect = p->pSelect;
4639 int rc; /* Return code */
4640 int nCol; /* Number of columns in table */
4641 int op; /* Changset operation (SQLITE_UPDATE etc.) */
4642 const char *zDummy; /* Unused */
4644 sqlite3_clear_bindings(pSelect);
4645 sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);
4646 rc = sessionBindRow(pIter,
4647 op==SQLITE_INSERT ? sqlite3changeset_new : sqlite3changeset_old,
4648 nCol, p->abPK, pSelect
4651 if( op!=SQLITE_DELETE && p->bIgnoreNoop ){
4652 int ii;
4653 for(ii=0; rc==SQLITE_OK && ii<nCol; ii++){
4654 if( p->abPK[ii]==0 ){
4655 sqlite3_value *pVal = 0;
4656 sqlite3changeset_new(pIter, ii, &pVal);
4657 sqlite3_bind_int(pSelect, ii+1+nCol, (pVal==0));
4658 if( pVal ) rc = sessionBindValue(pSelect, ii+1, pVal);
4663 if( rc==SQLITE_OK ){
4664 rc = sqlite3_step(pSelect);
4665 if( rc!=SQLITE_ROW ) rc = sqlite3_reset(pSelect);
4668 return rc;
4672 ** This function is called from within sqlite3changeset_apply_v2() when
4673 ** a conflict is encountered and resolved using conflict resolution
4674 ** mode eType (either SQLITE_CHANGESET_OMIT or SQLITE_CHANGESET_REPLACE)..
4675 ** It adds a conflict resolution record to the buffer in
4676 ** SessionApplyCtx.rebase, which will eventually be returned to the caller
4677 ** of apply_v2() as the "rebase" buffer.
4679 ** Return SQLITE_OK if successful, or an SQLite error code otherwise.
4681 static int sessionRebaseAdd(
4682 SessionApplyCtx *p, /* Apply context */
4683 int eType, /* Conflict resolution (OMIT or REPLACE) */
4684 sqlite3_changeset_iter *pIter /* Iterator pointing at current change */
4686 int rc = SQLITE_OK;
4687 if( p->bRebase ){
4688 int i;
4689 int eOp = pIter->op;
4690 if( p->bRebaseStarted==0 ){
4691 /* Append a table-header to the rebase buffer */
4692 const char *zTab = pIter->zTab;
4693 sessionAppendByte(&p->rebase, 'T', &rc);
4694 sessionAppendVarint(&p->rebase, p->nCol, &rc);
4695 sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc);
4696 sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc);
4697 p->bRebaseStarted = 1;
4700 assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT );
4701 assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE );
4703 sessionAppendByte(&p->rebase,
4704 (eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc
4706 sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc);
4707 for(i=0; i<p->nCol; i++){
4708 sqlite3_value *pVal = 0;
4709 if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){
4710 sqlite3changeset_old(pIter, i, &pVal);
4711 }else{
4712 sqlite3changeset_new(pIter, i, &pVal);
4714 sessionAppendValue(&p->rebase, pVal, &rc);
4717 return rc;
4721 ** Invoke the conflict handler for the change that the changeset iterator
4722 ** currently points to.
4724 ** Argument eType must be either CHANGESET_DATA or CHANGESET_CONFLICT.
4725 ** If argument pbReplace is NULL, then the type of conflict handler invoked
4726 ** depends solely on eType, as follows:
4728 ** eType value Value passed to xConflict
4729 ** -------------------------------------------------
4730 ** CHANGESET_DATA CHANGESET_NOTFOUND
4731 ** CHANGESET_CONFLICT CHANGESET_CONSTRAINT
4733 ** Or, if pbReplace is not NULL, then an attempt is made to find an existing
4734 ** record with the same primary key as the record about to be deleted, updated
4735 ** or inserted. If such a record can be found, it is available to the conflict
4736 ** handler as the "conflicting" record. In this case the type of conflict
4737 ** handler invoked is as follows:
4739 ** eType value PK Record found? Value passed to xConflict
4740 ** ----------------------------------------------------------------
4741 ** CHANGESET_DATA Yes CHANGESET_DATA
4742 ** CHANGESET_DATA No CHANGESET_NOTFOUND
4743 ** CHANGESET_CONFLICT Yes CHANGESET_CONFLICT
4744 ** CHANGESET_CONFLICT No CHANGESET_CONSTRAINT
4746 ** If pbReplace is not NULL, and a record with a matching PK is found, and
4747 ** the conflict handler function returns SQLITE_CHANGESET_REPLACE, *pbReplace
4748 ** is set to non-zero before returning SQLITE_OK.
4750 ** If the conflict handler returns SQLITE_CHANGESET_ABORT, SQLITE_ABORT is
4751 ** returned. Or, if the conflict handler returns an invalid value,
4752 ** SQLITE_MISUSE. If the conflict handler returns SQLITE_CHANGESET_OMIT,
4753 ** this function returns SQLITE_OK.
4755 static int sessionConflictHandler(
4756 int eType, /* Either CHANGESET_DATA or CONFLICT */
4757 SessionApplyCtx *p, /* changeset_apply() context */
4758 sqlite3_changeset_iter *pIter, /* Changeset iterator */
4759 int(*xConflict)(void *, int, sqlite3_changeset_iter*),
4760 void *pCtx, /* First argument for conflict handler */
4761 int *pbReplace /* OUT: Set to true if PK row is found */
4763 int res = 0; /* Value returned by conflict handler */
4764 int rc;
4765 int nCol;
4766 int op;
4767 const char *zDummy;
4769 sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);
4771 assert( eType==SQLITE_CHANGESET_CONFLICT || eType==SQLITE_CHANGESET_DATA );
4772 assert( SQLITE_CHANGESET_CONFLICT+1==SQLITE_CHANGESET_CONSTRAINT );
4773 assert( SQLITE_CHANGESET_DATA+1==SQLITE_CHANGESET_NOTFOUND );
4775 /* Bind the new.* PRIMARY KEY values to the SELECT statement. */
4776 if( pbReplace ){
4777 rc = sessionSeekToRow(pIter, p);
4778 }else{
4779 rc = SQLITE_OK;
4782 if( rc==SQLITE_ROW ){
4783 /* There exists another row with the new.* primary key. */
4784 if( p->bIgnoreNoop
4785 && sqlite3_column_int(p->pSelect, sqlite3_column_count(p->pSelect)-1)
4787 res = SQLITE_CHANGESET_OMIT;
4788 }else{
4789 pIter->pConflict = p->pSelect;
4790 res = xConflict(pCtx, eType, pIter);
4791 pIter->pConflict = 0;
4793 rc = sqlite3_reset(p->pSelect);
4794 }else if( rc==SQLITE_OK ){
4795 if( p->bDeferConstraints && eType==SQLITE_CHANGESET_CONFLICT ){
4796 /* Instead of invoking the conflict handler, append the change blob
4797 ** to the SessionApplyCtx.constraints buffer. */
4798 u8 *aBlob = &pIter->in.aData[pIter->in.iCurrent];
4799 int nBlob = pIter->in.iNext - pIter->in.iCurrent;
4800 sessionAppendBlob(&p->constraints, aBlob, nBlob, &rc);
4801 return SQLITE_OK;
4802 }else{
4803 /* No other row with the new.* primary key. */
4804 res = xConflict(pCtx, eType+1, pIter);
4805 if( res==SQLITE_CHANGESET_REPLACE ) rc = SQLITE_MISUSE;
4809 if( rc==SQLITE_OK ){
4810 switch( res ){
4811 case SQLITE_CHANGESET_REPLACE:
4812 assert( pbReplace );
4813 *pbReplace = 1;
4814 break;
4816 case SQLITE_CHANGESET_OMIT:
4817 break;
4819 case SQLITE_CHANGESET_ABORT:
4820 rc = SQLITE_ABORT;
4821 break;
4823 default:
4824 rc = SQLITE_MISUSE;
4825 break;
4827 if( rc==SQLITE_OK ){
4828 rc = sessionRebaseAdd(p, res, pIter);
4832 return rc;
4836 ** Attempt to apply the change that the iterator passed as the first argument
4837 ** currently points to to the database. If a conflict is encountered, invoke
4838 ** the conflict handler callback.
4840 ** If argument pbRetry is NULL, then ignore any CHANGESET_DATA conflict. If
4841 ** one is encountered, update or delete the row with the matching primary key
4842 ** instead. Or, if pbRetry is not NULL and a CHANGESET_DATA conflict occurs,
4843 ** invoke the conflict handler. If it returns CHANGESET_REPLACE, set *pbRetry
4844 ** to true before returning. In this case the caller will invoke this function
4845 ** again, this time with pbRetry set to NULL.
4847 ** If argument pbReplace is NULL and a CHANGESET_CONFLICT conflict is
4848 ** encountered invoke the conflict handler with CHANGESET_CONSTRAINT instead.
4849 ** Or, if pbReplace is not NULL, invoke it with CHANGESET_CONFLICT. If such
4850 ** an invocation returns SQLITE_CHANGESET_REPLACE, set *pbReplace to true
4851 ** before retrying. In this case the caller attempts to remove the conflicting
4852 ** row before invoking this function again, this time with pbReplace set
4853 ** to NULL.
4855 ** If any conflict handler returns SQLITE_CHANGESET_ABORT, this function
4856 ** returns SQLITE_ABORT. Otherwise, if no error occurs, SQLITE_OK is
4857 ** returned.
4859 static int sessionApplyOneOp(
4860 sqlite3_changeset_iter *pIter, /* Changeset iterator */
4861 SessionApplyCtx *p, /* changeset_apply() context */
4862 int(*xConflict)(void *, int, sqlite3_changeset_iter *),
4863 void *pCtx, /* First argument for the conflict handler */
4864 int *pbReplace, /* OUT: True to remove PK row and retry */
4865 int *pbRetry /* OUT: True to retry. */
4867 const char *zDummy;
4868 int op;
4869 int nCol;
4870 int rc = SQLITE_OK;
4872 assert( p->pDelete && p->pInsert && p->pSelect );
4873 assert( p->azCol && p->abPK );
4874 assert( !pbReplace || *pbReplace==0 );
4876 sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);
4878 if( op==SQLITE_DELETE ){
4880 /* Bind values to the DELETE statement. If conflict handling is required,
4881 ** bind values for all columns and set bound variable (nCol+1) to true.
4882 ** Or, if conflict handling is not required, bind just the PK column
4883 ** values and, if it exists, set (nCol+1) to false. Conflict handling
4884 ** is not required if:
4886 ** * this is a patchset, or
4887 ** * (pbRetry==0), or
4888 ** * all columns of the table are PK columns (in this case there is
4889 ** no (nCol+1) variable to bind to).
4891 u8 *abPK = (pIter->bPatchset ? p->abPK : 0);
4892 rc = sessionBindRow(pIter, sqlite3changeset_old, nCol, abPK, p->pDelete);
4893 if( rc==SQLITE_OK && sqlite3_bind_parameter_count(p->pDelete)>nCol ){
4894 rc = sqlite3_bind_int(p->pDelete, nCol+1, (pbRetry==0 || abPK));
4896 if( rc!=SQLITE_OK ) return rc;
4898 sqlite3_step(p->pDelete);
4899 rc = sqlite3_reset(p->pDelete);
4900 if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 && p->bIgnoreNoop==0 ){
4901 rc = sessionConflictHandler(
4902 SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry
4904 }else if( (rc&0xff)==SQLITE_CONSTRAINT ){
4905 rc = sessionConflictHandler(
4906 SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0
4910 }else if( op==SQLITE_UPDATE ){
4911 int i;
4912 sqlite3_stmt *pUp = 0;
4913 int bPatchset = (pbRetry==0 || pIter->bPatchset);
4915 rc = sessionUpdateFind(pIter, p, bPatchset, &pUp);
4917 /* Bind values to the UPDATE statement. */
4918 for(i=0; rc==SQLITE_OK && i<nCol; i++){
4919 sqlite3_value *pOld = sessionChangesetOld(pIter, i);
4920 sqlite3_value *pNew = sessionChangesetNew(pIter, i);
4921 if( p->abPK[i] || (bPatchset==0 && pOld) ){
4922 rc = sessionBindValue(pUp, i*2+2, pOld);
4924 if( rc==SQLITE_OK && pNew ){
4925 rc = sessionBindValue(pUp, i*2+1, pNew);
4928 if( rc!=SQLITE_OK ) return rc;
4930 /* Attempt the UPDATE. In the case of a NOTFOUND or DATA conflict,
4931 ** the result will be SQLITE_OK with 0 rows modified. */
4932 sqlite3_step(pUp);
4933 rc = sqlite3_reset(pUp);
4935 if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){
4936 /* A NOTFOUND or DATA error. Search the table to see if it contains
4937 ** a row with a matching primary key. If so, this is a DATA conflict.
4938 ** Otherwise, if there is no primary key match, it is a NOTFOUND. */
4940 rc = sessionConflictHandler(
4941 SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry
4944 }else if( (rc&0xff)==SQLITE_CONSTRAINT ){
4945 /* This is always a CONSTRAINT conflict. */
4946 rc = sessionConflictHandler(
4947 SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0
4951 }else{
4952 assert( op==SQLITE_INSERT );
4953 if( p->bStat1 ){
4954 /* Check if there is a conflicting row. For sqlite_stat1, this needs
4955 ** to be done using a SELECT, as there is no PRIMARY KEY in the
4956 ** database schema to throw an exception if a duplicate is inserted. */
4957 rc = sessionSeekToRow(pIter, p);
4958 if( rc==SQLITE_ROW ){
4959 rc = SQLITE_CONSTRAINT;
4960 sqlite3_reset(p->pSelect);
4964 if( rc==SQLITE_OK ){
4965 rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
4966 if( rc!=SQLITE_OK ) return rc;
4968 sqlite3_step(p->pInsert);
4969 rc = sqlite3_reset(p->pInsert);
4972 if( (rc&0xff)==SQLITE_CONSTRAINT ){
4973 rc = sessionConflictHandler(
4974 SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace
4979 return rc;
4983 ** Attempt to apply the change that the iterator passed as the first argument
4984 ** currently points to to the database. If a conflict is encountered, invoke
4985 ** the conflict handler callback.
4987 ** The difference between this function and sessionApplyOne() is that this
4988 ** function handles the case where the conflict-handler is invoked and
4989 ** returns SQLITE_CHANGESET_REPLACE - indicating that the change should be
4990 ** retried in some manner.
4992 static int sessionApplyOneWithRetry(
4993 sqlite3 *db, /* Apply change to "main" db of this handle */
4994 sqlite3_changeset_iter *pIter, /* Changeset iterator to read change from */
4995 SessionApplyCtx *pApply, /* Apply context */
4996 int(*xConflict)(void*, int, sqlite3_changeset_iter*),
4997 void *pCtx /* First argument passed to xConflict */
4999 int bReplace = 0;
5000 int bRetry = 0;
5001 int rc;
5003 rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, &bReplace, &bRetry);
5004 if( rc==SQLITE_OK ){
5005 /* If the bRetry flag is set, the change has not been applied due to an
5006 ** SQLITE_CHANGESET_DATA problem (i.e. this is an UPDATE or DELETE and
5007 ** a row with the correct PK is present in the db, but one or more other
5008 ** fields do not contain the expected values) and the conflict handler
5009 ** returned SQLITE_CHANGESET_REPLACE. In this case retry the operation,
5010 ** but pass NULL as the final argument so that sessionApplyOneOp() ignores
5011 ** the SQLITE_CHANGESET_DATA problem. */
5012 if( bRetry ){
5013 assert( pIter->op==SQLITE_UPDATE || pIter->op==SQLITE_DELETE );
5014 rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0);
5017 /* If the bReplace flag is set, the change is an INSERT that has not
5018 ** been performed because the database already contains a row with the
5019 ** specified primary key and the conflict handler returned
5020 ** SQLITE_CHANGESET_REPLACE. In this case remove the conflicting row
5021 ** before reattempting the INSERT. */
5022 else if( bReplace ){
5023 assert( pIter->op==SQLITE_INSERT );
5024 rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0);
5025 if( rc==SQLITE_OK ){
5026 rc = sessionBindRow(pIter,
5027 sqlite3changeset_new, pApply->nCol, pApply->abPK, pApply->pDelete);
5028 sqlite3_bind_int(pApply->pDelete, pApply->nCol+1, 1);
5030 if( rc==SQLITE_OK ){
5031 sqlite3_step(pApply->pDelete);
5032 rc = sqlite3_reset(pApply->pDelete);
5034 if( rc==SQLITE_OK ){
5035 rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0);
5037 if( rc==SQLITE_OK ){
5038 rc = sqlite3_exec(db, "RELEASE replace_op", 0, 0, 0);
5043 return rc;
5047 ** Retry the changes accumulated in the pApply->constraints buffer.
5049 static int sessionRetryConstraints(
5050 sqlite3 *db,
5051 int bPatchset,
5052 const char *zTab,
5053 SessionApplyCtx *pApply,
5054 int(*xConflict)(void*, int, sqlite3_changeset_iter*),
5055 void *pCtx /* First argument passed to xConflict */
5057 int rc = SQLITE_OK;
5059 while( pApply->constraints.nBuf ){
5060 sqlite3_changeset_iter *pIter2 = 0;
5061 SessionBuffer cons = pApply->constraints;
5062 memset(&pApply->constraints, 0, sizeof(SessionBuffer));
5064 rc = sessionChangesetStart(
5065 &pIter2, 0, 0, cons.nBuf, cons.aBuf, pApply->bInvertConstraints, 1
5067 if( rc==SQLITE_OK ){
5068 size_t nByte = 2*pApply->nCol*sizeof(sqlite3_value*);
5069 int rc2;
5070 pIter2->bPatchset = bPatchset;
5071 pIter2->zTab = (char*)zTab;
5072 pIter2->nCol = pApply->nCol;
5073 pIter2->abPK = pApply->abPK;
5074 sessionBufferGrow(&pIter2->tblhdr, nByte, &rc);
5075 pIter2->apValue = (sqlite3_value**)pIter2->tblhdr.aBuf;
5076 if( rc==SQLITE_OK ) memset(pIter2->apValue, 0, nByte);
5078 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter2) ){
5079 rc = sessionApplyOneWithRetry(db, pIter2, pApply, xConflict, pCtx);
5082 rc2 = sqlite3changeset_finalize(pIter2);
5083 if( rc==SQLITE_OK ) rc = rc2;
5085 assert( pApply->bDeferConstraints || pApply->constraints.nBuf==0 );
5087 sqlite3_free(cons.aBuf);
5088 if( rc!=SQLITE_OK ) break;
5089 if( pApply->constraints.nBuf>=cons.nBuf ){
5090 /* No progress was made on the last round. */
5091 pApply->bDeferConstraints = 0;
5095 return rc;
5099 ** Argument pIter is a changeset iterator that has been initialized, but
5100 ** not yet passed to sqlite3changeset_next(). This function applies the
5101 ** changeset to the main database attached to handle "db". The supplied
5102 ** conflict handler callback is invoked to resolve any conflicts encountered
5103 ** while applying the change.
5105 static int sessionChangesetApply(
5106 sqlite3 *db, /* Apply change to "main" db of this handle */
5107 sqlite3_changeset_iter *pIter, /* Changeset to apply */
5108 int(*xFilter)(
5109 void *pCtx, /* Copy of sixth arg to _apply() */
5110 const char *zTab /* Table name */
5112 int(*xConflict)(
5113 void *pCtx, /* Copy of fifth arg to _apply() */
5114 int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
5115 sqlite3_changeset_iter *p /* Handle describing change and conflict */
5117 void *pCtx, /* First argument passed to xConflict */
5118 void **ppRebase, int *pnRebase, /* OUT: Rebase information */
5119 int flags /* SESSION_APPLY_XXX flags */
5121 int schemaMismatch = 0;
5122 int rc = SQLITE_OK; /* Return code */
5123 const char *zTab = 0; /* Name of current table */
5124 int nTab = 0; /* Result of sqlite3Strlen30(zTab) */
5125 SessionApplyCtx sApply; /* changeset_apply() context object */
5126 int bPatchset;
5128 assert( xConflict!=0 );
5130 pIter->in.bNoDiscard = 1;
5131 memset(&sApply, 0, sizeof(sApply));
5132 sApply.bRebase = (ppRebase && pnRebase);
5133 sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
5134 sApply.bIgnoreNoop = !!(flags & SQLITE_CHANGESETAPPLY_IGNORENOOP);
5135 sqlite3_mutex_enter(sqlite3_db_mutex(db));
5136 if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
5137 rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
5139 if( rc==SQLITE_OK ){
5140 rc = sqlite3_exec(db, "PRAGMA defer_foreign_keys = 1", 0, 0, 0);
5142 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter) ){
5143 int nCol;
5144 int op;
5145 const char *zNew;
5147 sqlite3changeset_op(pIter, &zNew, &nCol, &op, 0);
5149 if( zTab==0 || sqlite3_strnicmp(zNew, zTab, nTab+1) ){
5150 u8 *abPK;
5152 rc = sessionRetryConstraints(
5153 db, pIter->bPatchset, zTab, &sApply, xConflict, pCtx
5155 if( rc!=SQLITE_OK ) break;
5157 sessionUpdateFree(&sApply);
5158 sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */
5159 sqlite3_finalize(sApply.pDelete);
5160 sqlite3_finalize(sApply.pInsert);
5161 sqlite3_finalize(sApply.pSelect);
5162 sApply.db = db;
5163 sApply.pDelete = 0;
5164 sApply.pInsert = 0;
5165 sApply.pSelect = 0;
5166 sApply.nCol = 0;
5167 sApply.azCol = 0;
5168 sApply.abPK = 0;
5169 sApply.bStat1 = 0;
5170 sApply.bDeferConstraints = 1;
5171 sApply.bRebaseStarted = 0;
5172 sApply.bRowid = 0;
5173 memset(&sApply.constraints, 0, sizeof(SessionBuffer));
5175 /* If an xFilter() callback was specified, invoke it now. If the
5176 ** xFilter callback returns zero, skip this table. If it returns
5177 ** non-zero, proceed. */
5178 schemaMismatch = (xFilter && (0==xFilter(pCtx, zNew)));
5179 if( schemaMismatch ){
5180 zTab = sqlite3_mprintf("%s", zNew);
5181 if( zTab==0 ){
5182 rc = SQLITE_NOMEM;
5183 break;
5185 nTab = (int)strlen(zTab);
5186 sApply.azCol = (const char **)zTab;
5187 }else{
5188 int nMinCol = 0;
5189 int i;
5191 sqlite3changeset_pk(pIter, &abPK, 0);
5192 rc = sessionTableInfo(0, db, "main", zNew,
5193 &sApply.nCol, &zTab, &sApply.azCol, 0, &sApply.abPK, &sApply.bRowid
5195 if( rc!=SQLITE_OK ) break;
5196 for(i=0; i<sApply.nCol; i++){
5197 if( sApply.abPK[i] ) nMinCol = i+1;
5200 if( sApply.nCol==0 ){
5201 schemaMismatch = 1;
5202 sqlite3_log(SQLITE_SCHEMA,
5203 "sqlite3changeset_apply(): no such table: %s", zTab
5206 else if( sApply.nCol<nCol ){
5207 schemaMismatch = 1;
5208 sqlite3_log(SQLITE_SCHEMA,
5209 "sqlite3changeset_apply(): table %s has %d columns, "
5210 "expected %d or more",
5211 zTab, sApply.nCol, nCol
5214 else if( nCol<nMinCol || memcmp(sApply.abPK, abPK, nCol)!=0 ){
5215 schemaMismatch = 1;
5216 sqlite3_log(SQLITE_SCHEMA, "sqlite3changeset_apply(): "
5217 "primary key mismatch for table %s", zTab
5220 else{
5221 sApply.nCol = nCol;
5222 if( 0==sqlite3_stricmp(zTab, "sqlite_stat1") ){
5223 if( (rc = sessionStat1Sql(db, &sApply) ) ){
5224 break;
5226 sApply.bStat1 = 1;
5227 }else{
5228 if( (rc = sessionSelectRow(db, zTab, &sApply))
5229 || (rc = sessionDeleteRow(db, zTab, &sApply))
5230 || (rc = sessionInsertRow(db, zTab, &sApply))
5232 break;
5234 sApply.bStat1 = 0;
5237 nTab = sqlite3Strlen30(zTab);
5241 /* If there is a schema mismatch on the current table, proceed to the
5242 ** next change. A log message has already been issued. */
5243 if( schemaMismatch ) continue;
5245 rc = sessionApplyOneWithRetry(db, pIter, &sApply, xConflict, pCtx);
5248 bPatchset = pIter->bPatchset;
5249 if( rc==SQLITE_OK ){
5250 rc = sqlite3changeset_finalize(pIter);
5251 }else{
5252 sqlite3changeset_finalize(pIter);
5255 if( rc==SQLITE_OK ){
5256 rc = sessionRetryConstraints(db, bPatchset, zTab, &sApply, xConflict, pCtx);
5259 if( rc==SQLITE_OK ){
5260 int nFk, notUsed;
5261 sqlite3_db_status(db, SQLITE_DBSTATUS_DEFERRED_FKS, &nFk, &notUsed, 0);
5262 if( nFk!=0 ){
5263 int res = SQLITE_CHANGESET_ABORT;
5264 sqlite3_changeset_iter sIter;
5265 memset(&sIter, 0, sizeof(sIter));
5266 sIter.nCol = nFk;
5267 res = xConflict(pCtx, SQLITE_CHANGESET_FOREIGN_KEY, &sIter);
5268 if( res!=SQLITE_CHANGESET_OMIT ){
5269 rc = SQLITE_CONSTRAINT;
5273 sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0);
5275 if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
5276 if( rc==SQLITE_OK ){
5277 rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
5278 }else{
5279 sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0);
5280 sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
5284 assert( sApply.bRebase || sApply.rebase.nBuf==0 );
5285 if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){
5286 *ppRebase = (void*)sApply.rebase.aBuf;
5287 *pnRebase = sApply.rebase.nBuf;
5288 sApply.rebase.aBuf = 0;
5290 sessionUpdateFree(&sApply);
5291 sqlite3_finalize(sApply.pInsert);
5292 sqlite3_finalize(sApply.pDelete);
5293 sqlite3_finalize(sApply.pSelect);
5294 sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */
5295 sqlite3_free((char*)sApply.constraints.aBuf);
5296 sqlite3_free((char*)sApply.rebase.aBuf);
5297 sqlite3_mutex_leave(sqlite3_db_mutex(db));
5298 return rc;
5302 ** Apply the changeset passed via pChangeset/nChangeset to the main
5303 ** database attached to handle "db".
5305 int sqlite3changeset_apply_v2(
5306 sqlite3 *db, /* Apply change to "main" db of this handle */
5307 int nChangeset, /* Size of changeset in bytes */
5308 void *pChangeset, /* Changeset blob */
5309 int(*xFilter)(
5310 void *pCtx, /* Copy of sixth arg to _apply() */
5311 const char *zTab /* Table name */
5313 int(*xConflict)(
5314 void *pCtx, /* Copy of sixth arg to _apply() */
5315 int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
5316 sqlite3_changeset_iter *p /* Handle describing change and conflict */
5318 void *pCtx, /* First argument passed to xConflict */
5319 void **ppRebase, int *pnRebase,
5320 int flags
5322 sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
5323 int bInv = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
5324 int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset, bInv, 1);
5325 u64 savedFlag = db->flags & SQLITE_FkNoAction;
5327 if( flags & SQLITE_CHANGESETAPPLY_FKNOACTION ){
5328 db->flags |= ((u64)SQLITE_FkNoAction);
5329 db->aDb[0].pSchema->schema_cookie -= 32;
5332 if( rc==SQLITE_OK ){
5333 rc = sessionChangesetApply(
5334 db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
5338 if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){
5339 assert( db->flags & SQLITE_FkNoAction );
5340 db->flags &= ~((u64)SQLITE_FkNoAction);
5341 db->aDb[0].pSchema->schema_cookie -= 32;
5343 return rc;
5347 ** Apply the changeset passed via pChangeset/nChangeset to the main database
5348 ** attached to handle "db". Invoke the supplied conflict handler callback
5349 ** to resolve any conflicts encountered while applying the change.
5351 int sqlite3changeset_apply(
5352 sqlite3 *db, /* Apply change to "main" db of this handle */
5353 int nChangeset, /* Size of changeset in bytes */
5354 void *pChangeset, /* Changeset blob */
5355 int(*xFilter)(
5356 void *pCtx, /* Copy of sixth arg to _apply() */
5357 const char *zTab /* Table name */
5359 int(*xConflict)(
5360 void *pCtx, /* Copy of fifth arg to _apply() */
5361 int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
5362 sqlite3_changeset_iter *p /* Handle describing change and conflict */
5364 void *pCtx /* First argument passed to xConflict */
5366 return sqlite3changeset_apply_v2(
5367 db, nChangeset, pChangeset, xFilter, xConflict, pCtx, 0, 0, 0
5372 ** Apply the changeset passed via xInput/pIn to the main database
5373 ** attached to handle "db". Invoke the supplied conflict handler callback
5374 ** to resolve any conflicts encountered while applying the change.
5376 int sqlite3changeset_apply_v2_strm(
5377 sqlite3 *db, /* Apply change to "main" db of this handle */
5378 int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
5379 void *pIn, /* First arg for xInput */
5380 int(*xFilter)(
5381 void *pCtx, /* Copy of sixth arg to _apply() */
5382 const char *zTab /* Table name */
5384 int(*xConflict)(
5385 void *pCtx, /* Copy of sixth arg to _apply() */
5386 int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
5387 sqlite3_changeset_iter *p /* Handle describing change and conflict */
5389 void *pCtx, /* First argument passed to xConflict */
5390 void **ppRebase, int *pnRebase,
5391 int flags
5393 sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
5394 int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
5395 int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse, 1);
5396 if( rc==SQLITE_OK ){
5397 rc = sessionChangesetApply(
5398 db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
5401 return rc;
5403 int sqlite3changeset_apply_strm(
5404 sqlite3 *db, /* Apply change to "main" db of this handle */
5405 int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
5406 void *pIn, /* First arg for xInput */
5407 int(*xFilter)(
5408 void *pCtx, /* Copy of sixth arg to _apply() */
5409 const char *zTab /* Table name */
5411 int(*xConflict)(
5412 void *pCtx, /* Copy of sixth arg to _apply() */
5413 int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
5414 sqlite3_changeset_iter *p /* Handle describing change and conflict */
5416 void *pCtx /* First argument passed to xConflict */
5418 return sqlite3changeset_apply_v2_strm(
5419 db, xInput, pIn, xFilter, xConflict, pCtx, 0, 0, 0
5424 ** sqlite3_changegroup handle.
5426 struct sqlite3_changegroup {
5427 int rc; /* Error code */
5428 int bPatch; /* True to accumulate patchsets */
5429 SessionTable *pList; /* List of tables in current patch */
5431 sqlite3 *db; /* Configured by changegroup_schema() */
5432 char *zDb; /* Configured by changegroup_schema() */
5436 ** This function is called to merge two changes to the same row together as
5437 ** part of an sqlite3changeset_concat() operation. A new change object is
5438 ** allocated and a pointer to it stored in *ppNew.
5440 static int sessionChangeMerge(
5441 SessionTable *pTab, /* Table structure */
5442 int bRebase, /* True for a rebase hash-table */
5443 int bPatchset, /* True for patchsets */
5444 SessionChange *pExist, /* Existing change */
5445 int op2, /* Second change operation */
5446 int bIndirect, /* True if second change is indirect */
5447 u8 *aRec, /* Second change record */
5448 int nRec, /* Number of bytes in aRec */
5449 SessionChange **ppNew /* OUT: Merged change */
5451 SessionChange *pNew = 0;
5452 int rc = SQLITE_OK;
5453 assert( aRec!=0 );
5455 if( !pExist ){
5456 pNew = (SessionChange *)sqlite3_malloc64(sizeof(SessionChange) + nRec);
5457 if( !pNew ){
5458 return SQLITE_NOMEM;
5460 memset(pNew, 0, sizeof(SessionChange));
5461 pNew->op = op2;
5462 pNew->bIndirect = bIndirect;
5463 pNew->aRecord = (u8*)&pNew[1];
5464 if( bIndirect==0 || bRebase==0 ){
5465 pNew->nRecord = nRec;
5466 memcpy(pNew->aRecord, aRec, nRec);
5467 }else{
5468 int i;
5469 u8 *pIn = aRec;
5470 u8 *pOut = pNew->aRecord;
5471 for(i=0; i<pTab->nCol; i++){
5472 int nIn = sessionSerialLen(pIn);
5473 if( *pIn==0 ){
5474 *pOut++ = 0;
5475 }else if( pTab->abPK[i]==0 ){
5476 *pOut++ = 0xFF;
5477 }else{
5478 memcpy(pOut, pIn, nIn);
5479 pOut += nIn;
5481 pIn += nIn;
5483 pNew->nRecord = pOut - pNew->aRecord;
5485 }else if( bRebase ){
5486 if( pExist->op==SQLITE_DELETE && pExist->bIndirect ){
5487 *ppNew = pExist;
5488 }else{
5489 sqlite3_int64 nByte = nRec + pExist->nRecord + sizeof(SessionChange);
5490 pNew = (SessionChange*)sqlite3_malloc64(nByte);
5491 if( pNew==0 ){
5492 rc = SQLITE_NOMEM;
5493 }else{
5494 int i;
5495 u8 *a1 = pExist->aRecord;
5496 u8 *a2 = aRec;
5497 u8 *pOut;
5499 memset(pNew, 0, nByte);
5500 pNew->bIndirect = bIndirect || pExist->bIndirect;
5501 pNew->op = op2;
5502 pOut = pNew->aRecord = (u8*)&pNew[1];
5504 for(i=0; i<pTab->nCol; i++){
5505 int n1 = sessionSerialLen(a1);
5506 int n2 = sessionSerialLen(a2);
5507 if( *a1==0xFF || (pTab->abPK[i]==0 && bIndirect) ){
5508 *pOut++ = 0xFF;
5509 }else if( *a2==0 ){
5510 memcpy(pOut, a1, n1);
5511 pOut += n1;
5512 }else{
5513 memcpy(pOut, a2, n2);
5514 pOut += n2;
5516 a1 += n1;
5517 a2 += n2;
5519 pNew->nRecord = pOut - pNew->aRecord;
5521 sqlite3_free(pExist);
5523 }else{
5524 int op1 = pExist->op;
5527 ** op1=INSERT, op2=INSERT -> Unsupported. Discard op2.
5528 ** op1=INSERT, op2=UPDATE -> INSERT.
5529 ** op1=INSERT, op2=DELETE -> (none)
5531 ** op1=UPDATE, op2=INSERT -> Unsupported. Discard op2.
5532 ** op1=UPDATE, op2=UPDATE -> UPDATE.
5533 ** op1=UPDATE, op2=DELETE -> DELETE.
5535 ** op1=DELETE, op2=INSERT -> UPDATE.
5536 ** op1=DELETE, op2=UPDATE -> Unsupported. Discard op2.
5537 ** op1=DELETE, op2=DELETE -> Unsupported. Discard op2.
5539 if( (op1==SQLITE_INSERT && op2==SQLITE_INSERT)
5540 || (op1==SQLITE_UPDATE && op2==SQLITE_INSERT)
5541 || (op1==SQLITE_DELETE && op2==SQLITE_UPDATE)
5542 || (op1==SQLITE_DELETE && op2==SQLITE_DELETE)
5544 pNew = pExist;
5545 }else if( op1==SQLITE_INSERT && op2==SQLITE_DELETE ){
5546 sqlite3_free(pExist);
5547 assert( pNew==0 );
5548 }else{
5549 u8 *aExist = pExist->aRecord;
5550 sqlite3_int64 nByte;
5551 u8 *aCsr;
5553 /* Allocate a new SessionChange object. Ensure that the aRecord[]
5554 ** buffer of the new object is large enough to hold any record that
5555 ** may be generated by combining the input records. */
5556 nByte = sizeof(SessionChange) + pExist->nRecord + nRec;
5557 pNew = (SessionChange *)sqlite3_malloc64(nByte);
5558 if( !pNew ){
5559 sqlite3_free(pExist);
5560 return SQLITE_NOMEM;
5562 memset(pNew, 0, sizeof(SessionChange));
5563 pNew->bIndirect = (bIndirect && pExist->bIndirect);
5564 aCsr = pNew->aRecord = (u8 *)&pNew[1];
5566 if( op1==SQLITE_INSERT ){ /* INSERT + UPDATE */
5567 u8 *a1 = aRec;
5568 assert( op2==SQLITE_UPDATE );
5569 pNew->op = SQLITE_INSERT;
5570 if( bPatchset==0 ) sessionSkipRecord(&a1, pTab->nCol);
5571 sessionMergeRecord(&aCsr, pTab->nCol, aExist, a1);
5572 }else if( op1==SQLITE_DELETE ){ /* DELETE + INSERT */
5573 assert( op2==SQLITE_INSERT );
5574 pNew->op = SQLITE_UPDATE;
5575 if( bPatchset ){
5576 memcpy(aCsr, aRec, nRec);
5577 aCsr += nRec;
5578 }else{
5579 if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aExist, 0,aRec,0) ){
5580 sqlite3_free(pNew);
5581 pNew = 0;
5584 }else if( op2==SQLITE_UPDATE ){ /* UPDATE + UPDATE */
5585 u8 *a1 = aExist;
5586 u8 *a2 = aRec;
5587 assert( op1==SQLITE_UPDATE );
5588 if( bPatchset==0 ){
5589 sessionSkipRecord(&a1, pTab->nCol);
5590 sessionSkipRecord(&a2, pTab->nCol);
5592 pNew->op = SQLITE_UPDATE;
5593 if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aRec, aExist,a1,a2) ){
5594 sqlite3_free(pNew);
5595 pNew = 0;
5597 }else{ /* UPDATE + DELETE */
5598 assert( op1==SQLITE_UPDATE && op2==SQLITE_DELETE );
5599 pNew->op = SQLITE_DELETE;
5600 if( bPatchset ){
5601 memcpy(aCsr, aRec, nRec);
5602 aCsr += nRec;
5603 }else{
5604 sessionMergeRecord(&aCsr, pTab->nCol, aRec, aExist);
5608 if( pNew ){
5609 pNew->nRecord = (int)(aCsr - pNew->aRecord);
5611 sqlite3_free(pExist);
5615 *ppNew = pNew;
5616 return rc;
5620 ** Check if a changeset entry with nCol columns and the PK array passed
5621 ** as the final argument to this function is compatible with SessionTable
5622 ** pTab. If so, return 1. Otherwise, if they are incompatible in some way,
5623 ** return 0.
5625 static int sessionChangesetCheckCompat(
5626 SessionTable *pTab,
5627 int nCol,
5628 u8 *abPK
5630 if( pTab->azCol && nCol<pTab->nCol ){
5631 int ii;
5632 for(ii=0; ii<pTab->nCol; ii++){
5633 u8 bPK = (ii < nCol) ? abPK[ii] : 0;
5634 if( pTab->abPK[ii]!=bPK ) return 0;
5636 return 1;
5638 return (pTab->nCol==nCol && 0==memcmp(abPK, pTab->abPK, nCol));
5641 static int sessionChangesetExtendRecord(
5642 sqlite3_changegroup *pGrp,
5643 SessionTable *pTab,
5644 int nCol,
5645 int op,
5646 const u8 *aRec,
5647 int nRec,
5648 SessionBuffer *pOut
5650 int rc = SQLITE_OK;
5651 int ii = 0;
5653 assert( pTab->azCol );
5654 assert( nCol<pTab->nCol );
5656 pOut->nBuf = 0;
5657 if( op==SQLITE_INSERT || (op==SQLITE_DELETE && pGrp->bPatch==0) ){
5658 /* Append the missing default column values to the record. */
5659 sessionAppendBlob(pOut, aRec, nRec, &rc);
5660 if( rc==SQLITE_OK && pTab->pDfltStmt==0 ){
5661 rc = sessionPrepareDfltStmt(pGrp->db, pTab, &pTab->pDfltStmt);
5663 for(ii=nCol; rc==SQLITE_OK && ii<pTab->nCol; ii++){
5664 int eType = sqlite3_column_type(pTab->pDfltStmt, ii);
5665 sessionAppendByte(pOut, eType, &rc);
5666 switch( eType ){
5667 case SQLITE_FLOAT:
5668 case SQLITE_INTEGER: {
5669 i64 iVal;
5670 if( eType==SQLITE_INTEGER ){
5671 iVal = sqlite3_column_int64(pTab->pDfltStmt, ii);
5672 }else{
5673 double rVal = sqlite3_column_int64(pTab->pDfltStmt, ii);
5674 memcpy(&iVal, &rVal, sizeof(i64));
5676 if( SQLITE_OK==sessionBufferGrow(pOut, 8, &rc) ){
5677 sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal);
5679 break;
5682 case SQLITE_BLOB:
5683 case SQLITE_TEXT: {
5684 int n = sqlite3_column_bytes(pTab->pDfltStmt, ii);
5685 sessionAppendVarint(pOut, n, &rc);
5686 if( eType==SQLITE_TEXT ){
5687 const u8 *z = (const u8*)sqlite3_column_text(pTab->pDfltStmt, ii);
5688 sessionAppendBlob(pOut, z, n, &rc);
5689 }else{
5690 const u8 *z = (const u8*)sqlite3_column_blob(pTab->pDfltStmt, ii);
5691 sessionAppendBlob(pOut, z, n, &rc);
5693 break;
5696 default:
5697 assert( eType==SQLITE_NULL );
5698 break;
5701 }else if( op==SQLITE_UPDATE ){
5702 /* Append missing "undefined" entries to the old.* record. And, if this
5703 ** is an UPDATE, to the new.* record as well. */
5704 int iOff = 0;
5705 if( pGrp->bPatch==0 ){
5706 for(ii=0; ii<nCol; ii++){
5707 iOff += sessionSerialLen(&aRec[iOff]);
5709 sessionAppendBlob(pOut, aRec, iOff, &rc);
5710 for(ii=0; ii<(pTab->nCol-nCol); ii++){
5711 sessionAppendByte(pOut, 0x00, &rc);
5715 sessionAppendBlob(pOut, &aRec[iOff], nRec-iOff, &rc);
5716 for(ii=0; ii<(pTab->nCol-nCol); ii++){
5717 sessionAppendByte(pOut, 0x00, &rc);
5719 }else{
5720 assert( op==SQLITE_DELETE && pGrp->bPatch );
5721 sessionAppendBlob(pOut, aRec, nRec, &rc);
5724 return rc;
5728 ** Add all changes in the changeset traversed by the iterator passed as
5729 ** the first argument to the changegroup hash tables.
5731 static int sessionChangesetToHash(
5732 sqlite3_changeset_iter *pIter, /* Iterator to read from */
5733 sqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */
5734 int bRebase /* True if hash table is for rebasing */
5736 u8 *aRec;
5737 int nRec;
5738 int rc = SQLITE_OK;
5739 SessionTable *pTab = 0;
5740 SessionBuffer rec = {0, 0, 0};
5742 while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, 0) ){
5743 const char *zNew;
5744 int nCol;
5745 int op;
5746 int iHash;
5747 int bIndirect;
5748 SessionChange *pChange;
5749 SessionChange *pExist = 0;
5750 SessionChange **pp;
5752 /* Ensure that only changesets, or only patchsets, but not a mixture
5753 ** of both, are being combined. It is an error to try to combine a
5754 ** changeset and a patchset. */
5755 if( pGrp->pList==0 ){
5756 pGrp->bPatch = pIter->bPatchset;
5757 }else if( pIter->bPatchset!=pGrp->bPatch ){
5758 rc = SQLITE_ERROR;
5759 break;
5762 sqlite3changeset_op(pIter, &zNew, &nCol, &op, &bIndirect);
5763 if( !pTab || sqlite3_stricmp(zNew, pTab->zName) ){
5764 /* Search the list for a matching table */
5765 int nNew = (int)strlen(zNew);
5766 u8 *abPK;
5768 sqlite3changeset_pk(pIter, &abPK, 0);
5769 for(pTab = pGrp->pList; pTab; pTab=pTab->pNext){
5770 if( 0==sqlite3_strnicmp(pTab->zName, zNew, nNew+1) ) break;
5772 if( !pTab ){
5773 SessionTable **ppTab;
5775 pTab = sqlite3_malloc64(sizeof(SessionTable) + nCol + nNew+1);
5776 if( !pTab ){
5777 rc = SQLITE_NOMEM;
5778 break;
5780 memset(pTab, 0, sizeof(SessionTable));
5781 pTab->nCol = nCol;
5782 pTab->abPK = (u8*)&pTab[1];
5783 memcpy(pTab->abPK, abPK, nCol);
5784 pTab->zName = (char*)&pTab->abPK[nCol];
5785 memcpy(pTab->zName, zNew, nNew+1);
5787 if( pGrp->db ){
5788 pTab->nCol = 0;
5789 rc = sessionInitTable(0, pTab, pGrp->db, pGrp->zDb);
5790 if( rc ){
5791 assert( pTab->azCol==0 );
5792 sqlite3_free(pTab);
5793 break;
5797 /* The new object must be linked on to the end of the list, not
5798 ** simply added to the start of it. This is to ensure that the
5799 ** tables within the output of sqlite3changegroup_output() are in
5800 ** the right order. */
5801 for(ppTab=&pGrp->pList; *ppTab; ppTab=&(*ppTab)->pNext);
5802 *ppTab = pTab;
5805 if( !sessionChangesetCheckCompat(pTab, nCol, abPK) ){
5806 rc = SQLITE_SCHEMA;
5807 break;
5811 if( nCol<pTab->nCol ){
5812 assert( pGrp->db );
5813 rc = sessionChangesetExtendRecord(pGrp, pTab, nCol, op, aRec, nRec, &rec);
5814 if( rc ) break;
5815 aRec = rec.aBuf;
5816 nRec = rec.nBuf;
5819 if( sessionGrowHash(0, pIter->bPatchset, pTab) ){
5820 rc = SQLITE_NOMEM;
5821 break;
5823 iHash = sessionChangeHash(
5824 pTab, (pIter->bPatchset && op==SQLITE_DELETE), aRec, pTab->nChange
5827 /* Search for existing entry. If found, remove it from the hash table.
5828 ** Code below may link it back in.
5830 for(pp=&pTab->apChange[iHash]; *pp; pp=&(*pp)->pNext){
5831 int bPkOnly1 = 0;
5832 int bPkOnly2 = 0;
5833 if( pIter->bPatchset ){
5834 bPkOnly1 = (*pp)->op==SQLITE_DELETE;
5835 bPkOnly2 = op==SQLITE_DELETE;
5837 if( sessionChangeEqual(pTab, bPkOnly1, (*pp)->aRecord, bPkOnly2, aRec) ){
5838 pExist = *pp;
5839 *pp = (*pp)->pNext;
5840 pTab->nEntry--;
5841 break;
5845 rc = sessionChangeMerge(pTab, bRebase,
5846 pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange
5848 if( rc ) break;
5849 if( pChange ){
5850 pChange->pNext = pTab->apChange[iHash];
5851 pTab->apChange[iHash] = pChange;
5852 pTab->nEntry++;
5856 sqlite3_free(rec.aBuf);
5857 if( rc==SQLITE_OK ) rc = pIter->rc;
5858 return rc;
5862 ** Serialize a changeset (or patchset) based on all changesets (or patchsets)
5863 ** added to the changegroup object passed as the first argument.
5865 ** If xOutput is not NULL, then the changeset/patchset is returned to the
5866 ** user via one or more calls to xOutput, as with the other streaming
5867 ** interfaces.
5869 ** Or, if xOutput is NULL, then (*ppOut) is populated with a pointer to a
5870 ** buffer containing the output changeset before this function returns. In
5871 ** this case (*pnOut) is set to the size of the output buffer in bytes. It
5872 ** is the responsibility of the caller to free the output buffer using
5873 ** sqlite3_free() when it is no longer required.
5875 ** If successful, SQLITE_OK is returned. Or, if an error occurs, an SQLite
5876 ** error code. If an error occurs and xOutput is NULL, (*ppOut) and (*pnOut)
5877 ** are both set to 0 before returning.
5879 static int sessionChangegroupOutput(
5880 sqlite3_changegroup *pGrp,
5881 int (*xOutput)(void *pOut, const void *pData, int nData),
5882 void *pOut,
5883 int *pnOut,
5884 void **ppOut
5886 int rc = SQLITE_OK;
5887 SessionBuffer buf = {0, 0, 0};
5888 SessionTable *pTab;
5889 assert( xOutput==0 || (ppOut==0 && pnOut==0) );
5891 /* Create the serialized output changeset based on the contents of the
5892 ** hash tables attached to the SessionTable objects in list p->pList.
5894 for(pTab=pGrp->pList; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
5895 int i;
5896 if( pTab->nEntry==0 ) continue;
5898 sessionAppendTableHdr(&buf, pGrp->bPatch, pTab, &rc);
5899 for(i=0; i<pTab->nChange; i++){
5900 SessionChange *p;
5901 for(p=pTab->apChange[i]; p; p=p->pNext){
5902 sessionAppendByte(&buf, p->op, &rc);
5903 sessionAppendByte(&buf, p->bIndirect, &rc);
5904 sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc);
5905 if( rc==SQLITE_OK && xOutput && buf.nBuf>=sessions_strm_chunk_size ){
5906 rc = xOutput(pOut, buf.aBuf, buf.nBuf);
5907 buf.nBuf = 0;
5913 if( rc==SQLITE_OK ){
5914 if( xOutput ){
5915 if( buf.nBuf>0 ) rc = xOutput(pOut, buf.aBuf, buf.nBuf);
5916 }else if( ppOut ){
5917 *ppOut = buf.aBuf;
5918 if( pnOut ) *pnOut = buf.nBuf;
5919 buf.aBuf = 0;
5922 sqlite3_free(buf.aBuf);
5924 return rc;
5928 ** Allocate a new, empty, sqlite3_changegroup.
5930 int sqlite3changegroup_new(sqlite3_changegroup **pp){
5931 int rc = SQLITE_OK; /* Return code */
5932 sqlite3_changegroup *p; /* New object */
5933 p = (sqlite3_changegroup*)sqlite3_malloc(sizeof(sqlite3_changegroup));
5934 if( p==0 ){
5935 rc = SQLITE_NOMEM;
5936 }else{
5937 memset(p, 0, sizeof(sqlite3_changegroup));
5939 *pp = p;
5940 return rc;
5944 ** Provide a database schema to the changegroup object.
5946 int sqlite3changegroup_schema(
5947 sqlite3_changegroup *pGrp,
5948 sqlite3 *db,
5949 const char *zDb
5951 int rc = SQLITE_OK;
5953 if( pGrp->pList || pGrp->db ){
5954 /* Cannot add a schema after one or more calls to sqlite3changegroup_add(),
5955 ** or after sqlite3changegroup_schema() has already been called. */
5956 rc = SQLITE_MISUSE;
5957 }else{
5958 pGrp->zDb = sqlite3_mprintf("%s", zDb);
5959 if( pGrp->zDb==0 ){
5960 rc = SQLITE_NOMEM;
5961 }else{
5962 pGrp->db = db;
5965 return rc;
5969 ** Add the changeset currently stored in buffer pData, size nData bytes,
5970 ** to changeset-group p.
5972 int sqlite3changegroup_add(sqlite3_changegroup *pGrp, int nData, void *pData){
5973 sqlite3_changeset_iter *pIter; /* Iterator opened on pData/nData */
5974 int rc; /* Return code */
5976 rc = sqlite3changeset_start(&pIter, nData, pData);
5977 if( rc==SQLITE_OK ){
5978 rc = sessionChangesetToHash(pIter, pGrp, 0);
5980 sqlite3changeset_finalize(pIter);
5981 return rc;
5985 ** Obtain a buffer containing a changeset representing the concatenation
5986 ** of all changesets added to the group so far.
5988 int sqlite3changegroup_output(
5989 sqlite3_changegroup *pGrp,
5990 int *pnData,
5991 void **ppData
5993 return sessionChangegroupOutput(pGrp, 0, 0, pnData, ppData);
5997 ** Streaming versions of changegroup_add().
5999 int sqlite3changegroup_add_strm(
6000 sqlite3_changegroup *pGrp,
6001 int (*xInput)(void *pIn, void *pData, int *pnData),
6002 void *pIn
6004 sqlite3_changeset_iter *pIter; /* Iterator opened on pData/nData */
6005 int rc; /* Return code */
6007 rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
6008 if( rc==SQLITE_OK ){
6009 rc = sessionChangesetToHash(pIter, pGrp, 0);
6011 sqlite3changeset_finalize(pIter);
6012 return rc;
6016 ** Streaming versions of changegroup_output().
6018 int sqlite3changegroup_output_strm(
6019 sqlite3_changegroup *pGrp,
6020 int (*xOutput)(void *pOut, const void *pData, int nData),
6021 void *pOut
6023 return sessionChangegroupOutput(pGrp, xOutput, pOut, 0, 0);
6027 ** Delete a changegroup object.
6029 void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){
6030 if( pGrp ){
6031 sqlite3_free(pGrp->zDb);
6032 sessionDeleteTable(0, pGrp->pList);
6033 sqlite3_free(pGrp);
6038 ** Combine two changesets together.
6040 int sqlite3changeset_concat(
6041 int nLeft, /* Number of bytes in lhs input */
6042 void *pLeft, /* Lhs input changeset */
6043 int nRight /* Number of bytes in rhs input */,
6044 void *pRight, /* Rhs input changeset */
6045 int *pnOut, /* OUT: Number of bytes in output changeset */
6046 void **ppOut /* OUT: changeset (left <concat> right) */
6048 sqlite3_changegroup *pGrp;
6049 int rc;
6051 rc = sqlite3changegroup_new(&pGrp);
6052 if( rc==SQLITE_OK ){
6053 rc = sqlite3changegroup_add(pGrp, nLeft, pLeft);
6055 if( rc==SQLITE_OK ){
6056 rc = sqlite3changegroup_add(pGrp, nRight, pRight);
6058 if( rc==SQLITE_OK ){
6059 rc = sqlite3changegroup_output(pGrp, pnOut, ppOut);
6061 sqlite3changegroup_delete(pGrp);
6063 return rc;
6067 ** Streaming version of sqlite3changeset_concat().
6069 int sqlite3changeset_concat_strm(
6070 int (*xInputA)(void *pIn, void *pData, int *pnData),
6071 void *pInA,
6072 int (*xInputB)(void *pIn, void *pData, int *pnData),
6073 void *pInB,
6074 int (*xOutput)(void *pOut, const void *pData, int nData),
6075 void *pOut
6077 sqlite3_changegroup *pGrp;
6078 int rc;
6080 rc = sqlite3changegroup_new(&pGrp);
6081 if( rc==SQLITE_OK ){
6082 rc = sqlite3changegroup_add_strm(pGrp, xInputA, pInA);
6084 if( rc==SQLITE_OK ){
6085 rc = sqlite3changegroup_add_strm(pGrp, xInputB, pInB);
6087 if( rc==SQLITE_OK ){
6088 rc = sqlite3changegroup_output_strm(pGrp, xOutput, pOut);
6090 sqlite3changegroup_delete(pGrp);
6092 return rc;
6096 ** Changeset rebaser handle.
6098 struct sqlite3_rebaser {
6099 sqlite3_changegroup grp; /* Hash table */
6103 ** Buffers a1 and a2 must both contain a sessions module record nCol
6104 ** fields in size. This function appends an nCol sessions module
6105 ** record to buffer pBuf that is a copy of a1, except that for
6106 ** each field that is undefined in a1[], swap in the field from a2[].
6108 static void sessionAppendRecordMerge(
6109 SessionBuffer *pBuf, /* Buffer to append to */
6110 int nCol, /* Number of columns in each record */
6111 u8 *a1, int n1, /* Record 1 */
6112 u8 *a2, int n2, /* Record 2 */
6113 int *pRc /* IN/OUT: error code */
6115 sessionBufferGrow(pBuf, n1+n2, pRc);
6116 if( *pRc==SQLITE_OK ){
6117 int i;
6118 u8 *pOut = &pBuf->aBuf[pBuf->nBuf];
6119 for(i=0; i<nCol; i++){
6120 int nn1 = sessionSerialLen(a1);
6121 int nn2 = sessionSerialLen(a2);
6122 if( *a1==0 || *a1==0xFF ){
6123 memcpy(pOut, a2, nn2);
6124 pOut += nn2;
6125 }else{
6126 memcpy(pOut, a1, nn1);
6127 pOut += nn1;
6129 a1 += nn1;
6130 a2 += nn2;
6133 pBuf->nBuf = pOut-pBuf->aBuf;
6134 assert( pBuf->nBuf<=pBuf->nAlloc );
6139 ** This function is called when rebasing a local UPDATE change against one
6140 ** or more remote UPDATE changes. The aRec/nRec buffer contains the current
6141 ** old.* and new.* records for the change. The rebase buffer (a single
6142 ** record) is in aChange/nChange. The rebased change is appended to buffer
6143 ** pBuf.
6145 ** Rebasing the UPDATE involves:
6147 ** * Removing any changes to fields for which the corresponding field
6148 ** in the rebase buffer is set to "replaced" (type 0xFF). If this
6149 ** means the UPDATE change updates no fields, nothing is appended
6150 ** to the output buffer.
6152 ** * For each field modified by the local change for which the
6153 ** corresponding field in the rebase buffer is not "undefined" (0x00)
6154 ** or "replaced" (0xFF), the old.* value is replaced by the value
6155 ** in the rebase buffer.
6157 static void sessionAppendPartialUpdate(
6158 SessionBuffer *pBuf, /* Append record here */
6159 sqlite3_changeset_iter *pIter, /* Iterator pointed at local change */
6160 u8 *aRec, int nRec, /* Local change */
6161 u8 *aChange, int nChange, /* Record to rebase against */
6162 int *pRc /* IN/OUT: Return Code */
6164 sessionBufferGrow(pBuf, 2+nRec+nChange, pRc);
6165 if( *pRc==SQLITE_OK ){
6166 int bData = 0;
6167 u8 *pOut = &pBuf->aBuf[pBuf->nBuf];
6168 int i;
6169 u8 *a1 = aRec;
6170 u8 *a2 = aChange;
6172 *pOut++ = SQLITE_UPDATE;
6173 *pOut++ = pIter->bIndirect;
6174 for(i=0; i<pIter->nCol; i++){
6175 int n1 = sessionSerialLen(a1);
6176 int n2 = sessionSerialLen(a2);
6177 if( pIter->abPK[i] || a2[0]==0 ){
6178 if( !pIter->abPK[i] && a1[0] ) bData = 1;
6179 memcpy(pOut, a1, n1);
6180 pOut += n1;
6181 }else if( a2[0]!=0xFF && a1[0] ){
6182 bData = 1;
6183 memcpy(pOut, a2, n2);
6184 pOut += n2;
6185 }else{
6186 *pOut++ = '\0';
6188 a1 += n1;
6189 a2 += n2;
6191 if( bData ){
6192 a2 = aChange;
6193 for(i=0; i<pIter->nCol; i++){
6194 int n1 = sessionSerialLen(a1);
6195 int n2 = sessionSerialLen(a2);
6196 if( pIter->abPK[i] || a2[0]!=0xFF ){
6197 memcpy(pOut, a1, n1);
6198 pOut += n1;
6199 }else{
6200 *pOut++ = '\0';
6202 a1 += n1;
6203 a2 += n2;
6205 pBuf->nBuf = (pOut - pBuf->aBuf);
6211 ** pIter is configured to iterate through a changeset. This function rebases
6212 ** that changeset according to the current configuration of the rebaser
6213 ** object passed as the first argument. If no error occurs and argument xOutput
6214 ** is not NULL, then the changeset is returned to the caller by invoking
6215 ** xOutput zero or more times and SQLITE_OK returned. Or, if xOutput is NULL,
6216 ** then (*ppOut) is set to point to a buffer containing the rebased changeset
6217 ** before this function returns. In this case (*pnOut) is set to the size of
6218 ** the buffer in bytes. It is the responsibility of the caller to eventually
6219 ** free the (*ppOut) buffer using sqlite3_free().
6221 ** If an error occurs, an SQLite error code is returned. If ppOut and
6222 ** pnOut are not NULL, then the two output parameters are set to 0 before
6223 ** returning.
6225 static int sessionRebase(
6226 sqlite3_rebaser *p, /* Rebaser hash table */
6227 sqlite3_changeset_iter *pIter, /* Input data */
6228 int (*xOutput)(void *pOut, const void *pData, int nData),
6229 void *pOut, /* Context for xOutput callback */
6230 int *pnOut, /* OUT: Number of bytes in output changeset */
6231 void **ppOut /* OUT: Inverse of pChangeset */
6233 int rc = SQLITE_OK;
6234 u8 *aRec = 0;
6235 int nRec = 0;
6236 int bNew = 0;
6237 SessionTable *pTab = 0;
6238 SessionBuffer sOut = {0,0,0};
6240 while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, &bNew) ){
6241 SessionChange *pChange = 0;
6242 int bDone = 0;
6244 if( bNew ){
6245 const char *zTab = pIter->zTab;
6246 for(pTab=p->grp.pList; pTab; pTab=pTab->pNext){
6247 if( 0==sqlite3_stricmp(pTab->zName, zTab) ) break;
6249 bNew = 0;
6251 /* A patchset may not be rebased */
6252 if( pIter->bPatchset ){
6253 rc = SQLITE_ERROR;
6256 /* Append a table header to the output for this new table */
6257 sessionAppendByte(&sOut, pIter->bPatchset ? 'P' : 'T', &rc);
6258 sessionAppendVarint(&sOut, pIter->nCol, &rc);
6259 sessionAppendBlob(&sOut, pIter->abPK, pIter->nCol, &rc);
6260 sessionAppendBlob(&sOut,(u8*)pIter->zTab,(int)strlen(pIter->zTab)+1,&rc);
6263 if( pTab && rc==SQLITE_OK ){
6264 int iHash = sessionChangeHash(pTab, 0, aRec, pTab->nChange);
6266 for(pChange=pTab->apChange[iHash]; pChange; pChange=pChange->pNext){
6267 if( sessionChangeEqual(pTab, 0, aRec, 0, pChange->aRecord) ){
6268 break;
6273 if( pChange ){
6274 assert( pChange->op==SQLITE_DELETE || pChange->op==SQLITE_INSERT );
6275 switch( pIter->op ){
6276 case SQLITE_INSERT:
6277 if( pChange->op==SQLITE_INSERT ){
6278 bDone = 1;
6279 if( pChange->bIndirect==0 ){
6280 sessionAppendByte(&sOut, SQLITE_UPDATE, &rc);
6281 sessionAppendByte(&sOut, pIter->bIndirect, &rc);
6282 sessionAppendBlob(&sOut, pChange->aRecord, pChange->nRecord, &rc);
6283 sessionAppendBlob(&sOut, aRec, nRec, &rc);
6286 break;
6288 case SQLITE_UPDATE:
6289 bDone = 1;
6290 if( pChange->op==SQLITE_DELETE ){
6291 if( pChange->bIndirect==0 ){
6292 u8 *pCsr = aRec;
6293 sessionSkipRecord(&pCsr, pIter->nCol);
6294 sessionAppendByte(&sOut, SQLITE_INSERT, &rc);
6295 sessionAppendByte(&sOut, pIter->bIndirect, &rc);
6296 sessionAppendRecordMerge(&sOut, pIter->nCol,
6297 pCsr, nRec-(pCsr-aRec),
6298 pChange->aRecord, pChange->nRecord, &rc
6301 }else{
6302 sessionAppendPartialUpdate(&sOut, pIter,
6303 aRec, nRec, pChange->aRecord, pChange->nRecord, &rc
6306 break;
6308 default:
6309 assert( pIter->op==SQLITE_DELETE );
6310 bDone = 1;
6311 if( pChange->op==SQLITE_INSERT ){
6312 sessionAppendByte(&sOut, SQLITE_DELETE, &rc);
6313 sessionAppendByte(&sOut, pIter->bIndirect, &rc);
6314 sessionAppendRecordMerge(&sOut, pIter->nCol,
6315 pChange->aRecord, pChange->nRecord, aRec, nRec, &rc
6318 break;
6322 if( bDone==0 ){
6323 sessionAppendByte(&sOut, pIter->op, &rc);
6324 sessionAppendByte(&sOut, pIter->bIndirect, &rc);
6325 sessionAppendBlob(&sOut, aRec, nRec, &rc);
6327 if( rc==SQLITE_OK && xOutput && sOut.nBuf>sessions_strm_chunk_size ){
6328 rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
6329 sOut.nBuf = 0;
6331 if( rc ) break;
6334 if( rc!=SQLITE_OK ){
6335 sqlite3_free(sOut.aBuf);
6336 memset(&sOut, 0, sizeof(sOut));
6339 if( rc==SQLITE_OK ){
6340 if( xOutput ){
6341 if( sOut.nBuf>0 ){
6342 rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
6344 }else if( ppOut ){
6345 *ppOut = (void*)sOut.aBuf;
6346 *pnOut = sOut.nBuf;
6347 sOut.aBuf = 0;
6350 sqlite3_free(sOut.aBuf);
6351 return rc;
6355 ** Create a new rebaser object.
6357 int sqlite3rebaser_create(sqlite3_rebaser **ppNew){
6358 int rc = SQLITE_OK;
6359 sqlite3_rebaser *pNew;
6361 pNew = sqlite3_malloc(sizeof(sqlite3_rebaser));
6362 if( pNew==0 ){
6363 rc = SQLITE_NOMEM;
6364 }else{
6365 memset(pNew, 0, sizeof(sqlite3_rebaser));
6367 *ppNew = pNew;
6368 return rc;
6372 ** Call this one or more times to configure a rebaser.
6374 int sqlite3rebaser_configure(
6375 sqlite3_rebaser *p,
6376 int nRebase, const void *pRebase
6378 sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */
6379 int rc; /* Return code */
6380 rc = sqlite3changeset_start(&pIter, nRebase, (void*)pRebase);
6381 if( rc==SQLITE_OK ){
6382 rc = sessionChangesetToHash(pIter, &p->grp, 1);
6384 sqlite3changeset_finalize(pIter);
6385 return rc;
6389 ** Rebase a changeset according to current rebaser configuration
6391 int sqlite3rebaser_rebase(
6392 sqlite3_rebaser *p,
6393 int nIn, const void *pIn,
6394 int *pnOut, void **ppOut
6396 sqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */
6397 int rc = sqlite3changeset_start(&pIter, nIn, (void*)pIn);
6399 if( rc==SQLITE_OK ){
6400 rc = sessionRebase(p, pIter, 0, 0, pnOut, ppOut);
6401 sqlite3changeset_finalize(pIter);
6404 return rc;
6408 ** Rebase a changeset according to current rebaser configuration
6410 int sqlite3rebaser_rebase_strm(
6411 sqlite3_rebaser *p,
6412 int (*xInput)(void *pIn, void *pData, int *pnData),
6413 void *pIn,
6414 int (*xOutput)(void *pOut, const void *pData, int nData),
6415 void *pOut
6417 sqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */
6418 int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
6420 if( rc==SQLITE_OK ){
6421 rc = sessionRebase(p, pIter, xOutput, pOut, 0, 0);
6422 sqlite3changeset_finalize(pIter);
6425 return rc;
6429 ** Destroy a rebaser object
6431 void sqlite3rebaser_delete(sqlite3_rebaser *p){
6432 if( p ){
6433 sessionDeleteTable(0, p->grp.pList);
6434 sqlite3_free(p);
6439 ** Global configuration
6441 int sqlite3session_config(int op, void *pArg){
6442 int rc = SQLITE_OK;
6443 switch( op ){
6444 case SQLITE_SESSION_CONFIG_STRMSIZE: {
6445 int *pInt = (int*)pArg;
6446 if( *pInt>0 ){
6447 sessions_strm_chunk_size = *pInt;
6449 *pInt = sessions_strm_chunk_size;
6450 break;
6452 default:
6453 rc = SQLITE_MISUSE;
6454 break;
6456 return rc;
6459 #endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */