/ Check-in [03c4f003]
Login

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

Overview
Comment:Revert the rearrangement of VDBE code in [219b39e14] so that vdbe.c matches trunk. Since the new call to sqlite3Init() in OP_ParseSchema was removed, the rearrangement no longer provides any performance advantage.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | reuse-schema
Files: files | file ages | folders
SHA3-256:03c4f00317233a34f29e1218786166d17837d47206532a29d2713093f01adea5
User & Date: dan 2019-02-15 11:54:57
Wiki:reuse-schema
Context
2019-02-15
19:00
Fix a problem with eponymous virtual tables and SHARED_SCHEMA databases. Also, after preparing statements that require all database schemas (REINDEX, ANALYZE, CREATE, DROP and some PRAGMA statements), do not allow the database connection to return more than one schema to each schema-pool. check-in: ecf6251e user: dan tags: reuse-schema
11:54
Revert the rearrangement of VDBE code in [219b39e14] so that vdbe.c matches trunk. Since the new call to sqlite3Init() in OP_ParseSchema was removed, the rearrangement no longer provides any performance advantage. check-in: 03c4f003 user: dan tags: reuse-schema
2019-02-14
21:04
Fix SQLITE_DBSTATUS_SCHEMA_USED so that it works with SQLITE_OPEN_SHARED_SCHEMA connections. check-in: d43b3c05 user: dan tags: reuse-schema
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

   408    408     }
   409    409     if( pMem->flags & (MEM_Str|MEM_Blob) ){
   410    410       return computeNumericType(pMem);
   411    411     }
   412    412     return 0;
   413    413   }
   414    414   
   415         -/*
   416         -** This is the implementation of the OP_ParseSchema opcode.  It is factored
   417         -** out of the main sqlite3VdbeExec() routine because it is not a performance-
   418         -** critical opcode and by factoring it out, it frees up registers in order
   419         -** to help the compiler optimizer do a better job with the other opcodes
   420         -** that are performance critical.
   421         -*/
   422         -static SQLITE_NOINLINE int parseSchemaOp(Vdbe *p, VdbeOp *pOp, sqlite3 *db){
   423         -  int iDb;
   424         -  const char *zMaster;
   425         -  char *zSql;
   426         -  InitData initData;
   427         -  int bRelease;
   428         -  int rc = SQLITE_OK;
   429         -
   430         -  /* Any prepared statement that invokes this opcode will hold mutexes
   431         -  ** on every btree.  This is a prerequisite for invoking 
   432         -  ** sqlite3InitCallback().
   433         -  */
   434         -#ifdef SQLITE_DEBUG
   435         -  for(iDb=0; iDb<db->nDb; iDb++){
   436         -    assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
   437         -  }
   438         -#endif
   439         -
   440         -  iDb = pOp->p1;
   441         -  assert( iDb>=0 && iDb<db->nDb );
   442         -  assert( DbHasProperty(db, iDb, DB_SchemaLoaded) );
   443         -
   444         -#ifndef SQLITE_OMIT_ALTERTABLE
   445         -  if( pOp->p4.z==0 ){
   446         -    assert( !IsReuseSchema(db) || iDb==1 );
   447         -    sqlite3SchemaClear(db->aDb[iDb].pSchema);
   448         -    db->mDbFlags &= ~DBFLAG_SchemaKnownOk;
   449         -    rc = sqlite3InitOne(db, iDb, &p->zErrMsg, INITFLAG_AlterTable);
   450         -    db->mDbFlags |= DBFLAG_SchemaChange;
   451         -    p->expired = 0;
   452         -  }else
   453         -#endif
   454         -  {
   455         -    zMaster = MASTER_NAME;
   456         -    initData.db = db;
   457         -    initData.iDb = iDb;
   458         -    initData.pzErrMsg = &p->zErrMsg;
   459         -    initData.mInitFlags = 0;
   460         -    zSql = sqlite3MPrintf(db,
   461         -       "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
   462         -       db->aDb[iDb].zDbSName, zMaster, pOp->p4.z);
   463         -    if( zSql==0 ){
   464         -      rc = SQLITE_NOMEM_BKPT;
   465         -    }else{
   466         -      assert( db->init.busy==0 );
   467         -      db->init.busy = 1;
   468         -      initData.rc = SQLITE_OK;
   469         -      initData.nInitRow = 0;
   470         -      assert( !db->mallocFailed );
   471         -      rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
   472         -      if( rc==SQLITE_OK ) rc = initData.rc;
   473         -      if( rc==SQLITE_OK && initData.nInitRow==0 ){
   474         -        /* The OP_ParseSchema opcode with a non-NULL P4 argument should parse
   475         -        ** at least one SQL statement. Any less than that indicates that
   476         -        ** the sqlite_master table is corrupt. */
   477         -        rc = SQLITE_CORRUPT_BKPT;
   478         -      }
   479         -      sqlite3DbFreeNN(db, zSql);
   480         -      db->init.busy = 0;
   481         -    }
   482         -  }
   483         -  return rc;
   484         -}
   485         -
   486    415   #ifdef SQLITE_DEBUG
   487    416   /*
   488    417   ** Write a nice string representation of the contents of cell pMem
   489    418   ** into buffer zBuf, length nBuf.
   490    419   */
   491    420   void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
   492    421     char *zCsr = zBuf;
................................................................................
  5813   5742   ** that match the WHERE clause P4.  If P4 is a NULL pointer, then the
  5814   5743   ** entire schema for P1 is reparsed.
  5815   5744   **
  5816   5745   ** This opcode invokes the parser to create a new virtual machine,
  5817   5746   ** then runs the new virtual machine.  It is thus a re-entrant opcode.
  5818   5747   */
  5819   5748   case OP_ParseSchema: {
  5820         -  rc = parseSchemaOp(p, pOp, db);
         5749  +  int iDb;
         5750  +  const char *zMaster;
         5751  +  char *zSql;
         5752  +  InitData initData;
         5753  +
         5754  +  /* Any prepared statement that invokes this opcode will hold mutexes
         5755  +  ** on every btree.  This is a prerequisite for invoking 
         5756  +  ** sqlite3InitCallback().
         5757  +  */
         5758  +#ifdef SQLITE_DEBUG
         5759  +  for(iDb=0; iDb<db->nDb; iDb++){
         5760  +    assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
         5761  +  }
         5762  +#endif
         5763  +
         5764  +  iDb = pOp->p1;
         5765  +  assert( iDb>=0 && iDb<db->nDb );
         5766  +  assert( DbHasProperty(db, iDb, DB_SchemaLoaded) );
         5767  +
         5768  +#ifndef SQLITE_OMIT_ALTERTABLE
         5769  +  if( pOp->p4.z==0 ){
         5770  +    sqlite3SchemaClear(db->aDb[iDb].pSchema);
         5771  +    db->mDbFlags &= ~DBFLAG_SchemaKnownOk;
         5772  +    rc = sqlite3InitOne(db, iDb, &p->zErrMsg, INITFLAG_AlterTable);
         5773  +    db->mDbFlags |= DBFLAG_SchemaChange;
         5774  +    p->expired = 0;
         5775  +  }else
         5776  +#endif
         5777  +  {
         5778  +    zMaster = MASTER_NAME;
         5779  +    initData.db = db;
         5780  +    initData.iDb = iDb;
         5781  +    initData.pzErrMsg = &p->zErrMsg;
         5782  +    initData.mInitFlags = 0;
         5783  +    zSql = sqlite3MPrintf(db,
         5784  +       "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
         5785  +       db->aDb[iDb].zDbSName, zMaster, pOp->p4.z);
         5786  +    if( zSql==0 ){
         5787  +      rc = SQLITE_NOMEM_BKPT;
         5788  +    }else{
         5789  +      assert( db->init.busy==0 );
         5790  +      db->init.busy = 1;
         5791  +      initData.rc = SQLITE_OK;
         5792  +      initData.nInitRow = 0;
         5793  +      assert( !db->mallocFailed );
         5794  +      rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
         5795  +      if( rc==SQLITE_OK ) rc = initData.rc;
         5796  +      if( rc==SQLITE_OK && initData.nInitRow==0 ){
         5797  +        /* The OP_ParseSchema opcode with a non-NULL P4 argument should parse
         5798  +        ** at least one SQL statement. Any less than that indicates that
         5799  +        ** the sqlite_master table is corrupt. */
         5800  +        rc = SQLITE_CORRUPT_BKPT;
         5801  +      }
         5802  +      sqlite3DbFreeNN(db, zSql);
         5803  +      db->init.busy = 0;
         5804  +    }
         5805  +  }
  5821   5806     if( rc ){
  5822   5807       sqlite3ResetAllSchemasOfConnection(db);
  5823   5808       if( rc==SQLITE_NOMEM ){
  5824   5809         goto no_mem;
  5825   5810       }
  5826   5811       goto abort_due_to_error;
  5827   5812     }