SQLite

Check-in [ffd3312b66]
Login

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

Overview
Comment:Bug-fixes to get the two threadtest C programs working again. (CVS 1756)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ffd3312b66e2657c3431eab814aadec254af2403
User & Date: danielk1977 2004-06-29 07:45:33.000
Context
2004-06-29
08:59
Fix error reporting path for errors that occur while reading the database schema. (CVS 1757) (check-in: 157db33e09 user: danielk1977 tags: trunk)
07:45
Bug-fixes to get the two threadtest C programs working again. (CVS 1756) (check-in: ffd3312b66 user: danielk1977 tags: trunk)
03:29
Try to get threads working again on Linux. (CVS 1755) (check-in: a8417cb83e user: drh tags: trunk)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to src/build.c.
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33







-
+







**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.235 2004/06/28 01:11:47 danielk1977 Exp $
** $Id: build.c,v 1.236 2004/06/29 07:45:33 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs
143
144
145
146
147
148
149





150

151
152
153
154
155
156
157
143
144
145
146
147
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162







+
+
+
+
+
-
+







** where sqlite3FindTable() does not.
*/
Table *sqlite3LocateTable(Parse *pParse, const char *zName, const char *zDbase){
  Table *p;

  p = sqlite3FindTable(pParse->db, zName, zDbase);
  if( p==0 ){
    if( !(pParse->db->flags & SQLITE_Initialized) ){
      /* If the schema is not initialised at this point, it must be because
      ** the database is locked. */
      pParse->nErr++;
      pParse->rc = SQLITE_BUSY;
    if( zDbase ){
    }else if( zDbase ){
      sqlite3ErrorMsg(pParse, "no such table: %s.%s", zDbase, zName);
    }else if( sqlite3FindTable(pParse->db, zName, 0)!=0 ){
      sqlite3ErrorMsg(pParse, "table \"%s\" is not in database \"%s\"",
         zName, zDbase);
    }else{
      sqlite3ErrorMsg(pParse, "no such table: %s", zName);
    }
613
614
615
616
617
618
619

620
621
622
623
624
625
626
627
628

629
630
631
632
633
634
635
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







+









+







  */
  if( isTemp && db->aDb[1].pBt==0 && !pParse->explain ){
    int rc = sqlite3BtreeFactory(db, 0, 0, MAX_PAGES, &db->aDb[1].pBt);
    if( rc!=SQLITE_OK ){
      sqlite3ErrorMsg(pParse, "unable to open a temporary database "
        "file for storing temporary tables");
      pParse->nErr++;
      pParse->rc = rc;
      sqliteFree(zName);
      return;
    }
    if( db->flags & !db->autoCommit ){
      rc = sqlite3BtreeBeginTrans(db->aDb[1].pBt, 1);
      if( rc!=SQLITE_OK ){
        sqlite3ErrorMsg(pParse, "unable to get a write lock on "
          "the temporary database file");
        sqliteFree(zName);
        pParse->rc = rc;
        return;
      }
    }
  }

  /* Make sure the new table name does not collide with an existing
  ** index or table name in the same database.  Issue an error message if
Changes to src/main.c.
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24







-
+







**
*************************************************************************
** 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.237 2004/06/28 01:11:47 danielk1977 Exp $
** $Id: main.c,v 1.238 2004/06/29 07:45:34 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
81
82
83
84
85
86
87

88
89
90
91
92



93
94

95
96
97
98
99
100
101
102
103
81
82
83
84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99

100
101
102
103
104
105
106







+




-
+
+
+


+

-







      if( argv[3] && argv[3][0] ){
        /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
        ** But because db->init.busy is set to 1, no VDBE code is generated
        ** or executed.  All the parser does is build the internal data
        ** structures that describe the table, index, or view.
        */
        char *zErr;
        int rc;
        assert( db->init.busy );
        db->init.iDb = atoi(argv[4]);
        assert( db->init.iDb>=0 && db->init.iDb<db->nDb );
        db->init.newTnum = atoi(argv[2]);
        if( sqlite3_exec(db, argv[3], 0, 0, &zErr) ){
        rc = sqlite3_exec(db, argv[3], 0, 0, &zErr);
        db->init.iDb = 0;
        if( SQLITE_OK!=rc ){
          corruptSchema(pData, zErr);
          sqlite3_free(zErr);
          return rc;
        }
        db->init.iDb = 0;
      }else{
        /* If the SQL column is blank it means this is an index that
        ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
        ** constraint for a CREATE TABLE.  The index should have already
        ** been created when we processed the CREATE TABLE.  All we have
        ** to do here is record the root page number for that index.
        */
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132







-

+







          ** safely ignore the index on the permanent table.
          */
          /* Do Nothing */;
        }else{
          pIndex->tnum = atoi(argv[2]);
        }
      }
      break;
    }
    break;
    default: {
      /* This can not happen! */
      nErr = 1;
      assert( nErr==0 );
    }
  }
  return nErr;
192
193
194
195
196
197
198
199





200
201
202
203
204
205
206
195
196
197
198
199
200
201

202
203
204
205
206
207
208
209
210
211
212
213







-
+
+
+
+
+







  azArg[2] = "1";
  azArg[3] = zMasterSchema;
  sprintf(zDbNum, "%d", iDb);
  azArg[4] = zDbNum;
  azArg[5] = 0;
  initData.db = db;
  initData.pzErrMsg = pzErrMsg;
  sqlite3InitCallback(&initData, 5, (char **)azArg, 0);
  rc = sqlite3InitCallback(&initData, 5, (char **)azArg, 0);
  if( rc!=SQLITE_OK ){
    sqlite3SafetyOn(db);
    return rc;
  }
  pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName);
  if( pTab ){
    pTab->readOnly = 1;
  }
  sqlite3SafetyOn(db);

  /* Create a cursor to hold the database open
Changes to src/os_common.h.
40
41
42
43
44
45
46


47
48
49
50
51
52
53
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55







+
+







#define SEEK(X)           last_page=(X)
#define TRACE1(X)         if( sqlite3_os_trace ) sqlite3DebugPrintf(X)
#define TRACE2(X,Y)       if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y)
#define TRACE3(X,Y,Z)     if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z)
#define TRACE4(X,Y,Z,A)   if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A)
#define TRACE5(X,Y,Z,A,B) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A,B)
#define TRACE6(X,Y,Z,A,B,C) if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C)
#define TRACE7(X,Y,Z,A,B,C,D) \
    if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D)
#else
#define TIMER_START
#define TIMER_END
#define SEEK(X)
#define TRACE1(X)
#define TRACE2(X,Y)
#define TRACE3(X,Y,Z)
Changes to src/os_unix.c.
755
756
757
758
759
760
761


















762
763
764
765
766
767
768
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







  
  sqlite3OsLeaveMutex();
  TRACE3("TEST WR-LOCK %d %d\n", id->h, r);

  return r;
}

#ifdef SQLITE_DEBUG
/*
** Helper function for printing out trace information from debugging
** binaries. This returns the string represetation of the supplied
** integer lock-type.
*/
static const char * locktypeName(int locktype){
  switch( locktype ){
  case NO_LOCK: return "NONE";
  case SHARED_LOCK: return "SHARED";
  case RESERVED_LOCK: return "RESERVED";
  case PENDING_LOCK: return "PENDING";
  case EXCLUSIVE_LOCK: return "EXCLUSIVE";
  }
  return "ERROR";
}
#endif

/*
** Lock the file with the lock specified by parameter locktype - one
** of the following:
**
**     (1) SHARED_LOCK
**     (2) RESERVED_LOCK
**     (3) PENDING_LOCK
824
825
826
827
828
829
830
831
832



833
834
835
836
837
838

839
840
841
842
843
844
845
842
843
844
845
846
847
848


849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865







-
-
+
+
+






+







  */
  int rc = SQLITE_OK;
  struct lockInfo *pLock = id->pLock;
  struct flock lock;
  int s;

  assert( id->isOpen );
  TRACE6("LOCK %d %d was %d(%d,%d)\n",
          id->h, locktype, id->locktype, pLock->locktype, pLock->cnt);
  TRACE7("LOCK %d %s was %s(%s,%d) pid=%d\n", id->h, locktypeName(locktype), 
      locktypeName(id->locktype), locktypeName(pLock->locktype), pLock->cnt
      ,getpid() );

  /* If there is already a lock of this type or more restrictive on the
  ** OsFile, do nothing. Don't use the end_lock: exit path, as
  ** sqlite3OsEnterMutex() hasn't been called yet.
  */
  if( id->locktype>=locktype ){
    TRACE3("LOCK %d %s ok (already held)\n", id->h, locktypeName(locktype));
    return SQLITE_OK;
  }

  /* Make sure the locking sequence is correct
  */
  assert( id->locktype!=NO_LOCK || locktype==SHARED_LOCK );
  assert( locktype!=PENDING_LOCK );
952
953
954
955
956
957
958

959

960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978


979
980
981
982
983
984
985
972
973
974
975
976
977
978
979

980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997


998
999
1000
1001
1002
1003
1004
1005
1006







+
-
+

















-
-
+
+







  }else if( locktype==EXCLUSIVE_LOCK ){
    id->locktype = PENDING_LOCK;
    pLock->locktype = PENDING_LOCK;
  }

end_lock:
  sqlite3OsLeaveMutex();
  TRACE4("LOCK %d %s %s\n", id->h, locktypeName(locktype), 
  TRACE4("LOCK %d %d %s\n", id->h, locktype, rc==SQLITE_OK ? "ok" : "failed");
      rc==SQLITE_OK ? "ok" : "failed");
  return rc;
}

/*
** Lower the locking level on file descriptor id to locktype.  locktype
** must be either NO_LOCK or SHARED_LOCK.
**
** If the locking level of the file descriptor is already at or below
** the requested locking level, this routine is a no-op.
**
** It is not possible for this routine to fail.
*/
int sqlite3OsUnlock(OsFile *id, int locktype){
  struct lockInfo *pLock;
  struct flock lock;

  assert( id->isOpen );
  TRACE6("UNLOCK %d %d was %d(%d,%d)\n",
          id->h, locktype, id->locktype, id->pLock->locktype, id->pLock->cnt);
  TRACE7("UNLOCK %d %d was %d(%d,%d) pid=%d\n", id->h, locktype, id->locktype, 
      id->pLock->locktype, id->pLock->cnt, getpid());

  assert( locktype<=SHARED_LOCK );
  if( id->locktype<=locktype ){
    return SQLITE_OK;
  }
  sqlite3OsEnterMutex();
  pLock = id->pLock;
Changes to src/pragma.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21













-
+







/*
** 2003 April 6
**
** 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.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.54 2004/06/26 19:35:30 drh Exp $
** $Id: pragma.c,v 1.55 2004/06/29 07:45:34 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
# include "pager.h"
# include "btree.h"
115
116
117
118
119
120
121
122


123

124
125
126
127
128
129
130
115
116
117
118
119
120
121

122
123
124
125
126
127
128
129
130
131
132







-
+
+

+







  return 0;
}

/*
** Check to make sure the schema is loaded.  Return 1 if it is not.
*/
static int checkSchema(Parse *pParse){
  if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
  int rc = sqlite3ReadSchema(pParse->db, &pParse->zErrMsg);
  if( SQLITE_OK!=rc ){
    pParse->nErr++;
    pParse->rc = rc;
    return 1;
  }
  return 0;
}

/*
** Process a pragma statement.  
496
497
498
499
500
501
502

503
504
505
506
507
508
509
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512







+







        cnt++;
        for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
          if( sqlite3CheckIndexCollSeq(pParse, pIdx) ) goto pragma_out;
          sqlite3VdbeAddOp(v, OP_Integer, pIdx->tnum, 0);
          cnt++;
        }
      }
      assert( cnt>0 );
      sqlite3VdbeAddOp(v, OP_IntegrityCk, cnt, i);
      sqlite3VdbeAddOp(v, OP_Dup, 0, 1);
      addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_Eq, 0, addr+6);
      sqlite3VdbeOp3(v, OP_String8, 0, 0,
         sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName),
         P3_DYNAMIC);
Changes to test/threadtest1.c.
258
259
260
261
262
263
264





265





266
267
268
269
270
271
272
258
259
260
261
262
263
264
265
266
267
268
269

270
271
272
273
274
275
276
277
278
279
280
281







+
+
+
+
+
-
+
+
+
+
+







  for(i=0; i<n; i++){
    char zBuf[200];
    sprintf(zBuf, "testdb-%d", (i+1)/2);
    unlink(zBuf);
  }
  for(i=0; i<n; i++){
    zFile = sqlite3_mprintf("%d.testdb-%d", i%2+1, (i+2)/2);
    if( (i%2)==0 ){
      /* Remove both the database file and any old journal for the file
      ** being used by this thread and the next one. */
      char *zDb = &zFile[2];
      char *zJournal = sqlite3_mprintf("%s-journal", zDb);
    unlink(zFile);
      unlink(zDb);
      unlink(zJournal);
      free(zJournal);
    }
      
    pthread_create(&id, 0, worker_bee, (void*)zFile);
    pthread_detach(id);
  }
  pthread_mutex_lock(&lock);
  while( thread_cnt>0 ){
    pthread_cond_wait(&sig, &lock);
  }
Changes to test/threadtest2.c.
92
93
94
95
96
97
98
99






100
101
102
103
104
105
106
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106
107
108
109
110
111







-
+
+
+
+
+
+







** Initialize the database and start the threads
*/
int main(int argc, char **argv){
  sqlite *db;
  int i, rc;
  pthread_t aThread[5];

  if( strcmp(DB_FILE,":memory:") ) unlink(DB_FILE);
  if( strcmp(DB_FILE,":memory:") ){
    char *zJournal = sqlite3_mprintf("%s-journal", DB_FILE);
    unlink(DB_FILE);
    unlink(zJournal);
    free(zJournal);
  }  
  sqlite3_open(DB_FILE, &db);
  if( db==0 ){
    fprintf(stderr,"unable to initialize database\n");
    exit(1);
  }
  rc = sqlite3_exec(db, "CREATE TABLE t1(x);", 0,0,0);
  if( rc ){