Fix a bug in changeset generation code.

FossilOrigin-Name: 825df75ba453c853953e17ec29653e11c46f92bb
This commit is contained in:
dan 2011-03-19 18:46:15 +00:00
parent 4565faa990
commit 1f34f8cc71
4 changed files with 47 additions and 26 deletions

View File

@ -112,6 +112,11 @@ do_common_sql {
CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b)); CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b));
} }
# Execute each of the following blocks of SQL on database [db1]. Collect
# changes using a session object. Apply the resulting changeset to
# database [db2]. Then check that the contents of the two databases are
# identical.
#
foreach {tn sql} { foreach {tn sql} {
1 { INSERT INTO t1 VALUES(1, 2) } 1 { INSERT INTO t1 VALUES(1, 2) }
@ -150,7 +155,23 @@ foreach {tn sql} {
DELETE FROM t1 WHERE (rowid%3)==0; DELETE FROM t1 WHERE (rowid%3)==0;
} }
8 {
BEGIN;
INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1;
ROLLBACK;
}
9 {
BEGIN;
UPDATE t1 SET b = 'xxx';
ROLLBACK;
}
10 {
BEGIN;
DELETE FROM t1 WHERE 1;
ROLLBACK;
}
} { } {
if {$tn==9} breakpoint
do_then_apply_sql $sql do_then_apply_sql $sql
do_test $tn { compare_db db db2 } {} do_test $tn { compare_db db db2 } {}
} }

View File

@ -1115,6 +1115,7 @@ static void sessionAppendUpdate(
if( *pRc==SQLITE_OK ){ if( *pRc==SQLITE_OK ){
SessionBuffer buf2 = {0,0,0}; /* Buffer to accumulate new.* record in */ SessionBuffer buf2 = {0,0,0}; /* Buffer to accumulate new.* record in */
int bNoop = 1; /* Set to zero if any values are modified */ int bNoop = 1; /* Set to zero if any values are modified */
int nRewind = pBuf->nBuf; /* Set to zero if any values are modified */
int i; /* Used to iterate through columns */ int i; /* Used to iterate through columns */
u8 *pCsr = p->aRecord; /* Used to iterate through old.* values */ u8 *pCsr = p->aRecord; /* Used to iterate through old.* values */
@ -1180,11 +1181,11 @@ static void sessionAppendUpdate(
} }
if( bNoop ){ if( bNoop ){
pBuf->nBuf -= (1 + sqlite3_column_count(pStmt)); pBuf->nBuf = nRewind;
}else{ }else{
sessionAppendBlob(pBuf, buf2.aBuf, buf2.nBuf, pRc); sessionAppendBlob(pBuf, buf2.aBuf, buf2.nBuf, pRc);
sqlite3_free(buf2.aBuf);
} }
sqlite3_free(buf2.aBuf);
} }
} }
@ -1314,10 +1315,10 @@ int sqlite3session_changeset(
if( pTab->nEntry ){ if( pTab->nEntry ){
int nCol = pTab->nCol; /* Local copy of member variable */ int nCol = pTab->nCol; /* Local copy of member variable */
u8 *abPK = pTab->abPK; /* Local copy of member variable */ u8 *abPK = pTab->abPK; /* Local copy of member variable */
int i; int i; /* Used to iterate through hash buckets */
sqlite3_stmt *pStmt = 0; sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */
int bNoop = 1; int nRewind = buf.nBuf; /* Initial size of write buffer */
int nRewind = buf.nBuf; int nNoop; /* Size of buffer after writing tbl header */
/* Write a table header */ /* Write a table header */
sessionAppendByte(&buf, 'T', &rc); sessionAppendByte(&buf, 'T', &rc);
@ -1326,44 +1327,43 @@ int sqlite3session_changeset(
/* Build and compile a statement to execute: */ /* Build and compile a statement to execute: */
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
rc = sessionSelectStmt(db, pTab->zName, nCol, pTab->azCol, abPK,&pStmt); rc = sessionSelectStmt(db, pTab->zName, nCol, pTab->azCol, abPK, &pSel);
} }
if( rc==SQLITE_OK && nCol!=sqlite3_column_count(pStmt) ){ if( rc==SQLITE_OK && nCol!=sqlite3_column_count(pSel) ){
rc = SQLITE_SCHEMA; rc = SQLITE_SCHEMA;
} }
nNoop = buf.nBuf;
for(i=0; i<pTab->nChange; i++){ for(i=0; i<pTab->nChange; i++){
SessionChange *p; /* Used to iterate through changes */ SessionChange *p; /* Used to iterate through changes */
for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){ for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){
rc = sessionSelectBind(pStmt, nCol, abPK, p->aRecord, p->nRecord); rc = sessionSelectBind(pSel, nCol, abPK, p->aRecord, p->nRecord);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
if( sqlite3_step(pStmt)==SQLITE_ROW ){ if( sqlite3_step(pSel)==SQLITE_ROW ){
int iCol; int iCol;
if( p->bInsert ){ if( p->bInsert ){
sessionAppendByte(&buf, SQLITE_INSERT, &rc); sessionAppendByte(&buf, SQLITE_INSERT, &rc);
for(iCol=0; iCol<nCol; iCol++){ for(iCol=0; iCol<nCol; iCol++){
sessionAppendCol(&buf, pStmt, iCol, &rc); sessionAppendCol(&buf, pSel, iCol, &rc);
} }
}else{ }else{
sessionAppendUpdate(&buf, pStmt, p, abPK, &rc); sessionAppendUpdate(&buf, pSel, p, abPK, &rc);
} }
bNoop = 0;
}else if( !p->bInsert ){ }else if( !p->bInsert ){
/* A DELETE change */ /* A DELETE change */
sessionAppendByte(&buf, SQLITE_DELETE, &rc); sessionAppendByte(&buf, SQLITE_DELETE, &rc);
sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc); sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc);
bNoop = 0;
} }
rc = sqlite3_reset(pStmt); rc = sqlite3_reset(pSel);
} }
} }
} }
sqlite3_finalize(pStmt); sqlite3_finalize(pSel);
if( bNoop ){ if( buf.nBuf==nNoop ){
buf.nBuf = nRewind; buf.nBuf = nRewind;
} }
} }

View File

@ -1,5 +1,5 @@
C Move\ssession1.test\sfrom\stest/\sto\sext/session/. C Fix\sa\sbug\sin\schangeset\sgeneration\scode.
D 2011-03-19T17:07:58 D 2011-03-19T18:46:16
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -99,9 +99,9 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea
F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
F ext/session/session1.test 3f982c74ee4ba97069917cc35aae25b4ed858e6a w test/session1.test F ext/session/session1.test 3f982c74ee4ba97069917cc35aae25b4ed858e6a
F ext/session/session2.test 61c7ee56d158ab614b058b860508c85db2985810 F ext/session/session2.test 09cbe57d949a315c68fb59822314990fd0e2af33
F ext/session/sqlite3session.c 55ec4205c7a12e417c38743d81e229a31a0f7e25 F ext/session/sqlite3session.c 4cb15010040b093e452e6de52e8b5a9161032ebf
F ext/session/sqlite3session.h 9551c002efd5fde07c52994c6b592308e0df2d6a F ext/session/sqlite3session.h 9551c002efd5fde07c52994c6b592308e0df2d6a
F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
@ -921,7 +921,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P 6e5907e14d3316d56313243c4f8ce8f14d0858fc P c4436a936ab302aec3b7f41a4552f69ad5815744
R 611730f89810ada9d2f188c5b6da861b R 633c4c2a52a8f04fd2ba1fea02dc8ad5
U dan U dan
Z a6a229bf3ddc4c217d0e04afae66c6a2 Z 046a676deaa5ff1f82305a84f859a0a7

View File

@ -1 +1 @@
c4436a936ab302aec3b7f41a4552f69ad5815744 825df75ba453c853953e17ec29653e11c46f92bb