SQLite

Check-in [e3ad61e030]
Login

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

Overview
Comment: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.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | shared-cache-memdb
Files: files | file ages | folders
SHA1: e3ad61e0308a8442c2bdb7cdb3465576cd39ed4a
User & Date: drh 2012-05-26 20:08:49.030
Context
2012-05-27
01:19
Have user interfaces report out the filename of in-memory databases as an empty string, as it always has. This simplifies the changes. (Closed-Leaf check-in: 595dfdbffe user: drh tags: shared-cache-memdb)
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)
18:06
Enable the use of shared cache for an in-memory database, so that separate database connections can share the same in-memory database. (check-in: 4590e433f2 user: drh tags: shared-cache-memdb)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/btree.c.
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
#endif

#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
  /*
  ** If this Btree is a candidate for shared cache, try to find an
  ** existing BtShared object that we can share with
  */
  if( isTempDb==0 ){
    if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
      int nFullPathname = pVfs->mxPathname+1;
      char *zFullPathname = sqlite3Malloc(nFullPathname);
      MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
      p->sharable = 1;
      if( !zFullPathname ){
        sqlite3_free(p);







|







1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
#endif

#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
  /*
  ** If this Btree is a candidate for shared cache, try to find an
  ** existing BtShared object that we can share with
  */
  if( isTempDb==0 && (isMemdb==0 || (vfsFlags&SQLITE_OPEN_URI)!=0) ){
    if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
      int nFullPathname = pVfs->mxPathname+1;
      char *zFullPathname = sqlite3Malloc(nFullPathname);
      MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
      p->sharable = 1;
      if( !zFullPathname ){
        sqlite3_free(p);
Changes to src/main.c.
2051
2052
2053
2054
2055
2056
2057

2058
2059
2060
2061
2062
2063
2064

  }else{
    zFile = sqlite3_malloc(nUri+2);
    if( !zFile ) return SQLITE_NOMEM;
    memcpy(zFile, zUri, nUri);
    zFile[nUri] = '\0';
    zFile[nUri+1] = '\0';

  }

  *ppVfs = sqlite3_vfs_find(zVfs);
  if( *ppVfs==0 ){
    *pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs);
    rc = SQLITE_ERROR;
  }







>







2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065

  }else{
    zFile = sqlite3_malloc(nUri+2);
    if( !zFile ) return SQLITE_NOMEM;
    memcpy(zFile, zUri, nUri);
    zFile[nUri] = '\0';
    zFile[nUri+1] = '\0';
    flags &= ~SQLITE_OPEN_URI;
  }

  *ppVfs = sqlite3_vfs_find(zVfs);
  if( *ppVfs==0 ){
    *pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs);
    rc = SQLITE_ERROR;
  }
Changes to src/pager.c.
4356
4357
4358
4359
4360
4361
4362

4363

4364
4365

4366
4367
4368
4369
4370
4371
4372

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

#ifndef SQLITE_OMIT_MEMORYDB
  if( flags & PAGER_MEMORY ){
    memDb = 1;

    zPathname = sqlite3DbStrDup(0, zFilename);

    nPathname = sqlite3Strlen30(zPathname);
    zFilename = 0;

  }
#endif

  /* Compute and store the full pathname in an allocated buffer pointed
  ** to by zPathname, length nPathname. Or, if this is a temporary file,
  ** leave both nPathname and zPathname set to 0.
  */







>
|
>
|
|
>







4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375

  /* 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 ){
      zPathname = sqlite3DbStrDup(0, zFilename);
      if( zPathname==0  ) return SQLITE_NOMEM;
      nPathname = sqlite3Strlen30(zPathname);
      zFilename = 0;
    }
  }
#endif

  /* Compute and store the full pathname in an allocated buffer pointed
  ** to by zPathname, length nPathname. Or, if this is a temporary file,
  ** leave both nPathname and zPathname set to 0.
  */
Changes to test/shared.test.
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079


















1080
1081
1082
1083
1084
} {1 2 6 8 9 12 1 2 5 11 12 14 1 2 4}
do_test shared-$av-15.2 {
  execsql { DROP TABLE t1 } db2
} {}
db close
db2 close

# Shared cache on a :memory: database.
#
do_test shared-$av-16.1 {
  sqlite3 db1 :memory:
  sqlite3 db2 :memory:
  db1 eval {
    CREATE TABLE t1(x); INSERT INTO t1 VALUES(1),(2),(3);
  }
  db2 eval {
    SELECT x FROM t1 ORDER BY x;
  }
} {1 2 3}
do_test shared-$av-16.2 {
  db2 eval {
    INSERT INTO t1 VALUES(99);
    DELETE FROM t1 WHERE x=2;
  }
  db1 eval {
    SELECT x FROM t1 ORDER BY x;
  }
} {1 3 99}



















}  ;# end of autovacuum on/off loop

sqlite3_enable_shared_cache $::enable_shared_cache
finish_test







|


|
|
















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





1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
} {1 2 6 8 9 12 1 2 5 11 12 14 1 2 4}
do_test shared-$av-15.2 {
  execsql { DROP TABLE t1 } db2
} {}
db close
db2 close

# Shared cache on a :memory: database.  This only works for URI filenames.
#
do_test shared-$av-16.1 {
  sqlite3 db1 file::memory: -uri 1
  sqlite3 db2 file::memory: -uri 1
  db1 eval {
    CREATE TABLE t1(x); INSERT INTO t1 VALUES(1),(2),(3);
  }
  db2 eval {
    SELECT x FROM t1 ORDER BY x;
  }
} {1 2 3}
do_test shared-$av-16.2 {
  db2 eval {
    INSERT INTO t1 VALUES(99);
    DELETE FROM t1 WHERE x=2;
  }
  db1 eval {
    SELECT x FROM t1 ORDER BY x;
  }
} {1 3 99}

# Verify that there is no cache sharing ordinary (non-URI) filenames are
# used.
#
do_test shared-$av-16.3 {
  db1 close
  db2 close
  sqlite3 db1 :memory:
  sqlite3 db2 :memory:
  db1 eval {
    CREATE TABLE t1(x); INSERT INTO t1 VALUES(4),(5),(6);
  }
  catchsql {
    SELECT * FROM t1;
  } db2
} {1 {no such table: t1}}
db1 close
db2 close

}  ;# end of autovacuum on/off loop

sqlite3_enable_shared_cache $::enable_shared_cache
finish_test