-C Version\s2.1.7\s(CVS\s454)
-D 2001-12-15T03:05:00
+C Comment\sand\sdocumentation\schanges.\s(CVS\s331)
+D 2001-12-15T14:22:19
F Makefile.in 352fed589f09dd94347e0bb391d047118ebd6105
F Makefile.template 0fbf0ee1fe38183d760170a13e91fffec64e73f5
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
F ltmain.sh e9ed72eb1d690f447c13945eaf69e28af531eda1
F publish.sh cb0f8f7bcb65b8360d0f6668a216a9ac9d5da892
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
-F src/btree.c c27474fdafb7036eef17673c7291e54c2116d6ff
-F src/btree.h 0250a0a577a98cc64ddf1582d50c08b8d2451650
+F src/btree.c c3c36b3b5f07c3efdabf76df9ea423086b1ce142
+F src/btree.h 8767bd4ecf841c4999b7aee6876906bd607546e7
F src/build.c 5127f737837a9d2a8cb4b998dbab505c08b8f06a
F src/delete.c 5d93a21c1388cfb1359bda01c072f25583a2f4f2
F src/expr.c 6b25c5bb1e750af2e2217c0134a7aa1fc0b11444
F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
F src/os.c 07882cde5c61f26751b8ee76fd84726c1f7e453c
F src/os.h 00a18e0ae1139a64f1d3ead465ae2b9ff43f3db2
-F src/pager.c f39d99e9339e5fff3fd9852f48d2fc8308933d3b
-F src/pager.h df1fb8a759ab69112ea88b9f14601a7633d0ccc0
+F src/pager.c dde0eb5bf9af0ac0ff8a4429b2bee2aec2194ec9
+F src/pager.h f78d064c780855ff70beacbeba0e2324471b26fe
F src/parse.y 5295f393f41ea89958287e5738e6c12c7cd67482
F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d
F src/random.c 2a9cc2c9716d14815fd4c2accf89d87a1143e46b
F www/crosscompile.tcl 3622ebbe518927a3854a12de51344673eb2dd060
F www/download.tcl 1ea61f9d89a2a5a9b2cee36b0d5cf97321bdefe0
F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
-F www/faq.tcl 3c26fb2f2acfc9254f2685e23a34acae2490b44f
+F www/faq.tcl 5c6fba68e238a52b4d9d86b0a63ed2d706fc7f1f
F www/index.tcl 6d6d847dd3e39e9aa7b0c9b8f3144819ff3f9f51
F www/lang.tcl 6482d90e40fb5ee004a86cf98f3007312a75444e
F www/mingw.tcl f1c7c0a7f53387dd9bb4f8c7e8571b7561510ebc
F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
F www/tclsqlite.tcl 880ef67cb4f2797b95bf1368fc4e0d8ca0fda956
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P 3a31daf6465b989a2b0790a2d1ba22ff955486a0
-R fe372d30b06d43519de0595e4ea6a38e
+P 0d44465347125c8e7e962ffb67213f9953a9b7ab
+R f9524b24c72db56ae24d23e4dfe8d2a7
U drh
-Z 1ebde59941b4e5e9dcfe12e6c3caef81
+Z c454c32fd5ff2d794a364b8c8ca2dfec
-0d44465347125c8e7e962ffb67213f9953a9b7ab
\ No newline at end of file
+e8595579a5218aa3f344f967a23ac52ea89daca1
\ No newline at end of file
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.44 2001/12/15 02:47:28 drh Exp $
+** $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
/*
** 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 that held in memory only. The
+** 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.
**
}
/*
-** Change the number of pages in the cache.
+** Change the limit on the number of pages allowed the cache.
*/
int sqliteBtreeSetCacheSize(Btree *pBt, int mxPage){
sqlitepager_set_cachesize(pBt->pPager, mxPage);
** 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 is any one of
+** 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;
**
*************************************************************************
** This header file defines the interface that the sqlite B-Tree file
-** subsystem.
+** subsystem. See comments in the source code for a detailed description
+** of what each interface routine does.
**
-** @(#) $Id: btree.h,v 1.17 2001/11/07 14:22:00 drh Exp $
+** @(#) $Id: btree.h,v 1.18 2001/12/15 14:22:19 drh Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.33 2001/12/14 15:09:57 drh Exp $
+** @(#) $Id: pager.c,v 1.34 2001/12/15 14:22:19 drh Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
** 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.
-**
-** We have to release the write lock before acquiring the read lock,
-** so there is a race condition where another process can get the lock
-** while we are not holding it. But, no other process should do this
-** because we are also holding a lock on the journal, and no process
-** should get a write lock on the database without first getting a lock
-** on the journal. So this routine should never fail. But it can fail
-** if another process is not playing by the rules. If it does fail,
-** all in-memory cache pages are invalidated, the PAGER_ERR_LOCK bit
-** is set in pPager->errMask, and this routine returns SQLITE_PROTOCOL.
-** SQLITE_OK is returned on success.
*/
static int pager_unwritelock(Pager *pPager){
int rc;
** consists of a Pgno and SQLITE_PAGE_SIZE bytes of data. See
** the PageRecord structure for details.
**
-** For playback, the pages have to be read from the journal in
+** 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
** 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 random temporary file is created and used
-** as the file to be cached. The file will be deleted automatically when
-** it is closed.
+** 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 */
**
** 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 that occur. So after an fsync() is forced
-** and we are free to write dirty pages back to the database, it is best
-** to go ahead and do as much of that as possible to minimize the chance
-** of having to do another fsync() later on. Writing dirty free pages
-** in this way make database operations go up to 10 times faster.
+** 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;
*/
rc = sqliteOsWriteLock(&pPager->fd);
if( rc!=SQLITE_OK ){
- rc = sqliteOsReadLock(&pPager->fd);
+ rc = sqliteOsUnlock(&pPager->fd);
assert( rc==SQLITE_OK );
*ppPage = 0;
return SQLITE_BUSY;
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 );
}
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 ){
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;
** 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.12 2001/11/10 13:51:09 drh Exp $
+** @(#) $Id: pager.h,v 1.13 2001/12/15 14:22:19 drh Exp $
*/
/*
*/
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);
#
# 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 $}
+set rcsid {$Id: faq.tcl,v 1.4 2001/12/15 14:22:19 drh Exp $}
puts {<html>
<head>
}
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>
+ 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>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
+ <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 and the
- constraint fails.</p>
+ (See the previous question.) Hence the values are not unique.</p>
- <p>You can work around this issue in several ways:</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 so that
- <b>s</b> can contain more than one entry with the same value.
- If you need an index on the <b>s</b> column then create it separately.
- </p></li>
- <li><p>Prepend a space to the beginning of every <b>s</b> value. 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>
+ <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 {
- Is there any known size limits to SQLite databases.
+ 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
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.
#############