/ Check-in [a7bc7752]
Login

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

Overview
Comment:Defer schema resets when the query planner is running. Proposed fix for ticket [be436a7f4587ce517].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:a7bc7752ba0266684f5317e424a4ee9add4af002272082183519e708ab9ffc79
User & Date: drh 2017-08-17 02:26:35
Context
2017-08-17
14:12
Add test cases for ticket [be436a7f4587ce517] using virtual table modules fts5 and rtree. check-in: 2101b420 user: dan tags: trunk
02:26
Defer schema resets when the query planner is running. Proposed fix for ticket [be436a7f4587ce517]. check-in: a7bc7752 user: drh tags: trunk
2017-08-16
19:20
Avoid a test for CURTYPE_BTREE in sqlite3VdbeCursorMoveto() in order to reduce the size and improve the performance of OP_Column. check-in: f078deb2 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

510
511
512
513
514
515
516
517

518
519
520

521
522
523
524
525
526
527
528
529

530
531
532
533
534
535

536
537
538


539
540
541
542
543
544
545
546
547

548
549
550
551
552
553
554
....
2151
2152
2153
2154
2155
2156
2157



2158
2159
2160
2161
2162
2163
2164

2165


2166
2167
2168
2169
2170
2171
2172
    sqlite3DbFree(db, db->aDb);
    db->aDb = db->aDbStatic;
  }
}

/*
** Reset the schema for the database at index iDb.  Also reset the
** TEMP schema.

*/
void sqlite3ResetOneSchema(sqlite3 *db, int iDb){
  Db *pDb;

  assert( iDb<db->nDb );

  /* Case 1:  Reset the single schema identified by iDb */
  pDb = &db->aDb[iDb];
  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  assert( pDb->pSchema!=0 );
  sqlite3SchemaClear(pDb->pSchema);

  /* If any database other than TEMP is reset, then also reset TEMP

  ** since TEMP might be holding triggers that reference tables in the
  ** other database.
  */
  if( iDb!=1 ){
    pDb = &db->aDb[1];
    assert( pDb->pSchema!=0 );

    sqlite3SchemaClear(pDb->pSchema);
  }
  return;


}

/*
** Erase all schema information from all attached databases (including
** "main" and "temp") for a single database connection.
*/
void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
  int i;
  sqlite3BtreeEnterAll(db);

  for(i=0; i<db->nDb; i++){
    Db *pDb = &db->aDb[i];
    if( pDb->pSchema ){
      sqlite3SchemaClear(pDb->pSchema);
    }
  }
  db->mDbFlags &= ~DBFLAG_SchemaChange;
................................................................................
*/
int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
  Table *pSelTab;   /* A fake table from which we get the result set */
  Select *pSel;     /* Copy of the SELECT that implements the view */
  int nErr = 0;     /* Number of errors encountered */
  int n;            /* Temporarily holds the number of cursors assigned */
  sqlite3 *db = pParse->db;  /* Database connection for malloc errors */



#ifndef SQLITE_OMIT_AUTHORIZATION
  sqlite3_xauth xAuth;       /* Saved xAuth pointer */
#endif

  assert( pTable );

#ifndef SQLITE_OMIT_VIRTUALTABLE

  if( sqlite3VtabCallConnect(pParse, pTable) ){


    return SQLITE_ERROR;
  }
  if( IsVirtual(pTable) ) return 0;
#endif

#ifndef SQLITE_OMIT_VIEW
  /* A positive nCol means the columns names for this view are







|
>


<
>


<
|
|
|
|
|
<
>
|
|
<
<
<
<
>
|
|
<
>
>









>







 







>
>
>







>
|
>
>







510
511
512
513
514
515
516
517
518
519
520

521
522
523

524
525
526
527
528

529
530
531




532
533
534

535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
....
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
    sqlite3DbFree(db, db->aDb);
    db->aDb = db->aDbStatic;
  }
}

/*
** Reset the schema for the database at index iDb.  Also reset the
** TEMP schema.  The reset is deferred if db->nSchemaLock is not zero.
** Deferred resets may be run by calling with iDb<0.
*/
void sqlite3ResetOneSchema(sqlite3 *db, int iDb){

  int i;
  assert( iDb<db->nDb );


  if( iDb>=0 ){
    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
    DbSetProperty(db, iDb, DB_ResetWanted);
    DbSetProperty(db, 1, DB_ResetWanted);
  }


  if( db->nSchemaLock==0 ){
    for(i=0; i<db->nDb; i++){




      if( DbHasProperty(db, i, DB_ResetWanted) ){
        sqlite3SchemaClear(db->aDb[i].pSchema);
      }

    }
  }
}

/*
** Erase all schema information from all attached databases (including
** "main" and "temp") for a single database connection.
*/
void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
  int i;
  sqlite3BtreeEnterAll(db);
  assert( db->nSchemaLock==0 );
  for(i=0; i<db->nDb; i++){
    Db *pDb = &db->aDb[i];
    if( pDb->pSchema ){
      sqlite3SchemaClear(pDb->pSchema);
    }
  }
  db->mDbFlags &= ~DBFLAG_SchemaChange;
................................................................................
*/
int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
  Table *pSelTab;   /* A fake table from which we get the result set */
  Select *pSel;     /* Copy of the SELECT that implements the view */
  int nErr = 0;     /* Number of errors encountered */
  int n;            /* Temporarily holds the number of cursors assigned */
  sqlite3 *db = pParse->db;  /* Database connection for malloc errors */
#ifndef SQLITE_OMIT_VIRTUALTABLE	
  int rc;
#endif
#ifndef SQLITE_OMIT_AUTHORIZATION
  sqlite3_xauth xAuth;       /* Saved xAuth pointer */
#endif

  assert( pTable );

#ifndef SQLITE_OMIT_VIRTUALTABLE
  db->nSchemaLock++;
  rc = sqlite3VtabCallConnect(pParse, pTable);
  db->nSchemaLock--;
  if( rc ){
    return SQLITE_ERROR;
  }
  if( IsVirtual(pTable) ) return 0;
#endif

#ifndef SQLITE_OMIT_VIEW
  /* A positive nCol means the columns names for this view are

Changes to src/callback.c.

453
454
455
456
457
458
459
460
461

462
463
464
465
466
467
468
    sqlite3DeleteTable(0, pTab);
  }
  sqlite3HashClear(&temp1);
  sqlite3HashClear(&pSchema->fkeyHash);
  pSchema->pSeqTab = 0;
  if( pSchema->schemaFlags & DB_SchemaLoaded ){
    pSchema->iGeneration++;
    pSchema->schemaFlags &= ~DB_SchemaLoaded;
  }

}

/*
** Find and return the schema associated with a BTree.  Create
** a new one if necessary.
*/
Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){







<

>







453
454
455
456
457
458
459

460
461
462
463
464
465
466
467
468
    sqlite3DeleteTable(0, pTab);
  }
  sqlite3HashClear(&temp1);
  sqlite3HashClear(&pSchema->fkeyHash);
  pSchema->pSeqTab = 0;
  if( pSchema->schemaFlags & DB_SchemaLoaded ){
    pSchema->iGeneration++;

  }
  pSchema->schemaFlags &= ~(DB_SchemaLoaded|DB_ResetWanted);
}

/*
** Find and return the schema associated with a BTree.  Create
** a new one if necessary.
*/
Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){

Changes to src/prepare.c.

682
683
684
685
686
687
688
689

690
691
692
693
694
695
696
  *ppStmt = 0;
  if( !sqlite3SafetyCheckOk(db)||zSql==0 ){
    return SQLITE_MISUSE_BKPT;
  }
  sqlite3_mutex_enter(db->mutex);
  sqlite3BtreeEnterAll(db);
  rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
  if( rc==SQLITE_SCHEMA ){

    sqlite3_finalize(*ppStmt);
    rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
  }
  sqlite3BtreeLeaveAll(db);
  sqlite3_mutex_leave(db->mutex);
  assert( rc==SQLITE_OK || *ppStmt==0 );
  return rc;







|
>







682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
  *ppStmt = 0;
  if( !sqlite3SafetyCheckOk(db)||zSql==0 ){
    return SQLITE_MISUSE_BKPT;
  }
  sqlite3_mutex_enter(db->mutex);
  sqlite3BtreeEnterAll(db);
  rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
  if( rc==SQLITE_SCHEMA && db->nSchemaLock==0 ){
    sqlite3ResetOneSchema(db, -1);
    sqlite3_finalize(*ppStmt);
    rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
  }
  sqlite3BtreeLeaveAll(db);
  sqlite3_mutex_leave(db->mutex);
  assert( rc==SQLITE_OK || *ppStmt==0 );
  return rc;

Changes to src/sqliteInt.h.

1209
1210
1211
1212
1213
1214
1215

1216
1217
1218
1219
1220
1221
1222
....
1325
1326
1327
1328
1329
1330
1331

1332
1333
1334
1335
1336
1337
1338
** DB_UnresetViews means that one or more views have column names that
** have been filled out.  If the schema changes, these column names might
** changes and so the view will need to be reset.
*/
#define DB_SchemaLoaded    0x0001  /* The schema has been loaded */
#define DB_UnresetViews    0x0002  /* Some views have defined column names */
#define DB_Empty           0x0004  /* The file is empty (length 0 bytes) */


/*
** The number of different kinds of things that can be limited
** using the sqlite3_limit() interface.
*/
#define SQLITE_N_LIMIT (SQLITE_LIMIT_WORKER_THREADS+1)

................................................................................
  sqlite3_mutex *mutex;         /* Connection mutex */
  Db *aDb;                      /* All backends */
  int nDb;                      /* Number of backends currently in use */
  u32 mDbFlags;                 /* flags recording internal state */
  u32 flags;                    /* flags settable by pragmas. See below */
  i64 lastRowid;                /* ROWID of most recent insert (see above) */
  i64 szMmap;                   /* Default mmap_size setting */

  unsigned int openFlags;       /* Flags passed to sqlite3_vfs.xOpen() */
  int errCode;                  /* Most recent error code (SQLITE_*) */
  int errMask;                  /* & result codes with this before returning */
  int iSysErrno;                /* Errno value from last system error */
  u16 dbOptFlags;               /* Flags to enable/disable optimizations */
  u8 enc;                       /* Text encoding */
  u8 autoCommit;                /* The auto-commit flag. */







>







 







>







1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
....
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
** DB_UnresetViews means that one or more views have column names that
** have been filled out.  If the schema changes, these column names might
** changes and so the view will need to be reset.
*/
#define DB_SchemaLoaded    0x0001  /* The schema has been loaded */
#define DB_UnresetViews    0x0002  /* Some views have defined column names */
#define DB_Empty           0x0004  /* The file is empty (length 0 bytes) */
#define DB_ResetWanted     0x0008  /* Reset the schema when nSchemaLock==0 */

/*
** The number of different kinds of things that can be limited
** using the sqlite3_limit() interface.
*/
#define SQLITE_N_LIMIT (SQLITE_LIMIT_WORKER_THREADS+1)

................................................................................
  sqlite3_mutex *mutex;         /* Connection mutex */
  Db *aDb;                      /* All backends */
  int nDb;                      /* Number of backends currently in use */
  u32 mDbFlags;                 /* flags recording internal state */
  u32 flags;                    /* flags settable by pragmas. See below */
  i64 lastRowid;                /* ROWID of most recent insert (see above) */
  i64 szMmap;                   /* Default mmap_size setting */
  u32 nSchemaLock;              /* Do not reset the schema when non-zero */
  unsigned int openFlags;       /* Flags passed to sqlite3_vfs.xOpen() */
  int errCode;                  /* Most recent error code (SQLITE_*) */
  int errMask;                  /* & result codes with this before returning */
  int iSysErrno;                /* Errno value from last system error */
  u16 dbOptFlags;               /* Flags to enable/disable optimizations */
  u8 enc;                       /* Text encoding */
  u8 autoCommit;                /* The auto-commit flag. */