SQLite

Check-in [5dfbef8349]
Login

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
Timelines: family | ancestors | descendants | both | reuse-schema
Files: files | file ages | folders
SHA3-256: 5dfbef8349e47f9d9fcdbb648ecd18b5bc7eebdb1a3ddaf91789d036b7de8a90
User & Date: dan 2019-02-04 21:02:00.454
Context
2019-02-05
19:15
Fix memory leaks on this branch. (check-in: e9c5e1891f user: dan tags: reuse-schema)
2019-02-04
21:02
Fix a problem with reloading the schema on this branch. (check-in: 5dfbef8349 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: 9e8e5f52cf user: dan tags: reuse-schema)
Changes
Unified Diff 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
  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;








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







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
  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;

573
574
575
576
577
578
579

580
581
582
583
584


585
586
587
588
589
590
591
    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) );
  }
}

/*







>





>
>







588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
    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 {