/ Check-in [0fb6d91c]
Login

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

Overview
Comment:Allow "BEGIN CONCURRENT" transactions to modify the temp schema.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | begin-concurrent
Files: files | file ages | folders
SHA3-256: 0fb6d91cea347384fc081ce4c79582b365801dd4f56f5bf2ed40922bbfca0344
User & Date: dan 2017-11-06 10:04:45
Wiki:begin-concurrent
Context
2017-11-06
20:02
Merge latest trunk changes into this branch. check-in: 7f217eda user: dan tags: begin-concurrent
10:04
Allow "BEGIN CONCURRENT" transactions to modify the temp schema. check-in: 0fb6d91c user: dan tags: begin-concurrent
2017-09-22
11:09
Cherrypick [ec37ad6d08] into this branch. With this patch, if SQLITE_SHARED_MAPPING is defined at build-time SQLite will use a single memory mapping for multiple connections to the same database file within a single process. check-in: c7a5880d user: dan tags: begin-concurrent
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

  3302   3302       goto abort_due_to_error;
  3303   3303     }
  3304   3304   #endif
  3305   3305     /* See note about index shifting on OP_ReadCookie */
  3306   3306     rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, pOp->p3);
  3307   3307     if( pOp->p2==BTREE_SCHEMA_VERSION ){
  3308   3308       /* When the schema cookie changes, record the new cookie internally */
  3309         -    assert( db->bConcurrent==0 );
         3309  +    assert( pOp->p1==1 || db->bConcurrent==0 );
  3310   3310       pDb->pSchema->schema_cookie = pOp->p3;
  3311   3311       db->mDbFlags |= DBFLAG_SchemaChange;
  3312   3312     }else if( pOp->p2==BTREE_FILE_FORMAT ){
  3313   3313       /* Record changes in the file format */
  3314   3314       pDb->pSchema->file_format = pOp->p3;
  3315   3315     }
  3316   3316     if( pOp->p1==1 ){
................................................................................
  6505   6505   **
  6506   6506   ** P4 contains a pointer to the name of the table being locked. This is only
  6507   6507   ** used to generate an error message if the lock cannot be obtained.
  6508   6508   */
  6509   6509   case OP_TableLock: {
  6510   6510     u8 isWriteLock = (u8)pOp->p3;
  6511   6511   #ifndef SQLITE_OMIT_CONCURRENT
  6512         -  if( isWriteLock && db->bConcurrent && pOp->p2==1 ){
         6512  +  if( isWriteLock && db->bConcurrent && pOp->p2==1 && pOp->p1!=1 ){
  6513   6513       rc = SQLITE_ERROR;
  6514   6514       sqlite3VdbeError(p, 
  6515   6515           "cannot modify database schema within CONCURRENT transaction");
  6516   6516       goto abort_due_to_error;
  6517   6517     }
  6518   6518   #endif
  6519   6519     if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommit) ){

Changes to test/concurrent.test.

   108    108   # CONCURRENT transactions may not modify the db schema.
   109    109   #
   110    110   foreach {tn sql} {
   111    111     1 { CREATE TABLE xx(a, b) }
   112    112     2 { DROP TABLE t1 }
   113    113     3 { CREATE INDEX i1 ON t1(a) }
   114    114     4 { CREATE VIEW v1 AS SELECT * FROM t1 }
   115         -  5 { CREATE TEMP TABLE xx(a, b) }
   116    115   } {
   117         -  do_catchsql_test 1.7.$tn.1 "
          116  +  do_catchsql_test 1.7.0.$tn.1 "
   118    117       BEGIN CONCURRENT;
   119    118       $sql
   120    119     " {1 {cannot modify database schema within CONCURRENT transaction}}
   121    120   
   122         -  do_execsql_test 1.7.$tn.2 {
          121  +  do_execsql_test 1.7.0.$tn.2 {
   123    122       SELECT sql FROM sqlite_master;
   124    123       SELECT sql FROM sqlite_temp_master;
   125    124     } {{CREATE TABLE t1(a, b)}}
   126    125   
   127         -  do_execsql_test 1.7.$tn.3 COMMIT
          126  +  do_execsql_test 1.7.0.$tn.3 COMMIT
          127  +}
          128  +
          129  +# Except the temp db schema.
          130  +foreach {tn sql} {
          131  +  1 { CREATE TEMP TABLE xx(a, b) }
          132  +  2 { DROP TABLE xx }
          133  +  3 { CREATE TEMP TABLE yy(a, b) }
          134  +  4 { CREATE VIEW temp.v1 AS SELECT * FROM t1 }
          135  +  5 { CREATE INDEX yyi1 ON yy(a); }
          136  +  6 { CREATE TABLE temp.zz(a, b) }
          137  +} {
          138  +  do_catchsql_test 1.7.1.$tn.1 "
          139  +    BEGIN CONCURRENT;
          140  +    $sql
          141  +  " {0 {}}
          142  +
          143  +  do_execsql_test 1.7.1.$tn.2 COMMIT
          144  +}
          145  +
          146  +
          147  +do_execsql_test 1.7.1.x {
          148  +  SELECT sql FROM sqlite_master;
          149  +  SELECT sql FROM sqlite_temp_master;
          150  +} {
          151  +  {CREATE TABLE t1(a, b)}
          152  +  {CREATE TABLE yy(a, b)} 
          153  +  {CREATE VIEW v1 AS SELECT * FROM t1} 
          154  +  {CREATE INDEX yyi1 ON yy(a)} 
          155  +  {CREATE TABLE zz(a, b)}
   128    156   }
   129    157   
   130    158   #-------------------------------------------------------------------------
   131    159   # If an auto-vacuum database is written within an CONCURRENT transaction, it
   132    160   # is handled in the same way as for a non-CONCURRENT transaction.
   133    161   #
   134    162   reset_db