]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Documentation updates. (CVS 720)
authordrh <drh@noemail.net>
Sun, 18 Aug 2002 19:09:22 +0000 (19:09 +0000)
committerdrh <drh@noemail.net>
Sun, 18 Aug 2002 19:09:22 +0000 (19:09 +0000)
FossilOrigin-Name: e372a60be8de3332ab6e45d82f21227b8b9acf82

main.mk
manifest
manifest.uuid
www/changes.tcl
www/datatypes.tcl
www/faq.tcl
www/fileformat.tcl [new file with mode: 0644]
www/index.tcl
www/lang.tcl
www/quickstart.tcl

diff --git a/main.mk b/main.mk
index f850e10eb4176a32ecd54b1278197d652b08e77a..da7feeac75aa7dd662fd467f5aa16e17d02ea92f 100644 (file)
--- a/main.mk
+++ b/main.mk
@@ -305,6 +305,9 @@ datatypes.html:     $(TOP)/www/datatypes.tcl
 quickstart.html:       $(TOP)/www/quickstart.tcl
        tclsh $(TOP)/www/quickstart.tcl >quickstart.html
 
+fileformat.html:       $(TOP)/www/fileformat.tcl
+       tclsh $(TOP)/www/fileformat.tcl >fileformat.html
+
 
 # Files to be published on the website.
 #
@@ -328,7 +331,8 @@ DOC = \
   conflict.html \
   omitted.html \
   datatypes.html \
-  quickstart.html
+  quickstart.html \
+  fileformat.html
 
 doc:   $(DOC)
        mkdir -p doc
index 952c105d890064a892fd5a957a1f40c7a5bd5ed3..de5e2022fd725f39decf24af3518b706e2704017 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sfor\sticket\s#135:\sRemove\sunused\svariables\sfrom\sthree\sfiles.\s(CVS\s719)
-D 2002-08-15T13:50:49
+C Documentation\supdates.\s(CVS\s720)
+D 2002-08-18T19:09:23
 F Makefile.in 6291a33b87d2a395aafd7646ee1ed562c6f2c28c
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -14,7 +14,7 @@ F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
 F libtool c56e618713c9510a103bda6b95f3ea3900dcacd6
 F ltmain.sh e9ed72eb1d690f447c13945eaf69e28af531eda1
-F main.mk 8a44951de2a6791646fe65a11d47f43223d23e86
+F main.mk 6116e91c7f747e9a881f8f94a7ffd17489039ddb
 F publish.sh a7a8d23e6525bd25d4f5ba9b0fc6edc107d94050
 F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e
 F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
@@ -128,25 +128,26 @@ F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
 F www/arch.tcl 679a0c48817f71bc91d5911ef386e5ef35d4f178
 F www/audit.tcl 90e09d580f79c7efec0c7d6f447b7ec5c2dce5c0
 F www/c_interface.tcl 70548ff5f73c6adcdb7aeced929ebb30a99f5807
-F www/changes.tcl df6f06b1aa97ef285c744bf19ec3efddf707b05f
+F www/changes.tcl 7326bd48555132ca7f21a0dec84dacea76eacc65
 F www/conflict.tcl 81dd21f9a679e60aae049e9dd8ab53d59570cda2
 F www/crosscompile.tcl 3622ebbe518927a3854a12de51344673eb2dd060
-F www/datatypes.tcl d528c3e29e1b289f27b44c164feace2541e4f261
+F www/datatypes.tcl 0cb28565580554fa7e03e8fcb303e87ce57757ae
 F www/download.tcl 0932d7f4f0e8b2adbbd22fac73132f86e43ab4a9
 F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
-F www/faq.tcl 9262ad6f7f25ab253a9771ab1fbd48a1a14f2957
+F www/faq.tcl 291b8921c5f1ccdeafd88d05127e1d2842a750c1
+F www/fileformat.tcl a4b5c2c6e89b7d42d09f97fd4d7bbd39cbf24936
 F www/formatchng.tcl b4449e065d2da38b6563bdf12cf46cfe1d4d765e
-F www/index.tcl 43dc2ae4b6d39d9923ab49adbdf25e6f729acb9d
-F www/lang.tcl a2785964e80627381e953849e227a3ff2a38cb09
+F www/index.tcl 33881038e9664a36e56df3b80ef0828594c8dcd9
+F www/lang.tcl d2be2be0328f5c2fea06add825a1e442a1f8ed55
 F www/mingw.tcl f1c7c0a7f53387dd9bb4f8c7e8571b7561510ebc
 F www/omitted.tcl aa5145a79f5a8919ac41885c30007da9face1d48
 F www/opcode.tcl 33c5f2061a05c5d227c72b84c080b3bf74c74f8b
-F www/quickstart.tcl 247f2ba9009f8114036080e758e7d9d3b884dd32
+F www/quickstart.tcl fde79aa2de20074842b60f780800cdeee6a5dec2
 F www/speed.tcl 7fc83f1b018e1ecc451838449542c3079ed12425
 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P 9c0400aa7a0244605828fa6450ea1cc723240b16
-R ddf988ebfceb731da194e672ddbf06c6
+P 8cf17f2a24ee9bd5d1ea66484922819626c412dd
+R 2272702716d4156d8e188d7580097427
 U drh
-Z 29d5419af0f9c5edc39a8a40ac6613e3
+Z c4160e0e70fb429cfa81e989b76baa3d
index 20ebf49f06b812ffc48d524fd613c2bb6d6a0c08..9a59c97e0cfef5449224bd7176518b815e0cc161 100644 (file)
@@ -1 +1 @@
-8cf17f2a24ee9bd5d1ea66484922819626c412dd
\ No newline at end of file
+e372a60be8de3332ab6e45d82f21227b8b9acf82
\ No newline at end of file
index 0653ccb6b38122690efa4a276551113121412ccf..f392bac71c4cc2cbcf3d4478b2e5671229f2e883 100644 (file)
@@ -29,6 +29,8 @@ chng {2002 Aug ?? (2.7.0)} {
 <li>Make a distinction between numeric and text values when sorting.
     Text values sort according to memcmp().  Numeric values sort in
     numeric order.</li>
+<li>Allow multiple simulataneous readers under windows by simulating
+    the reader/writers locks that are missing from Win95/98/ME.</li>
 }
 
 chng {2002 Aug 12 (2.6.3)} {
index 4c136fe5626103bd903913e185dd450cce6e2966..35717ed200a71f156f5e27a28d9afec6f500fdaa 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Run this script to generated a datatypes.html output file
 #
-set rcsid {$Id: datatypes.tcl,v 1.4 2002/08/15 13:45:17 drh Exp $}
+set rcsid {$Id: datatypes.tcl,v 1.5 2002/08/18 19:09:24 drh Exp $}
 
 puts {<html>
 <head>
@@ -117,13 +117,13 @@ If data is of type <b>text</b> then the comparison is determined by
 the standard C data comparison functions <b>memcmp()</b> or
 <b>strcmp()</b>.  The comparison looks at bytes from two inputs one
 by one and returns the first non-zero difference.
-String are '\000' terminated so shorter
+Strings are '\000' terminated so shorter
 strings sort before longer strings, as you would expect.
 </p>
 
 <p>
-For numeric data, this situation is more complex.  If both strings
-being compared look like well-formed numbers, then they are converted
+For numeric data, this situation is more complex.  If both inputs
+look like well-formed numbers, then they are converted
 into floating point values using <b>atof()</b> and compared numerically.
 If one input is not a well-formed number but the other is, then the
 number is considered to be less than the non-number.  If neither inputs
@@ -214,7 +214,7 @@ they are distinct.</p>
 
 <p>SQLite always converts numbers into double-precision (64-bit) floats
 for comparison purposes.  This means that a long sequence of digits that
-differ only in digits of far to the right will compare equal if they
+differ only in insignificant digits will compare equal if they
 are in a numeric column but will compare unequal if they are in a text
 column.  We have:</p>
 
index ecd7249159d0c32daa2e7f4bd145c9a644b2984b..e67382f3f8903d2979bc958a9ff14b24eeb25f2e 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Run this script to generated a faq.html output file
 #
-set rcsid {$Id: faq.tcl,v 1.17 2002/08/15 11:48:14 drh Exp $}
+set rcsid {$Id: faq.tcl,v 1.18 2002/08/18 19:09:24 drh Exp $}
 
 puts {<html>
 <head>
@@ -354,8 +354,8 @@ faq {
   and you can not include binary data in the middle of the ASCII text string
   of an INSERT statement.</p>
 
-  <p>SQLite is 8-bit clean with regard to the data is stores as long as
-  the data does not contain any NUL characters.  If you want to store binary
+  <p>SQLite is 8-bit clean with regard to the data it stores as long as
+  the data does not contain any '\000' characters.  If you want to store binary
   data, consider encoding your data in such a way that it contains no NUL
   characters and inserting it that way.  You might use URL-style encoding:
   encode NUL as "%00" and "%" as "%25".  Or, you might consider encoding your
diff --git a/www/fileformat.tcl b/www/fileformat.tcl
new file mode 100644 (file)
index 0000000..9f2275b
--- /dev/null
@@ -0,0 +1,754 @@
+#
+# Run this script to generated a fileformat.html output file
+#
+set rcsid {$Id: fileformat.tcl,v 1.6 2002/08/18 19:09:24 drh Exp $}
+
+puts {<html>
+<head>
+  <title>SQLite Database File Format</title>
+</head>
+<body bgcolor="white">
+<h1 align="center">
+SQLite Database File Format
+</h1>
+}
+puts "<p align=center>
+(This page was last modified on [lrange $rcsid 3 4] UTC)
+</p>"
+
+puts {
+<h2>1.0 &nbsp; Layers</h2>
+
+<p>
+SQLite is implemented in layers.
+(See the <a href="arch.html">architecture description</a>.)
+The format of database files is determined by three different
+layers in the architecture.
+</p>
+
+<ul>
+<li>The <b>schema</b> layer implemented by the VDBE.</li>
+<li>The <b>b-tree</b> layer implemented by btree.c</li>
+<li>The <b>pager</b> layer implemented by pager.c</li>
+</ul>
+
+<p>
+We wil describe each layer beginning with the bottom (pager)
+layer and working upwards.
+</p>
+
+<h2>2.0 &nbsp; The Pager Layer</h2>
+
+<p>
+An SQLite database consists of
+"pages" of data.  Each page is 1024 bytes in size.
+Pages are numbered beginning with 1.
+A page number of 0 is used to indicate "no such page" in the
+B-Tree and Schema layers.
+</p>
+
+<p>
+The pager layer is responsible for implementing transactions
+with atomic commit and rollback.  It does this using a separate
+journal file.  Whenever a new transaction is started, a journal
+file is created that records the original state of the database.
+If the program terminates before completing the transaction, the next
+process to open the database can use the journal file to restore
+the database to its original state.
+</p>
+
+<p>
+The journal file is located in the same directory as the database
+file and has the same name as the database file but with the
+characters "<tt>-journal</tt>" appended.
+</p>
+
+<p>
+The pager layer does not impose any content restrictions on the
+main database file.  As far as the pager is concerned, each page
+contains 1024 bytes of arbitrary data.  But there is structure to
+the journal file.
+</p>
+
+<p>
+A journal file begins with 8 bytes as follows:
+0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, and 0xd5.
+Processes that are attempting to rollback a journal use these 8 bytes
+as a sanity check to make sure the file they think is a journal really
+is a valid journal.  There is no significance to the choice of
+bytes here - the values were obtained from /dev/random. 
+</p>
+
+<p>
+Following the 8 byte prefix is a single 4-byte integer that is the
+original size of the main database file before the transaction was
+started.  The main database file is truncated back to this size
+as part of the rollback process.
+The size is expressed in pages (1024 bytes per page) and is
+a big-endian number.  That means that the most significant byte
+occurs first.  All multi-byte integers in the journal file are
+written as big-endian numbers.  That way, a journal file that is
+originally created on one machine can be rolled back by another
+machine that uses a different byte order.  So, for example, a
+transaction that failed to complete on your big-endian SparcStation
+can still be rolled back on your little-endian Linux box.
+</p>
+
+<p>
+After the 8-byte prefix and the 4-byte initial database size, the
+journal file consists of zero or more page records.  Each page
+record is a 4-byte (big-endian) page number followed by 1024 bytes
+of data.  The data is the original content of the database page
+before the transaction was started.  So to roll back the transaction,
+the data is simply written into the corresponding page of the
+main database file.  Pages can appear in the journal in any order,
+but they are guaranteed to appear only once. All page numbers will be
+between 1 and the maximum specified by the page size integer that
+appeared at the beginning of the journal.
+</p>
+
+<p>
+Here is a summary of the journal file format:
+</p>
+
+<ul>
+<li>8 byte prefix: 0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, x0d5</li>
+<li>4 byte initial database page count, big-endian.</li>
+<li>Zero or more instances of the following:
+   <ul>
+   <li>4 byte page number - big-endian</li>
+   <li>1024 bytes of original data for the page</li>
+   </ul>
+</li>
+</ul>
+
+<h2>3.0 &nbsp; The B-Tree Layer</h2>
+
+<p>
+The B-Tree layer builds on top of the pager layer to implement
+one or more separate b-trees all in the same disk file.  The
+algorithms used are taken from Knuth's <i>The Art Of Computer
+Programming.</i></p>
+
+<p>
+Page 1 of a database contains a header string used for sanity
+checking, a few 32-bit words of configuration data, and a pointer
+to the beginning of a list of unused pages in the database.
+All other pages in the
+database are either pages of a b-tree, overflow pages, or unused
+pages on the freelist.
+</p>
+
+<p>
+Each b-tree page contains zero or more database entries.
+Each entry has an unique key of one or more bytes and data of
+zero or more bytes.
+Both the key and data are arbitrary byte sequences.  The combination
+of key and data are collectively known as "payload".  The current
+implementation limits the amount of payload in a single entry to
+1048576 bytes.  This limit can be raised to 16777216 by adjusting
+a single #define in the source code and recompiling.  But most entries
+contain less than a hundred bytes of payload so a megabyte limit seems
+more than enough.
+</p>
+
+<p>
+Up to 238 bytes of payload for an entry can be held directly on
+a b-tree page.  Any additional payload is contained on a linked list
+of overflow pages.  This limit on the amount of payload held directly
+on b-tree pages guarantees that each b-tree page can hold at least
+4 entries.  In practice, most entries are smaller than 238 bytes and
+thus most pages can hold more than 4 entries.
+</p>
+
+<p>
+A single database file can hold any number of separate, independent b-trees.
+Each b-tree is identified by its root page, which never changes.
+Child pages of the b-tree may change as entries are added and removed
+and pages split and combine.  But the root page always stays the same.
+The b-tree itself does not record which pages are root pages and which
+are not.  That information is handled entirely at the schema layer.
+</p>
+
+<h3>3.1 &nbsp; B-Tree Page 1 Details</h3>
+
+<p>
+Page 1 begins with the following 48-byte string:
+</p>
+
+<blockquote><pre>
+** This file contains an SQLite 2.1 database **
+</pre></blockquote>
+
+<p>
+If you count the number of characters in the string above, you will
+see that there are only 47.  A '\000' terminator byte is added to
+bring the total to 48.
+</p>
+
+<p>
+A frequent question is why the string says version 2.1 when (as
+of this writing) we are up to version 2.7.0 of SQLite and any
+change to the second digit of the version is suppose to represent
+a database format change.  The answer to this is that the B-tree
+layer has not changed any since version 2.1.  There have been
+database format changes since version 2.1 but those changes have
+all been in the schema layer.  Because the format of the b-tree
+layer is unchanged since version 2.1.0, the header string still
+says version 2.1.
+</p>
+
+<p>
+After the format string is a 4-byte integer used to determine the
+byte-order of the database.  The integer has a value of
+0xdae37528.  If this number is expressed as 0xda, 0xe3, 0x75, 0x28, then
+the database is in a big-endian format and all 16 and 32-bit integers
+elsewhere in the b-tree layer are also big-endian.  If the number is
+expressed as 0x28, 0x75, 0xe3, and 0xda, then the database is in a
+little-endian format and all other multi-byte numbers in the b-tree 
+layer are also little-endian.  
+Prior to version 2.6.3, the SQLite engine was only able to read databases
+that used the same byte order as the processor they were running on.
+But beginning with 2.6.3, SQLite can read or write databases in any
+byte order.
+</p>
+
+<p>
+After the byte-order code are six 4-byte integers.  Each integer is in the
+byte order determined by the byte-order code.  The first integer is the
+page number for the first page of the freelist.  If there are no unused
+pages in the database, then this integer is 0.  The second integer is
+the number of unused pages in the database.  The last 4 integers are
+not used by the b-tree layer.  These are the so-called "meta" values that
+are passed up to the schema layer
+and used there for configuration and format version information.
+All bytes of page 1 past beyond the meta-value integers are unused 
+and are initialized to zero.
+</p>
+
+<p>
+Here is a summary of the information contained on page 1 in the b-tree layer:
+</p>
+
+<ul>
+<li>48 byte header string</li>
+<li>4 byte integer used to determine the byte-order</li>
+<li>4 byte integer which is the first page of the freelist</li>
+<li>4 byte integer which is the number of pages on the freelist</li>
+<li>16 bytes of meta-data arranged as four 4-byte integers</li>
+<li>948 bytes of unused space</li>
+</ul>
+
+<h3>3.2 &nbsp; Structure Of A Single B-Tree Page</h3>
+
+<p>
+Conceptually, a b-tree page contains N database entries and N+1 pointers
+to other b-tree pages.
+</p>
+
+<blockquote>
+<table border=1 cellspacing=0 cellpadding=5>
+<tr>
+<td align="center">Ptr<br>0</td>
+<td align="center">Entry<br>0</td>
+<td align="center">Ptr<br>1</td>
+<td align="center">Entry<br>1</td>
+<td align="center"><b>...</b></td>
+<td align="center">Ptr<br>N-1</td>
+<td align="center">Entry<br>N-1</td>
+<td align="center">Ptr<br>N</td>
+</tr>
+</table>
+</blockquote>
+
+<p>
+The entries are arranged in increasing order.  That is, the key to
+Entry 0 is less than the key to Entry 1, and the key to Entry 1 is
+less than the key of Entry 2, and so forth.  The pointers point to
+pages containing additional entries that have keys in between the
+entries on either side.  So Ptr 0 points to another b-tree page that
+contains entries that all have keys less than Key 0, and Ptr 1
+points to a b-tree pages where all entries have keys greater than Key 0
+but less than Key 1, and so forth.
+</p>
+
+<p>
+Each b-tree page in SQLite consists of a header, zero or more "cells"
+each holding a single entry and pointer, and zero or more "free blocks"
+that represent unused space on the page.
+</p>
+
+<p>
+The header on a b-tree page is the first 8 bytes of the page.
+The header contains the value
+of the right-most pointer (Ptr N) and the byte offset into the page
+of the first cell and the first free block.  The pointer is a 32-bit
+value and the offsets are each 16-bit values.  We have:
+</p>
+
+<blockquote>
+<table border=1 cellspacing=0 cellpadding=5>
+<tr>
+<td align="center" width=30>0</td>
+<td align="center" width=30>1</td>
+<td align="center" width=30>2</td>
+<td align="center" width=30>3</td>
+<td align="center" width=30>4</td>
+<td align="center" width=30>5</td>
+<td align="center" width=30>6</td>
+<td align="center" width=30>7</td>
+</tr>
+<tr>
+<td align="center" colspan=4>Ptr N</td>
+<td align="center" colspan=2>Cell 0</td>
+<td align="center" colspan=2>Freeblock 0</td>
+</tr>
+</table>
+</blockquote>
+
+<p>
+The 1016 bytes of a b-tree page that come after the header contain
+cells and freeblocks.  All 1016 bytes are covered by either a cell
+or a freeblock.
+</p>
+
+<p>
+The cells are connected in a linked list.  Cell 0 contains Ptr 0 and
+Entry 0.  Bytes 4 and 5 of the header point to Cell 0.  Cell 0 then
+points to Cell 1 which contains Ptr 1 and Entry 1.  And so forth.
+Cells vary in size.  Every cell has a 12-byte header and at least 4
+bytes of payload space.  Space is allocated to payload in increments
+of 4 bytes.  Thus the minimum size of a cell is 16 bytes and up to
+63 cells can fit on a single page.  The size of a cell is always a multiple
+of 4 bytes.
+A cell can have up to 238 byte of payload space.  If
+the payload is more than 238 bytes, then an addition 4 point page
+number is appended to the cell which is the page number of the first
+overflow page containing the additional payload.  The maximum size
+of a cell is thus 254 bytes, meaning that a least 4 cells can fit into
+the 1016 bytes of space available on a b-tree page.
+An average cell is usually around 52 to 100 bytes in size with about
+10 or 20 cells to a page.
+</p>
+
+<p>
+The data layout of a cell looks like this:
+</p>
+
+<blockquote>
+<table border=1 cellspacing=0 cellpadding=5>
+<tr>
+<td align="center" width=20>0</td>
+<td align="center" width=20>1</td>
+<td align="center" width=20>2</td>
+<td align="center" width=20>3</td>
+<td align="center" width=20>4</td>
+<td align="center" width=20>5</td>
+<td align="center" width=20>6</td>
+<td align="center" width=20>7</td>
+<td align="center" width=20>8</td>
+<td align="center" width=20>9</td>
+<td align="center" width=20>10</td>
+<td align="center" width=20>11</td>
+<td align="center" width=100>12 ... 249</td>
+<td align="center" width=20>250</td>
+<td align="center" width=20>251</td>
+<td align="center" width=20>252</td>
+<td align="center" width=20>253</td>
+</tr>
+<tr>
+<td align="center" colspan=4>Ptr</td>
+<td align="center" colspan=2>Keysize<br>(low)</td>
+<td align="center" colspan=2>Next</td>
+<td align="center" colspan=1>Ksz<br>(hi)</td>
+<td align="center" colspan=1>Dsz<br>(hi)</td>
+<td align="center" colspan=2>Datasize<br>(low)</td>
+<td align="center" colspan=1>Payload</td>
+<td align="center" colspan=4>Overflow<br>Pointer</td>
+</tr>
+</table>
+</blockquote>
+
+<p>
+The first four bytes are the pointer.  The size of the key is a 24-bit
+where the upper 8 bits are taken from by 8 and the lower 16 bits are
+token from bytes 4 and 5 (or bytes 5 and 4 on little-endian machines.)
+The size of the data is another 24-bit value where the upper 8 bits
+are taken from byte 9 and the lower 16 bits are taken from bytes 10 and
+11 or 11 and 10, depending on the byte order.  Bytes 6 and 7 are the
+offset to the next cell in the linked list of all cells on the current
+page.  This offset is 0 for the last cell on the page.
+</p>
+
+<p>
+The payload itself can be any number of bytes between 1 and 1048576.
+But space to hold the payload is allocated in 4-byte chunks up to
+238 bytes.  If the entry contains more than 238 bytes of payload, then
+additional payload data is stored on a linked list of overflow pages.
+A 4 byte page number is appended to the cell that contains the first
+page of this linked list.
+</p>
+
+<p>
+Each overflow page begins with a 4-byte value which is the
+page number of the next overflow page in the list.   This value is
+0 for the last page in the list.  The remaining
+1020 bytes of the overflow page are available for storing payload.
+Note that a full page is allocated regardless of the number of overflow
+bytes stored.  Thus, if the total payload for an entry is 239 bytes,
+the first 238 are stored in the cell and the overflow page stores just
+one byte.
+</p>
+
+<p>
+The structure of an overflow page looks like this:
+</p>
+
+<blockquote>
+<table border=1 cellspacing=0 cellpadding=5>
+<tr>
+<td align="center" width=20>0</td>
+<td align="center" width=20>1</td>
+<td align="center" width=20>2</td>
+<td align="center" width=20>3</td>
+<td align="center" width=200>4 ... 1023</td>
+</tr>
+<tr>
+<td align="center" colspan=4>Next Page</td>
+<td align="center" colspan=1>Overflow Data</td>
+</tr>
+</table>
+</blockquote>
+
+<p>
+All space on a b-tree page which is not used by the header or by cells
+is filled by freeblocks.  Freeblocks, like cells, are variable in size.
+The size of a freeblock is at least 4 bytes and is always a multiple of
+4 bytes.
+The first 4 bytes contain a header and the remaining bytes
+are unused.  The structure of the freeblock is as follows:
+</p>
+
+<blockquote>
+<table border=1 cellspacing=0 cellpadding=5>
+<tr>
+<td align="center" width=20>0</td>
+<td align="center" width=20>1</td>
+<td align="center" width=20>2</td>
+<td align="center" width=20>3</td>
+<td align="center" width=200>4 ... 1015</td>
+</tr>
+<tr>
+<td align="center" colspan=2>Size</td>
+<td align="center" colspan=2>Next</td>
+<td align="center" colspan=1>Unused</td>
+</tr>
+</table>
+</blockquote>
+
+<p>
+Freeblocks are stored in a linked list in increasing order.  That is
+to say, the first freeblock occurs at a lower index into the page than
+the second free block, and so forth.  The first 2 bytes of the header
+are an integer which is the total number of bytes in the freeblock.
+The second 2 bytes are the index into the page of the next freeblock
+in the list.  The last freeblock has a Next value of 0.
+</p>
+
+<p>
+When a new b-tree is created in a database, the root page of the b-tree
+consist of a header and a single 1016 byte freeblock.  As entries are
+added, space is carved off of that freeblock and used to make cells.
+When b-tree entries are deleted, the space used by their cells is converted
+into freeblocks.  Adjacent freeblocks are merged, but the page can still
+become fragmented.  The b-tree code will occasionally try to defragment
+the page by moving all cells to the beginning and constructing a single
+freeblock at the end to take up all remaining space.
+</p>
+
+<h3>3.3 &nbsp; The B-Tree Free Page List</h3>
+
+<p>
+When information is removed from an SQLite database such that one or
+more pages are no longer needed, those pages are added to a list of
+free pages so that they can be reused later when new information is
+added.  This subsection describes the structure of this freelist.
+</p>
+
+<p>
+The 32-bit integer beginning at byte-offset 52 in page 1 of the database
+contains the address of the first page in a linked list of free pages.
+If there are no free pages available, this integer has a value of 0.
+The 32-bit integer at byte-offset 56 in page 1 contains the number of
+free pages on the freelist.
+</p>
+
+<p>
+The freelist contains a trunk and many branches.  The trunk of
+the freelist is composed of overflow pages.  That is to say, each page
+contains a single 32-bit integer at byte offset 0 which
+is the page number of the next page on the freelist trunk.
+The payload area
+of each trunk page is used to record pointers to branch pages. 
+The first 32-bit integer in the payload area of a trunk page
+is the number of branch pages to follow (between 0 and 254)
+and each subsequent 32-bit integer is a page number for a branch page.
+The following diagram shows the structure of a trunk freelist page:
+</p>
+
+<blockquote>
+<table border=1 cellspacing=0 cellpadding=5>
+<tr>
+<td align="center" width=20>0</td>
+<td align="center" width=20>1</td>
+<td align="center" width=20>2</td>
+<td align="center" width=20>3</td>
+<td align="center" width=20>4</td>
+<td align="center" width=20>5</td>
+<td align="center" width=20>6</td>
+<td align="center" width=20>7</td>
+<td align="center" width=200>8 ... 1023</td>
+</tr>
+<tr>
+<td align="center" colspan=4>Next trunk page</td>
+<td align="center" colspan=4># of branch pages</td>
+<td align="center" colspan=1>Page numbers for branch pages</td>
+</tr>
+</table>
+</blockquote>
+
+<p>
+It is important to note that only the pages on the trunk of the freelist
+contain pointers to other pages.  The branch pages contain no
+data whatsoever.  The fact that the branch pages are completely
+blank allows for an important optimization in the paging layer.  When
+a branch page is removed from the freelist to be reused, it is not
+necessary to write the original content of that page into the rollback
+journal.  The branch page contained no data to begin with, so there is
+no need to restore the page in the event of a rollback.  Similarly,
+when a page is not longer needed and is added to the freelist as a branch
+page, it is not necessary to write the content of that page
+into the database file.
+Again, the page contains no real data so it is not necessary to record the
+content of that page.  By reducing the amount of disk I/O required,
+these two optimizations allow some database operations
+to go four to six times faster than they would otherwise.
+</p>
+
+<h2>4.0 &nbsp; The Schema Layer</h2>
+
+<p>
+The schema layer implements an SQL database on top of one or more
+b-trees and keeps track of the root page numbers for all b-trees.
+Where the b-tree layer provides only unformatted data storage with
+a unique key, the schema layer allows each entry to contain multiple
+columns.  The schema layer also allows indices and non-unique key values.
+</p>
+
+<p>
+The schema layer implements two separate data storage abstractions:
+tables and indices.  Each table and each index uses its own b-tree
+but they use the b-tree capabilities in different ways.  For a table,
+the b-tree key is a unique 4-byte integer and the b-tree data is the
+content of the table row, encoded so that columns can be separately
+extracted.  For indices, the b-tree key varies in size depending on the
+size of the fields being indexed and the b-tree data is empty.
+</p>
+
+<h3>4.1 &nbsp; SQL Table Implementation Details</h3>
+
+<p>Each row of an SQL table is stored in a single b-tree entry.
+The b-tree key is a 4-byte big-endian integer that is the ROWID
+or INTEGER PRIMARY KEY for that table row.
+The key is stored in a big-endian format so
+that keys will sort in numerical order using memcmp() function.</p>
+
+<p>The content of a table row is stored in the data portion of
+the corresponding b-tree table.  The content is encoded to allow
+individual columns of the row to be extracted as necessary.  Assuming
+that the table has N columns, the content is encoded as N+1 offsets
+followed by N column values, as follows:
+</p>
+
+<blockquote>
+<table border=1 cellspacing=0 cellpadding=5>
+<tr>
+<td>offset 0</td>
+<td>offset 1</td>
+<td><b>...</b></td>
+<td>offset N-1</td>
+<td>offset N</td>
+<td>value 0</td>
+<td>value 1</td>
+<td><b>...</b></td>
+<td>value N-1</td>
+</tr>
+</table>
+</blockquote>
+
+<p>
+The offsets can be either 8-bit, 16-bit, or 24-bit integers depending
+on how much data is to be stored.  If the total size of the content
+is less than 256 bytes then 8-bit offsets are used.  If the total size
+of the b-tree data is less than 65536 then 16-bit offsets are used.
+24-bit offsets are used otherwise.  Offsets are always little-endian,
+which means that the least significant byte occurs first.
+</p>
+
+<p>
+Data is stored as a nul-terminated string.  Any empty string consists
+of just the nul terminator.  A NULL value is an empty string with no
+nul-terminator.  Thus a NULL value occupies zero bytes and an empty string
+occupies 1 byte.
+</p>
+
+<p>
+Column values are stored in the order that they appear in the CREATE TABLE
+statement.  The offsets at the beginning of the record contain the
+byte index of the corresponding column value.  Thus, Offset 0 contains
+the byte index for Value 0, Offset 1 contains the byte offset
+of Value 1, and so forth.  The number of bytes in a column value can
+always be found by subtracting offsets.  This allows NULLs to be
+recovered from the record unabiguously.
+</p>
+
+<p>
+Most columns are stored in the b-tree data as described above.
+The one exception is column that has type INTEGER PRIMARY KEY.
+INTEGER PRIMARY KEY columns correspond to the 4-byte b-tree key.
+When an SQL statement attempts to read the INTEGER PRIMARY KEY,
+the 4-byte b-tree key is read rather than information out of the
+b-tree data.  But there is still an Offset associated with the
+INTEGER PRIMARY KEY, just like any other column.  But the Value
+associated with that offset is always NULL.
+</p>
+
+<h3>4.2 &nbsp; SQL Index Implementation Details</h3>
+
+<p>
+SQL indices are implement using a b-tree in which the key is used
+but the data is always empty.  The purpose of an index is to map
+one or more column values into the ROWID for the table entry that
+contains those column values.
+</p>
+
+<p>
+Each b-tree in an index consists of one or more column values followed
+by a 4-byte ROWID.  Each column value is nul-terminated (even NULL values)
+and begins with a single character that indicates the datatype for that
+column value.  Only three datatypes are supported: NULL, Number, and
+Text.  NULL values are encoded as the character 'a' followed by the
+nul terminator.  Numbers are encoded as the character 'b' followed by
+a string that has been crafted so that sorting the string using memcmp()
+will sort the corresponding numbers in numerical order.  (See the
+sqliteRealToSortable() function in util.c of the SQLite sources for
+additional information on this encoding.)  Numbers are also nul-terminated.
+Text values consists of the character 'c' followed by a copy of the
+text string and a nul-terminator.  These encoding rules result in
+NULLs being sorted first, followed by numerical values in numerical
+order, followed by text values in lexigraphical order.
+</p>
+
+<h3>4.4 &nbsp; SQL Schema Storage And Root B-Tree Page Numbers</h3>
+
+<p>
+The database schema is stored in the database in a special tabled named
+"sqlite_master" and which always has a root b-tree page number of 2.
+This table contains the original CREATE TABLE,
+CREATE INDEX, CREATE VIEW, and CREATE TRIGGER statements used to define
+the database to begin with.  Whenever an SQLite database is opened,
+the sqlite_master table is scanned from beginning to end and 
+all the original CREATE statements are played back through the parser
+in order to reconstruct an in-memory representation of the database
+schema for use in subsequent command parsing.  For each CREATE TABLE
+and CREATE INDEX statement, the root page number for the corresponding
+b-tree is also recorded in the sqlite_master table so that SQLite will
+know where to look for the appropriate b-tree.
+</p>
+
+<p>
+SQLite users can query the sqlite_master table just like any other table
+in the database.  But the sqlite_master table cannot be directly written.
+The sqlite_master table is automatically updated in response to CREATE
+and DROP statements but it cannot be changed using INSERT, UPDATE, or
+DELETE statements as that would risk corrupting the database.
+</p>
+
+<p>
+SQLite stores temporary tables and indices in a separate
+file from the main database file.  The temporary table database file
+is the same structure as the main database file.  The schema table
+for the temporary tables is stored on page 2 just as in the main
+database.  But the schema table for the temporary database named
+"sqlite_temp_master" instead of "sqlite_master".  Other than the
+name change, it works exactly the same.
+</p>
+
+<h3>4.4 &nbsp; Schema Version Numbering And Other Meta-Information</h3>
+
+<p>
+The four 32-bit integers that are stored beginning at byte offset
+60 of Page 1 in the b-tree layer are passed up into the schema layer
+and used for versioning and configuration information.  The meaning
+of these four integers is as follows:
+</p>
+
+<ol>
+<li>The schema version number</li>
+<li>The format version number</li>
+<li>The recommended pager cache size</li>
+<li>Unused</li>
+</ol>
+
+<p>
+The first meta-value, the schema version number, is used to detect when
+the schema of the database is changed by a CREATE or DROP statement.
+Recall that when a database is first opened the sqlite_master table is
+scanned and an internal representation of the tables, indices, views,
+and triggers for the database is built in memory.  This internal
+representation is used for all subsequent SQL command parsing and
+execution.  But what if another process were to change the schema
+by adding or removing a table, index, view, or trigger?  If the original
+process were to continue using the old schema, it could potentially
+corrupt the database by writing to a table that no longer exists.
+To avoid this problem, the schema version number is changed whenever
+a CREATE or DROP statement is executed.  Before each command is
+executed, the current schema version number for the database file
+is compared against the schema version number from when the sqlite_master
+table was last read.  If those numbers are different, the internal
+schema representation is erased and the sqlite_master table is reread
+to reconstruct the internal schema representation.
+(Calls to sqlite_exec() generally return SQLITE_SCHEMA when this happens.)
+</p>
+
+<p>
+The second meta-value is the schema format version number.  This
+number tells what version of the schema layer should be used to
+interpret the file.  There have been changes to the schema layer
+over time and this number is used to detect when an older database
+file is being processed by a newer version of the library.
+As of this writing (SQLite version 2.7.0) the current format version
+is "4".
+</p>
+
+<p>
+The third meta-value is the recommended pager cache size as set 
+by the DEFAULT_CACHE_SIZE pragma.  If the value is positive it
+means that synchronous behavior is enable (via the DEFAULT_SYNCHRONOUS
+pragma) and if negative it means that synchronous behavior is
+disabled.
+</p>
+
+<p>
+The fourth meta-value is currently unused.
+</p>
+
+}
+
+puts {
+<p><hr /></p>
+<p><a href="index.html"><img src="/goback.jpg" border=0 />
+Back to the SQLite Home Page</a>
+</p>
+
+</body></html>}
index ff5a60176dd0485c8a7dbd8aac3198076888d8c6..a0ebe7e69ed4ff7497cde71a61852436f1bcb80e 100644 (file)
@@ -1,12 +1,12 @@
 #
 # Run this TCL script to generate HTML for the index.html file.
 #
-set rcsid {$Id: index.tcl,v 1.66 2002/08/15 13:45:17 drh Exp $}
+set rcsid {$Id: index.tcl,v 1.67 2002/08/18 19:09:24 drh Exp $}
 
 puts {<html>
-<head><title>SQLite: An SQL Database Engine In A C Library</title></head>
+<head><title>SQLite: An Embeddable SQL Database Engine</title></head>
 <body bgcolor=white>
-<h1 align=center>SQLite: An SQL Database Engine In A C Library</h1>
+<h1 align=center>SQLite<br>An Embeddable SQL Database Engine</h1>
 <p align=center>}
 puts "This page was last modified on [lrange $rcsid 3 4] UTC<br>"
 set vers [lindex $argv 0]
@@ -104,12 +104,13 @@ IP address has recently changed.  Try again in a few days.
 <p>
 Whenever either of the first two digits in the version number
 for SQLite change, it means that the underlying file format
-has changed.  See <a href="formatchng.html">formatchng.html</a>
+has changed.  Usually these changes are backwards compatible.
+See <a href="formatchng.html">formatchng.html</a>
 for additional information.
 </p>
 }
 
-puts {<h2>Database File Format Change - Version 2.6.0 - 2002 July 17</h2>
+puts {<h2>Major Database File Format Change - Version 2.6.0 - 2002 July 17</h2>
 
 <p>Beginning with version 2.6.0, the SQLite database file format changed
 in an incompatible way.  If you open a database file from version 2.5.6
@@ -143,12 +144,14 @@ puts {<h2>Documentation</h2>
     how the library is put together.</li>
 <li>A description of the <a href="opcode.html">virtual machine</a> that
     SQLite uses to access the database.</li>
+<li>A description of the 
+    <a href="fileformat.html">database file format</a> used by SQLite.
 <li>A <a href="speed.html">speed comparison</a> between SQLite, PostgreSQL,
     and MySQL.</li>
 </ul>
 </p>
 
-<p>The SQLite source code is 35% comment.  These comments are
+<p>The SQLite source code is 30% comment.  These comments are
 another important source of information. </p>
 
 }
@@ -199,6 +202,13 @@ $ ../sqlite/configure
 $ make                       <i> Builds "sqlite" and "libsqlite.a" </i>
 $ make test                  <i> Optional: run regression tests </i>
 </pre></blockquote>
+
+<p>If you prefer, you can also build by making whatever modifications
+you desire to the file "Makefile.linux-gcc" and then executing that
+makefile.  Tha latter method is used for all official development
+and testing of SQLite and for building the precompiled
+binaries found on this website.  Windows binaries are generated by
+cross-compiling from Linux using <a href="www.mingw.org">MinGW</a></p>
 }
 
 puts {<h2>Related Sites</h2>
index 72a55ceee162b37fbf634015d4f4452759cb6f9b..9e184611a49e505ed8ad46d42462cdf7fbeea47b 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Run this Tcl script to generate the sqlite.html file.
 #
-set rcsid {$Id: lang.tcl,v 1.43 2002/08/15 11:48:14 drh Exp $}
+set rcsid {$Id: lang.tcl,v 1.44 2002/08/18 19:09:24 drh Exp $}
 
 puts {<html>
 <head>
@@ -17,7 +17,8 @@ puts "<p align=center>
 
 puts {
 <p>The SQLite library understands most of the standard SQL
-language.  But it does omit some features while at the same time
+language.  But it does <a href="omitted.html">omit some features</a>
+while at the same time
 adding a few features of its own.  This document attempts to
 describe percisely what parts of the SQL language SQLite does
 and does not support.</p>
@@ -130,7 +131,7 @@ rollback and atomic commit.</p>
 No changes can be made to the database except within a transaction.
 Any command that changes the database (basically, any SQL command
 other than SELECT) will automatically starts a transaction if
-one is not already in effect.  Automatically stared transactions
+one is not already in effect.  Automatically started transactions
 are committed at the conclusion of the command.
 </p>
 
@@ -222,9 +223,9 @@ attached to a single table, nor on the number of columns in an index.</p>
 
 <p>If the UNIQUE keyword appears between CREATE and INDEX then duplicate
 index entries are not allowed.  Any attempt to insert a duplicate entry
-will result in a rollback and an error message.</p>
+will result in an error.</p>
 
-<p>The optional conflict-clause allows the specification of al alternative
+<p>The optional conflict-clause allows the specification of an alternative
 default constraint conflict resolution algorithm for this index.
 This only makes sense if the UNIQUE keyword is used since otherwise
 there are not constraints on the index.  The default algorithm is
@@ -653,8 +654,7 @@ OR</font>
 For arithmetic operations, integers are treated as integers.
 Strings are first converted to real numbers using <b>atof()</b>.
 For comparison operators, numbers compare as numbers and strings
-compare as strings.  For string comparisons, case is significant
-but is only used to break a tie.
+compare using the <b>strcmp()</b> function.
 Note that there are two variations of the equals and not equals
 operators.  Equals can be either}
 puts "[Operator =] or [Operator ==].
@@ -702,7 +702,7 @@ of a row key in an UPDATE or INSERT statement.
 right-hand operand of the IN operator or as a scalar quantity.
 In both cases, the SELECT should have only a single column in its
 result.  Compound SELECTs (connected with keywords like UNION or
-EXCEPT) are allowed.  Any ORDER BY clause on the select is ignored.
+EXCEPT) are allowed.
 A SELECT in an expression is evaluated once before any other processing
 is performed, so none of the expressions within the select itself can
 refer to quantities in the containing expression.</p>
@@ -989,7 +989,7 @@ PRAGMA <function>(<arg>)
 
 puts {
 <p>The PRAGMA command is used to modify the operation of the SQLite library.
-The pragma command is experimental and specific pragma statements may
+The pragma command is experimental and specific pragma statements may be
 removed or added in future releases of SQLite.  Use this command
 with caution.</p>
 
@@ -1174,7 +1174,7 @@ as a result.  If a result expression is }
 puts "[Operator *] then all columns of all tables are substituted"
 puts {for that one expression.</p>
 
-<p>The query is executed again one or more tables specified after
+<p>The query is executed against one or more tables specified after
 the FROM keyword.  If multiple tables names are separated by commas,
 then the query is against the cross join of the various tables.
 The full SQL-92 join syntax can also be used to specify joins.
@@ -1185,10 +1185,7 @@ single row consisting of the values of the expression list.
 </p>
 
 <p>The WHERE clause can be used to limit the number of rows over
-which the query operates.  In the current implementation,
-indices will only be used to
-optimize the query if WHERE expression contains equality comparisons
-connected by the AND operator.</p>
+which the query operates.</p>
 
 <p>The GROUP BY clauses causes one or more rows of the result to
 be combined into a single row of output.  This is especially useful
index 99a956a2b758708579696b8938f2fa4b01c21a77..6f5b0797522120e9b4e305cb0b7c17ac0fb24ff5 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Run this TCL script to generate HTML for the quickstart.html file.
 #
-set rcsid {$Id: quickstart.tcl,v 1.1 2002/08/15 13:45:17 drh Exp $}
+set rcsid {$Id: quickstart.tcl,v 1.2 2002/08/18 19:09:24 drh Exp $}
 
 puts {<html>
 <head><title>SQLite In 5 Minutes Or Less</title></head>
@@ -36,7 +36,12 @@ new database.</p></li>
 <li><p>Below is a simple TCL program that demonstrates how to use
 the TCL interface to SQLite.  The program executes the SQL statements
 given as the second argument on the database defined by the first
-argument.</p>
+argument.  The commands to watch for are the <b>sqlite</b> command
+on line 7 which opens an SQLite database and creates
+a new TCL command named "<b>db</b>" to access that database, the
+invocation of the <b>db</b> command on line 8 to execute
+SQL commands against the database, and the closing of the database connection
+on the last line of the script.</p>
 
 <blockquote><pre>
 #!/usr/bin/tclsh
@@ -45,21 +50,25 @@ if {$argc!=2} {
   exit 1
 }
 load /usr/lib/tclsqlite.so Sqlite
-sqlite db [lindex $argv 0]
-db eval [lindex $argv 1] x {
+<b>sqlite</b> db [lindex $argv 0]
+<b>db</b> eval [lindex $argv 1] x {
   foreach v $x(*) {
     puts "$v = $x($v)"
   }
   puts ""
 }
-db close
+<b>db</b> close
 </pre></blockquote>
 </li>
 
 <li><p>Below is a simple C program that demonstrates how to use
 the C/C++ interface to SQLite.  The name of a database is given by
 the first argument and the second argument is one or more SQL statements
-to execute against the database.</p>
+to execute against the database.  The function calls to pay attention
+to here are the call to <b>sqlite_open()</b> on line 22 which opens
+the database, <b>sqlite_exec()</b> on line 27 that executes SQL
+command against the database, and <b>sqlite_close()</b> on line 31
+that closes the database connection.</p>
 
 <blockquote><pre>
 #include &lt;stdio.h&gt;
@@ -83,16 +92,16 @@ int main(int argc, char **argv){
     fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);
     exit(1);
   }
-  db = sqlite_open(argv[1], 0, &zErrMsg);
+  db = <b>sqlite_open</b>(argv[1], 0, &zErrMsg);
   if( db==0 ){
     fprintf(stderr, "Can't open database: %s\n", &zErrMsg);
     exit(1);
   }
-  rc = sqlite_exec(db, argv[2], callback, 0, &zErrMsg);
+  rc = <b>sqlite_exec</b>(db, argv[2], callback, 0, &zErrMsg);
   if( rc!=SQLITE_OK ){
     fprintf(stderr, "SQL error: %s\n", zErrMsg);
   }
-  sqlite_close(db);
+  <b>sqlite_close</b>(db);
   return 0;
 }
 </pre></blockquote>