SQLite

Check-in [997ef5f61e]
Login

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

Overview
Comment:Fix corner-case problems with shared-cache for in-memory databases.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | shared-cache-memdb
Files: files | file ages | folders
SHA1: 997ef5f61e2a603ee2c36e87c42784ca48eebdc3
User & Date: drh 2012-05-27 00:11:02.076
Context
2012-05-27
00:11
Fix corner-case problems with shared-cache for in-memory databases. (Closed-Leaf check-in: 997ef5f61e user: drh tags: shared-cache-memdb)
2012-05-26
20:08
Only allow :memory: databases to share cache if there are created using a URI filename. This minimizes the risk of breakages in legacy applications that have shared-cache enabled but also use :memory: databases which they expect to keep separate. (check-in: e3ad61e030 user: drh tags: shared-cache-memdb)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to src/btree.c.
8056
8057
8058
8059
8060
8061
8062












8063
8064
8065
8066
8067
8068
8069
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081







+
+
+
+
+
+
+
+
+
+
+
+







** The pager filename is invariant as long as the pager is
** open so it is safe to access without the BtShared mutex.
*/
const char *sqlite3BtreeGetFilename(Btree *p){
  assert( p->pBt->pPager!=0 );
  return sqlite3PagerFilename(p->pBt->pPager);
}

/*
** Return true if the Btree is a persistent database, not an in-memory
** or temporary database.
*/
int sqlite3BtreePersists(Btree *p){
  Pager *pPager = p->pBt->pPager;
  const char *z;
  assert( pPager!=0 );
  return sqlite3PagerIsMemdb(pPager)==0
      && (z = sqlite3PagerFilename(pPager))!=0 && z[0]!=0;
}

/*
** Return the pathname of the journal file for this database. The return
** value of this routine is the same regardless of whether the journal file
** has been created or not.
**
** The pager journal filename is invariant as long as the pager is
Changes to src/btree.h.
86
87
88
89
90
91
92

93
94
95
96
97
98
99
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100







+







void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
int sqlite3BtreeSchemaLocked(Btree *pBtree);
int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock);
int sqlite3BtreeSavepoint(Btree *, int, int);

const char *sqlite3BtreeGetFilename(Btree *);
const char *sqlite3BtreeGetJournalname(Btree *);
int sqlite3BtreePersists(Btree*);
int sqlite3BtreeCopyFile(Btree *, Btree *);

int sqlite3BtreeIncrVacuum(Btree *);

/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR
** of the flags shown below.
**
Changes to src/pager.c.
4356
4357
4358
4359
4360
4361
4362
4363

4364
4365
4366
4367
4368
4369
4370
4356
4357
4358
4359
4360
4361
4362

4363
4364
4365
4366
4367
4368
4369
4370







-
+








  /* Set the output variable to NULL in case an error occurs. */
  *ppPager = 0;

#ifndef SQLITE_OMIT_MEMORYDB
  if( flags & PAGER_MEMORY ){
    memDb = 1;
    if( zFilename ){
    if( zFilename && zFilename[0] ){
      zPathname = sqlite3DbStrDup(0, zFilename);
      if( zPathname==0  ) return SQLITE_NOMEM;
      nPathname = sqlite3Strlen30(zPathname);
      zFilename = 0;
    }
  }
#endif
Changes to src/vdbeaux.c.
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794


1795
1796
1797

1798
1799
1800
1801
1802
1803
1804
1785
1786
1787
1788
1789
1790
1791



1792
1793
1794
1795

1796
1797
1798
1799
1800
1801
1802
1803







-
-
-
+
+


-
+







    }
  }

  /* The simple case - no more than one database file (not counting the
  ** TEMP database) has a transaction active.   There is no need for the
  ** master-journal.
  **
  ** If the return value of sqlite3BtreeGetFilename() is a zero length
  ** string, it means the main database is :memory: or a temp file.  In 
  ** that case we do not support atomic multi-file commits, so use the 
  ** If the main database is :memory: or a temp file then
  ** we do not support atomic multi-file commits, so use the 
  ** simple case then too.
  */
  if( 0==sqlite3Strlen30(sqlite3BtreeGetFilename(db->aDb[0].pBt))
  if( 0==sqlite3BtreePersists(db->aDb[0].pBt)
   || nTrans<=1
  ){
    for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
      Btree *pBt = db->aDb[i].pBt;
      if( pBt ){
        rc = sqlite3BtreeCommitPhaseOne(pBt, 0);
      }