Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Comment and documentation changes. (CVS 331) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
e8595579a5218aa3f344f967a23ac52e |
User & Date: | drh 2001-12-15 14:22:19.000 |
Context
2001-12-16
| ||
20:05 | Added the ability to say things like "SELECT rowid, * FROM table1;" (CVS 332) (check-in: ffbdd43f5d user: drh tags: trunk) | |
2001-12-15
| ||
14:22 | Comment and documentation changes. (CVS 331) (check-in: e8595579a5 user: drh tags: trunk) | |
03:05 | Version 2.1.7 (CVS 454) (check-in: 0d44465347 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.45 2001/12/15 14:22:19 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. |
︙ | ︙ | |||
247 248 249 250 251 252 253 | Pgno iNext; char aPayload[OVERFLOW_SIZE]; }; /* ** For every page in the database file, an instance of the following structure ** is stored in memory. The u.aDisk[] array contains the raw bits read from | | | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | Pgno iNext; char aPayload[OVERFLOW_SIZE]; }; /* ** For every page in the database file, an instance of the following structure ** is stored in memory. The u.aDisk[] array contains the raw bits read from ** the disk. The rest is auxiliary information held in memory only. The ** auxiliary info is only valid for regular database pages - it is not ** used for overflow pages and pages on the freelist. ** ** Of particular interest in the auxiliary info is the apCell[] entry. Each ** apCell[] entry is a pointer to a Cell structure in u.aDisk[]. The cells are ** put in this array so that they can be accessed in constant time, rather ** than in linear time which would be needed if we had to walk the linked |
︙ | ︙ | |||
631 632 633 634 635 636 637 | sqlitepager_close(pBt->pPager); sqliteHashClear(&pBt->locks); sqliteFree(pBt); return SQLITE_OK; } /* | | | 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 | sqlitepager_close(pBt->pPager); sqliteHashClear(&pBt->locks); sqliteFree(pBt); return SQLITE_OK; } /* ** Change the limit on the number of pages allowed the cache. */ int sqliteBtreeSetCacheSize(Btree *pBt, int mxPage){ sqlitepager_set_cachesize(pBt->pPager, mxPage); return SQLITE_OK; } /* |
︙ | ︙ | |||
802 803 804 805 806 807 808 | ** Create a new cursor for the BTree whose root is on the page ** iTable. The act of acquiring a cursor gets a read lock on ** the database file. ** ** If wrFlag==0, then the cursor can only be used for reading. ** If wrFlag==1, then the cursor can be used for reading or writing. ** A read/write cursor requires exclusive access to its table. There | | > > > > | 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 | ** Create a new cursor for the BTree whose root is on the page ** iTable. The act of acquiring a cursor gets a read lock on ** the database file. ** ** If wrFlag==0, then the cursor can only be used for reading. ** If wrFlag==1, then the cursor can be used for reading or writing. ** A read/write cursor requires exclusive access to its table. There ** cannot be two or more cursors open on the same table if any one of ** cursors is a read/write cursor. But there can be two or more ** read-only cursors open on the same table. ** ** No checking is done to make sure that page iTable really is the ** root page of a b-tree. If it is not, then the cursor acquired ** will not work correctly. */ int sqliteBtreeCursor(Btree *pBt, int iTable, int wrFlag, BtCursor **ppCur){ int rc; BtCursor *pCur; ptr nLock; if( pBt->page1==0 ){ |
︙ | ︙ |
Changes to src/btree.h.
1 2 3 4 5 6 7 8 9 10 11 12 | /* ** 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. ** ************************************************************************* ** This header file defines the interface that the sqlite B-Tree file | | > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /* ** 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. ** ************************************************************************* ** This header file defines the interface that the sqlite B-Tree file ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** ** @(#) $Id: btree.h,v 1.18 2001/12/15 14:22:19 drh Exp $ */ #ifndef _BTREE_H_ #define _BTREE_H_ typedef struct Btree Btree; typedef struct BtCursor BtCursor; |
︙ | ︙ |
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.34 2001/12/15 14:22:19 drh Exp $ */ #include "sqliteInt.h" #include "pager.h" #include "os.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
226 227 228 229 230 231 232 | } /* ** When this routine is called, the pager has the journal file open and ** a write lock on the database. This routine releases the database ** write lock and acquires a read lock in its place. The journal file ** is deleted and closed. | < < < < < < < < < < < | 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | } /* ** When this routine is called, the pager has the journal file open and ** a write lock on the database. This routine releases the database ** write lock and acquires a read lock in its place. The journal file ** is deleted and closed. */ static int pager_unwritelock(Pager *pPager){ int rc; PgHdr *pPg; if( pPager->state!=SQLITE_WRITELOCK ) return SQLITE_OK; sqliteOsClose(&pPager->jfd); pPager->journalOpen = 0; |
︙ | ︙ | |||
269 270 271 272 273 274 275 | ** file-type string for sanity checking. Then there is a single ** Pgno number which is the number of pages in the database before ** changes were made. The database is truncated to this size. ** Next come zero or more page records where each page record ** consists of a Pgno and SQLITE_PAGE_SIZE bytes of data. See ** the PageRecord structure for details. ** | | > > > > > > > | 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | ** file-type string for sanity checking. Then there is a single ** Pgno number which is the number of pages in the database before ** changes were made. The database is truncated to this size. ** Next come zero or more page records where each page record ** consists of a Pgno and SQLITE_PAGE_SIZE bytes of data. See ** the PageRecord structure for details. ** ** For playback, the pages are read from the journal in ** reverse order and put back into the original database file. ** It used to be required to replay pages in reverse order because ** there was a possibility of a page appearing in the journal more ** than once. In that case, the original value of the page was ** the first entry so it should be reset last. But now, a bitmap ** is used to record every page that is in the journal. No pages ** are ever repeated. So we could, in theory, playback the journal ** in the forward direction and it would still work. ** ** If the file opened as the journal file is not a well-formed ** journal file (as determined by looking at the magic number ** at the beginning) then this routine returns SQLITE_PROTOCOL. ** If any other errors occur during playback, the database will ** likely be corrupted, so the PAGER_ERR_CORRUPT bit is set in ** pPager->errMask and SQLITE_CORRUPT is returned. If it all |
︙ | ︙ | |||
379 380 381 382 383 384 385 | /* ** Create a new page cache and put a pointer to the page cache in *ppPager. ** The file to be cached need not exist. The file is not locked until ** the first call to sqlitepager_get() and is only held open until the ** last page is released using sqlitepager_unref(). ** | | | | | 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 | /* ** Create a new page cache and put a pointer to the page cache in *ppPager. ** The file to be cached need not exist. The file is not locked until ** the first call to sqlitepager_get() and is only held open until the ** last page is released using sqlitepager_unref(). ** ** If zFilename is NULL then a randomly-named temporary file is created ** and used as the file to be cached. The file will be deleted ** automatically when it is closed. */ int sqlitepager_open( Pager **ppPager, /* Return the Pager structure here */ const char *zFilename, /* Name of the database file to open */ int mxPage, /* Max number of in-memory cache pages */ int nExtra /* Extra bytes append to each in-memory page */ ){ |
︙ | ︙ | |||
569 570 571 572 573 574 575 | /* ** Sync the journal and then write all free dirty pages to the database ** file. ** ** Writing all free dirty pages to the database after the sync is a ** non-obvious optimization. fsync() is an expensive operation so we | | | | | > | | 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 | /* ** Sync the journal and then write all free dirty pages to the database ** file. ** ** Writing all free dirty pages to the database after the sync is a ** non-obvious optimization. fsync() is an expensive operation so we ** want to minimize the number it is called. After an fsync() call, ** we are free to write dirty pages back to the database. It is best ** to go ahead and write as many dirty pages as possible to minimize ** the risk of having to do another fsync() later on. Writing dirty ** free pages in this way was observed to make database operations go ** up to 10 times faster. */ static int syncAllPages(Pager *pPager){ PgHdr *pPg; int rc = SQLITE_OK; if( pPager->needSync ){ rc = sqliteOsSync(&pPager->jfd); if( rc!=0 ) return rc; |
︙ | ︙ | |||
648 649 650 651 652 653 654 | if( sqliteOsFileExists(pPager->zJournal) ){ int rc, dummy; /* Get a write lock on the database */ rc = sqliteOsWriteLock(&pPager->fd); if( rc!=SQLITE_OK ){ | | | 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 | if( sqliteOsFileExists(pPager->zJournal) ){ int rc, dummy; /* Get a write lock on the database */ rc = sqliteOsWriteLock(&pPager->fd); if( rc!=SQLITE_OK ){ rc = sqliteOsUnlock(&pPager->fd); assert( rc==SQLITE_OK ); *ppPage = 0; return SQLITE_BUSY; } pPager->state = SQLITE_WRITELOCK; /* Open the journal for exclusive access. Return SQLITE_BUSY if |
︙ | ︙ | |||
908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 | ** reset. */ int sqlitepager_write(void *pData){ PgHdr *pPg = DATA_TO_PGHDR(pData); Pager *pPager = pPg->pPager; int rc = SQLITE_OK; if( pPager->errMask ){ return pager_errcode(pPager); } if( pPager->readOnly ){ return SQLITE_PERM; } pPg->dirty = 1; if( pPg->inJournal ){ return SQLITE_OK; } assert( pPager->state!=SQLITE_UNLOCK ); if( pPager->state==SQLITE_READLOCK ){ assert( pPager->aInJournal==0 ); rc = sqliteOsWriteLock(&pPager->fd); if( rc!=SQLITE_OK ){ return rc; } | > > > > > > > > > > > | 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 | ** reset. */ int sqlitepager_write(void *pData){ PgHdr *pPg = DATA_TO_PGHDR(pData); Pager *pPager = pPg->pPager; int rc = SQLITE_OK; /* Check for errors */ if( pPager->errMask ){ return pager_errcode(pPager); } if( pPager->readOnly ){ return SQLITE_PERM; } /* Mark the page as dirty. If the page has already been written ** to the journal then we can return right away. */ pPg->dirty = 1; if( pPg->inJournal ){ return SQLITE_OK; } /* If we get this far, it means that the page needs to be ** written to the journal file. First check to see if the ** journal exists and create it if it does not. */ assert( pPager->state!=SQLITE_UNLOCK ); if( pPager->state==SQLITE_READLOCK ){ assert( pPager->aInJournal==0 ); rc = sqliteOsWriteLock(&pPager->fd); if( rc!=SQLITE_OK ){ return rc; } |
︙ | ︙ | |||
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 | rc = pager_unwritelock(pPager); if( rc==SQLITE_OK ) rc = SQLITE_FULL; return rc; } } assert( pPager->state==SQLITE_WRITELOCK ); assert( pPager->journalOpen ); if( pPg->pgno <= pPager->origDbSize ){ rc = sqliteOsWrite(&pPager->jfd, &pPg->pgno, sizeof(Pgno)); if( rc==SQLITE_OK ){ rc = sqliteOsWrite(&pPager->jfd, pData, SQLITE_PAGE_SIZE); } if( rc!=SQLITE_OK ){ sqlitepager_rollback(pPager); pPager->errMask |= PAGER_ERR_FULL; return rc; } assert( pPager->aInJournal!=0 ); pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7); pPager->needSync = 1; } pPg->inJournal = 1; if( pPager->dbSize<pPg->pgno ){ pPager->dbSize = pPg->pgno; } return rc; } | > > > > > > > | 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 986 987 988 989 990 991 992 993 994 | rc = pager_unwritelock(pPager); if( rc==SQLITE_OK ) rc = SQLITE_FULL; return rc; } } assert( pPager->state==SQLITE_WRITELOCK ); assert( pPager->journalOpen ); /* The journal now exists and we have a write lock on the ** main database file. Write the current page to the journal. */ if( pPg->pgno <= pPager->origDbSize ){ rc = sqliteOsWrite(&pPager->jfd, &pPg->pgno, sizeof(Pgno)); if( rc==SQLITE_OK ){ rc = sqliteOsWrite(&pPager->jfd, pData, SQLITE_PAGE_SIZE); } if( rc!=SQLITE_OK ){ sqlitepager_rollback(pPager); pPager->errMask |= PAGER_ERR_FULL; return rc; } assert( pPager->aInJournal!=0 ); pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7); pPager->needSync = 1; } /* Mark the current page as being in the journal and return. */ pPg->inJournal = 1; if( pPager->dbSize<pPg->pgno ){ pPager->dbSize = pPg->pgno; } return rc; } |
︙ | ︙ |
Changes to src/pager.h.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite page cache ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite page cache ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** ** @(#) $Id: pager.h,v 1.13 2001/12/15 14:22:19 drh Exp $ */ /* ** The size of one page ** ** You can change this value to another (reasonable) power of two ** such as 512, 2048, 4096, or 8192 and things will still work. But |
︙ | ︙ | |||
39 40 41 42 43 44 45 46 47 48 49 50 51 52 | typedef unsigned int Pgno; /* ** Each open file is managed by a separate instance of the "Pager" structure. */ typedef struct Pager Pager; int sqlitepager_open(Pager **ppPager,const char *zFilename,int nPage,int nEx); void sqlitepager_set_destructor(Pager*, void(*)(void*)); void sqlitepager_set_cachesize(Pager*, int); int sqlitepager_close(Pager *pPager); int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage); void *sqlitepager_lookup(Pager *pPager, Pgno pgno); int sqlitepager_ref(void*); | > > > > | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | typedef unsigned int Pgno; /* ** Each open file is managed by a separate instance of the "Pager" structure. */ typedef struct Pager Pager; /* ** See source code comments for a detailed description of the following ** routines: */ int sqlitepager_open(Pager **ppPager,const char *zFilename,int nPage,int nEx); void sqlitepager_set_destructor(Pager*, void(*)(void*)); void sqlitepager_set_cachesize(Pager*, int); int sqlitepager_close(Pager *pPager); int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage); void *sqlitepager_lookup(Pager *pPager, Pgno pgno); int sqlitepager_ref(void*); |
︙ | ︙ |
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.4 2001/12/15 14:22:19 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 110 111 112 113 114 115 116 117 | <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 doesn't SQLite allow me to use '0' and '0.0' as the primary key on two different rows of the same table? } { <p>Every row much have a unique primary key. 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.</p> <p>You can work around this issue in two ways:</p> <ol> <li><p>Remove the <b>primary key</b> clause from the CREATE TABLE.</p></li> <li><p>Prepend a space to the beginning of every value you use for the primary key. The initial space will mean that the entries are not pure numerics and hence will be compared as strings using <b>strcmp()</b>.</p></li> </ol> } faq { My linux box is not able to read an SQLite database that was created on my SparcStation. } { |
︙ | ︙ | |||
230 231 232 233 234 235 236 | 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 { | | | 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | 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 { Are 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 |
︙ | ︙ | |||
252 253 254 255 256 257 258 259 260 261 262 263 264 265 | 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>" | > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | 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> } faq { How do I add or delete columns from an existing table in SQLite. } { <p>SQLite does not support the "ALTER TABLE" SQL command. If you what to change the structure of a table, you have to recreate the table. You can save existing data to a temporary table, drop the old table, create the new table, then copy the data back in from the temporary table.</p> <p>For example, suppose you have a table named "t1" with columns names "a", "b", and "c" and that you want to delete column "c" from this table. The following steps illustrate how this could be done: </p> <blockquote><pre> BEGIN TRANSACTION; CREATE TEMPORARY TABLE t1_backup(a,b); INSERT INTO t1_backup SELECT a,b FROM t1; DROP TABLE t1; CREATE TABLE t1(a,b); INSERT INTO t1 SELECT a,b FROM t1_backup; DROP TABLE t1_backup; COMMIT; </pre></blockquote> } # 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>" |
︙ | ︙ |