SQLite

Changes On Branch attach-in-trans
Login

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

Changes In Branch attach-in-trans Excluding Merge-Ins

This is equivalent to a diff from 622b1089 to ac1fd6be

2017-08-01
00:20
Allow ATTACH and DETACH inside of a transaction. (check-in: 95e8f316 user: drh tags: trunk)
2017-07-26
19:59
Add the new sqlite3.mDbFlags field. Factor out bits of sqlite3.flags that do not interact with PRAGMA statements into sqlite3.mDbFlags. (check-in: 3808a00f user: drh tags: trunk)
18:26
Allow ATTACH and DETACH to occur inside of a transaction. (Closed-Leaf check-in: ac1fd6be user: drh tags: attach-in-trans)
10:04
Fix a comment on the UnpackedRecord.r1 and UnpackedRecord.r2 fields. No changes to code. (check-in: 622b1089 user: drh tags: trunk)
2017-07-25
01:34
Fix a bug in the deterministic date/time function logic that can only appear with STAT3 or STAT4. (check-in: 1ca707a4 user: drh tags: trunk)

Changes to src/attach.c.

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
  */
  if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){
    zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", 
      db->aLimit[SQLITE_LIMIT_ATTACHED]
    );
    goto attach_error;
  }
  if( !db->autoCommit ){
    zErrDyn = sqlite3MPrintf(db, "cannot ATTACH database within transaction");
    goto attach_error;
  }
  for(i=0; i<db->nDb; i++){
    char *z = db->aDb[i].zDbSName;
    assert( z && zName );
    if( sqlite3StrICmp(z, zName)==0 ){
      zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
      goto attach_error;
    }







<
<
<
<







89
90
91
92
93
94
95




96
97
98
99
100
101
102
  */
  if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){
    zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", 
      db->aLimit[SQLITE_LIMIT_ATTACHED]
    );
    goto attach_error;
  }




  for(i=0; i<db->nDb; i++){
    char *z = db->aDb[i].zDbSName;
    assert( z && zName );
    if( sqlite3StrICmp(z, zName)==0 ){
      zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
      goto attach_error;
    }
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
    sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName);
    goto detach_error;
  }
  if( i<2 ){
    sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName);
    goto detach_error;
  }
  if( !db->autoCommit ){
    sqlite3_snprintf(sizeof(zErr), zErr,
                     "cannot DETACH database within transaction");
    goto detach_error;
  }
  if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){
    sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
    goto detach_error;
  }

  sqlite3BtreeClose(pDb->pBt);
  pDb->pBt = 0;







<
<
<
<
<







280
281
282
283
284
285
286





287
288
289
290
291
292
293
    sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName);
    goto detach_error;
  }
  if( i<2 ){
    sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName);
    goto detach_error;
  }





  if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){
    sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
    goto detach_error;
  }

  sqlite3BtreeClose(pDb->pBt);
  pDb->pBt = 0;

Changes to test/attach2.test.

370
371
372
373
374
375
376

377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
  execsql {
    BEGIN;
  }
} {}
do_test attach2-6.2 {
  catchsql {
    ATTACH 'test3.db' as aux2;

  }
} {1 {cannot ATTACH database within transaction}}

# EVIDENCE-OF: R-59740-55581 This statement will fail if SQLite is in
# the middle of a transaction.
#
do_test attach2-6.3 {
  catchsql {
    DETACH aux;
  }
} {1 {cannot DETACH database within transaction}}
do_test attach2-6.4 {
  execsql {
    COMMIT;
    DETACH aux;
  }
} {}

db close

finish_test







>

|








<
<
<
<
<
<
|




370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387






388
389
390
391
392
  execsql {
    BEGIN;
  }
} {}
do_test attach2-6.2 {
  catchsql {
    ATTACH 'test3.db' as aux2;
    DETACH aux2;
  }
} {0 {}}

# EVIDENCE-OF: R-59740-55581 This statement will fail if SQLite is in
# the middle of a transaction.
#
do_test attach2-6.3 {
  catchsql {
    DETACH aux;
  }






} {0 {}}

db close

finish_test

Changes to test/savepoint.test.

611
612
613
614
615
616
617



618
619
620
621
622

623
624
625
626
627
628
629
630
631
632

633
634
635
636
637
638
639
640
641
#-------------------------------------------------------------------------
# The following tests - savepoint-10.* - test the interaction of 
# savepoints and ATTACH statements.
# 

# First make sure it is not possible to attach or detach a database while
# a savepoint is open (it is not possible if any transaction is open).



#
do_test savepoint-10.1.1 {
  catchsql {
    SAVEPOINT one;
    ATTACH 'test2.db' AS aux;

  }
} {1 {cannot ATTACH database within transaction}}
do_test savepoint-10.1.2 {
  execsql {
    RELEASE one;
    ATTACH 'test2.db' AS aux;
  }
  catchsql {
    SAVEPOINT one;
    DETACH aux;

  }
} {1 {cannot DETACH database within transaction}}
do_test savepoint-10.1.3 {
  execsql {
    RELEASE one;
    DETACH aux;
  }
} {}








>
>
>





>

|








>

|







611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
#-------------------------------------------------------------------------
# The following tests - savepoint-10.* - test the interaction of 
# savepoints and ATTACH statements.
# 

# First make sure it is not possible to attach or detach a database while
# a savepoint is open (it is not possible if any transaction is open).
#
# UPDATE 2017-07-26:  It is not possible to ATTACH and DETACH within a
# a transaction.
#
do_test savepoint-10.1.1 {
  catchsql {
    SAVEPOINT one;
    ATTACH 'test2.db' AS aux;
    DETACH aux;
  }
} {0 {}}
do_test savepoint-10.1.2 {
  execsql {
    RELEASE one;
    ATTACH 'test2.db' AS aux;
  }
  catchsql {
    SAVEPOINT one;
    DETACH aux;
    ATTACH 'test2.db' AS aux;
  }
} {0 {}}
do_test savepoint-10.1.3 {
  execsql {
    RELEASE one;
    DETACH aux;
  }
} {}