Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Bug fix: sqlite_exec() would sometimes return SQLITE_PROTOCOL when it should have returned SQLITE_BUSY. There was also a deadlock that the previous bug was masking. (CVS 322) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
585ed5ebf1c1afc8ae1d569b12120801 |
User & Date: | drh 2001-12-05 00:21:20.000 |
Context
2001-12-05
| ||
00:22 | Version 2.1.4 (CVS 323) (check-in: 003f967e87 user: drh tags: trunk) | |
00:21 | Bug fix: sqlite_exec() would sometimes return SQLITE_PROTOCOL when it should have returned SQLITE_BUSY. There was also a deadlock that the previous bug was masking. (CVS 322) (check-in: 585ed5ebf1 user: drh tags: trunk) | |
2001-11-25
| ||
13:18 | Add the ability to do a single .command as the second argument to the command-line shell. (CVS 321) (check-in: 653f37c365 user: drh tags: trunk) | |
Changes
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** 2001 September 15 ** ** 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: btree.c,v 1.42 2001/12/05 00:21:20 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to ** ** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: ** "Sorting And Searching", pages 473-480. Addison-Wesley ** Publishing Company, Reading, Massachusetts. |
︙ | ︙ | |||
671 672 673 674 675 676 677 678 679 680 681 682 683 684 | return rc; page1_init_failed: sqlitepager_unref(pBt->page1); pBt->page1 = 0; return rc; } /* ** Create a new database by initializing the first two pages of the ** file. */ static int newDatabase(Btree *pBt){ MemPage *pRoot; | > > > > > > > > > > > > > > > > > > | 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 | return rc; page1_init_failed: sqlitepager_unref(pBt->page1); pBt->page1 = 0; return rc; } /* ** If there are no outstanding cursors and we are not in the middle ** of a transaction but there is a read lock on the database, then ** this routine unrefs the first page of the database file which ** has the effect of releasing the read lock. ** ** If there are any outstanding cursors, this routine is a no-op. ** ** If there is a transaction in progress, this routine is a no-op. */ static void unlockBtreeIfUnused(Btree *pBt){ if( pBt->inTrans==0 && pBt->pCursor==0 && pBt->page1!=0 ){ sqlitepager_unref(pBt->page1); pBt->page1 = 0; pBt->inTrans = 0; } } /* ** Create a new database by initializing the first two pages of the ** file. */ static int newDatabase(Btree *pBt){ MemPage *pRoot; |
︙ | ︙ | |||
721 722 723 724 725 726 727 | if( pBt->inTrans ) return SQLITE_ERROR; if( pBt->page1==0 ){ rc = lockBtree(pBt); if( rc!=SQLITE_OK ){ return rc; } } | | < < | | > > > | < | < < < < < < < < < < < | < < < < > | 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 | if( pBt->inTrans ) return SQLITE_ERROR; if( pBt->page1==0 ){ rc = lockBtree(pBt); if( rc!=SQLITE_OK ){ return rc; } } if( sqlitepager_isreadonly(pBt->pPager) ){ return SQLITE_READONLY; } rc = sqlitepager_write(pBt->page1); if( rc==SQLITE_OK ){ rc = newDatabase(pBt); } if( rc==SQLITE_OK ){ pBt->inTrans = 1; }else{ unlockBtreeIfUnused(pBt); } return rc; } /* ** Commit the transaction currently in progress. ** ** This will release the write lock on the database file. If there ** are no active cursors, it also releases the read lock. */ int sqliteBtreeCommit(Btree *pBt){ |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
21 22 23 24 25 26 27 | ** COPY ** VACUUM ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | ** COPY ** VACUUM ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** ** $Id: build.c,v 1.58 2001/12/05 00:21:20 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 |
︙ | ︙ | |||
549 550 551 552 553 554 555 | ** the schema to change multiple times and for the cookie to be ** set back to prior value. But schema changes are infrequent ** and the probability of hitting the same cookie value is only ** 1 chance in 2^32. So we're safe enough. */ static void changeCookie(sqlite *db){ if( db->next_cookie==db->schema_cookie ){ | | | 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 | ** the schema to change multiple times and for the cookie to be ** set back to prior value. But schema changes are infrequent ** and the probability of hitting the same cookie value is only ** 1 chance in 2^32. So we're safe enough. */ static void changeCookie(sqlite *db){ if( db->next_cookie==db->schema_cookie ){ db->next_cookie = db->schema_cookie + sqliteRandomByte() + 1; db->flags |= SQLITE_InternChanges; } } /* ** This routine is called to report the final ")" that terminates ** a CREATE TABLE statement. |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** 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. ** | | | 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.51 2001/12/05 00:21:20 drh Exp $ */ #include "sqliteInt.h" #include "os.h" /* ** This is the callback routine for the code that initializes the ** database. See sqliteInit() below for additional information. |
︙ | ︙ | |||
261 262 263 264 265 266 267 | /* Allocate the sqlite data structure */ db = sqliteMalloc( sizeof(sqlite) ); if( pzErrMsg ) *pzErrMsg = 0; if( db==0 ) goto no_mem_on_open; sqliteHashInit(&db->tblHash, SQLITE_HASH_STRING, 0); sqliteHashInit(&db->idxHash, SQLITE_HASH_STRING, 0); | | | 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | /* Allocate the sqlite data structure */ db = sqliteMalloc( sizeof(sqlite) ); if( pzErrMsg ) *pzErrMsg = 0; if( db==0 ) goto no_mem_on_open; sqliteHashInit(&db->tblHash, SQLITE_HASH_STRING, 0); sqliteHashInit(&db->idxHash, SQLITE_HASH_STRING, 0); db->nextRowid = sqliteRandomInteger(); /* Open the backend database driver */ rc = sqliteBtreeOpen(zFilename, mode, MAX_PAGES, &db->pBe); if( rc!=SQLITE_OK ){ switch( rc ){ default: { if( pzErrMsg ){ |
︙ | ︙ |
Changes to src/os.h.
︙ | ︙ | |||
55 56 57 58 59 60 61 | int sqliteOsSync(OsFile); int sqliteOsTruncate(OsFile, int size); int sqliteOsFileSize(OsFile, int *pSize); int sqliteOsLock(OsFile, int wrlock); int sqliteOsUnlock(OsFile); int sqliteOsRandomSeed(char*); int sqliteOsSleep(int ms); | | | | 55 56 57 58 59 60 61 62 63 64 65 66 67 | int sqliteOsSync(OsFile); int sqliteOsTruncate(OsFile, int size); int sqliteOsFileSize(OsFile, int *pSize); int sqliteOsLock(OsFile, int wrlock); int sqliteOsUnlock(OsFile); int sqliteOsRandomSeed(char*); int sqliteOsSleep(int ms); void sqliteOsEnterMutex(void); void sqliteOsLeaveMutex(void); #endif /* _SQLITE_OS_H_ */ |
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** 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. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** 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.32 2001/12/05 00:21:20 drh Exp $ */ #include "sqliteInt.h" #include "pager.h" #include "os.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
951 952 953 954 955 956 957 958 959 960 961 | sqliteOsClose(pPager->jfd); sqliteOsDelete(pPager->zJournal); pPager->journalOpen = 0; return SQLITE_BUSY; } sqliteOsUnlock(pPager->fd); if( sqliteOsLock(pPager->fd, 1)!=SQLITE_OK ){ sqliteFree(pPager->aInJournal); sqliteOsClose(pPager->jfd); sqliteOsDelete(pPager->zJournal); pPager->journalOpen = 0; | > > > | | | > > > > | 951 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 | sqliteOsClose(pPager->jfd); sqliteOsDelete(pPager->zJournal); pPager->journalOpen = 0; return SQLITE_BUSY; } sqliteOsUnlock(pPager->fd); if( sqliteOsLock(pPager->fd, 1)!=SQLITE_OK ){ sqliteOsUnlock(pPager->fd); rc = sqliteOsLock(pPager->fd, 0); sqliteFree(pPager->aInJournal); sqliteOsClose(pPager->jfd); sqliteOsDelete(pPager->zJournal); pPager->journalOpen = 0; if( rc ){ pPager->state = SQLITE_UNLOCK; pPager->errMask |= PAGER_ERR_LOCK; return SQLITE_PROTOCOL; }else{ pPager->state = SQLITE_READLOCK; return SQLITE_BUSY; } } pPager->state = SQLITE_WRITELOCK; sqlitepager_pagecount(pPager); pPager->origDbSize = pPager->dbSize; rc = sqliteOsWrite(pPager->jfd, aJournalMagic, sizeof(aJournalMagic)); if( rc==SQLITE_OK ){ rc = sqliteOsWrite(pPager->jfd, &pPager->dbSize, sizeof(Pgno)); |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.72 2001/12/05 00:21:20 drh Exp $ */ #include "sqlite.h" #include "hash.h" #include "vdbe.h" #include "parse.h" #include "btree.h" #include <stdio.h> |
︙ | ︙ | |||
515 516 517 518 519 520 521 | int sqliteExprCompare(Expr*, Expr*); int sqliteFuncId(Token*); int sqliteExprResolveIds(Parse*, IdList*, Expr*); void sqliteExprResolveInSelect(Parse*, Expr*); int sqliteExprAnalyzeAggregates(Parse*, Expr*); void sqliteParseInfoReset(Parse*); Vdbe *sqliteGetVdbe(Parse*); | | | | 515 516 517 518 519 520 521 522 523 524 525 526 527 | int sqliteExprCompare(Expr*, Expr*); int sqliteFuncId(Token*); int sqliteExprResolveIds(Parse*, IdList*, Expr*); void sqliteExprResolveInSelect(Parse*, Expr*); int sqliteExprAnalyzeAggregates(Parse*, Expr*); void sqliteParseInfoReset(Parse*); Vdbe *sqliteGetVdbe(Parse*); int sqliteRandomByte(void); int sqliteRandomInteger(void); void sqliteBeginTransaction(Parse*); void sqliteCommitTransaction(Parse*); void sqliteRollbackTransaction(Parse*); char *sqlite_mprintf(const char *, ...); |
Changes to www/changes.tcl.
︙ | ︙ | |||
13 14 15 16 17 18 19 | proc chng {date desc} { puts "<DT><B>$date</B></DT>" puts "<DD><P><UL>$desc</UL></P></DD>" } | | > > > > > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | proc chng {date desc} { puts "<DT><B>$date</B></DT>" puts "<DD><P><UL>$desc</UL></P></DD>" } chng {2001 Dec 4 (2.1.4)} { <li>Sometime <b>sqlite_exec()</b> would return SQLITE_PROTOCOL when it should have returned SQLITE_BUSY.</li> <li>The fix to the previous bug uncovered a deadlock which was also fixed.</li> <li>Add the ability to put a single .command in the second argument of the sqlite shell</li> <li>Updates to the FAQ</li> } chng {2001 Nov 23 (2.1.3)} { <li>Fix the behavior of comparison operators (ex: "<b><</b>", "<b>==</b>", etc.) so that they are consistent with the order of entries in an index.</li> <li>Correct handling of integers in SQL expressions that are larger than |
︙ | ︙ |
Changes to www/faq.tcl.
1 2 3 | # # Run this script to generated a faq.html output file # | | | 1 2 3 4 5 6 7 8 9 10 11 | # # Run this script to generated a faq.html output file # set rcsid {$Id: faq.tcl,v 1.3 2001/12/05 00:21:21 drh Exp $} puts {<html> <head> <title>SQLite Frequently Asked Questions</title> </head> <body bgcolor="white"> <h1 align="center">Frequently Asked Questions</h1> |
︙ | ︙ | |||
89 90 91 92 93 94 95 | <p>If only one string in a comparison is a pure numeric, then that string is assumed to be less than the other. Of neither string is a pure numeric, then <b>strcmp()</b> is used for the comparison.</p> } faq { | | | < | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | <p>If only one string in a comparison is a pure numeric, then that string is assumed to be less than the other. Of neither string is a pure numeric, then <b>strcmp()</b> is used for the comparison.</p> } faq { Why does the second INSERT in the following sequence of commands throw a constraint exception? <blockquote> CREATE TABLE t(s varchar(10) primary key);<br> INSERT INTO t VALUES('0');<br> INSERT INTO t VALUES('0.0');<br> </blockquote> } { <p>Because column <b>s</b> is a primary key, all values of <b>s</b> must be unique. But SQLite thinks that <b>'0'</b> and <b>'0.0'</b> are the same value because they compare equal to one another numerically. (See the previous question.) Hence the values are not unique and the constraint fails.</p> |
︙ | ︙ | |||
120 121 122 123 124 125 126 | </ol> } faq { My linux box is not able to read an SQLite database that was created on my SparcStation. } { | | | 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | </ol> } faq { My linux box is not able to read an SQLite database that was created on my SparcStation. } { <p>The x86 processor on your linux box is little-endian (meaning that the least signification byte of integers comes first) but the Sparc is big-endian (the most significant bytes comes first). SQLite databases created on a little-endian architecture cannot be used on a big-endian machine and vice versa.</p> <p>If you need to move the database from one machine to another, you'll have to do an ASCII dump of the database on the source machine and then |
︙ | ︙ | |||
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | <p>The SQLITE_MASTER table is read-only. You cannot change this table using UPDATE, INSERT, or DELETE. The table is automatically updated by CREATE TABLE, CREATE INDEX, DROP TABLE, and DROP INDEX commands.</p> <p>Temporary tables do not appear in the SQLITE_MASTER table. At this time there is no way to get a listing of temporary tables and indices.</p> } # End of questions and answers. ############# puts {<DL COMPACT>} for {set i 1} {$i<$cnt} {incr i} { puts " <DT><A HREF=\"#q$i\">($i)</A></DT>" puts " <DD>[lindex $faq($i) 0]</DD>" } | > > > > > > > > > > > > > > > > > > > > > > > > | | | > | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | <p>The SQLITE_MASTER table is read-only. You cannot change this table using UPDATE, INSERT, or DELETE. The table is automatically updated by CREATE TABLE, CREATE INDEX, DROP TABLE, and DROP INDEX commands.</p> <p>Temporary tables do not appear in the SQLITE_MASTER table. At this time there is no way to get a listing of temporary tables and indices.</p> } faq { Is there any known size limits to SQLite databases. } { <p>Internally, SQLite can handle databases up to 2^40 bytes (1 terabyte) in size. But the backend interface to POSIX and Win32 limits files to 2^31 (2 gigabytes).</p> <p>SQLite arbitrarily limits the amount of data in one row to 1 megabyte. There is a single #define in the source code that can be changed to raise this limit as high as 16 megabytes if desired.</p> <p>There is a theoretical limit of about 2^32 (4 billion) rows in a single table, but there is no way to test this limit without exceeding the maximum file size, so it is not really an issue. There is also a theoretical limit of about 2^32 tables and indices, but again it is not really possible to reach this limit due to the file size constraint.</p> <p>The name and "CREATE TABLE" statement for a table must fit entirely within a 1-megabyte row of the SQLITE_MASTER table. Other than this, there are no constraints on the length of the name of a table, or on the number of columns, etc. Indices are similarly unconstrained.</p> } # End of questions and answers. ############# puts {<DL COMPACT>} for {set i 1} {$i<$cnt} {incr i} { puts " <DT><A HREF=\"#q$i\">($i)</A></DT>" puts " <DD>[lindex $faq($i) 0]</DD>" } puts {</DL>} for {set i 1} {$i<$cnt} {incr i} { puts "<A NAME=\"q$i\"><HR />" puts "<P><B>($i) [lindex $faq($i) 0]</B></P>\n" puts "<BLOCKQUOTE>[lindex $faq($i) 1]</BLOCKQUOTE></LI>\n" } puts { </OL> <p><hr /></p> <p><a href="index.html"><img src="/goback.jpg" border=0 /> Back to the SQLite Home Page</a> </p> </body></html>} |