/ Check-in [c49d8bdc]
Login

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

Overview
Comment:Make sure ATTACH and DETACH fail if a transaction is active. (CVS 1633)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:c49d8bdc3e1172a283f7aaf208fbb9096acd5ab6
User & Date: danielk1977 2004-06-19 09:08:16
Context
2004-06-19
09:35
Remove the unused 'next_cookie' mechanism. (CVS 1634) check-in: c94a9759 user: danielk1977 tags: trunk
09:08
Make sure ATTACH and DETACH fail if a transaction is active. (CVS 1633) check-in: c49d8bdc user: danielk1977 tags: trunk
08:18
Remove the iCollate argument from sqlite3_create_function() (CVS 1632) check-in: 728d57ff user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/attach.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
36
37
38
39
40
41
42






43
44
45
46
47
48
49
...
144
145
146
147
148
149
150





151
152
153
154
155
156
157
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.14 2004/06/09 12:30:05 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called by the parser to process an ATTACH statement:
**
**     ATTACH DATABASE filename AS dbname
................................................................................
  db = pParse->db;
  if( db->nDb>=MAX_ATTACHED+2 ){
    sqlite3ErrorMsg(pParse, "too many attached databases - max %d", 
       MAX_ATTACHED);
    pParse->rc = SQLITE_ERROR;
    return;
  }







  zFile = 0;
  sqlite3SetNString(&zFile, pFilename->z, pFilename->n, 0);
  if( zFile==0 ) return;
  sqlite3Dequote(zFile);
#ifndef SQLITE_OMIT_AUTHORIZATION
  if( sqlite3AuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){
................................................................................
  if( i>=db->nDb ){
    sqlite3ErrorMsg(pParse, "no such database: %T", pDbname);
    return;
  }
  if( i<2 ){
    sqlite3ErrorMsg(pParse, "cannot detach database %T", pDbname);
    return;





  }
#ifndef SQLITE_OMIT_AUTHORIZATION
  if( sqlite3AuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){
    return;
  }
#endif /* SQLITE_OMIT_AUTHORIZATION */
  sqlite3BtreeClose(db->aDb[i].pBt);







|







 







>
>
>
>
>
>







 







>
>
>
>
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
...
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.15 2004/06/19 09:08:16 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called by the parser to process an ATTACH statement:
**
**     ATTACH DATABASE filename AS dbname
................................................................................
  db = pParse->db;
  if( db->nDb>=MAX_ATTACHED+2 ){
    sqlite3ErrorMsg(pParse, "too many attached databases - max %d", 
       MAX_ATTACHED);
    pParse->rc = SQLITE_ERROR;
    return;
  }

  if( !db->autoCommit ){
    sqlite3ErrorMsg(pParse, "cannot ATTACH database within transaction");
    pParse->rc = SQLITE_ERROR;
    return;
  }

  zFile = 0;
  sqlite3SetNString(&zFile, pFilename->z, pFilename->n, 0);
  if( zFile==0 ) return;
  sqlite3Dequote(zFile);
#ifndef SQLITE_OMIT_AUTHORIZATION
  if( sqlite3AuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){
................................................................................
  if( i>=db->nDb ){
    sqlite3ErrorMsg(pParse, "no such database: %T", pDbname);
    return;
  }
  if( i<2 ){
    sqlite3ErrorMsg(pParse, "cannot detach database %T", pDbname);
    return;
  }
  if( !db->autoCommit ){
    sqlite3ErrorMsg(pParse, "cannot DETACH database within transaction");
    pParse->rc = SQLITE_ERROR;
    return;
  }
#ifndef SQLITE_OMIT_AUTHORIZATION
  if( sqlite3AuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){
    return;
  }
#endif /* SQLITE_OMIT_AUTHORIZATION */
  sqlite3BtreeClose(db->aDb[i].pBt);

Changes to src/shell.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
...
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code to implement the "sqlite" command line
** utility for accessing SQLite databases.
**
** $Id: shell.c,v 1.104 2004/06/08 00:39:01 danielk1977 Exp $
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "sqlite3.h"
#include <ctype.h>
................................................................................
extern int isatty();

/*
** The following is the open SQLite database.  We make a pointer
** to this database a static variable so that it can be accessed
** by the SIGINT handler to interrupt database processing.
*/
static sqlite *db = 0;

/*
** True if an interrupt (Control-C) has been received.
*/
static int seenInterrupt = 0;

/*
................................................................................
};
/*
** An pointer to an instance of this structure is passed from
** the main program to the callback.  This is used to communicate
** state and mode information.
*/
struct callback_data {
  sqlite *db;            /* The database */
  int echoOn;            /* True to echo input commands */
  int cnt;               /* Number of records displayed so far */
  FILE *out;             /* Write results here */
  int mode;              /* An output mode setting */
  int showHeader;        /* True to show column names in List or Column mode */
  char *zDestTable;      /* Name of destination table when MODE_Insert */
  char separator[20];    /* Separator character for MODE_List */







|







 







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
...
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code to implement the "sqlite" command line
** utility for accessing SQLite databases.
**
** $Id: shell.c,v 1.105 2004/06/19 09:08:16 danielk1977 Exp $
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "sqlite3.h"
#include <ctype.h>
................................................................................
extern int isatty();

/*
** The following is the open SQLite database.  We make a pointer
** to this database a static variable so that it can be accessed
** by the SIGINT handler to interrupt database processing.
*/
static sqlite3 *db = 0;

/*
** True if an interrupt (Control-C) has been received.
*/
static int seenInterrupt = 0;

/*
................................................................................
};
/*
** An pointer to an instance of this structure is passed from
** the main program to the callback.  This is used to communicate
** state and mode information.
*/
struct callback_data {
  sqlite3 *db;            /* The database */
  int echoOn;            /* True to echo input commands */
  int cnt;               /* Number of records displayed so far */
  FILE *out;             /* Write results here */
  int mode;              /* An output mode setting */
  int showHeader;        /* True to show column names in List or Column mode */
  char *zDestTable;      /* Name of destination table when MODE_Insert */
  char separator[20];    /* Separator character for MODE_List */

Changes to src/vacuum.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
213
214
215
216
217
218
219
220
221

222
223
224
225
226
227
228
229
230
**
*************************************************************************
** This file contains code used to implement the VACUUM command.
**
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
** $Id: vacuum.c,v 1.22 2004/06/15 11:40:09 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"

#if !defined(SQLITE_OMIT_VACUUM) || SQLITE_OMIT_VACUUM
/*
** Generate a random name of 20 character in length.
................................................................................

    rc = sqlite3BtreeCopyFile(pMain, pTemp);
    if( rc!=SQLITE_OK ) goto end_of_vacuum;
    rc = sqlite3BtreeCommit(pMain);
  }

end_of_vacuum:
  execSql(db, "DETACH vacuum_db;");
  execSql(db, "ROLLBACK;");

  if( zTemp ){
    sqlite3OsDelete(zTemp);
    sqliteFree(zTemp);
  }
  if( zSql ) sqliteFree( zSql );
  if( pStmt ) sqlite3_finalize( pStmt );
#endif
  return rc;
} 







|







 







<

>









10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
213
214
215
216
217
218
219

220
221
222
223
224
225
226
227
228
229
230
**
*************************************************************************
** This file contains code used to implement the VACUUM command.
**
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
** $Id: vacuum.c,v 1.23 2004/06/19 09:08:16 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"

#if !defined(SQLITE_OMIT_VACUUM) || SQLITE_OMIT_VACUUM
/*
** Generate a random name of 20 character in length.
................................................................................

    rc = sqlite3BtreeCopyFile(pMain, pTemp);
    if( rc!=SQLITE_OK ) goto end_of_vacuum;
    rc = sqlite3BtreeCommit(pMain);
  }

end_of_vacuum:

  execSql(db, "ROLLBACK;");
  execSql(db, "DETACH vacuum_db;");
  if( zTemp ){
    sqlite3OsDelete(zTemp);
    sqliteFree(zTemp);
  }
  if( zSql ) sqliteFree( zSql );
  if( pStmt ) sqlite3_finalize( pStmt );
#endif
  return rc;
} 

Changes to test/attach2.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
334
335
336
337
338
339
340
























341
342
343
344
345
346
347
348
349
350
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the ATTACH and DETACH commands
# and related functionality.
#
# $Id: attach2.test,v 1.19 2004/06/19 00:16:31 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl


# Ticket #354
................................................................................
    DROP TABLE tbl;
    ROLLBACK;
  }
} {}
do_test attach2-5.5 {
  glob test.db*
} {test.db test.db2}

























db close

finish_test













|







 







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










8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the ATTACH and DETACH commands
# and related functionality.
#
# $Id: attach2.test,v 1.20 2004/06/19 09:08:16 danielk1977 Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl


# Ticket #354
................................................................................
    DROP TABLE tbl;
    ROLLBACK;
  }
} {}
do_test attach2-5.5 {
  glob test.db*
} {test.db test.db2}

# Check that a database cannot be ATTACHed or DETACHed during a transaction.
do_test attach2-6.1 {
  execsql {
    BEGIN;
  }
} {}
do_test attach2-6.2 {
  catchsql {
    ATTACH 'test3.db' as aux2;
  }
} {1 {cannot ATTACH database within 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