Index: ext/session/sqlite3session.c ================================================================== --- ext/session/sqlite3session.c +++ ext/session/sqlite3session.c @@ -3793,14 +3793,24 @@ } return rc; } +/* +** This function is called from within sqlite3changset_apply_v2() when +** a conflict is encountered and resolved using conflict resolution +** mode eType (either SQLITE_CHANGESET_OMIT or SQLITE_CHANGESET_REPLACE).. +** It adds a conflict resolution record to the buffer in +** SessionApplyCtx.rebase, which will eventually be returned to the caller +** of apply_v2() as the "rebase" buffer. +** +** Return SQLITE_OK if successful, or an SQLite error code otherwise. +*/ static int sessionRebaseAdd( - SessionApplyCtx *p, - int eType, - sqlite3_changeset_iter *pIter + SessionApplyCtx *p, /* Apply context */ + int eType, /* Conflict resolution (OMIT or REPLACE) */ + sqlite3_changeset_iter *pIter /* Iterator pointing at current change */ ){ int rc = SQLITE_OK; int i; int eOp = pIter->op; if( p->bRebaseStarted==0 ){ @@ -4397,10 +4407,14 @@ sqlite3_free((char*)sApply.rebase.aBuf); sqlite3_mutex_leave(sqlite3_db_mutex(db)); return rc; } +/* +** Apply the changeset passed via pChangeset/nChangeset to the main +** database attached to handle "db". +*/ int sqlite3changeset_apply_v2( sqlite3 *db, /* Apply change to "main" db of this handle */ int nChangeset, /* Size of changeset in bytes */ void *pChangeset, /* Changeset blob */ int(*xFilter)( @@ -5015,49 +5029,33 @@ }; /* ** Buffers a1 and a2 must both contain a sessions module record nCol ** fields in size. This function appends an nCol sessions module -** record to buffer pBuf that is a copy of a1, except that: -** -** + If bUndefined is 0, for each field that is not "undefined" in either -** a1[] or a2[], swap in the field from a2[]. -** -** + If bUndefined is 1, for each field that is "undefined" in a1[] -** swap in the field from a2[]. +** record to buffer pBuf that is a copy of a1, except that for +** each field that is undefined in a1[], swap in the field from a2[]. */ static void sessionAppendRecordMerge( - SessionBuffer *pBuf, - int nCol, - int bUndefined, - u8 *a1, int n1, - u8 *a2, int n2, - int *pRc + SessionBuffer *pBuf, /* Buffer to append to */ + int nCol, /* Number of columns in each record */ + u8 *a1, int n1, /* Record 1 */ + u8 *a2, int n2, /* Record 2 */ + int *pRc /* IN/OUT: error code */ ){ sessionBufferGrow(pBuf, n1+n2, pRc); if( *pRc==SQLITE_OK ){ int i; u8 *pOut = &pBuf->aBuf[pBuf->nBuf]; for(i=0; ibIndirect==0 ){ u8 *pCsr = aRec; sessionSkipRecord(&pCsr, pIter->nCol); sessionAppendByte(&sOut, SQLITE_INSERT, &rc); sessionAppendByte(&sOut, pIter->bIndirect, &rc); - sessionAppendRecordMerge(&sOut, pIter->nCol, 1, + sessionAppendRecordMerge(&sOut, pIter->nCol, pCsr, nRec-(pCsr-aRec), pChange->aRecord, pChange->nRecord, &rc ); } }else{ @@ -5207,11 +5205,11 @@ assert( pIter->op==SQLITE_DELETE ); bDone = 1; if( pChange->op==SQLITE_INSERT ){ sessionAppendByte(&sOut, SQLITE_DELETE, &rc); sessionAppendByte(&sOut, pIter->bIndirect, &rc); - sessionAppendRecordMerge(&sOut, pIter->nCol, 1, + sessionAppendRecordMerge(&sOut, pIter->nCol, pChange->aRecord, pChange->nRecord, aRec, nRec, &rc ); } break; }