/ Check-in [6e5907e1]
Login

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

Overview
Comment:Fix a problem with resizing a hash table in sqlite3session.c.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1: 6e5907e14d3316d56313243c4f8ce8f14d0858fc
User & Date: dan 2011-03-19 16:26:12
Context
2011-03-19
17:07
Move session1.test from test/ to ext/session/. check-in: c4436a93 user: dan tags: sessions
16:26
Fix a problem with resizing a hash table in sqlite3session.c. check-in: 6e5907e1 user: dan tags: sessions
15:37
Fix some bugs in sqlite3changeset_apply(). check-in: 7250318d user: dan tags: sessions
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to ext/session/session2.test.

   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    115   foreach {tn sql} {
   116    116     1 { INSERT INTO t1 VALUES(1, 2) } 
          117  +
   117    118     2 {
   118    119       INSERT INTO t2 VALUES(1, NULL);
   119    120       INSERT INTO t2 VALUES(2, NULL);
   120    121       INSERT INTO t2 VALUES(3, NULL);
   121    122       DELETE FROM t2 WHERE a = 2;
   122    123       INSERT INTO t2 VALUES(4, NULL);
   123    124       UPDATE t2 SET b=0 WHERE b=1;
   124    125     } 
          126  +
   125    127     3 { INSERT INTO t3 SELECT *, NULL FROM t2 }
          128  +
   126    129     4 {
   127    130       INSERT INTO t3 SELECT a||a, b||b, NULL FROM t3;
   128    131       DELETE FROM t3 WHERE rowid%2;
   129    132     }
          133  +
   130    134     5 { UPDATE t3 SET c = a||b }
          135  +
   131    136     6 { UPDATE t1 SET a = 32 }
          137  +
          138  +  7 { 
          139  +    INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; --    2
          140  +    INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; --    4
          141  +    INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; --    8
          142  +    INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; --   16
          143  +    INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; --   32
          144  +    INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; --   64
          145  +    INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; --  128
          146  +    INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; --  256
          147  +    INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; --  512
          148  +    INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 1024
          149  +    INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 2048
          150  +    DELETE FROM t1 WHERE (rowid%3)==0;
          151  +  }
          152  +
   132    153   } {
   133    154     do_then_apply_sql $sql
   134    155     do_test $tn { compare_db db db2 } {}
   135    156   }
   136    157   
   137    158   finish_test
   138    159   

Changes to ext/session/sqlite3session.c.

   261    261       }
   262    262     }
   263    263   
   264    264     *pnWrite += nByte;
   265    265     return SQLITE_OK;
   266    266   }
   267    267   
   268         -#define HASH_APPEND(hash, add) ((hash) << 3) ^ (hash) ^ (int)(add)
   269         -static int sessionHashAppendI64(int h, i64 i){
          268  +#define HASH_APPEND(hash, add) ((hash) << 3) ^ (hash) ^ (unsigned int)(add)
          269  +static unsigned int sessionHashAppendI64(unsigned int h, i64 i){
   270    270     h = HASH_APPEND(h, i & 0xFFFFFFFF);
   271    271     return HASH_APPEND(h, (i>>32)&0xFFFFFFFF);
   272    272   }
   273         -static int sessionHashAppendBlob(int h, int n, const u8 *z){
          273  +static unsigned int sessionHashAppendBlob(unsigned int h, int n, const u8 *z){
   274    274     int i;
   275    275     for(i=0; i<n; i++) h = HASH_APPEND(h, z[i]);
   276    276     return h;
   277    277   }
   278    278   
   279    279   /*
   280         -** This function calculates a hash based on the primary key values of
   281         -** the old.* or new.* row currently available.
          280  +** This function may only be called from within a pre-update callback.
          281  +** It calculates a hash based on the primary key values of the old.* or 
          282  +** new.* row currently available. The value returned is guaranteed to
          283  +** be less than pTab->nBucket.
   282    284   */
   283         -static int sessionPreupdateHash(
          285  +static unsigned int sessionPreupdateHash(
   284    286     sqlite3 *db,                    /* Database handle */
   285    287     SessionTable *pTab,             /* Session table handle */
   286    288     int bNew,                       /* True to hash the new.* PK */
   287    289     int *piHash                     /* OUT: Hash value */
   288    290   ){
   289         -  int h = 0;
   290         -  int i;
          291  +  unsigned int h = 0;             /* Hash value to return */
          292  +  int i;                          /* Used to iterate through columns */
   291    293   
   292    294     assert( pTab->nCol==sqlite3_preupdate_count(db) );
   293    295     for(i=0; i<pTab->nCol; i++){
   294    296       if( pTab->abPK[i] ){
   295    297         int rc;
   296    298         int eType;
   297    299         sqlite3_value *pVal;
................................................................................
   331    333       }
   332    334     }
   333    335   
   334    336     *piHash = (h % pTab->nChange);
   335    337     return SQLITE_OK;
   336    338   }
   337    339   
   338         -static int sessionChangeHash(
   339         -  sqlite3 *db,
   340         -  SessionTable *pTab,
   341         -  SessionChange *pChange,
   342         -  int nBucket
          340  +/*
          341  +** Based on the primary key values stored in change pChange, calculate a
          342  +** hash key, assuming the has table has nBucket buckets. The hash keys
          343  +** calculated by this function are compatible with those calculated by
          344  +** sessionPreupdateHash().
          345  +*/
          346  +static unsigned int sessionChangeHash(
          347  +  sqlite3 *db,                    /* Database handle */
          348  +  SessionTable *pTab,             /* Table handle */
          349  +  SessionChange *pChange,         /* Change handle */
          350  +  int nBucket                     /* Assume this many buckets in hash table */
   343    351   ){
   344         -  int h = 0;
   345         -  int i;
   346         -  u8 *a = pChange->aRecord;
          352  +  unsigned int h = 0;             /* Value to return */
          353  +  int i;                          /* Used to iterate through columns */
          354  +  u8 *a = pChange->aRecord;       /* Used to iterate through change record */
   347    355   
   348    356     for(i=0; i<pTab->nCol; i++){
   349    357       int eType = *a++;
   350    358       int isPK = pTab->abPK[i];
   351    359   
   352    360       if( isPK ) h = HASH_APPEND(h, eType);
   353    361       switch( eType ){