/ Check-in [5dfbef83]
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 a problem with reloading the schema on this branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | reuse-schema
Files: files | file ages | folders
SHA3-256: 5dfbef8349e47f9d9fcdbb648ecd18b5bc7eebdb1a3ddaf91789d036b7de8a90
User & Date: dan 2019-02-04 21:02:00
Wiki:reuse-schema
Context
2019-02-05
19:15
Fix memory leaks on this branch. check-in: e9c5e189 user: dan tags: reuse-schema
2019-02-04
21:02
Fix a problem with reloading the schema on this branch. check-in: 5dfbef83 user: dan tags: reuse-schema
2019-02-02
21:02
Try new approach ensuring that each Schema object is only used by one connection/database at any one time. check-in: 9e8e5f52 user: dan tags: reuse-schema
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
    DbSetProperty(db, iDb, DB_ResetWanted);
    DbSetProperty(db, 1, DB_ResetWanted);
    db->mDbFlags &= ~DBFLAG_SchemaKnownOk;
  }
  if( db->nSchemaLock==0 ){
    for(i=0; i<db->nDb; i++){
      if( DbHasProperty(db, i, DB_ResetWanted) ){
        sqlite3SchemaClear(db->aDb[1].pSchema);
      }
    }
  }
}

/*
** Erase all schema information from all attached databases (including







|







526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
    DbSetProperty(db, iDb, DB_ResetWanted);
    DbSetProperty(db, 1, DB_ResetWanted);
    db->mDbFlags &= ~DBFLAG_SchemaKnownOk;
  }
  if( db->nSchemaLock==0 ){
    for(i=0; i<db->nDb; i++){
      if( DbHasProperty(db, i, DB_ResetWanted) ){
        sqlite3SchemaZero(db, i);
      }
    }
  }
}

/*
** Erase all schema information from all attached databases (including

Changes to src/callback.c.

482
483
484
485
486
487
488















489
490
491
492
493
494
495
...
573
574
575
576
577
578
579

580
581
582
583
584


585
586
587
588
589
590
591
  sqlite3HashClear(&pSchema->fkeyHash);
  pSchema->pSeqTab = 0;
  if( pSchema->schemaFlags & DB_SchemaLoaded ){
    pSchema->iGeneration++;
  }
  pSchema->schemaFlags &= ~(DB_SchemaLoaded|DB_ResetWanted);
}
















/*
** Global linked list of SchemaPool objects. Read and write access must
** be protected by the SQLITE_MUTEX_STATIC_MASTER mutex.
*/
static SchemaPool *SQLITE_WSD schemaPoolList = 0;

................................................................................
    assert( iDb!=1 );

    sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
    assert( pSPool->nRef>=1 );
    pSPool->nRef--;
    if( pSPool->nRef<=0 ){
      Schema *pNext;

      while( pSPool->pSchema ){
        Schema *pNext = pSPool->pSchema->pNext;
        schemaDelete(pSPool->pSchema);
        pSPool->pSchema = pNext;
      }


      sqlite3_free(pSPool);
    }
    sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
  }
}

/*







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>





>
>







482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
...
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
  sqlite3HashClear(&pSchema->fkeyHash);
  pSchema->pSeqTab = 0;
  if( pSchema->schemaFlags & DB_SchemaLoaded ){
    pSchema->iGeneration++;
  }
  pSchema->schemaFlags &= ~(DB_SchemaLoaded|DB_ResetWanted);
}

void sqlite3SchemaZero(sqlite3 *db, int iDb){
  Db *pDb = &db->aDb[iDb];
  if( IsReuseSchema(db) && iDb!=1 ){
    if( pDb->pSPool ){
      Schema *pNew = sqlite3SchemaGet(db, 0);
      if( pNew ){
        sqlite3SchemaDisconnect(db, iDb);
        pDb->pSchema = pNew;
      }
      return;
    }
  }
  sqlite3SchemaClear(pDb->pSchema);
}

/*
** Global linked list of SchemaPool objects. Read and write access must
** be protected by the SQLITE_MUTEX_STATIC_MASTER mutex.
*/
static SchemaPool *SQLITE_WSD schemaPoolList = 0;

................................................................................
    assert( iDb!=1 );

    sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
    assert( pSPool->nRef>=1 );
    pSPool->nRef--;
    if( pSPool->nRef<=0 ){
      Schema *pNext;
      SchemaPool **pp;
      while( pSPool->pSchema ){
        Schema *pNext = pSPool->pSchema->pNext;
        schemaDelete(pSPool->pSchema);
        pSPool->pSchema = pNext;
      }
      for(pp=&schemaPoolList; (*pp)!=pSPool; pp=&((*pp)->pNext));
      *pp = pSPool->pNext;
      sqlite3_free(pSPool);
    }
    sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
  }
}

/*

Changes to src/sqliteInt.h.

4291
4292
4293
4294
4295
4296
4297

4298
4299
4300
4301
4302
4303
4304
void sqlite3DeleteIndexSamples(sqlite3*,Index*);
void sqlite3DefaultRowEst(Index*);
void sqlite3RegisterLikeFunctions(sqlite3*, int);
int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
void sqlite3SchemaClear(void *);
int sqlite3SchemaConnect(sqlite3*, int, u64);
void sqlite3SchemaDisconnect(sqlite3 *, int);

Schema *sqlite3SchemaExtract(SchemaPool*);
void sqlite3SchemaReleaseAll(sqlite3 *);
void sqlite3SchemaWritable(Parse*, int);
Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int);
void sqlite3KeyInfoUnref(KeyInfo*);







>







4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
void sqlite3DeleteIndexSamples(sqlite3*,Index*);
void sqlite3DefaultRowEst(Index*);
void sqlite3RegisterLikeFunctions(sqlite3*, int);
int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
void sqlite3SchemaClear(void *);
int sqlite3SchemaConnect(sqlite3*, int, u64);
void sqlite3SchemaDisconnect(sqlite3 *, int);
void sqlite3SchemaZero(sqlite3*, int);
Schema *sqlite3SchemaExtract(SchemaPool*);
void sqlite3SchemaReleaseAll(sqlite3 *);
void sqlite3SchemaWritable(Parse*, int);
Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int);
void sqlite3KeyInfoUnref(KeyInfo*);

Changes to test/reuse1.test.

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
  PRAGMA integrity_check;
} {1 2 3 4 5 6 ok}

sqlite3 db3 test.db2
do_execsql_test -db db3 1.4.1 {
  ALTER TABLE t1 ADD COLUMN a;
}
breakpoint
do_execsql_test -db db2 1.4.2 {
  SELECT * FROM t1;
} {1 2 3 {} 4 5 6 {}}
exit
do_execsql_test 1.4.3 {
  SELECT * FROM t1;
} {}

db3 close
sqlite3 db3 test.db
do_execsql_test -db db3 1.5.0 {







<



<







54
55
56
57
58
59
60

61
62
63

64
65
66
67
68
69
70
  PRAGMA integrity_check;
} {1 2 3 4 5 6 ok}

sqlite3 db3 test.db2
do_execsql_test -db db3 1.4.1 {
  ALTER TABLE t1 ADD COLUMN a;
}

do_execsql_test -db db2 1.4.2 {
  SELECT * FROM t1;
} {1 2 3 {} 4 5 6 {}}

do_execsql_test 1.4.3 {
  SELECT * FROM t1;
} {}

db3 close
sqlite3 db3 test.db
do_execsql_test -db db3 1.5.0 {