/ Check-in [d197afd6]
Login

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

Overview
Comment:In sqlite3_table_column_metadata(), hold the mutex on all attached BtShared objects while accessing schema objects. Fix for #3679. (CVS 6328)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:d197afd658eecfc0e24913e5a779c8f1e2a138a6
User & Date: danielk1977 2009-02-26 07:15:59
Context
2009-02-28
10:47
Instead of linking temporary triggers on non-temporary tables into the Table.pTrigger list, search the temp schema for them on demand. Fix for #3688. (CVS 6329) check-in: 3befe1ef user: danielk1977 tags: trunk
2009-02-26
07:15
In sqlite3_table_column_metadata(), hold the mutex on all attached BtShared objects while accessing schema objects. Fix for #3679. (CVS 6328) check-in: d197afd6 user: danielk1977 tags: trunk
2009-02-25
19:07
Move the new genfkey shell command out from within #ifdef _WIN32_ (CVS 6327) check-in: 48ee0e47 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/main.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
....
1985
1986
1987
1988
1989
1990
1991

1992
1993
1994
1995
1996
1997
1998
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.529 2009/02/23 14:42:53 danielk1977 Exp $
*/
#include "sqliteInt.h"

#ifdef SQLITE_ENABLE_FTS3
# include "fts3.h"
#endif
#ifdef SQLITE_ENABLE_RTREE
................................................................................
  int autoinc = 0;

  /* Ensure the database schema has been loaded */
  sqlite3_mutex_enter(db->mutex);
  (void)sqlite3SafetyOn(db);
  sqlite3BtreeEnterAll(db);
  rc = sqlite3Init(db, &zErrMsg);
  sqlite3BtreeLeaveAll(db);
  if( SQLITE_OK!=rc ){
    goto error_out;
  }

  /* Locate the table in question */
  pTab = sqlite3FindTable(db, zTableName, zDbName);
  if( !pTab || pTab->pSelect ){
................................................................................
    primarykey = 1;
  }
  if( !zCollSeq ){
    zCollSeq = "BINARY";
  }

error_out:

  (void)sqlite3SafetyOff(db);

  /* Whether the function call succeeded or failed, set the output parameters
  ** to whatever their local counterparts contain. If an error did occur,
  ** this has the effect of zeroing all output parameters.
  */
  if( pzDataType ) *pzDataType = zDataType;







|







 







<







 







>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1929
1930
1931
1932
1933
1934
1935

1936
1937
1938
1939
1940
1941
1942
....
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.530 2009/02/26 07:15:59 danielk1977 Exp $
*/
#include "sqliteInt.h"

#ifdef SQLITE_ENABLE_FTS3
# include "fts3.h"
#endif
#ifdef SQLITE_ENABLE_RTREE
................................................................................
  int autoinc = 0;

  /* Ensure the database schema has been loaded */
  sqlite3_mutex_enter(db->mutex);
  (void)sqlite3SafetyOn(db);
  sqlite3BtreeEnterAll(db);
  rc = sqlite3Init(db, &zErrMsg);

  if( SQLITE_OK!=rc ){
    goto error_out;
  }

  /* Locate the table in question */
  pTab = sqlite3FindTable(db, zTableName, zDbName);
  if( !pTab || pTab->pSelect ){
................................................................................
    primarykey = 1;
  }
  if( !zCollSeq ){
    zCollSeq = "BINARY";
  }

error_out:
  sqlite3BtreeLeaveAll(db);
  (void)sqlite3SafetyOff(db);

  /* Whether the function call succeeded or failed, set the output parameters
  ** to whatever their local counterparts contain. If an error did occur,
  ** this has the effect of zeroing all output parameters.
  */
  if( pzDataType ) *pzDataType = zDataType;

Changes to test/quick.test.

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
81
82
83
84
85
86
87

88
89
90
91
92
93
94
#    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 runs all tests.
#
# $Id: quick.test,v 1.92 2009/02/03 16:51:25 danielk1977 Exp $

proc lshift {lvar} {
  upvar $lvar l
  set ret [lindex $l 0]
  set l [lrange $l 1 end]
  return $ret
}
................................................................................
  speed4.test
  speed4p.test
  sqllimits1.test
  tkt2686.test
  thread001.test
  thread002.test
  thread003.test

  trans2.test
  vacuum3.test

  incrvacuum_ioerr.test
  autovacuum_crash.test
  btree8.test
  shared_err.test







|







 







>







2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#    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 runs all tests.
#
# $Id: quick.test,v 1.93 2009/02/26 07:15:59 danielk1977 Exp $

proc lshift {lvar} {
  upvar $lvar l
  set ret [lindex $l 0]
  set l [lrange $l 1 end]
  return $ret
}
................................................................................
  speed4.test
  speed4p.test
  sqllimits1.test
  tkt2686.test
  thread001.test
  thread002.test
  thread003.test
  thread004.test
  trans2.test
  vacuum3.test

  incrvacuum_ioerr.test
  autovacuum_crash.test
  btree8.test
  shared_err.test

Added test/thread004.test.

































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# 2009 February 26
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    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.
#
#***********************************************************************
#
# $Id: thread004.test,v 1.1 2009/02/26 07:15:59 danielk1977 Exp $

set testdir [file dirname $argv0]

source $testdir/tester.tcl
ifcapable !mutex||!shared_cache {
  return
}
source $testdir/thread_common.tcl
if {[info commands sqlthread] eq "" 
 || [info commands sqlite3_table_column_metadata] eq ""
} {
  return
}

# Use shared-cache mode for this test.
# 
db close
set ::enable_shared_cache [sqlite3_enable_shared_cache]
sqlite3_enable_shared_cache 1

# Create a table in database test.db
#
sqlite3 db test.db
do_test thread004-1.1 {
  execsql { CREATE TABLE t1(a, b, c) }
} {}

do_test thread004-1.2 {

  set ThreadOne {
    set iStart [clock_seconds]
    while {[clock_seconds]<$iStart+20} {
      set ::DB [sqlite3_open test.db]
      sqlite3_close $::DB
    }
  }
  set ThreadTwo {
    set ::DB [sqlite3_open test.db]
    set iStart [clock_seconds]
    set nErr 0
    while {[clock_seconds] <$iStart+20} {
      incr nErr [catch {sqlite3_table_column_metadata $::DB main t1 a}]
    }
    sqlite3_close $::DB
    set nErr
  }
  
  # Run two threads. The first thread opens and closes database test.db
  # repeatedly. Each time this happens, the in-memory schema used by
  # all connections to test.db is discarded.
  #
  # The second thread calls sqlite3_table_column_metadata() over and
  # over again. Each time it is called, the database schema is loaded
  # if it is not already in memory. At one point this was crashing.
  #
  unset -nocomplain finished
  thread_spawn finished(1) $thread_procs $ThreadOne
  thread_spawn finished(2) $thread_procs $ThreadTwo
  
  foreach t {1 2} {
    if {![info exists finished($t)]} { vwait finished($t) }
  }

  set finished(2)
} {0}
sqlite3_enable_shared_cache $::enable_shared_cache
finish_test