/ Check-in [a9db1c12]
Login
Overview
Comment:Fix a bug in the locking protocol. (CVS 315)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:a9db1c12c5a4d5741de0e5eb5aa87c647a5646b8
User & Date: drh 2001-11-22 00:01:27
Context
2001-11-23
00:24
Fix a bug in DROP TABLE that could cause SQLITE_MASTER table corruption. The root problem was that the sequence of BTree operations (Delete, Next) would not always leave the cursor pointing at the first entry after the entry that was deleted. A consequence of this error was that a DROP TABLE on a table with indices would not always remove every index associated with that table from the SQLITE_MASTER table. Subsequent attempts to open the database will fail when the index for the missing table was parsed. Changes have also been made to ignore extra indices in the SQLITE_MASTER table so that a database previously corrupted by this bug is once again readable. (CVS 316) check-in: 8a984667 user: drh tags: trunk
2001-11-22
00:01
Fix a bug in the locking protocol. (CVS 315) check-in: a9db1c12 user: drh tags: trunk
2001-11-21
02:21
Attempting to add support for 64-bit platforms. (CVS 314) check-in: 03673adb user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
....
1459
1460
1461
1462
1463
1464
1465








1466
1467
1468
1469
1470
1471
1472
**     COPY
**     VACUUM
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.56 2001/11/21 02:21:12 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called after a single SQL statement has been
** parsed and we want to execute the VDBE code to implement 
................................................................................
  if( sqliteStrICmp(zLeft, "full_column_names")==0 ){
    if( getBoolean(zRight) ){
      db->flags |= SQLITE_FullColNames;
    }else{
      db->flags &= ~SQLITE_FullColNames;
    }
  }else









  if( sqliteStrICmp(zLeft, "count_changes")==0 ){
    if( getBoolean(zRight) ){
      db->flags |= SQLITE_CountRows;
    }else{
      db->flags &= ~SQLITE_CountRows;
    }







|







 







>
>
>
>
>
>
>
>







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
....
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
**     COPY
**     VACUUM
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.57 2001/11/22 00:01:27 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called after a single SQL statement has been
** parsed and we want to execute the VDBE code to implement 
................................................................................
  if( sqliteStrICmp(zLeft, "full_column_names")==0 ){
    if( getBoolean(zRight) ){
      db->flags |= SQLITE_FullColNames;
    }else{
      db->flags &= ~SQLITE_FullColNames;
    }
  }else

  if( sqliteStrICmp(zLeft, "result_set_details")==0 ){
    if( getBoolean(zRight) ){
      db->flags |= SQLITE_ResultDetails;
    }else{
      db->flags &= ~SQLITE_ResultDetails;
    }
  }else

  if( sqliteStrICmp(zLeft, "count_changes")==0 ){
    if( getBoolean(zRight) ){
      db->flags |= SQLITE_CountRows;
    }else{
      db->flags &= ~SQLITE_CountRows;
    }

Changes to src/os.c.

458
459
460
461
462
463
464
465
466

467
468
469
470
471
472
473
#if OS_WIN
  CloseHandle(id);
  return SQLITE_OK;
#endif
}

/*
** Read data from a file into a buffer.  Return the number of
** bytes actually read.

*/
int sqliteOsRead(OsFile id, void *pBuf, int amt){
#if OS_UNIX
  int got;
  SimulateIOError(SQLITE_IOERR);
  got = read(id.fd, pBuf, amt);
  if( got<0 ) got = 0;







|
|
>







458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
#if OS_WIN
  CloseHandle(id);
  return SQLITE_OK;
#endif
}

/*
** Read data from a file into a buffer.  Return SQLITE_OK if all
** bytes were read successfully and SQLITE_IOERR if anything goes
** wrong.
*/
int sqliteOsRead(OsFile id, void *pBuf, int amt){
#if OS_UNIX
  int got;
  SimulateIOError(SQLITE_IOERR);
  got = read(id.fd, pBuf, amt);
  if( got<0 ) got = 0;

Changes to src/pager.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
296
297
298
299
300
301
302
303
304
305
306
307












308
309
310
311
312
313
314
...
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.30 2001/11/10 13:51:09 drh Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
#include "os.h"
#include <assert.h>
#include <string.h>

................................................................................
  int i;                   /* Loop counter */
  Pgno mxPg = 0;           /* Size of the original file in pages */
  PgHdr *pPg;              /* An existing page in the cache */
  PageRecord pgRec;
  unsigned char aMagic[sizeof(aJournalMagic)];
  int rc;

  /* Read the beginning of the journal and truncate the
  ** database file back to its original size.
  */
  assert( pPager->journalOpen );
  sqliteOsSeek(pPager->jfd, 0);












  rc = sqliteOsRead(pPager->jfd, aMagic, sizeof(aMagic));
  if( rc!=SQLITE_OK || memcmp(aMagic,aJournalMagic,sizeof(aMagic))!=0 ){
    rc = SQLITE_PROTOCOL;
    goto end_playback;
  }
  rc = sqliteOsRead(pPager->jfd, &mxPg, sizeof(mxPg));
  if( rc!=SQLITE_OK ){
................................................................................
  }
  rc = sqliteOsTruncate(pPager->fd, mxPg*SQLITE_PAGE_SIZE);
  if( rc!=SQLITE_OK ){
    goto end_playback;
  }
  pPager->dbSize = mxPg;
  
  /* Begin reading the journal beginning at the end and moving
  ** toward the beginning.
  */
  rc = sqliteOsFileSize(pPager->jfd, &nRec);
  if( rc!=SQLITE_OK ){
    goto end_playback;
  }
  nRec = (nRec - (sizeof(aMagic)+sizeof(Pgno))) / sizeof(PageRecord);

  /* Process segments beginning with the last and working backwards
  ** to the first.
  */
  for(i=nRec-1; i>=0; i--){
    /* Seek to the beginning of the segment */
    int ofst;
    ofst = i*sizeof(PageRecord) + sizeof(aMagic) + sizeof(Pgno);







|







 







|
|



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







 







<
<
<
<
<
<
<
<
<







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
...
328
329
330
331
332
333
334









335
336
337
338
339
340
341
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.31 2001/11/22 00:01:27 drh Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
#include "os.h"
#include <assert.h>
#include <string.h>

................................................................................
  int i;                   /* Loop counter */
  Pgno mxPg = 0;           /* Size of the original file in pages */
  PgHdr *pPg;              /* An existing page in the cache */
  PageRecord pgRec;
  unsigned char aMagic[sizeof(aJournalMagic)];
  int rc;

  /* Figure out how many records are in the journal.  Abort early if
  ** the journal is empty.
  */
  assert( pPager->journalOpen );
  sqliteOsSeek(pPager->jfd, 0);
  rc = sqliteOsFileSize(pPager->jfd, &nRec);
  if( rc!=SQLITE_OK ){
    goto end_playback;
  }
  nRec = (nRec - (sizeof(aMagic)+sizeof(Pgno))) / sizeof(PageRecord);
  if( nRec<=0 ){
    goto end_playback;
  }

  /* Read the beginning of the journal and truncate the
  ** database file back to its original size.
  */
  rc = sqliteOsRead(pPager->jfd, aMagic, sizeof(aMagic));
  if( rc!=SQLITE_OK || memcmp(aMagic,aJournalMagic,sizeof(aMagic))!=0 ){
    rc = SQLITE_PROTOCOL;
    goto end_playback;
  }
  rc = sqliteOsRead(pPager->jfd, &mxPg, sizeof(mxPg));
  if( rc!=SQLITE_OK ){
................................................................................
  }
  rc = sqliteOsTruncate(pPager->fd, mxPg*SQLITE_PAGE_SIZE);
  if( rc!=SQLITE_OK ){
    goto end_playback;
  }
  pPager->dbSize = mxPg;
  









  /* Process segments beginning with the last and working backwards
  ** to the first.
  */
  for(i=nRec-1; i>=0; i--){
    /* Seek to the beginning of the segment */
    int ofst;
    ofst = i*sizeof(PageRecord) + sizeof(aMagic) + sizeof(Pgno);

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
194
195
196
197
198
199
200

201
202
203
204
205
206
207
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.70 2001/11/21 02:21:12 drh Exp $
*/
#include "sqlite.h"
#include "hash.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
#include <stdio.h>
................................................................................
#define SQLITE_InternChanges  0x00000010  /* Uncommitted Hash table changes */
#define SQLITE_FullColNames   0x00000020  /* Show full column names on SELECT */
#define SQLITE_CountRows      0x00000040  /* Count rows changed by INSERT, */
                                          /*   DELETE, or UPDATE and return */
                                          /*   the count using a callback. */
#define SQLITE_NullCallback   0x00000080  /* Invoke the callback once if the */
                                          /*   result set is empty */


/*
** Current file format version
*/
#define SQLITE_FileFormat 2

/*







|







 







>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.71 2001/11/22 00:01:27 drh Exp $
*/
#include "sqlite.h"
#include "hash.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
#include <stdio.h>
................................................................................
#define SQLITE_InternChanges  0x00000010  /* Uncommitted Hash table changes */
#define SQLITE_FullColNames   0x00000020  /* Show full column names on SELECT */
#define SQLITE_CountRows      0x00000040  /* Count rows changed by INSERT, */
                                          /*   DELETE, or UPDATE and return */
                                          /*   the count using a callback. */
#define SQLITE_NullCallback   0x00000080  /* Invoke the callback once if the */
                                          /*   result set is empty */
#define SQLITE_ResultDetails  0x00000100  /* Details added to result set */

/*
** Current file format version
*/
#define SQLITE_FileFormat 2

/*

Changes to www/changes.tcl.

15
16
17
18
19
20
21

22
23
24
25
26
27
28
proc chng {date desc} {
  puts "<DT><B>$date</B></DT>"
  puts "<DD><P><UL>$desc</UL></P></DD>"
}

chng {2001 Nov ?? (2.1.2)} {
<li>Changes to support 64-bit architectures.</li>

}

chng {2001 Nov 13 (2.1.1)} {
<li>Bug fix: Sometimes arbirary strings were passed to the callback
    function when the actual value of a column was NULL.</li>
}








>







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
proc chng {date desc} {
  puts "<DT><B>$date</B></DT>"
  puts "<DD><P><UL>$desc</UL></P></DD>"
}

chng {2001 Nov ?? (2.1.2)} {
<li>Changes to support 64-bit architectures.</li>
<li>Fix a bug in the locking protocol.</li>
}

chng {2001 Nov 13 (2.1.1)} {
<li>Bug fix: Sometimes arbirary strings were passed to the callback
    function when the actual value of a column was NULL.</li>
}