/ Check-in [34f0f96f]
Login

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

Overview
Comment:Fix a problem with the incrblob API and reusable schemas.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | reuse-schema
Files: files | file ages | folders
SHA3-256:34f0f96f47040df1e305ac9fd4664c5ed4246580e22a00573c73d6528a5725b5
User & Date: dan 2019-02-13 15:51:07
Wiki:reuse-schema
Context
2019-02-13
18:29
Avoid crashing after parsing a corrupt schema with a REUSE_SCHEMA connection. check-in: b102148e user: dan tags: reuse-schema
15:51
Fix a problem with the incrblob API and reusable schemas. check-in: 34f0f96f user: dan tags: reuse-schema
14:06
Rearrange the code in the VDBE to help out the C-compiler optimizer. And fix a harmless compiler warning. check-in: 219b39e1 user: drh tags: reuse-schema
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbeblob.c.

   128    128     int nAttempt = 0;
   129    129     int iCol;               /* Index of zColumn in row-record */
   130    130     int rc = SQLITE_OK;
   131    131     char *zErr = 0;
   132    132     Table *pTab;
   133    133     Incrblob *pBlob = 0;
   134    134     Parse sParse;
          135  +  int bUnlock;            /* True to unlock reusable schemas before returning */
   135    136   
   136    137   #ifdef SQLITE_ENABLE_API_ARMOR
   137    138     if( ppBlob==0 ){
   138    139       return SQLITE_MISUSE_BKPT;
   139    140     }
   140    141   #endif
   141    142     *ppBlob = 0;
................................................................................
   144    145       return SQLITE_MISUSE_BKPT;
   145    146     }
   146    147   #endif
   147    148     wrFlag = !!wrFlag;                /* wrFlag = (wrFlag ? 1 : 0); */
   148    149   
   149    150     sqlite3_mutex_enter(db->mutex);
   150    151   
          152  +  bUnlock = sqlite3LockReusableSchema(db);
   151    153     pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob));
   152    154     do {
   153    155       memset(&sParse, 0, sizeof(Parse));
   154    156       if( !pBlob ) goto blob_open_out;
   155    157       sParse.db = db;
   156    158       sqlite3DbFree(db, zErr);
   157    159       zErr = 0;
................................................................................
   327    329       if( db->mallocFailed ){
   328    330         goto blob_open_out;
   329    331       }
   330    332       rc = blobSeekToRow(pBlob, iRow, &zErr);
   331    333     } while( (++nAttempt)<SQLITE_MAX_SCHEMA_RETRY && rc==SQLITE_SCHEMA );
   332    334   
   333    335   blob_open_out:
          336  +  sqlite3UnlockReusableSchema(db, bUnlock);
   334    337     if( rc==SQLITE_OK && db->mallocFailed==0 ){
   335    338       *ppBlob = (sqlite3_blob *)pBlob;
   336    339     }else{
   337    340       if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt);
   338    341       sqlite3DbFree(db, pBlob);
   339    342     }
   340    343     sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);

Changes to test/reuse2.test.

   242    242   }
   243    243   
   244    244   do_execsql_test -db db2 4.3.6 {
   245    245     SELECT * FROM db5.x1, db4.x1, db1.x1;
   246    246     SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;
   247    247   } {26 17 18 13 14 15 4 5 6 nref=6 nschema=3}
   248    248   
   249         -finish_test
          249  +#--------------------------------------------------------------------------
          250  +# Test the incremental-blob API with REUSE_SCHEMA connections.
          251  +#
          252  +catch {db1 close}
          253  +catch {db2 close}
          254  +catch {db3 close}
          255  +reset_db
          256  +do_execsql_test 5.0.1 {
          257  +  CREATE TABLE bbb(a INTEGER PRIMARY KEY, b);
          258  +}
          259  +db close
          260  +do_test 5.0.2 {
          261  +  sqlite3 db2 test.db -reuse-schema 1
          262  +  register_schemapool_module db2
          263  +  for {set i 1} {$i<6} {incr i} {
          264  +    forcedelete test.db${i}-journal test.db${i}-wal test.db${i}-wal2 
          265  +    forcecopy test.db test.db${i}
          266  +    sqlite3 db test.db${i}
          267  +    db eval { INSERT INTO bbb VALUES(123, 'database_' || $i) }
          268  +    db close
          269  +    db2 eval "ATTACH 'test.db${i}' AS db${i}"
          270  +  }
          271  +  execsql {
          272  +    SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;
          273  +  } db2
          274  +} {nref=6 nschema=1}
          275  +
          276  +do_test 5.1.1 {
          277  +  set res [list]
          278  +  for {set i 1} {$i<6} {incr i} {
          279  +    set chan [db2 incrblob db${i} bbb b 123]
          280  +    lappend res [gets $chan]
          281  +    close $chan
          282  +  }
          283  +  set res
          284  +} {database_1 database_2 database_3 database_4 database_5}
          285  +
          286  +do_execsql_test -db db2 5.1.2 {
          287  +  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;
          288  +} {nref=6 nschema=1}
          289  +
   250    290   
          291  +finish_test
   251    292