/ Check-in [825df75b]
Login

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

Overview
Comment:Fix a bug in changeset generation code.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1: 825df75ba453c853953e17ec29653e11c46f92bb
User & Date: dan 2011-03-19 18:46:16
Context
2011-03-19
19:19
Fix a problem involving session objects and attached databases. check-in: ad91d300 user: dan tags: sessions
18:46
Fix a bug in changeset generation code. check-in: 825df75b user: dan tags: sessions
17:07
Move session1.test from test/ to ext/session/. check-in: c4436a93 user: dan tags: sessions
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/session/session2.test.

   108    108   test_reset
   109    109   do_common_sql {
   110    110     CREATE TABLE t1(a PRIMARY KEY, b);
   111    111     CREATE TABLE t2(a, b INTEGER PRIMARY KEY);
   112    112     CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b));
   113    113   }
   114    114   
          115  +# Execute each of the following blocks of SQL on database [db1]. Collect
          116  +# changes using a session object. Apply the resulting changeset to
          117  +# database [db2]. Then check that the contents of the two databases are
          118  +# identical.
          119  +#
   115    120   foreach {tn sql} {
   116    121     1 { INSERT INTO t1 VALUES(1, 2) } 
   117    122   
   118    123     2 {
   119    124       INSERT INTO t2 VALUES(1, NULL);
   120    125       INSERT INTO t2 VALUES(2, NULL);
   121    126       INSERT INTO t2 VALUES(3, NULL);
................................................................................
   146    151       INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; --  256
   147    152       INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; --  512
   148    153       INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 1024
   149    154       INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 2048
   150    155       DELETE FROM t1 WHERE (rowid%3)==0;
   151    156     }
   152    157   
          158  +  8 {
          159  +    BEGIN;
          160  +      INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1;
          161  +    ROLLBACK;
          162  +  }
          163  +  9 {
          164  +    BEGIN;
          165  +      UPDATE t1 SET b = 'xxx';
          166  +    ROLLBACK;
          167  +  }
          168  +  10 {
          169  +    BEGIN;
          170  +      DELETE FROM t1 WHERE 1;
          171  +    ROLLBACK;
          172  +  }
   153    173   } {
          174  +if {$tn==9} breakpoint
   154    175     do_then_apply_sql $sql
   155    176     do_test $tn { compare_db db db2 } {}
   156    177   }
   157    178   
   158    179   finish_test
   159    180   

Changes to ext/session/sqlite3session.c.

  1111   1111     SessionChange *p,               /* Object containing old values */
  1112   1112     u8 *abPK,                       /* Boolean array - true for PK columns */
  1113   1113     int *pRc                        /* IN/OUT: Error code */
  1114   1114   ){
  1115   1115     if( *pRc==SQLITE_OK ){
  1116   1116       SessionBuffer buf2 = {0,0,0}; /* Buffer to accumulate new.* record in */
  1117   1117       int bNoop = 1;                /* Set to zero if any values are modified */
         1118  +    int nRewind = pBuf->nBuf;     /* Set to zero if any values are modified */
  1118   1119       int i;                        /* Used to iterate through columns */
  1119   1120       u8 *pCsr = p->aRecord;        /* Used to iterate through old.* values */
  1120   1121   
  1121   1122       sessionAppendByte(pBuf, SQLITE_UPDATE, pRc);
  1122   1123       for(i=0; i<sqlite3_column_count(pStmt); i++){
  1123   1124         int bChanged = 0;
  1124   1125         int nAdvance;
................................................................................
  1176   1177           sessionAppendByte(&buf2, 0, pRc);
  1177   1178         }
  1178   1179   
  1179   1180         pCsr += nAdvance;
  1180   1181       }
  1181   1182   
  1182   1183       if( bNoop ){
  1183         -      pBuf->nBuf -= (1 + sqlite3_column_count(pStmt));
         1184  +      pBuf->nBuf = nRewind;
  1184   1185       }else{
  1185   1186         sessionAppendBlob(pBuf, buf2.aBuf, buf2.nBuf, pRc);
  1186         -      sqlite3_free(buf2.aBuf);
  1187   1187       }
         1188  +    sqlite3_free(buf2.aBuf);
  1188   1189     }
  1189   1190   }
  1190   1191   
  1191   1192   static int sessionSelectStmt(
  1192   1193     sqlite3 *db,                    /* Database handle */
  1193   1194     const char *zTab,               /* Table name */
  1194   1195     int nCol,
................................................................................
  1310   1311     *ppChangeset = 0;
  1311   1312     rc = pSession->rc;
  1312   1313   
  1313   1314     for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
  1314   1315       if( pTab->nEntry ){
  1315   1316         int nCol = pTab->nCol;      /* Local copy of member variable */
  1316   1317         u8 *abPK = pTab->abPK;      /* Local copy of member variable */
  1317         -      int i;
  1318         -      sqlite3_stmt *pStmt = 0;
  1319         -      int bNoop = 1;
  1320         -      int nRewind = buf.nBuf;
         1318  +      int i;                      /* Used to iterate through hash buckets */
         1319  +      sqlite3_stmt *pSel = 0;     /* SELECT statement to query table pTab */
         1320  +      int nRewind = buf.nBuf;     /* Initial size of write buffer */
         1321  +      int nNoop;                  /* Size of buffer after writing tbl header */
  1321   1322   
  1322   1323         /* Write a table header */
  1323   1324         sessionAppendByte(&buf, 'T', &rc);
  1324   1325         sessionAppendVarint(&buf, nCol, &rc);
  1325   1326         sessionAppendBlob(&buf, (u8 *)pTab->zName, strlen(pTab->zName)+1, &rc);
  1326   1327   
  1327   1328         /* Build and compile a statement to execute: */
  1328   1329         if( rc==SQLITE_OK ){
  1329         -        rc = sessionSelectStmt(db, pTab->zName, nCol, pTab->azCol, abPK,&pStmt);
         1330  +        rc = sessionSelectStmt(db, pTab->zName, nCol, pTab->azCol, abPK, &pSel);
  1330   1331         }
  1331   1332   
  1332         -      if( rc==SQLITE_OK && nCol!=sqlite3_column_count(pStmt) ){
         1333  +      if( rc==SQLITE_OK && nCol!=sqlite3_column_count(pSel) ){
  1333   1334           rc = SQLITE_SCHEMA;
  1334   1335         }
  1335   1336   
         1337  +      nNoop = buf.nBuf;
  1336   1338         for(i=0; i<pTab->nChange; i++){
  1337   1339           SessionChange *p;         /* Used to iterate through changes */
  1338   1340   
  1339   1341           for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){
  1340         -          rc = sessionSelectBind(pStmt, nCol, abPK, p->aRecord, p->nRecord);
         1342  +          rc = sessionSelectBind(pSel, nCol, abPK, p->aRecord, p->nRecord);
  1341   1343             if( rc==SQLITE_OK ){
  1342         -            if( sqlite3_step(pStmt)==SQLITE_ROW ){
         1344  +            if( sqlite3_step(pSel)==SQLITE_ROW ){
  1343   1345                 int iCol;
  1344   1346                 if( p->bInsert ){
  1345   1347                   sessionAppendByte(&buf, SQLITE_INSERT, &rc);
  1346   1348                   for(iCol=0; iCol<nCol; iCol++){
  1347         -                  sessionAppendCol(&buf, pStmt, iCol, &rc);
         1349  +                  sessionAppendCol(&buf, pSel, iCol, &rc);
  1348   1350                   }
  1349   1351                 }else{
  1350         -                sessionAppendUpdate(&buf, pStmt, p, abPK, &rc);
         1352  +                sessionAppendUpdate(&buf, pSel, p, abPK, &rc);
  1351   1353                 }
  1352         -              bNoop = 0;
  1353   1354               }else if( !p->bInsert ){
  1354   1355                 /* A DELETE change */
  1355   1356                 sessionAppendByte(&buf, SQLITE_DELETE, &rc);
  1356   1357                 sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc);
  1357         -              bNoop = 0;
  1358   1358               }
  1359         -            rc = sqlite3_reset(pStmt);
         1359  +            rc = sqlite3_reset(pSel);
  1360   1360             }
  1361   1361           }
  1362   1362         }
  1363   1363   
  1364         -      sqlite3_finalize(pStmt);
         1364  +      sqlite3_finalize(pSel);
  1365   1365   
  1366         -      if( bNoop ){
         1366  +      if( buf.nBuf==nNoop ){
  1367   1367           buf.nBuf = nRewind;
  1368   1368         }
  1369   1369       }
  1370   1370     }
  1371   1371   
  1372   1372     if( rc==SQLITE_OK ){
  1373   1373       *pnChangeset = buf.nBuf;