/ Check-in [53220ad7]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Fix for sqlite3_table_column_metadata() on REUSE_SCHEMA databases.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | reuse-schema
Files: files | file ages | folders
SHA3-256: 53220ad7809954eb4118d9127849efa82787f43898af00c9127cd4998a12c619
User & Date: dan 2019-02-13 19:17:30
Wiki:reuse-schema
Context
2019-02-14
15:47
Add missing comments and fix other code issues in the new functions in callback.c. check-in: 441cabb6 user: dan tags: reuse-schema
2019-02-13
19:17
Fix for sqlite3_table_column_metadata() on REUSE_SCHEMA databases. check-in: 53220ad7 user: dan tags: reuse-schema
18:29
Avoid crashing after parsing a corrupt schema with a REUSE_SCHEMA connection. check-in: b102148e user: dan tags: reuse-schema
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/main.c.

  3600   3600     const char *zColumnName,    /* Column name */
  3601   3601     char const **pzDataType,    /* OUTPUT: Declared data type */
  3602   3602     char const **pzCollSeq,     /* OUTPUT: Collation sequence name */
  3603   3603     int *pNotNull,              /* OUTPUT: True if NOT NULL constraint exists */
  3604   3604     int *pPrimaryKey,           /* OUTPUT: True if column part of PK */
  3605   3605     int *pAutoinc               /* OUTPUT: True if column is auto-increment */
  3606   3606   ){
  3607         -  int rc;
         3607  +  int rc = SQLITE_OK;
  3608   3608     char *zErrMsg = 0;
  3609   3609     Table *pTab = 0;
  3610   3610     Column *pCol = 0;
  3611   3611     int iCol = 0;
  3612   3612     char const *zDataType = 0;
  3613   3613     char const *zCollSeq = 0;
  3614   3614     int notnull = 0;
  3615   3615     int primarykey = 0;
  3616   3616     int autoinc = 0;
         3617  +  int bUnlock;
  3617   3618   
  3618   3619   
  3619   3620   #ifdef SQLITE_ENABLE_API_ARMOR
  3620   3621     if( !sqlite3SafetyCheckOk(db) || zTableName==0 ){
  3621   3622       return SQLITE_MISUSE_BKPT;
  3622   3623     }
  3623   3624   #endif
  3624   3625   
  3625   3626     /* Ensure the database schema has been loaded */
  3626   3627     sqlite3_mutex_enter(db->mutex);
         3628  +  bUnlock = sqlite3LockReusableSchema(db);
  3627   3629     sqlite3BtreeEnterAll(db);
  3628         -  rc = sqlite3Init(db, &zErrMsg);
         3630  +  if( IsReuseSchema(db)==0 ){
         3631  +    rc = sqlite3Init(db, &zErrMsg);
         3632  +  }
  3629   3633     if( SQLITE_OK!=rc ){
  3630   3634       goto error_out;
  3631   3635     }
         3636  +
  3632   3637   
  3633   3638     /* Locate the table in question */
  3634   3639     pTab = sqlite3FindTable(db, zTableName, zDbName);
  3635   3640     if( !pTab || pTab->pSelect ){
  3636   3641       pTab = 0;
  3637   3642       goto error_out;
  3638   3643     }
................................................................................
  3700   3705       zErrMsg = sqlite3MPrintf(db, "no such table column: %s.%s", zTableName,
  3701   3706           zColumnName);
  3702   3707       rc = SQLITE_ERROR;
  3703   3708     }
  3704   3709     sqlite3ErrorWithMsg(db, rc, (zErrMsg?"%s":0), zErrMsg);
  3705   3710     sqlite3DbFree(db, zErrMsg);
  3706   3711     rc = sqlite3ApiExit(db, rc);
         3712  +  sqlite3UnlockReusableSchema(db, bUnlock);
  3707   3713     sqlite3_mutex_leave(db->mutex);
  3708   3714     return rc;
  3709   3715   }
  3710   3716   
  3711   3717   /*
  3712   3718   ** Sleep for a little while.  Return the amount of time slept.
  3713   3719   */

Changes to src/vdbe.c.

   459    459       initData.mInitFlags = 0;
   460    460       zSql = sqlite3MPrintf(db,
   461    461          "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
   462    462          db->aDb[iDb].zDbSName, zMaster, pOp->p4.z);
   463    463       if( zSql==0 ){
   464    464         rc = SQLITE_NOMEM_BKPT;
   465    465       }else{
   466         -      bRelease = sqlite3LockReusableSchema(db);
   467         -      if( IsReuseSchema(db) ){
   468         -        rc = sqlite3Init(db, &p->zErrMsg);
   469         -        if( rc ){
   470         -          sqlite3UnlockReusableSchema(db, bRelease);
   471         -          return rc;
   472         -        }
   473         -      }
   474    466         assert( db->init.busy==0 );
   475    467         db->init.busy = 1;
   476    468         initData.rc = SQLITE_OK;
   477    469         initData.nInitRow = 0;
   478    470         assert( !db->mallocFailed );
   479    471         rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
   480         -      sqlite3UnlockReusableSchema(db, bRelease);
   481    472         if( rc==SQLITE_OK ) rc = initData.rc;
   482    473         if( rc==SQLITE_OK && initData.nInitRow==0 ){
   483    474           /* The OP_ParseSchema opcode with a non-NULL P4 argument should parse
   484    475           ** at least one SQL statement. Any less than that indicates that
   485    476           ** the sqlite_master table is corrupt. */
   486    477           rc = SQLITE_CORRUPT_BKPT;
   487    478         }

Changes to test/reuse2.test.

   283    283     set res
   284    284   } {database_1 database_2 database_3 database_4 database_5}
   285    285   
   286    286   do_execsql_test -db db2 5.1.2 {
   287    287     SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;
   288    288   } {nref=6 nschema=1}
   289    289   
          290  +do_test 5.2.1 {
          291  +  sqlite3_table_column_metadata db2 main bbb a
          292  +} {INTEGER BINARY 0 1 0}
          293  +do_test 5.2.2 {
          294  +  sqlite3_table_column_metadata db2 main bbb b
          295  +} {{} BINARY 0 0 0}
          296  +
          297  +do_execsql_test -db db2 5.2.3 {
          298  +  SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool ORDER BY 1;
          299  +} {nref=6 nschema=1}
   290    300   
   291    301   finish_test
   292    302