/ Check-in [f2930840]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix some bugs and other code issues in the session module.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1: f2930840e4af3d7d9cb199d316502932fcbbb867
User & Date: dan 2011-03-15 16:37:28
Context
2011-03-16
09:49
Remove the sqlite3_transaction_hook() API. check-in: b0015a1c user: dan tags: sessions
2011-03-15
16:37
Fix some bugs and other code issues in the session module. check-in: f2930840 user: dan tags: sessions
2011-03-14
19:49
Fix handling of return values from the conflict handler. Document the conflict handler arguments and return codes in sqlite3session.h. check-in: cbbb274e user: dan tags: sessions
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/session/sqlite3session.c.

     7      7   
     8      8   #include "sqliteInt.h"
     9      9   #include "vdbeInt.h"
    10     10   
    11     11   typedef struct RowChange RowChange;
    12     12   typedef struct SessionTable SessionTable;
    13     13   typedef struct SessionChange SessionChange;
           14  +typedef struct SessionBuffer SessionBuffer;
    14     15   
    15         -#if 0
    16         -#ifndef SQLITE_AMALGAMATION
    17         -typedef unsigned char u8;
    18         -typedef unsigned long u32;
    19         -typedef sqlite3_uint64 u64;
    20         -#endif
    21         -#endif
    22         -
           16  +/*
           17  +** Session handle structure.
           18  +*/
    23     19   struct sqlite3_session {
    24     20     sqlite3 *db;                    /* Database handle session is attached to */
    25     21     char *zDb;                      /* Name of database session is attached to */
           22  +  int bEnable;                    /* True if currently recording */
    26     23     int rc;                         /* Non-zero if an error has occurred */
    27     24     sqlite3_session *pNext;         /* Next session object on same db. */
    28     25     SessionTable *pTable;           /* List of attached tables */
    29     26   };
           27  +
           28  +/*
           29  +** Structure for changeset iterators.
           30  +*/
           31  +struct sqlite3_changeset_iter {
           32  +  u8 *aChangeset;                 /* Pointer to buffer containing changeset */
           33  +  int nChangeset;                 /* Number of bytes in aChangeset */
           34  +  u8 *pNext;                      /* Pointer to next change within aChangeset */
           35  +  int rc;                         /* Iterator error code */
           36  +  sqlite3_stmt *pConflict;        /* Points to conflicting row, if any */
           37  +  char *zTab;                     /* Current table */
           38  +  int nCol;                       /* Number of columns in zTab */
           39  +  int op;                         /* Current operation */
           40  +  sqlite3_value **apValue;        /* old.* and new.* values */
           41  +};
    30     42   
    31     43   /*
    32     44   ** Each session object maintains a set of the following structures, one
    33     45   ** for each table the session object is monitoring. The structures are
    34     46   ** stored in a linked list starting at sqlite3_session.pTable.
    35     47   **
    36     48   ** The keys of the SessionTable.aChange[] hash table are all rows that have
................................................................................
    41     53   ** a subset of the initial values that the modified row contained at the
    42     54   ** start of the session. Or no initial values if the row was inserted.
    43     55   */
    44     56   struct SessionTable {
    45     57     SessionTable *pNext;
    46     58     char *zName;                    /* Local name of table */
    47     59     int nCol;                       /* Number of columns in table zName */
    48         -
    49         -  /* Hash table of modified rows */
    50         -  int nEntry;                     /* NUmber of entries in hash table */
           60  +  int nEntry;                     /* Total number of entries in hash table */
    51     61     int nChange;                    /* Size of apChange[] array */
    52     62     SessionChange **apChange;       /* Hash table buckets */
    53     63   };
    54     64   
    55     65   /* 
    56     66   ** RECORD FORMAT:
    57     67   **
................................................................................
   120    130   struct SessionChange {
   121    131     sqlite3_int64 iKey;             /* Key value */
   122    132     int nRecord;                    /* Number of bytes in buffer aRecord[] */
   123    133     u8 *aRecord;                    /* Buffer containing old.* record */
   124    134     SessionChange *pNext;           /* For hash-table collisions */
   125    135   };
   126    136   
   127         -
   128         -static int sessionVarintPut(u8 *aBuf, u32 iVal){
   129         -  if( (iVal & ~0x7F)==0 ){
   130         -    if( aBuf ){
   131         -      aBuf[0] = (u8)iVal;
   132         -    }
   133         -    return 1;
   134         -  }
   135         -  if( (iVal & ~0x3FFF)==0 ){
   136         -    if( aBuf ){
   137         -      aBuf[0] = ((iVal >> 7) & 0x7F) | 0x80;
   138         -      aBuf[1] = iVal & 0x7F;
   139         -    }
   140         -    return 2;
   141         -  }
   142         -  if( aBuf ){
   143         -    aBuf[0] = ((iVal >> 28) & 0x7F) | 0x80;
   144         -    aBuf[1] = ((iVal >> 21) & 0x7F) | 0x80;
   145         -    aBuf[2] = ((iVal >> 14) & 0x7F) | 0x80;
   146         -    aBuf[3] = ((iVal >>  7) & 0x7F) | 0x80;
   147         -    aBuf[4] = iVal & 0x7F;
   148         -  }
   149         -  return 5;
   150         -}
   151         -
          137  +/*
          138  +** Instances of this structure are used to build strings or binary records.
          139  +*/
          140  +struct SessionBuffer {
          141  +  u8 *aBuf;                       /* Pointer to changeset buffer */
          142  +  int nBuf;                       /* Size of buffer aBuf */
          143  +  int nAlloc;                     /* Size of allocation containing aBuf */
          144  +};
          145  +
          146  +/*
          147  +** Write a varint with value iVal into the buffer at aBuf. Return the 
          148  +** number of bytes written.
          149  +*/
          150  +static int sessionVarintPut(u8 *aBuf, int iVal){
          151  +  return putVarint32(aBuf, iVal);
          152  +}
          153  +
          154  +/*
          155  +** Return the number of bytes required to store value iVal as a varint.
          156  +*/
          157  +static int sessionVarintLen(int iVal){
          158  +  return sqlite3VarintLen(iVal);
          159  +}
          160  +
          161  +/*
          162  +** Read a varint value from aBuf[] into *piVal. Return the number of 
          163  +** bytes read.
          164  +*/
   152    165   static int sessionVarintGet(u8 *aBuf, int *piVal){
   153         -  int ret;
   154         -  u64 v;
   155         -  ret = (int)sqlite3GetVarint(aBuf, &v);
   156         -  *piVal = (int)v;
   157         -  return ret;
          166  +  return getVarint32(aBuf, *piVal);
   158    167   }
   159    168   
          169  +/*
          170  +** Read a 64-bit big-endian integer value from buffer aRec[]. Return
          171  +** the value read.
          172  +*/
   160    173   static sqlite3_int64 sessionGetI64(u8 *aRec){
   161    174     return (((sqlite3_int64)aRec[0]) << 56)
   162    175          + (((sqlite3_int64)aRec[1]) << 48)
   163    176          + (((sqlite3_int64)aRec[2]) << 40)
   164    177          + (((sqlite3_int64)aRec[3]) << 32)
   165    178          + (((sqlite3_int64)aRec[4]) << 24)
   166    179          + (((sqlite3_int64)aRec[5]) << 16)
   167    180          + (((sqlite3_int64)aRec[6]) <<  8)
   168    181          + (((sqlite3_int64)aRec[7]) <<  0);
   169    182   }
          183  +
          184  +/*
          185  +** Write a 64-bit big-endian integer value to the buffer aBuf[].
          186  +*/
          187  +static void sessionPutI64(u8 *aBuf, sqlite3_int64 i){
          188  +  aBuf[0] = (i>>56) & 0xFF;
          189  +  aBuf[1] = (i>>48) & 0xFF;
          190  +  aBuf[2] = (i>>40) & 0xFF;
          191  +  aBuf[3] = (i>>32) & 0xFF;
          192  +  aBuf[4] = (i>>24) & 0xFF;
          193  +  aBuf[5] = (i>>16) & 0xFF;
          194  +  aBuf[6] = (i>> 8) & 0xFF;
          195  +  aBuf[7] = (i>> 0) & 0xFF;
          196  +}
   170    197   
   171    198   /*
   172    199   ** This function is used to serialize the contents of value pValue (see
   173    200   ** comment titled "RECORD FORMAT" above).
   174    201   **
   175    202   ** If it is non-NULL, the serialized form of the value is written to 
   176    203   ** buffer aBuf. *pnWrite is set to the number of bytes written before
................................................................................
   182    209   ** SQLITE_NOMEM is returned.
   183    210   */
   184    211   static int sessionSerializeValue(
   185    212     u8 *aBuf,                       /* If non-NULL, write serialized value here */
   186    213     sqlite3_value *pValue,          /* Value to serialize */
   187    214     int *pnWrite                    /* IN/OUT: Increment by bytes written */
   188    215   ){
   189         -  int eType; 
   190         -  int nByte;
          216  +  int eType;                      /* Value type (SQLITE_NULL, TEXT etc.) */
          217  +  int nByte;                      /* Size of serialized value in bytes */
   191    218   
   192    219     eType = sqlite3_value_type(pValue);
   193    220     if( aBuf ) aBuf[0] = eType;
   194    221   
   195    222     switch( eType ){
   196    223       case SQLITE_NULL: 
   197    224         nByte = 1;
................................................................................
   208    235             i = (u64)sqlite3_value_int64(pValue);
   209    236           }else{
   210    237             double r;
   211    238             assert( sizeof(double)==8 && sizeof(u64)==8 );
   212    239             r = sqlite3_value_double(pValue);
   213    240             memcpy(&i, &r, 8);
   214    241           }
   215         -        aBuf[1] = (i>>56) & 0xFF;
   216         -        aBuf[2] = (i>>48) & 0xFF;
   217         -        aBuf[3] = (i>>40) & 0xFF;
   218         -        aBuf[4] = (i>>32) & 0xFF;
   219         -        aBuf[5] = (i>>24) & 0xFF;
   220         -        aBuf[6] = (i>>16) & 0xFF;
   221         -        aBuf[7] = (i>> 8) & 0xFF;
   222         -        aBuf[8] = (i>> 0) & 0xFF;
          242  +        sessionPutI64(&aBuf[1], i);
   223    243         }
   224    244         nByte = 9; 
   225    245         break;
   226    246   
   227    247       case SQLITE_TEXT: 
   228    248       case SQLITE_BLOB: {
   229    249         int n = sqlite3_value_bytes(pValue);
   230         -      int nVarint = sessionVarintPut(0, n);
          250  +      int nVarint = sessionVarintLen(n);
   231    251         if( aBuf ){
   232    252           sessionVarintPut(&aBuf[1], n);
   233    253           memcpy(&aBuf[nVarint + 1], eType==SQLITE_TEXT ? 
   234    254               sqlite3_value_text(pValue) : sqlite3_value_blob(pValue), n
   235    255           );
   236    256         }
   237    257   
................................................................................
   294    314       pTab->nChange = nNew;
   295    315       pTab->apChange = apNew;
   296    316     }
   297    317   
   298    318     return SQLITE_OK;
   299    319   }
   300    320   
          321  +/*
          322  +** This function is only called from within a pre-update handler for a
          323  +** write to table pTab, part of session pSession. If this is the first
          324  +** write to this table, set the SessionTable.nCol variable to the number
          325  +** of columns in the table.
          326  +**
          327  +** Otherwise, if this is not the first time this table has been written
          328  +** to, check that the number of columns in the table has not changed. If
          329  +** it has not, return zero.
          330  +**
          331  +** If the number of columns in the table has changed since the last write
          332  +** was recorded, set the session error-code to SQLITE_SCHEMA and return
          333  +** non-zero. Users are not allowed to change the number of columns in a table
          334  +** for which changes are being recorded by the session module. If they do so, 
          335  +** it is an error.
          336  +*/
   301    337   static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){
   302    338     if( pTab->nCol==0 ){
   303    339       pTab->nCol = sqlite3_preupdate_count(pSession->db);
   304         -  }
   305         -
   306         -  if( pTab->nCol!=sqlite3_preupdate_count(pSession->db) ){
          340  +  }else if( pTab->nCol!=sqlite3_preupdate_count(pSession->db) ){
   307    341       pSession->rc = SQLITE_SCHEMA;
   308    342       return SQLITE_ERROR;
   309    343     }
   310         -
   311    344     return SQLITE_OK;
   312    345   }
   313    346   
   314    347   /*
   315    348   ** The 'pre-update' hook registered by this module with SQLite databases.
   316    349   */
   317    350   static void xPreUpdate(
................................................................................
   325    358   ){
   326    359     sqlite3_session *pSession;
   327    360     int nDb = strlen(zDb);
   328    361     int nName = strlen(zDb);
   329    362    
   330    363     for(pSession=(sqlite3_session *)pCtx; pSession; pSession=pSession->pNext){
   331    364       SessionTable *pTab;
          365  +
          366  +    /* If this session is already in the error-state, or if it is attached
          367  +    ** to a different database ("main", "temp" etc.), or if it is not 
          368  +    ** currently enabled, there is nothing to do. Skip to the next session
          369  +    ** object attached to this database. */
          370  +    if( pSession->bEnable==0 ) continue;
   332    371       if( pSession->rc ) continue;
   333    372       if( sqlite3_strnicmp(zDb, pSession->zDb, nDb+1) ) continue;
          373  +
   334    374       for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){
   335    375         if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ){
   336    376           SessionChange *pChange;
   337    377           SessionChange *pC;
   338    378           int iHash; 
   339    379           int rc = SQLITE_OK;
   340    380   
................................................................................
   361    401           ** all (if this is an INSERT). */
   362    402           if( op==SQLITE_INSERT ){
   363    403             pChange = (SessionChange *)sqlite3_malloc(sizeof(SessionChange));
   364    404             if( pChange ){
   365    405               memset(pChange, 0, sizeof(SessionChange));
   366    406             }
   367    407           }else{
   368         -          int nByte;            /* Number of bytes to allocate */
   369         -          int i;                /* Used to iterate through columns */
   370         -          sqlite3_value *pValue;
          408  +          int nByte;              /* Number of bytes to allocate */
          409  +          int i;                  /* Used to iterate through columns */
   371    410   
   372    411             /* Figure out how large an allocation is required */
   373    412             nByte = sizeof(SessionChange);
   374    413             for(i=0; i<pTab->nCol && rc==SQLITE_OK; i++){
   375         -            rc = sqlite3_preupdate_old(pSession->db, i, &pValue);
          414  +            sqlite3_value *p;     /* old.* value */
          415  +            rc = sqlite3_preupdate_old(pSession->db, i, &p);
   376    416               if( rc==SQLITE_OK ){
   377         -              rc = sessionSerializeValue(0, pValue, &nByte);
          417  +              rc = sessionSerializeValue(0, p, &nByte);
   378    418               }
   379    419             }
   380    420   
   381    421             /* Allocate the change object */
   382    422             pChange = (SessionChange *)sqlite3_malloc(nByte);
   383    423             if( !pChange ){
   384    424               rc = SQLITE_NOMEM;
................................................................................
   386    426               memset(pChange, 0, sizeof(SessionChange));
   387    427               pChange->aRecord = (u8 *)&pChange[1];
   388    428             }
   389    429   
   390    430             /* Populate the change object */
   391    431             nByte = 0;
   392    432             for(i=0; i<pTab->nCol && rc==SQLITE_OK; i++){
   393         -            rc = sqlite3_preupdate_old(pSession->db, i, &pValue);
          433  +            sqlite3_value *p;     /* old.* value */
          434  +            rc = sqlite3_preupdate_old(pSession->db, i, &p);
   394    435               if( rc==SQLITE_OK ){
   395         -              rc = sessionSerializeValue(
   396         -                  &pChange->aRecord[nByte], pValue, &nByte);
          436  +              rc = sessionSerializeValue(&pChange->aRecord[nByte], p, &nByte);
   397    437               }
   398    438             }
   399    439             pChange->nRecord = nByte;
   400    440           }
   401    441   
   402    442           /* If an error has occurred, mark the session object as failed. */
   403    443           if( rc!=SQLITE_OK ){
................................................................................
   406    446             return;
   407    447           }
   408    448   
   409    449           /* Add the change back to the hash-table */
   410    450           pChange->iKey = iKey2;
   411    451           pChange->pNext = pTab->apChange[iHash];
   412    452           pTab->apChange[iHash] = pChange;
          453  +        break;
   413    454         }
   414         -      break;
   415    455       }
   416    456     }
   417    457   }
   418    458   
   419    459   /*
   420    460   ** Create a session object. This session object will record changes to
   421    461   ** database zDb attached to connection db.
   422    462   */
   423    463   int sqlite3session_create(
   424    464     sqlite3 *db,                    /* Database handle */
   425    465     const char *zDb,                /* Name of db (e.g. "main") */
   426    466     sqlite3_session **ppSession     /* OUT: New session object */
   427    467   ){
   428         -  sqlite3_session *pNew;
   429         -  sqlite3_session *pOld;
          468  +  sqlite3_session *pNew;          /* Newly allocated session object */
          469  +  sqlite3_session *pOld;          /* Session object already attached to db */
   430    470     int nDb = strlen(zDb);          /* Length of zDb in bytes */
   431    471   
          472  +  /* Zero the output value in case an error occurs. */
   432    473     *ppSession = 0;
   433    474   
   434    475     /* Allocate and populate the new session object. */
   435    476     pNew = (sqlite3_session *)sqlite3_malloc(sizeof(sqlite3_session) + nDb + 1);
   436    477     if( !pNew ) return SQLITE_NOMEM;
   437    478     memset(pNew, 0, sizeof(sqlite3_session));
   438    479     pNew->db = db;
   439    480     pNew->zDb = (char *)&pNew[1];
          481  +  pNew->bEnable = 1;
   440    482     memcpy(pNew->zDb, zDb, nDb+1);
   441    483   
   442    484     /* Add the new session object to the linked list of session objects 
   443    485     ** attached to database handle $db. Do this under the cover of the db
   444    486     ** handle mutex.  */
   445    487     sqlite3_mutex_enter(sqlite3_db_mutex(db));
   446    488     pOld = (sqlite3_session*)sqlite3_preupdate_hook(db, xPreUpdate, (void*)pNew);
................................................................................
   455    497   ** Delete a session object previously allocated using sqlite3session_create().
   456    498   */
   457    499   void sqlite3session_delete(sqlite3_session *pSession){
   458    500     sqlite3 *db = pSession->db;
   459    501     sqlite3_session *pHead;
   460    502     sqlite3_session **pp;
   461    503   
          504  +  /* Unlink the session from the linked list of sessions attached to the
          505  +  ** database handle. Hold the db mutex while doing so.  */
   462    506     sqlite3_mutex_enter(sqlite3_db_mutex(db));
   463    507     pHead = (sqlite3_session*)sqlite3_preupdate_hook(db, 0, 0);
   464    508     for(pp=&pHead; (*pp)!=pSession; pp=&((*pp)->pNext));
   465    509     *pp = (*pp)->pNext;
   466    510     if( pHead ) sqlite3_preupdate_hook(db, xPreUpdate, (void *)pHead);
   467    511     sqlite3_mutex_leave(sqlite3_db_mutex(db));
   468    512   
          513  +  /* Delete all attached table objects. And the contents of their 
          514  +  ** associated hash-tables. */
   469    515     while( pSession->pTable ){
   470    516       int i;
   471    517       SessionTable *pTab = pSession->pTable;
   472    518       pSession->pTable = pTab->pNext;
   473    519       for(i=0; i<pTab->nChange; i++){
   474    520         SessionChange *p;
   475    521         SessionChange *pNext;
................................................................................
   478    524           sqlite3_free(p);
   479    525         }
   480    526       }
   481    527       sqlite3_free(pTab->apChange);
   482    528       sqlite3_free(pTab);
   483    529     }
   484    530   
          531  +  /* Free the session object itself. */
   485    532     sqlite3_free(pSession);
   486    533   }
   487    534   
   488    535   /*
   489    536   ** Attach a table to a session. All subsequent changes made to the table
   490    537   ** while the session object is enabled will be recorded.
   491    538   **
................................................................................
   493    540   ** not matter if the PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias)
   494    541   ** or not.
   495    542   */
   496    543   int sqlite3session_attach(
   497    544     sqlite3_session *pSession,      /* Session object */
   498    545     const char *zName               /* Table name */
   499    546   ){
   500         -  SessionTable *pTab;
   501         -  int nName;
          547  +  SessionTable *pTab;             /* New table object (if required) */
          548  +  int nName;                      /* Number of bytes in string zName */
   502    549   
   503    550     /* First search for an existing entry. If one is found, this call is
   504    551     ** a no-op. Return early. */
   505    552     nName = strlen(zName);
   506    553     for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){
   507    554       if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ){
   508    555         return SQLITE_OK;
................................................................................
   519    566     memcpy(pTab->zName, zName, nName+1);
   520    567     pTab->pNext = pSession->pTable;
   521    568     pSession->pTable = pTab;
   522    569   
   523    570     return SQLITE_OK;
   524    571   }
   525    572   
   526         -typedef struct SessionBuffer SessionBuffer;
   527         -struct SessionBuffer {
   528         -  u8 *aBuf;                       /* Pointer to changeset buffer */
   529         -  int nBuf;                       /* Size of buffer aBuf */
   530         -  int nAlloc;                     /* Size of allocation containing aBuf */
   531         -};
   532         -
          573  +/*
          574  +** Ensure that there is room in the buffer to append nByte bytes of data.
          575  +** If not, use sqlite3_realloc() to grow the buffer so that there is.
          576  +**
          577  +** If successful, return zero. Otherwise, if an OOM condition is encountered,
          578  +** set *pRc to SQLITE_NOMEM and return non-zero.
          579  +*/
   533    580   static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){
   534    581     if( p->nAlloc-p->nBuf<nByte ){
   535    582       u8 *aNew;
   536    583       int nNew = p->nAlloc ? p->nAlloc : 128;
   537    584       do {
   538    585         nNew = nNew*2;
   539    586       }while( nNew<(p->nAlloc+nByte) );
................................................................................
   545    592       }
   546    593       p->aBuf = aNew;
   547    594       p->nAlloc = nNew;
   548    595     }
   549    596     return 0;
   550    597   }
   551    598   
          599  +/*
          600  +** This function is a no-op if *pRc is other than SQLITE_OK when it is 
          601  +** called. Otherwise, append a single byte to the buffer. 
          602  +**
          603  +** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
          604  +** returning.
          605  +*/
   552    606   static void sessionAppendByte(SessionBuffer *p, u8 v, int *pRc){
   553    607     if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, 1, pRc) ){
   554    608       p->aBuf[p->nBuf++] = v;
   555    609     }
   556    610   }
   557    611   
          612  +/*
          613  +** This function is a no-op if *pRc is other than SQLITE_OK when it is 
          614  +** called. Otherwise, append a single varint to the buffer. 
          615  +**
          616  +** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
          617  +** returning.
          618  +*/
   558    619   static void sessionAppendVarint(SessionBuffer *p, sqlite3_int64 v, int *pRc){
   559    620     if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, 9, pRc) ){
   560    621       p->nBuf += sessionVarintPut(&p->aBuf[p->nBuf], v);
   561    622     }
   562    623   }
   563    624   
          625  +/*
          626  +** This function is a no-op if *pRc is other than SQLITE_OK when it is 
          627  +** called. Otherwise, append a blob of data to the buffer. 
          628  +**
          629  +** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
          630  +** returning.
          631  +*/
   564    632   static void sessionAppendBlob(
   565    633     SessionBuffer *p, 
   566    634     const u8 *aBlob, 
   567    635     int nBlob, 
   568    636     int *pRc
   569    637   ){
   570    638     if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, nBlob, pRc) ){
   571    639       memcpy(&p->aBuf[p->nBuf], aBlob, nBlob);
   572    640       p->nBuf += nBlob;
   573    641     }
   574    642   }
   575    643   
          644  +/*
          645  +** This function is a no-op if *pRc is other than SQLITE_OK when it is 
          646  +** called. Otherwise, append a string to the buffer. All bytes in the string
          647  +** up to (but not including) the nul-terminator are written to the buffer.
          648  +**
          649  +** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
          650  +** returning.
          651  +*/
   576    652   static void sessionAppendStr(
   577    653     SessionBuffer *p, 
   578    654     const char *zStr, 
   579    655     int *pRc
   580    656   ){
   581    657     int nStr = strlen(zStr);
   582    658     if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, nStr, pRc) ){
   583    659       memcpy(&p->aBuf[p->nBuf], zStr, nStr);
   584    660       p->nBuf += nStr;
   585    661     }
   586    662   }
   587    663   
          664  +/*
          665  +** This function is a no-op if *pRc is other than SQLITE_OK when it is 
          666  +** called. Otherwise, append the string representation of integer iVal
          667  +** to the buffer. No nul-terminator is written.
          668  +**
          669  +** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
          670  +** returning.
          671  +*/
   588    672   static void sessionAppendInteger(
   589         -  SessionBuffer *p, 
   590         -  int iVal,
   591         -  int *pRc
          673  +  SessionBuffer *p,               /* Buffer to append to */
          674  +  int iVal,                       /* Value to write the string rep. of */
          675  +  int *pRc                        /* IN/OUT: Error code */
   592    676   ){
   593    677     char aBuf[24];
   594    678     sqlite3_snprintf(sizeof(aBuf)-1, aBuf, "%d", iVal);
   595    679     sessionAppendStr(p, aBuf, pRc);
   596    680   }
   597    681   
          682  +/*
          683  +** This function is a no-op if *pRc is other than SQLITE_OK when it is 
          684  +** called. Otherwise, append the string zStr enclosed in quotes (") and
          685  +** with any embedded quote characters escaped to the buffer. No 
          686  +** nul-terminator byte is written.
          687  +**
          688  +** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before
          689  +** returning.
          690  +*/
   598    691   static void sessionAppendIdent(
   599         -  SessionBuffer *p, 
   600         -  const char *zStr, 
   601         -  int *pRc
          692  +  SessionBuffer *p,               /* Buffer to a append to */
          693  +  const char *zStr,               /* String to quote, escape and append */
          694  +  int *pRc                        /* IN/OUT: Error code */
   602    695   ){
   603    696     int nStr = strlen(zStr)*2 + 2 + 1;
   604    697     if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, nStr, pRc) ){
   605    698       char *zOut = (char *)&p->aBuf[p->nBuf];
   606    699       const char *zIn = zStr;
   607    700       *zOut++ = '"';
   608    701       while( *zIn ){
................................................................................
   610    703         *zOut++ = *(zIn++);
   611    704       }
   612    705       *zOut++ = '"';
   613    706       p->nBuf = ((u8 *)zOut - p->aBuf);
   614    707     }
   615    708   }
   616    709   
          710  +/*
          711  +** This function is a no-op if *pRc is other than SQLITE_OK when it is
          712  +** called. Otherwse, it appends the serialized version of the value stored
          713  +** in column iCol of the row that SQL statement pStmt currently points
          714  +** to to the buffer.
          715  +*/
   617    716   static void sessionAppendCol(
   618         -  SessionBuffer *p, 
   619         -  sqlite3_stmt *pStmt, 
   620         -  int iCol,
   621         -  int *pRc
          717  +  SessionBuffer *p,               /* Buffer to append to */
          718  +  sqlite3_stmt *pStmt,            /* Handle pointing to row containing value */
          719  +  int iCol,                       /* Column to read value from */
          720  +  int *pRc                        /* IN/OUT: Error code */
   622    721   ){
   623    722     if( *pRc==SQLITE_OK ){
   624    723       int eType = sqlite3_column_type(pStmt, iCol);
   625    724       sessionAppendByte(p, (u8)eType, pRc);
   626    725       if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
   627    726         sqlite3_int64 i;
   628    727         u8 aBuf[8];
   629    728         if( eType==SQLITE_INTEGER ){
   630    729           i = sqlite3_column_int64(pStmt, iCol);
   631    730         }else{
   632    731           double r = sqlite3_column_double(pStmt, iCol);
   633    732           memcpy(&i, &r, 8);
   634    733         }
   635         -      aBuf[0] = (i>>56) & 0xFF;
   636         -      aBuf[1] = (i>>48) & 0xFF;
   637         -      aBuf[2] = (i>>40) & 0xFF;
   638         -      aBuf[3] = (i>>32) & 0xFF;
   639         -      aBuf[4] = (i>>24) & 0xFF;
   640         -      aBuf[5] = (i>>16) & 0xFF;
   641         -      aBuf[6] = (i>> 8) & 0xFF;
   642         -      aBuf[7] = (i>> 0) & 0xFF;
          734  +      sessionPutI64(aBuf, i);
   643    735         sessionAppendBlob(p, aBuf, 8, pRc);
   644    736       }
   645    737       if( eType==SQLITE_BLOB || eType==SQLITE_TEXT ){
   646    738         int nByte = sqlite3_column_bytes(pStmt, iCol);
   647    739         sessionAppendVarint(p, nByte, pRc);
   648    740         sessionAppendBlob(p, eType==SQLITE_BLOB ? 
   649    741           sqlite3_column_blob(pStmt, iCol) : sqlite3_column_text(pStmt, iCol),
   650    742           nByte, pRc
   651    743         );
   652    744       }
   653    745     }
   654    746   }
   655    747   
          748  +/*
          749  +** This function is a no-op if *pRc is other than SQLITE_OK when it is
          750  +** called. 
          751  +**
          752  +** Otherwse, if *pRc is SQLITE_OK, then it appends an update change to
          753  +** the buffer (see the comments under "CHANGESET FORMAT" at the top of the
          754  +** file). An update change consists of:
          755  +**
          756  +**   1 byte:  SQLITE_UPDATE (0x17)
          757  +**   n bytes: old.* record (see RECORD FORMAT)
          758  +**   m bytes: new.* record (see RECORD FORMAT)
          759  +**
          760  +** The SessionChange object passed as the third argument contains the
          761  +** values that were stored in the row when the session began (the old.*
          762  +** values). The statement handle passed as the second argument points
          763  +** at the current version of the row (the new.* values).
          764  +**
          765  +** If all of the old.* values are equal to their corresponding new.* value
          766  +** (i.e. nothing has changed), then no data at all is appended to the buffer.
          767  +**
          768  +** Otherwise, the old.* record contains all primary key values and the 
          769  +** original values of any fields that have been modified. The new.* record 
          770  +** contains the new values of only those fields that have been modified.
          771  +*/ 
   656    772   static void sessionAppendUpdate(
   657         -  sqlite3_stmt *pStmt, 
   658         -  SessionBuffer *pBuf,
   659         -  SessionChange *p,
   660         -  u8 *abPK,
   661         -  int *pRc
          773  +  SessionBuffer *pBuf,            /* Buffer to append to */
          774  +  sqlite3_stmt *pStmt,            /* Statement handle pointing at new row */
          775  +  SessionChange *p,               /* Object containing old values */
          776  +  u8 *abPK,                       /* Boolean array - true for PK columns */
          777  +  int *pRc                        /* IN/OUT: Error code */
   662    778   ){
   663    779     if( *pRc==SQLITE_OK ){
   664         -    SessionBuffer buf2 = {0, 0, 0};
   665         -    int bNoop = 1;
   666         -    int i;
   667         -    u8 *pCsr = p->aRecord;
          780  +    SessionBuffer buf2 = {0,0,0}; /* Buffer to accumulate new.* record in */
          781  +    int bNoop = 1;                /* Set to zero if any values are modified */
          782  +    int i;                        /* Used to iterate through columns */
          783  +    u8 *pCsr = p->aRecord;        /* Used to iterate through old.* values */
          784  +
   668    785       sessionAppendByte(pBuf, SQLITE_UPDATE, pRc);
   669    786       for(i=0; i<sqlite3_column_count(pStmt); i++){
   670    787         int bChanged = 0;
   671    788         int nAdvance;
   672    789         int eType = *pCsr;
   673    790         switch( eType ){
   674    791           case SQLITE_NULL:
................................................................................
   731    848       }else{
   732    849         sessionAppendBlob(pBuf, buf2.aBuf, buf2.nBuf, pRc);
   733    850         sqlite3_free(buf2.aBuf);
   734    851       }
   735    852     }
   736    853   }
   737    854   
          855  +/*
          856  +** This function queries the database for the names of the columns of table
          857  +** zThis, in schema zDb. It is expected that the table has nCol columns. If
          858  +** not, SQLITE_SCHEMA is returned and none of the output variables are
          859  +** populated.
          860  +**
          861  +** Otherwise, if it is not NULL, variable *pzTab is set to point to a
          862  +** nul-terminated copy of the table name. *pazCol (if not NULL) is set to
          863  +** point to an array of pointers to column names. And *pabPK (again, if not
          864  +** NULL) is set to point to an array of booleans - true if the corresponding
          865  +** column is part of the primary key.
          866  +**
          867  +** For example, if the table is declared as:
          868  +**
          869  +**     CREATE TABLE tbl1(w, x, y, z, PRIMARY KEY(w, z));
          870  +**
          871  +** Then the three output variables are populated as follows:
          872  +**
          873  +**     *pzTab  = "tbl1"
          874  +**     *pazCol = {"w", "x", "y", "z"}
          875  +**     *pabPK  = {1, 0, 0, 1}
          876  +**
          877  +** All returned buffers are part of the same single allocation, which must
          878  +** be freed using sqlite3_free() by the caller. If pazCol was not NULL, then
          879  +** pointer *pazCol should be freed to release all memory. Otherwise, pointer
          880  +** *pabPK. It is illegal for both pazCol and pabPK to be NULL.
          881  +*/
   738    882   static int sessionTableInfo(
   739    883     sqlite3 *db,                    /* Database connection */
          884  +  const char *zDb,                /* Name of attached database (e.g. "main") */
   740    885     const char *zThis,              /* Table name */
   741    886     int nCol,                       /* Expected number of columns */
   742    887     const char **pzTab,             /* OUT: Copy of zThis */
   743    888     const char ***pazCol,           /* OUT: Array of column names for table */
   744    889     u8 **pabPK                      /* OUT: Array of booleans - true for PK col */
   745    890   ){
   746    891     char *zPragma;
................................................................................
   748    893     int rc;
   749    894     int nByte;
   750    895     int nDbCol = 0;
   751    896     int nThis;
   752    897     int i;
   753    898     u8 *pAlloc;
   754    899     u8 *pFree = 0;
   755         -
   756    900     char **azCol;
   757    901     u8 *abPK;
   758    902   
          903  +  assert( pazCol || pabPK );
          904  +
   759    905     nThis = strlen(zThis);
   760         -  zPragma = sqlite3_mprintf("PRAGMA main.table_info('%q')", zThis);
          906  +  zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
   761    907     if( !zPragma ) return SQLITE_NOMEM;
   762    908   
   763    909     rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0);
   764    910     sqlite3_free(zPragma);
   765    911     if( rc!=SQLITE_OK ) return rc;
   766    912   
   767    913     nByte = nThis + 1;
................................................................................
   809    955         }
   810    956         if( pabPK ) abPK[i] = sqlite3_column_int(pStmt, 5);
   811    957         i++;
   812    958       }
   813    959       rc = sqlite3_reset(pStmt);
   814    960     
   815    961     }
          962  +
          963  +  /* If successful, populate the output variables. Otherwise, zero them and
          964  +  ** free any allocation made. An error code will be returned in this case.
          965  +  */
   816    966     if( rc==SQLITE_OK ){
   817    967       if( pazCol ) *pazCol = (const char **)azCol;
   818    968       if( pabPK ) *pabPK = abPK;
   819    969     }else{
   820    970       if( pazCol ) *pazCol = 0;
   821    971       if( pabPK ) *pabPK = 0;
   822    972       if( pzTab ) *pzTab = 0;
   823    973       sqlite3_free(pFree);
   824    974     }
   825         -
   826    975     sqlite3_finalize(pStmt);
   827    976     return rc;
   828    977   }
   829    978   
   830    979   /*
   831    980   ** Obtain a changeset object containing all changes recorded by the 
   832    981   ** session object passed as the first argument.
................................................................................
   835    984   ** using sqlite3_free().
   836    985   */
   837    986   int sqlite3session_changeset(
   838    987     sqlite3_session *pSession,      /* Session object */
   839    988     int *pnChangeset,               /* OUT: Size of buffer at *ppChangeset */
   840    989     void **ppChangeset              /* OUT: Buffer containing changeset */
   841    990   ){
   842         -  sqlite3 *db = pSession->db;
   843         -  SessionTable *pTab;
   844         -  SessionBuffer buf = {0, 0, 0};
   845         -  int rc;
          991  +  sqlite3 *db = pSession->db;     /* Source database handle */
          992  +  SessionTable *pTab;             /* Used to iterate through attached tables */
          993  +  SessionBuffer buf = {0,0,0};    /* Buffer in which to accumlate changeset */
          994  +  int rc;                         /* Return code */
   846    995   
          996  +  /* Zero the output variables in case an error occurs. If this session
          997  +  ** object is already in the error state (sqlite3_session.rc != SQLITE_OK),
          998  +  ** this call will be a no-op.  */
   847    999     *pnChangeset = 0;
   848   1000     *ppChangeset = 0;
   849   1001     rc = pSession->rc;
   850   1002   
   851   1003     for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
   852   1004       if( pTab->nEntry ){
   853   1005         int i;
................................................................................
   875   1027         }
   876   1028   
   877   1029         if( rc==SQLITE_OK && pTab->nCol!=sqlite3_column_count(pStmt) ){
   878   1030           rc = SQLITE_SCHEMA;
   879   1031         }
   880   1032   
   881   1033         if( rc==SQLITE_OK ){
   882         -        rc = sessionTableInfo(db, pTab->zName, pTab->nCol, 0, 0, &abPK);
         1034  +        rc = sessionTableInfo(
         1035  +            db, pSession->zDb, pTab->zName, pTab->nCol, 0, 0, &abPK);
   883   1036         }
   884   1037   
   885   1038         for(i=0; i<pTab->nChange; i++){
   886   1039           SessionChange *p;
   887   1040           for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){
   888   1041             sqlite3_bind_int64(pStmt, 1, p->iKey);
   889   1042             if( sqlite3_step(pStmt)==SQLITE_ROW ){
   890   1043               int iCol;
   891   1044               if( p->aRecord ){
   892         -              sessionAppendUpdate(pStmt, &buf, p, abPK, &rc);
         1045  +              sessionAppendUpdate(&buf, pStmt, p, abPK, &rc);
   893   1046               }else{
   894   1047                 sessionAppendByte(&buf, SQLITE_INSERT, &rc);
   895   1048                 for(iCol=0; iCol<pTab->nCol; iCol++){
   896   1049                   sessionAppendCol(&buf, pStmt, iCol, &rc);
   897   1050                 }
   898   1051               }
   899   1052               bNoop = 0;
................................................................................
   918   1071   
   919   1072     if( rc==SQLITE_OK ){
   920   1073       *pnChangeset = buf.nBuf;
   921   1074       *ppChangeset = buf.aBuf;
   922   1075     }else{
   923   1076       sqlite3_free(buf.aBuf);
   924   1077     }
   925         -
   926   1078     return rc;
   927   1079   }
   928   1080   
         1081  +/*
         1082  +** Enable or disable the session object passed as the first argument.
         1083  +*/
   929   1084   int sqlite3session_enable(sqlite3_session *pSession, int bEnable){
   930         -  return bEnable;
         1085  +  if( bEnable>=0 ){
         1086  +    pSession->bEnable = bEnable;
         1087  +  }
         1088  +  return pSession->bEnable;
   931   1089   }
   932   1090   
   933         -/************************************************************************/
   934         -/************************************************************************/
   935         -/************************************************************************/
   936         -
   937         -struct sqlite3_changeset_iter {
   938         -  u8 *aChangeset;                 /* Pointer to buffer containing changeset */
   939         -  int nChangeset;                 /* Number of bytes in aChangeset */
   940         -  u8 *pNext;                      /* Pointer to next change within aChangeset */
   941         -  int rc;
   942         -
   943         -  sqlite3_stmt *pConflict;        /* Conflicting row, if any */
   944         -  char *zTab;                     /* Current table */
   945         -  int nCol;                       /* Number of columns in zTab */
   946         -  int op;                         /* Current operation */
   947         -  sqlite3_value **apValue;        /* old.* and new.* values */
   948         -};
   949         -
   950   1091   /*
   951   1092   ** Create an iterator used to iterate through the contents of a changeset.
   952   1093   */
   953   1094   int sqlite3changeset_start(
   954         -  sqlite3_changeset_iter **ppIter,
   955         -  int nChangeset, 
   956         -  void *pChangeset
         1095  +  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
         1096  +  int nChangeset,                 /* Size of buffer pChangeset in bytes */
         1097  +  void *pChangeset                /* Pointer to buffer containing changeset */
   957   1098   ){
   958   1099     sqlite3_changeset_iter *pRet;   /* Iterator to return */
   959   1100     int nByte;                      /* Number of bytes to allocate for iterator */
   960   1101   
   961         -  *ppIter = 0;
         1102  +  /* Zero the output variable in case an error occurs. */
         1103  +  *pp = 0;
   962   1104   
         1105  +  /* Allocate and initialize the iterator structure. */
   963   1106     nByte = sizeof(sqlite3_changeset_iter);
   964   1107     pRet = (sqlite3_changeset_iter *)sqlite3_malloc(nByte);
   965   1108     if( !pRet ) return SQLITE_NOMEM;
   966   1109     memset(pRet, 0, sizeof(sqlite3_changeset_iter));
   967         -
   968   1110     pRet->aChangeset = (u8 *)pChangeset;
   969   1111     pRet->nChangeset = nChangeset;
   970   1112     pRet->pNext = pRet->aChangeset;
   971   1113   
   972         -  *ppIter = pRet;
         1114  +  /* Populate the output variable and return success. */
         1115  +  *pp = pRet;
   973   1116     return SQLITE_OK;
   974   1117   }
   975   1118   
         1119  +/*
         1120  +** Deserialize a single record from a buffer in memory. See "RECORD FORMAT"
         1121  +** for details.
         1122  +**
         1123  +** When this function is called, *paChange points to the start of the record
         1124  +** to deserialize. Assuming no error occurs, *paChange is set to point to
         1125  +** one byte after the end of the same record before this function returns.
         1126  +**
         1127  +** If successful, each element of the apOut[] array (allocated by the caller)
         1128  +** is set to point to an sqlite3_value object containing the value read
         1129  +** from the corresponding position in the record. If that value is not
         1130  +** included in the record (i.e. because the record is part of an UPDATE change
         1131  +** and the field was not modified), the corresponding element of apOut[] is
         1132  +** set to NULL.
         1133  +**
         1134  +** It is the responsibility of the caller to free all sqlite_value structures
         1135  +** using sqlite3_free().
         1136  +**
         1137  +** If an error occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
         1138  +** The apOut[] array may have been partially populated in this case.
         1139  +*/
   976   1140   static int sessionReadRecord(
   977   1141     u8 **paChange,                  /* IN/OUT: Pointer to binary record */
   978   1142     int nCol,                       /* Number of values in record */
   979   1143     sqlite3_value **apOut           /* Write values to this array */
   980   1144   ){
   981         -  int i;
   982         -  u8 *aRec = *paChange;
         1145  +  int i;                          /* Used to iterate through columns */
         1146  +  u8 *aRec = *paChange;           /* Cursor for the serialized record */
   983   1147   
   984   1148     for(i=0; i<nCol; i++){
   985         -    int eType = *aRec++;
         1149  +    int eType = *aRec++;          /* Type of value (SQLITE_NULL, TEXT etc.) */
   986   1150       assert( !apOut || apOut[i]==0 );
   987   1151       if( eType ){
   988   1152         if( apOut ){
   989   1153           apOut[i] = sqlite3ValueNew(0);
   990   1154           if( !apOut[i] ) return SQLITE_NOMEM;
   991   1155         }
   992   1156   
................................................................................
  1028   1192   ** callback by changeset_apply().
  1029   1193   */
  1030   1194   int sqlite3changeset_next(sqlite3_changeset_iter *p){
  1031   1195     u8 *aChange;
  1032   1196     int i;
  1033   1197     u8 c;
  1034   1198   
         1199  +  /* If the iterator is in the error-state, return immediately. */
  1035   1200     if( p->rc!=SQLITE_OK ) return p->rc;
  1036   1201   
         1202  +  /* Free the current contents of p->apValue[]. */
  1037   1203     if( p->apValue ){
  1038   1204       for(i=0; i<p->nCol*2; i++){
  1039   1205         sqlite3ValueFree(p->apValue[i]);
  1040   1206       }
  1041   1207       memset(p->apValue, 0, sizeof(sqlite3_value*)*p->nCol*2);
  1042   1208     }
  1043   1209   
................................................................................
  1086   1252   
  1087   1253   /*
  1088   1254   ** The following three functions extract information on the current change
  1089   1255   ** from a changeset iterator. They may only be called after changeset_next()
  1090   1256   ** has returned SQLITE_ROW.
  1091   1257   */
  1092   1258   int sqlite3changeset_op(
  1093         -  sqlite3_changeset_iter *pIter,
         1259  +  sqlite3_changeset_iter *pIter,  /* Iterator handle */
  1094   1260     const char **pzTab,             /* OUT: Pointer to table name */
  1095   1261     int *pnCol,                     /* OUT: Number of columns in table */
  1096   1262     int *pOp                        /* OUT: SQLITE_INSERT, DELETE or UPDATE */
  1097   1263   ){
  1098   1264     *pOp = pIter->op;
  1099   1265     *pnCol = pIter->nCol;
  1100   1266     *pzTab = pIter->zTab;
  1101   1267     return SQLITE_OK;
  1102   1268   }
  1103   1269   
         1270  +/*
         1271  +** This function may only be called while the iterator is pointing to an
         1272  +** SQLITE_UPDATE or SQLITE_DELETE change (see sqlite3changeset_op()).
         1273  +** Otherwise, SQLITE_MISUSE is returned.
         1274  +**
         1275  +** It sets *ppValue to point to an sqlite3_value structure containing the
         1276  +** iVal'th value in the old.* record. Or, if that particular value is not
         1277  +** included in the record (because the change is an UPDATE and the field
         1278  +** was not modified and is not a PK column), set *ppValue to NULL.
         1279  +**
         1280  +** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is
         1281  +** not modified. Otherwise, SQLITE_OK.
         1282  +*/
  1104   1283   int sqlite3changeset_old(
  1105         -  sqlite3_changeset_iter *pIter,
  1106         -  int iVal,
         1284  +  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
         1285  +  int iVal,                       /* Index of old.* value to retrieve */
  1107   1286     sqlite3_value **ppValue         /* OUT: Old value (or NULL pointer) */
  1108   1287   ){
  1109   1288     if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_DELETE ){
  1110   1289       return SQLITE_MISUSE;
  1111   1290     }
  1112   1291     if( iVal<0 || iVal>=pIter->nCol ){
  1113   1292       return SQLITE_RANGE;
  1114   1293     }
  1115   1294     *ppValue = pIter->apValue[iVal];
  1116   1295     return SQLITE_OK;
  1117   1296   }
  1118   1297   
         1298  +/*
         1299  +** This function may only be called while the iterator is pointing to an
         1300  +** SQLITE_UPDATE or SQLITE_INSERT change (see sqlite3changeset_op()).
         1301  +** Otherwise, SQLITE_MISUSE is returned.
         1302  +**
         1303  +** It sets *ppValue to point to an sqlite3_value structure containing the
         1304  +** iVal'th value in the new.* record. Or, if that particular value is not
         1305  +** included in the record (because the change is an UPDATE and the field
         1306  +** was not modified), set *ppValue to NULL.
         1307  +**
         1308  +** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is
         1309  +** not modified. Otherwise, SQLITE_OK.
         1310  +*/
  1119   1311   int sqlite3changeset_new(
  1120         -  sqlite3_changeset_iter *pIter,
  1121         -  int iVal,
         1312  +  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
         1313  +  int iVal,                       /* Index of new.* value to retrieve */
  1122   1314     sqlite3_value **ppValue         /* OUT: New value (or NULL pointer) */
  1123   1315   ){
  1124   1316     if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_INSERT ){
  1125   1317       return SQLITE_MISUSE;
  1126   1318     }
  1127   1319     if( iVal<0 || iVal>=pIter->nCol ){
  1128   1320       return SQLITE_RANGE;
  1129   1321     }
  1130   1322     *ppValue = pIter->apValue[pIter->nCol+iVal];
  1131   1323     return SQLITE_OK;
  1132   1324   }
  1133   1325   
         1326  +/*
         1327  +** This function may only be called with a changeset iterator that has been
         1328  +** passed to an SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT 
         1329  +** conflict-handler function. Otherwise, SQLITE_MISUSE is returned.
         1330  +**
         1331  +** If successful, *ppValue is set to point to an sqlite3_value structure
         1332  +** containing the iVal'th value of the conflicting record.
         1333  +**
         1334  +** If value iVal is out-of-range or some other error occurs, an SQLite error
         1335  +** code is returned. Otherwise, SQLITE_OK.
         1336  +*/
  1134   1337   int sqlite3changeset_conflict(
  1135         -  sqlite3_changeset_iter *pIter,
  1136         -  int iVal,
         1338  +  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
         1339  +  int iVal,                       /* Index of conflict record value to fetch */
  1137   1340     sqlite3_value **ppValue         /* OUT: Value from conflicting row */
  1138   1341   ){
  1139   1342     if( !pIter->pConflict ){
  1140   1343       return SQLITE_MISUSE;
  1141   1344     }
  1142   1345     if( iVal<0 || iVal>=sqlite3_column_count(pIter->pConflict) ){
  1143   1346       return SQLITE_RANGE;
................................................................................
  1149   1352   /*
  1150   1353   ** Finalize an iterator allocated with sqlite3changeset_start().
  1151   1354   **
  1152   1355   ** This function may not be called on iterators passed to a conflict handler
  1153   1356   ** callback by changeset_apply().
  1154   1357   */
  1155   1358   int sqlite3changeset_finalize(sqlite3_changeset_iter *p){
  1156         -  int i;
  1157         -  int rc = p->rc;
         1359  +  int i;                          /* Used to iterate through p->apValue[] */
         1360  +  int rc = p->rc;                 /* Return code */
  1158   1361     for(i=0; i<p->nCol*2; i++) sqlite3ValueFree(p->apValue[i]);
  1159   1362     sqlite3_free(p->apValue);
  1160   1363     sqlite3_free(p);
  1161   1364     return rc;
  1162   1365   }
  1163   1366   
  1164   1367   /*
................................................................................
  1233   1436       }
  1234   1437     }
  1235   1438   
  1236   1439     *pnInverted = nChangeset;
  1237   1440     *ppInverted = (void *)aOut;
  1238   1441     return SQLITE_OK;
  1239   1442   }
  1240         -
  1241         -static void sessionUpdateDeleteWhere(
  1242         -  SessionBuffer *pBuf,            /* Buffer to append to */
  1243         -  int nCol,                       /* Number of entries in azCol and abPK */
  1244         -  const char **azCol,             /* Column names */
  1245         -  u8 *abPK,                       /* True for PK columns */ 
  1246         -  int *pRc                        /* IN/OUT: Error code */
  1247         -){
  1248         -  if( *pRc==SQLITE_OK ){
  1249         -    int i;
  1250         -    const char *zSep = "";
  1251         -
  1252         -    sessionAppendStr(pBuf, " WHERE ", pRc);
  1253         -
  1254         -    for(i=0; i<nCol; i++){
  1255         -      if( abPK[i] ){
  1256         -        sessionAppendStr(pBuf, zSep, pRc);
  1257         -        sessionAppendIdent(pBuf, azCol[i], pRc);
  1258         -        sessionAppendStr(pBuf, " = ?", pRc);
  1259         -        sessionAppendInteger(pBuf, i+1, pRc);
  1260         -        zSep = "AND ";
  1261         -      }
  1262         -    }
  1263         -
  1264         -    sessionAppendStr(pBuf, " AND (?", pRc);
  1265         -    sessionAppendInteger(pBuf, nCol+1, pRc);
  1266         -    sessionAppendStr(pBuf, " OR ", pRc);
  1267         -
  1268         -    zSep = "";
  1269         -    for(i=0; i<nCol; i++){
  1270         -      if( !abPK[i] ){
  1271         -        sessionAppendStr(pBuf, zSep, pRc);
  1272         -        sessionAppendIdent(pBuf, azCol[i], pRc);
  1273         -        sessionAppendStr(pBuf, " IS ?", pRc);
  1274         -        sessionAppendInteger(pBuf, i+1, pRc);
  1275         -        zSep = "AND ";
  1276         -      }
  1277         -    }
  1278         -    sessionAppendStr(pBuf, ")", pRc);
  1279         -  }
  1280         -}
  1281         -
  1282   1443   
  1283   1444   typedef struct SessionApplyCtx SessionApplyCtx;
  1284   1445   struct SessionApplyCtx {
  1285   1446     sqlite3 *db;
  1286   1447     sqlite3_stmt *pDelete;          /* DELETE statement */
  1287   1448     sqlite3_stmt *pUpdate;          /* DELETE statement */
  1288   1449     sqlite3_stmt *pInsert;          /* INSERT statement */
................................................................................
  1301   1462   ** The DELETE statement looks like this:
  1302   1463   **
  1303   1464   **     DELETE FROM x WHERE a = :1 AND c = :3 AND :5 OR (b IS :2 AND d IS :4)
  1304   1465   **
  1305   1466   ** Variable :5 (nCol+1) is a boolean. It should be set to 0 if we require
  1306   1467   ** matching b and d values, or 1 otherwise. The second case comes up if the
  1307   1468   ** conflict handler is invoked with NOTFOUND and returns CHANGESET_REPLACE.
         1469  +**
         1470  +** If successful, SQLITE_OK is returned and SessionApplyCtx.pDelete is left
         1471  +** pointing to the prepared version of the SQL statement.
  1308   1472   */
  1309   1473   static int sessionDeleteRow(
  1310   1474     sqlite3 *db,                    /* Database handle */
  1311   1475     const char *zTab,               /* Table name */
  1312   1476     SessionApplyCtx *p              /* Session changeset-apply context */
  1313   1477   ){
         1478  +  int i;
         1479  +  const char *zSep = "";
  1314   1480     int rc = SQLITE_OK;
  1315   1481     SessionBuffer buf = {0, 0, 0};
  1316   1482   
  1317   1483     sessionAppendStr(&buf, "DELETE FROM ", &rc);
  1318   1484     sessionAppendIdent(&buf, zTab, &rc);
  1319         -  sessionUpdateDeleteWhere(&buf, p->nCol, p->azCol, p->abPK, &rc);
         1485  +  sessionAppendStr(&buf, " WHERE ", &rc);
         1486  +
         1487  +  for(i=0; i<p->nCol; i++){
         1488  +    if( p->abPK[i] ){
         1489  +      sessionAppendStr(&buf, zSep, &rc);
         1490  +      sessionAppendIdent(&buf, p->azCol[i], &rc);
         1491  +      sessionAppendStr(&buf, " = ?", &rc);
         1492  +      sessionAppendInteger(&buf, i+1, &rc);
         1493  +      zSep = "AND ";
         1494  +    }
         1495  +  }
         1496  +
         1497  +  sessionAppendStr(&buf, " AND (?", &rc);
         1498  +  sessionAppendInteger(&buf, p->nCol+1, &rc);
         1499  +  sessionAppendStr(&buf, " OR ", &rc);
         1500  +
         1501  +  zSep = "";
         1502  +  for(i=0; i<p->nCol; i++){
         1503  +    if( !p->abPK[i] ){
         1504  +      sessionAppendStr(&buf, zSep, &rc);
         1505  +      sessionAppendIdent(&buf, p->azCol[i], &rc);
         1506  +      sessionAppendStr(&buf, " IS ?", &rc);
         1507  +      sessionAppendInteger(&buf, i+1, &rc);
         1508  +      zSep = "AND ";
         1509  +    }
         1510  +  }
         1511  +  sessionAppendStr(&buf, ")", &rc);
  1320   1512   
  1321   1513     if( rc==SQLITE_OK ){
  1322   1514       rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pDelete, 0);
  1323   1515     }
  1324   1516     sqlite3_free(buf.aBuf);
  1325   1517   
  1326   1518     return rc;
................................................................................
  1350   1542   **     ?(i*3+3)    The new.* value of the column, if any.
  1351   1543   **
  1352   1544   ** Also, a boolean flag that, if set to true, causes the statement to update
  1353   1545   ** a row even if the non-PK values do not match. This is required if the
  1354   1546   ** conflict-handler is invoked with CHANGESET_DATA and returns
  1355   1547   ** CHANGESET_REPLACE. This is variable "?(nCol*3+1)".
  1356   1548   **
         1549  +** If successful, SQLITE_OK is returned and SessionApplyCtx.pUpdate is left
         1550  +** pointing to the prepared version of the SQL statement.
  1357   1551   */
  1358   1552   static int sessionUpdateRow(
  1359   1553     sqlite3 *db,                    /* Database handle */
  1360   1554     const char *zTab,               /* Table name */
  1361   1555     SessionApplyCtx *p              /* Session changeset-apply context */
  1362   1556   ){
  1363   1557     int rc = SQLITE_OK;
................................................................................
  1416   1610       rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pUpdate, 0);
  1417   1611     }
  1418   1612     sqlite3_free(buf.aBuf);
  1419   1613   
  1420   1614     return rc;
  1421   1615   }
  1422   1616   
         1617  +/*
         1618  +** Formulate and prepare an SQL statement to query table zTab by primary
         1619  +** key. Assuming the following table structure:
         1620  +**
         1621  +**     CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
         1622  +**
         1623  +** The SELECT statement looks like this:
         1624  +**
         1625  +**     SELECT * FROM x WHERE a = ?1 AND c = ?3
         1626  +**
         1627  +** If successful, SQLITE_OK is returned and SessionApplyCtx.pSelect is left
         1628  +** pointing to the prepared version of the SQL statement.
         1629  +*/
  1423   1630   static int sessionSelectRow(
  1424   1631     sqlite3 *db,                    /* Database handle */
  1425   1632     const char *zTab,               /* Table name */
  1426   1633     SessionApplyCtx *p              /* Session changeset-apply context */
  1427   1634   ){
  1428   1635     int rc = SQLITE_OK;
  1429   1636     int i;
................................................................................
  1445   1652     if( rc==SQLITE_OK ){
  1446   1653       rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pSelect, 0);
  1447   1654     }
  1448   1655     sqlite3_free(buf.aBuf);
  1449   1656     return rc;
  1450   1657   }
  1451   1658   
         1659  +/*
         1660  +** Formulate and prepare an INSERT statement to add a record to table zTab.
         1661  +** For example:
         1662  +**
         1663  +**     INSERT INTO main."zTab" VALUES(?1, ?2, ?3 ...);
         1664  +**
         1665  +** If successful, SQLITE_OK is returned and SessionApplyCtx.pInsert is left
         1666  +** pointing to the prepared version of the SQL statement.
         1667  +*/
  1452   1668   static int sessionInsertRow(
  1453   1669     sqlite3 *db,                    /* Database handle */
  1454   1670     const char *zTab,               /* Table name */
  1455   1671     SessionApplyCtx *p              /* Session changeset-apply context */
  1456   1672   ){
  1457   1673     int rc = SQLITE_OK;
  1458   1674     int i;
................................................................................
  1469   1685     if( rc==SQLITE_OK ){
  1470   1686       rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pInsert, 0);
  1471   1687     }
  1472   1688     sqlite3_free(buf.aBuf);
  1473   1689     return rc;
  1474   1690   }
  1475   1691   
         1692  +/*
         1693  +** SQL statement pSelect is as generated by the sessionSelectRow() function.
         1694  +** This function binds the primary key values from the change that changeset
         1695  +** iterator pIter points to to the SELECT and attempts to seek to the table
         1696  +** entry. If a row is found, the SELECT statement left pointing at the row 
         1697  +** and SQLITE_ROW is returned. Otherwise, if no row is found and no error
         1698  +** has occured, the statement is reset and SQLITE_OK is returned. If an
         1699  +** error occurs, an SQLite error code is returned.
         1700  +**
         1701  +** If the iterator currently points to an INSERT record, bind values from the
         1702  +** new.* record to the SELECT statement. Or, if it points to a DELETE, bind
         1703  +** values from the old.* record. If the changeset iterator points to an
         1704  +** UPDATE, bind values from the new.* record, but use old.* values in place
         1705  +** of any undefined new.* values.
         1706  +*/
  1476   1707   static int sessionSeekToRow(
  1477   1708     sqlite3 *db,                    /* Database handle */
  1478   1709     sqlite3_changeset_iter *pIter,  /* Changeset iterator */
  1479   1710     u8 *abPK,                       /* Primary key flags array */
  1480   1711     sqlite3_stmt *pSelect           /* SELECT statement from sessionSelectRow() */
  1481   1712   ){
  1482         -  int rc = SQLITE_OK;
  1483         -
  1484         -  int i;
  1485         -  int nCol;
  1486         -  int op;
  1487         -  const char *zDummy;
         1713  +  int rc = SQLITE_OK;             /* Return code */
         1714  +  int i;                          /* Used to iterate through table columns */
         1715  +  int nCol;                       /* Number of columns in table */
         1716  +  int op;                         /* Changset operation (SQLITE_UPDATE etc.) */
         1717  +  const char *zDummy;             /* Unused */
  1488   1718   
  1489   1719     sqlite3changeset_op(pIter, &zDummy, &nCol, &op);
  1490   1720   
  1491   1721     for(i=0; rc==SQLITE_OK && i<nCol; i++){
  1492   1722       if( abPK[i] ){
  1493   1723         sqlite3_value *pVal = 0;
  1494   1724         if( op!=SQLITE_DELETE ){
................................................................................
  1507   1737       rc = sqlite3_step(pSelect);
  1508   1738       if( rc!=SQLITE_ROW ) rc = sqlite3_reset(pSelect);
  1509   1739     }
  1510   1740   
  1511   1741     return rc;
  1512   1742   }
  1513   1743   
         1744  +/*
         1745  +** Invoke the conflict handler for the change that the changeset iterator
         1746  +** currently points to.
         1747  +**
         1748  +** Argument eType must be either CHANGESET_DATA or CHANGESET_CONFLICT.
         1749  +** If argument pbReplace is NULL, then the type of conflict handler invoked
         1750  +** depends solely on eType, as follows:
         1751  +**
         1752  +**    eType value                 Value passed to xConflict
         1753  +**    -------------------------------------------------
         1754  +**    CHANGESET_DATA              CHANGESET_NOTFOUND
         1755  +**    CHANGESET_CONFLICT          CHANGESET_CONSTRAINT
         1756  +**
         1757  +** Or, if pbReplace is not NULL, then an attempt is made to find an existing
         1758  +** record with the same primary key as the record about to be deleted, updated
         1759  +** or inserted. If such a record can be found, it is available to the conflict
         1760  +** handler as the "conflicting" record. In this case the type of conflict
         1761  +** handler invoked is as follows:
         1762  +**
         1763  +**    eType value         PK Record found?   Value passed to xConflict
         1764  +**    ----------------------------------------------------------------
         1765  +**    CHANGESET_DATA      Yes                CHANGESET_DATA
         1766  +**    CHANGESET_DATA      No                 CHANGESET_NOTFOUND
         1767  +**    CHANGESET_CONFLICT  Yes                CHANGESET_CONFLICT
         1768  +**    CHANGESET_CONFLICT  No                 CHANGESET_CONSTRAINT
         1769  +**
         1770  +** If pbReplace is not NULL, and a record with a matching PK is found, and
         1771  +** the conflict handler function returns SQLITE_CHANGESET_REPLACE, *pbReplace
         1772  +** is set to non-zero before returning SQLITE_OK.
         1773  +**
         1774  +** If the conflict handler returns SQLITE_CHANGESET_ABORT, SQLITE_ABORT is
         1775  +** returned. Or, if the conflict handler returns an invalid value, 
         1776  +** SQLITE_MISUSE. If the conflict handler returns SQLITE_CHANGESET_OMIT,
         1777  +** this function returns SQLITE_OK.
         1778  +*/
  1514   1779   static int sessionConflictHandler(
  1515         -  int eType,
  1516         -  SessionApplyCtx *p,
         1780  +  int eType,                      /* Either CHANGESET_DATA or CONFLICT */
         1781  +  SessionApplyCtx *p,             /* changeset_apply() context */
  1517   1782     sqlite3_changeset_iter *pIter,  /* Changeset iterator */
  1518   1783     int(*xConflict)(void *, int, sqlite3_changeset_iter*),
  1519         -  void *pCtx,
  1520         -  int *pbReplace
         1784  +  void *pCtx,                     /* First argument for conflict handler */
         1785  +  int *pbReplace                  /* OUT: Set to true if PK row is found */
  1521   1786   ){
  1522         -  int res;
         1787  +  int res;                        /* Value returned by conflict handler */
  1523   1788     int rc;
  1524   1789     int nCol;
  1525   1790     int op;
  1526   1791     const char *zDummy;
  1527   1792   
  1528   1793     sqlite3changeset_op(pIter, &zDummy, &nCol, &op);
  1529   1794   
................................................................................
  1571   1836           break;
  1572   1837       }
  1573   1838     }
  1574   1839   
  1575   1840     return rc;
  1576   1841   }
  1577   1842   
         1843  +/*
         1844  +** Attempt to apply the change that the iterator passed as the first argument
         1845  +** currently points to to the database. If a conflict is encountered, invoke
         1846  +** the conflict handler callback.
         1847  +**
         1848  +** If argument pbRetry is NULL, then ignore any CHANGESET_DATA conflict. If
         1849  +** one is encountered, update or delete the row with the matching primary key
         1850  +** instead. Or, if pbRetry is not NULL and a CHANGESET_DATA conflict occurs,
         1851  +** invoke the conflict handler. If it returns CHANGESET_REPLACE, set *pbRetry
         1852  +** to true before returning. In this case the caller will invoke this function
         1853  +** again, this time with pbRetry set to NULL.
         1854  +**
         1855  +** If argument pbReplace is NULL and a CHANGESET_CONFLICT conflict is 
         1856  +** encountered invoke the conflict handler with CHANGESET_CONSTRAINT instead.
         1857  +** Or, if pbReplace is not NULL, invoke it with CHANGESET_CONFLICT. If such
         1858  +** an invocation returns SQLITE_CHANGESET_REPLACE, set *pbReplace to true
         1859  +** before retrying. In this case the caller attempts to remove the conflicting
         1860  +** row before invoking this function again, this time with pbReplace set 
         1861  +** to NULL.
         1862  +**
         1863  +** If any conflict handler returns SQLITE_CHANGESET_ABORT, this function
         1864  +** returns SQLITE_ABORT. Otherwise, if no error occurs, SQLITE_OK is 
         1865  +** returned.
         1866  +*/
  1578   1867   static int sessionApplyOneOp(
  1579         -  sqlite3_changeset_iter *pIter,
  1580         -  SessionApplyCtx *p,
         1868  +  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
         1869  +  SessionApplyCtx *p,             /* changeset_apply() context */
  1581   1870     int(*xConflict)(void *, int, sqlite3_changeset_iter *),
  1582         -  void *pCtx,
  1583         -  int *pbReplace,
  1584         -  int *pbRetry
         1871  +  void *pCtx,                     /* First argument for the conflict handler */
         1872  +  int *pbReplace,                 /* OUT: True to remove PK row and retry */
         1873  +  int *pbRetry                    /* OUT: True to retry. */
  1585   1874   ){
  1586   1875     const char *zDummy;
  1587   1876     int op;
  1588   1877     int nCol;
  1589   1878     int rc = SQLITE_OK;
  1590   1879   
  1591   1880     assert( p->pDelete && p->pUpdate && p->pInsert && p->pSelect );
................................................................................
  1698   1987         );
  1699   1988       }
  1700   1989     }
  1701   1990   
  1702   1991     return rc;
  1703   1992   }
  1704   1993   
         1994  +/*
         1995  +** Apply the changeset passed via pChangeset/nChangeset to the main database
         1996  +** attached to handle "db". Invoke the supplied conflict handler callback
         1997  +** to resolve any conflicts encountered while applying the change.
         1998  +*/
  1705   1999   int sqlite3changeset_apply(
  1706         -  sqlite3 *db,
  1707         -  int nChangeset,
  1708         -  void *pChangeset,
         2000  +  sqlite3 *db,                    /* Apply change to "main" db of this handle */
         2001  +  int nChangeset,                 /* Size of changeset in bytes */
         2002  +  void *pChangeset,               /* Changeset blob */
  1709   2003     int(*xConflict)(
  1710   2004       void *pCtx,                   /* Copy of fifth arg to _apply() */
  1711   2005       int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
  1712   2006       sqlite3_changeset_iter *p     /* Handle describing change and conflict */
  1713   2007     ),
  1714         -  void *pCtx
         2008  +  void *pCtx                      /* First argument passed to xConflict */
  1715   2009   ){
  1716         -  sqlite3_changeset_iter *pIter = 0;
  1717         -  int rc;
  1718         -  int rc2;
  1719         -
         2010  +  sqlite3_changeset_iter *pIter;  /* Iterator to skip through changeset */  
         2011  +  int rc;                         /* Return code */
  1720   2012     const char *zTab = 0;           /* Name of current table */
  1721   2013     int nTab = 0;                   /* Result of strlen(zTab) */
         2014  +  SessionApplyCtx sApply;         /* changeset_apply() context object */
  1722   2015   
  1723         -  SessionApplyCtx sApply;
  1724   2016     memset(&sApply, 0, sizeof(sApply));
  1725         -
  1726   2017     sqlite3changeset_start(&pIter, nChangeset, pChangeset);
  1727   2018   
  1728   2019     rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
  1729   2020     while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter) ){
  1730   2021       int nCol;
  1731   2022       int op;
  1732   2023       int bReplace = 0;
................................................................................
  1740   2031         sqlite3_finalize(sApply.pUpdate); 
  1741   2032         sqlite3_finalize(sApply.pInsert);
  1742   2033         sqlite3_finalize(sApply.pSelect);
  1743   2034         memset(&sApply, 0, sizeof(sApply));
  1744   2035         sApply.db = db;
  1745   2036         sApply.nCol = nCol;
  1746   2037   
  1747         -      rc = sessionTableInfo(db, zNew, nCol, &zTab, &sApply.azCol, &sApply.abPK);
         2038  +      rc = sessionTableInfo(
         2039  +          db, "main", zNew, nCol, &zTab, &sApply.azCol, &sApply.abPK);
  1748   2040   
  1749   2041         if( rc!=SQLITE_OK 
  1750   2042          || (rc = sessionSelectRow(db, zTab, &sApply))
  1751   2043          || (rc = sessionUpdateRow(db, zTab, &sApply))
  1752   2044          || (rc = sessionDeleteRow(db, zTab, &sApply))
  1753   2045          || (rc = sessionInsertRow(db, zTab, &sApply))
  1754   2046         ){
................................................................................
  1791   2083         }
  1792   2084         if( rc==SQLITE_OK ){
  1793   2085           rc = sqlite3_exec(db, "RELEASE replace_op", 0, 0, 0);
  1794   2086         }
  1795   2087       }
  1796   2088     }
  1797   2089   
  1798         -  rc2 = sqlite3changeset_finalize(pIter);
  1799         -  if( rc==SQLITE_OK ) rc = rc2;
         2090  +  if( rc==SQLITE_OK ){
         2091  +    rc = sqlite3changeset_finalize(pIter);
         2092  +  }else{
         2093  +    sqlite3changeset_finalize(pIter);
         2094  +  }
  1800   2095   
  1801   2096     if( rc==SQLITE_OK ){
  1802   2097       rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
  1803   2098     }else{
  1804   2099       sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0);
  1805   2100       sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
  1806   2101     }

Changes to ext/session/sqlite3session.h.

    65     65   );
    66     66   
    67     67   /*
    68     68   ** Delete a session object previously allocated using sqlite3session_create().
    69     69   */
    70     70   void sqlite3session_delete(sqlite3_session *pSession);
    71     71   
    72         -
    73     72   /*
    74     73   ** Create an iterator used to iterate through the contents of a changeset.
    75     74   */
    76     75   int sqlite3changeset_start(
    77     76     sqlite3_changeset_iter **ppIter,
    78     77     int nChangeset, 
    79     78     void *pChangeset
................................................................................
    91     90   
    92     91   /*
    93     92   ** The following three functions extract information on the current change
    94     93   ** from a changeset iterator. They may only be called after changeset_next()
    95     94   ** has returned SQLITE_ROW.
    96     95   */
    97     96   int sqlite3changeset_op(
    98         -  sqlite3_changeset_iter *pIter,      /* Iterator object */
    99         -  const char **pzTab,                 /* OUT: Pointer to table name */
   100         -  int *pnCol,                         /* OUT: Number of columns in table */
   101         -  int *pOp                            /* OUT: SQLITE_INSERT, DELETE or UPDATE */
           97  +  sqlite3_changeset_iter *pIter,  /* Iterator object */
           98  +  const char **pzTab,             /* OUT: Pointer to table name */
           99  +  int *pnCol,                     /* OUT: Number of columns in table */
          100  +  int *pOp                        /* OUT: SQLITE_INSERT, DELETE or UPDATE */
   102    101   );
   103         -
   104    102   int sqlite3changeset_old(
   105         -  sqlite3_changeset_iter *pIter,
   106         -  int iVal,
   107         -  sqlite3_value **ppValue             /* OUT: Old value (or NULL pointer) */
          103  +  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
          104  +  int iVal,                       /* Column number */
          105  +  sqlite3_value **ppValue         /* OUT: Old value (or NULL pointer) */
          106  +);
          107  +int sqlite3changeset_new(
          108  +  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
          109  +  int iVal,                       /* Column number */
          110  +  sqlite3_value **ppValue         /* OUT: New value (or NULL pointer) */
   108    111   );
   109    112   
   110         -int sqlite3changeset_new(
   111         -  sqlite3_changeset_iter *pIter,
   112         -  int iVal,
   113         -  sqlite3_value **ppValue             /* OUT: New value (or NULL pointer) */
   114         -);
   115    113   /*
   116    114   ** This function is only usable with sqlite3_changeset_iter objects passed
   117    115   ** to the xConflict callback by sqlite3changeset_apply(). It cannot be used
   118    116   ** with iterators created using sqlite3changeset_start().
   119    117   **
   120    118   ** It is used to access the "conflicting row" information available to the
   121    119   ** conflict handler if the second argument is either SQLITE_CHANGESET_DATA
   122    120   ** or SQLITE_CHANGESET_CONFLICT.
   123    121   */
   124    122   int sqlite3changeset_conflict(
   125         -  sqlite3_changeset_iter *pIter,
   126         -  int iVal,
          123  +  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
          124  +  int iVal,                       /* Column number */
   127    125     sqlite3_value **ppValue         /* OUT: Value from conflicting row */
   128    126   );
   129    127   
   130    128   
   131    129   /*
   132    130   ** Finalize an iterator allocated with sqlite3changeset_start().
   133    131   **
................................................................................
   149    147   **
   150    148   ** It is safe to execute SQL statements, including those that write to the
   151    149   ** table that the callback related to, from within the xConflict callback.
   152    150   ** This can be used to further customize the applications conflict
   153    151   ** resolution strategy.
   154    152   */
   155    153   int sqlite3changeset_apply(
   156         -  sqlite3 *db,
   157         -  int nChangeset,
   158         -  void *pChangeset,
          154  +  sqlite3 *db,                    /* Apply change to "main" db of this handle */
          155  +  int nChangeset,                 /* Size of changeset in bytes */
          156  +  void *pChangeset,               /* Changeset blob */
   159    157     int(*xConflict)(
   160    158       void *pCtx,                   /* Copy of fifth arg to _apply() */
   161    159       int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
   162    160       sqlite3_changeset_iter *p     /* Handle describing change and conflict */
   163    161     ),
   164         -  void *pCtx
          162  +  void *pCtx                      /* First argument passed to xConflict */
   165    163   );
   166    164   
   167    165   /* 
   168    166   ** Values passed as the second argument to a conflict-handler.
   169    167   **
   170    168   ** SQLITE_CHANGESET_DATA:
   171    169   **   The conflict handler is invoked with CHANGESET_DATA as the second argument

Changes to test/session1.test.

   287    287     {UPDATE t4 CONSTRAINT {i 7 i 8 i 9} {n {} {} {} {} {}}}
   288    288   }
   289    289   do_db2_test     3.3.4 { SELECT * FROM t4 } {0 2 3 4 5 7 7 8 9 x 11 12}
   290    290   do_execsql_test 3.3.5 { SELECT * FROM t4 } {-1 2 3 -1 5 6 {} 8 9 x 11 12}
   291    291   
   292    292   #-------------------------------------------------------------------------
   293    293   # This next block of tests verifies that values returned by the conflict
   294         -# handler are intepreted correctly. The following cases are tested:
   295         -#
   296         -#     Test case   Operation   Conflict   Return Code
   297         -#                 UPDATE      DATA       OMIT
   298         -#                 UPDATE      DATA       REPLACE
          294  +# handler are intepreted correctly.
   299    295   #
   300    296   
   301    297   proc test_reset {} {
   302    298     db close
   303    299     db2 close
   304    300     forcedelete test.db test.db2
   305    301     sqlite3 db test.db
................................................................................
   402    398       {DELETE d1 DATA {i 2 t two} {i 2 t TWO}}
   403    399     }
   404    400   
   405    401     set res(REPLACE) {1 one}
   406    402     set res(OMIT)    {1 one 2 TWO}
   407    403     do_db2_test 5.$tn.3 "SELECT * FROM d1" $res($conflict_return)
   408    404   }
          405  +
          406  +#-------------------------------------------------------------------------
          407  +# Test that two tables can be monitored by a single session object.
          408  +#
          409  +test_reset
          410  +set schema {
          411  +  CREATE TABLE t1(a COLLATE nocase PRIMARY KEY, b);
          412  +  CREATE TABLE t2(a, b PRIMARY KEY);
          413  +}
          414  +do_test 6.0 {
          415  +  execsql $schema db
          416  +  execsql $schema db2
          417  +  execsql {
          418  +    INSERT INTO t1 VALUES('a', 'b');
          419  +    INSERT INTO t2 VALUES('a', 'b');
          420  +  } db2
          421  +} {}
          422  +
          423  +set conflict_return ""
          424  +do_conflict_test 6.1 -tables {t1 t2} -sql {
          425  +  INSERT INTO t1 VALUES('1', '2');
          426  +  INSERT INTO t1 VALUES('A', 'B');
          427  +  INSERT INTO t2 VALUES('A', 'B');
          428  +} -conflicts {
          429  +  {INSERT t1 CONFLICT {t A t B} {t a t b}}
          430  +}
          431  +
          432  +do_db2_test 6.2 "SELECT * FROM t1" {a b 1 2}
          433  +do_db2_test 6.3 "SELECT * FROM t2" {a b A B}
   409    434   
   410    435   catch { db2 close }
   411    436   finish_test
   412    437