:-) (CVS 87)
FossilOrigin-Name: 3661b5ff93b01da7fea9f85370ecdda1402b7164
This commit is contained in:
parent
88923560db
commit
18df8cbede
13
Makefile.in
13
Makefile.in
@ -188,6 +188,16 @@ fileformat.html: $(TOP)/www/fileformat.tcl
|
||||
lang.html: $(TOP)/www/lang.tcl
|
||||
tclsh $(TOP)/www/lang.tcl >lang.html
|
||||
|
||||
arch.html: $(TOP)/www/arch.tcl
|
||||
tclsh $(TOP)/www/arch.tcl >arch.html
|
||||
|
||||
arch.png: $(TOP)/www/arch.png
|
||||
cp $(TOP)/www/arch.png .
|
||||
|
||||
opcode.html: $(TOP)/www/opcode.tcl
|
||||
tclsh $(TOP)/www/opcode.tcl $(TOP)/src/vdbe.c >opcode.html
|
||||
|
||||
|
||||
# Files to be published on the website.
|
||||
#
|
||||
PUBLISH = \
|
||||
@ -197,6 +207,9 @@ PUBLISH = \
|
||||
changes.html \
|
||||
fileformat.html \
|
||||
lang.html \
|
||||
opcode.html \
|
||||
arch.html \
|
||||
arch.png \
|
||||
c_interface.html
|
||||
|
||||
website: $(PUBLISH)
|
||||
|
20
manifest
20
manifest
@ -1,7 +1,7 @@
|
||||
C :-)\s(CVS\s86)
|
||||
D 2000-06-08T21:53:06
|
||||
C :-)\s(CVS\s87)
|
||||
D 2000-06-09T01:58:36
|
||||
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
|
||||
F Makefile.in c98978c886b94cf0d0ed414d6384501390cf0030
|
||||
F Makefile.in a0cc8da380c65002af452dfb72b3e82e1d33b04d
|
||||
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
|
||||
F configure 00a5b5c82147a576fa6e82d7c1b0d55c321d6d2c x
|
||||
F configure.in 6ccfd5fc80517f7cfe605a7fc7e0f62d962a233c
|
||||
@ -22,7 +22,7 @@ F src/tclsqlite.c 9f358618ae803bedf4fb96da5154fd45023bc1f7
|
||||
F src/tokenize.c 344754f81b55da5b19ea9504dfa16a9de68cd5ba
|
||||
F src/update.c d8d90df714bac99c68446a0c49f3d957ca6fc3c8
|
||||
F src/util.c 38e4bb5edf6fa92e677698c45785bf73c69b9e9f
|
||||
F src/vdbe.c cc5598c00935ec9ec349467487182ddce9c00bce
|
||||
F src/vdbe.c b7fb724aa69f4b4a488109c92cc8d64ce483821f
|
||||
F src/vdbe.h 8f79f57c66ce1030f6371ff067b326d627a52c6d
|
||||
F src/where.c c9b90e7672f4662a83ef9a27a193020d69fe034c
|
||||
F test/all.test 0950c135cab7e60c07bd745ccfad1476211e5bd7
|
||||
@ -53,13 +53,17 @@ F tool/memleak.awk a0a11dd84bf4582acc81c3c61271021ae49b3f15
|
||||
F tool/opNames.awk 2bd9071a138e4e2be13dc98fe066398a61219e1e
|
||||
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
|
||||
F tool/renumberOps.awk 6d067177ad5f8d711b79577b462da9b3634bd0a9
|
||||
F www/arch.fig 12da66c71585fff95bda022a9e2efda903fe2a0b
|
||||
F www/arch.png 0aa280d90d1d9249fd7ce3f08d7a227ae2963b9d
|
||||
F www/arch.tcl 282d91f509aadd0873f8aa9b357a2c0b4b175979
|
||||
F www/c_interface.tcl 9ac800854272db5fe439e07b7435b243a5422293
|
||||
F www/changes.tcl 04e66b4257589ff78a7e1de93e9dda4725fb03d6
|
||||
F www/fileformat.tcl b11435fcd2cf2238a1c5e6d16fe5e83bcd14d434
|
||||
F www/index.tcl b2c288000f14383501b157a57ee4506561d62f45
|
||||
F www/lang.tcl 2abf9ac0384b999c0c3f9752596abe8f8db7b2eb
|
||||
F www/lang.tcl eb6a297c55d9856c94da4635eab815b09e4f96bb
|
||||
F www/opcode.tcl 8be80bace48450ef4b9a34dcef4f846f7e5fb2b5
|
||||
F www/sqlite.tcl 5420eab24b539928f80ea9b3088e2549d34f438d
|
||||
P 8b1c151b7b2243672a0bf0ac8377e82c568bacfb
|
||||
R 6dab3d7551f8822711ca5b84a3310ca7
|
||||
P 049abcb37def4200fb8f4ad7cea60a1d53ee3219
|
||||
R cbc86aaf3901beefb4f0dfae3fd3db17
|
||||
U drh
|
||||
Z 1919fdb42862a0c5cf9947137480de24
|
||||
Z 0d4f983c5b2e1877564119b56f0ca7bf
|
||||
|
@ -1 +1 @@
|
||||
049abcb37def4200fb8f4ad7cea60a1d53ee3219
|
||||
3661b5ff93b01da7fea9f85370ecdda1402b7164
|
36
src/vdbe.c
36
src/vdbe.c
@ -41,7 +41,7 @@
|
||||
** But other routines are also provided to help in building up
|
||||
** a program instruction by instruction.
|
||||
**
|
||||
** $Id: vdbe.c,v 1.30 2000/06/08 16:26:25 drh Exp $
|
||||
** $Id: vdbe.c,v 1.31 2000/06/09 01:58:37 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <unistd.h>
|
||||
@ -946,7 +946,7 @@ int sqliteVdbeExec(
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: NULL * * *
|
||||
/* Opcode: Null * * *
|
||||
**
|
||||
** Push a NULL value onto the stack.
|
||||
*/
|
||||
@ -1893,7 +1893,7 @@ int sqliteVdbeExec(
|
||||
** Turn the key-as-data mode for cursor P1 either on (if P2==1) or
|
||||
** off (if P2==0). In key-as-data mode, the OP_Fetch opcode pulls
|
||||
** data off of the key rather than the data. This is useful for
|
||||
** outer joins and stuff...
|
||||
** processing compound selects.
|
||||
*/
|
||||
case OP_KeyAsData: {
|
||||
int i = pOp->p1;
|
||||
@ -1910,8 +1910,12 @@ int sqliteVdbeExec(
|
||||
**
|
||||
** The value pushed is just a pointer to the data in the cursor.
|
||||
** The value will go away the next time a record is fetched from P1,
|
||||
** or when P1 is closed. Make a copy of the string if it needs
|
||||
** to persist longer than that.
|
||||
** or when P1 is closed. Make a copy of the string (using
|
||||
** "Concat 1 0 0" if it needs to persist longer than that.
|
||||
**
|
||||
** If the KeyAsData opcode has previously executed on this cursor,
|
||||
** then the field might be extracted from the key rather than the
|
||||
** data.
|
||||
*/
|
||||
case OP_Field: {
|
||||
int *pAddr;
|
||||
@ -2756,8 +2760,11 @@ int sqliteVdbeExec(
|
||||
** with the given key exists, create one and make it current but
|
||||
** do not jump.
|
||||
**
|
||||
** This opcode should not be executed after an AggNext but before
|
||||
** the next AggReset.
|
||||
** The order of aggregator opcodes is important. The order is:
|
||||
** AggReset AggFocus AggNext. In other words, you must execute
|
||||
** AggReset first, then zero or more AggFocus operations, then
|
||||
** zero or more AggNext operations. You must not execute an AggFocus
|
||||
** in between an AggNext and an AggReset.
|
||||
*/
|
||||
case OP_AggFocus: {
|
||||
int tos = p->tos;
|
||||
@ -2852,8 +2859,8 @@ int sqliteVdbeExec(
|
||||
/* Opcode: AggGet * P2 *
|
||||
**
|
||||
** Push a new entry onto the stack which is a copy of the P2-th field
|
||||
** of the current aggregate. String are not duplicated so
|
||||
** string values will be ephemeral.
|
||||
** of the current aggregate. Strings are not duplicated so
|
||||
** string values will be ephemeral.
|
||||
*/
|
||||
case OP_AggGet: {
|
||||
AggElem *pFocus = AggInFocus(p->agg);
|
||||
@ -2876,8 +2883,11 @@ int sqliteVdbeExec(
|
||||
** aggregate is deleted. If all aggregate values have been consumed,
|
||||
** jump to P2.
|
||||
**
|
||||
** Do not execute an AggFocus after this opcode until after the
|
||||
** next AggReset.
|
||||
** The order of aggregator opcodes is important. The order is:
|
||||
** AggReset AggFocus AggNext. In other words, you must execute
|
||||
** AggReset first, then zero or more AggFocus operations, then
|
||||
** zero or more AggNext operations. You must not execute an AggFocus
|
||||
** in between an AggNext and an AggReset.
|
||||
*/
|
||||
case OP_AggNext: {
|
||||
if( p->agg.nHash ){
|
||||
@ -2905,7 +2915,7 @@ int sqliteVdbeExec(
|
||||
|
||||
/* Opcode: SetClear P1 * *
|
||||
**
|
||||
** Remove all elements from the given Set.
|
||||
** Remove all elements from the P1-th Set.
|
||||
*/
|
||||
case OP_SetClear: {
|
||||
int i = pOp->p1;
|
||||
@ -2917,7 +2927,7 @@ int sqliteVdbeExec(
|
||||
|
||||
/* Opcode: SetInsert P1 * P3
|
||||
**
|
||||
** If Set p1 does not exist then create it. Then insert value
|
||||
** If Set P1 does not exist then create it. Then insert value
|
||||
** P3 into that set. If P3 is NULL, then insert the top of the
|
||||
** stack into the set.
|
||||
*/
|
||||
|
49
www/arch.fig
Normal file
49
www/arch.fig
Normal file
@ -0,0 +1,49 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
2550 2250 4875 2250 4875 3525 2550 3525 2550 2250
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
2550 4050 4875 4050 4875 5325 2550 5325 2550 4050
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
2550 5850 4875 5850 4875 7125 2550 7125 2550 5850
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
2550 7650 4875 7650 4875 8925 2550 8925 2550 7650
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
2550 450 4875 450 4875 1725 2550 1725 2550 450
|
||||
2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
|
||||
2550 9450 4875 9450 4875 10725 2550 10725 2550 9450
|
||||
2 1 0 3 0 7 100 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 3.00 75.00 135.00
|
||||
3675 1725 3675 2250
|
||||
2 1 0 3 0 7 100 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 3.00 75.00 135.00
|
||||
3675 3525 3675 4050
|
||||
2 1 0 3 0 7 100 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 3.00 75.00 135.00
|
||||
3675 5325 3675 5850
|
||||
2 1 0 3 0 7 100 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 3.00 75.00 135.00
|
||||
3675 7125 3675 7650
|
||||
2 1 0 3 0 7 100 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 3.00 75.00 135.00
|
||||
3675 8925 3675 9450
|
||||
4 1 0 100 0 0 20 0.0000 4 195 1920 3675 8025 Virtual Machine\001
|
||||
4 1 0 100 0 0 20 0.0000 4 195 1830 3675 6225 Code Generator\001
|
||||
4 1 0 100 0 0 20 0.0000 4 195 735 3675 4350 Parser\001
|
||||
4 1 0 100 0 0 20 0.0000 4 195 1140 3675 2550 Tokenizer\001
|
||||
4 1 0 100 0 0 20 0.0000 4 195 1020 3675 750 Interface\001
|
||||
4 1 0 100 0 0 20 0.0000 4 195 990 3675 9825 Backend\001
|
||||
4 1 0 100 0 0 14 0.0000 4 150 570 3675 10650 dbbe.c\001
|
||||
4 1 0 100 0 0 14 0.0000 4 150 570 3675 8850 vdbe.c\001
|
||||
4 1 0 100 0 0 14 0.0000 4 195 2190 3675 7050 select.c update.c where.c\001
|
||||
4 1 0 100 0 0 14 0.0000 4 195 1860 3675 6825 build.c delete.c expr.c\001
|
||||
4 1 0 100 0 0 14 0.0000 4 150 630 3675 5250 parse.y\001
|
||||
4 1 0 100 0 0 14 0.0000 4 150 870 3675 3450 tokenize.c\001
|
||||
4 1 0 100 0 0 14 0.0000 4 150 570 3675 1575 main.c\001
|
BIN
www/arch.png
Normal file
BIN
www/arch.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
126
www/arch.tcl
Normal file
126
www/arch.tcl
Normal file
@ -0,0 +1,126 @@
|
||||
#
|
||||
# Run this Tcl script to generate the sqlite.html file.
|
||||
#
|
||||
set rcsid {$Id: arch.tcl,v 1.1 2000/06/09 01:58:51 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head>
|
||||
<title>Architecture of SQLite</title>
|
||||
</head>
|
||||
<body bgcolor=white>
|
||||
<h1 align=center>
|
||||
The Architecture Of SQLite
|
||||
</h1>}
|
||||
puts "<p align=center>
|
||||
(This page was last modified on [lrange $rcsid 3 4] GMT)
|
||||
</p>"
|
||||
|
||||
puts {
|
||||
<h2>Introduction</h2>
|
||||
|
||||
<table align="right" border="1" cellpadding="15" cellspacing="1">
|
||||
<tr><th>Block Diagram Of SQLite</th></tr>
|
||||
<tr><td><img src="arch.png"></td></tr>
|
||||
</table>
|
||||
<p>This file describes the architecture of the SQLite library.
|
||||
A block diagram showing the main components of SQLite
|
||||
and how that interrelate is shown at the right. The text that
|
||||
follows will provide a quick overview of each of these components.
|
||||
</p>
|
||||
|
||||
<h2>Interface</h2>
|
||||
|
||||
<p>The public interface to the SQLite library is implemented by
|
||||
four functions found in the <b>main.c</b> source file. Additional
|
||||
information on the C interface to SQLite is
|
||||
<a href="c_interface.html">available separately</a>.<p>
|
||||
|
||||
<p>To avoid name collisions with other software, all external
|
||||
symbols in the SQLite library begin with the prefix <b>sqlite</b>.
|
||||
Those symbols that are intended for external use (as oppose to
|
||||
those which are for internal use only but which have to be exported
|
||||
do to limitations of the C linker's scoping mechanism) begin
|
||||
with <b>sqlite_</b>.</p>
|
||||
|
||||
<h2>Tokenizer</h2>
|
||||
|
||||
<p>When a string containing SQL statements is to be executed, the
|
||||
interface passes that string to the tokenizer. The job of the tokenizer
|
||||
is to break the original string up into tokens and pass those tokens
|
||||
one by one to the parser. The tokenizer is hand-coded in C.
|
||||
(There is no "lex" code here.) All of the code for the tokenizer
|
||||
is contained in the <b>tokenize.c</b> source file.</p>
|
||||
|
||||
<p>Note that in this design, the tokenizer calls the parser. People
|
||||
who are familiar with YACC and BISON may be used to doing things the
|
||||
other way around -- having the parser call the tokenizer. This author
|
||||
as done it both ways, and finds things generally work out nicer for
|
||||
the tokenizer to call the parser. YACC has it backwards.</p>
|
||||
|
||||
<h2>Parser</h2>
|
||||
|
||||
<p>The parser is the piece that assigns meaning to tokens based on
|
||||
their context. The parser for SQLite is generated using the
|
||||
<a href="http://www.hwaci.com/sw/lemon/">Lemon</a> LALR(1) parser
|
||||
generator. Lemon does the same job as YACC/BISON, but is uses
|
||||
a different input syntax which is less error-prone than the
|
||||
clumsy YACC/BISON syntax.
|
||||
Lemon also generates a parser which is reentrant and thread-safe.
|
||||
And lemon defines the concept of a non-terminal destructor so
|
||||
that it does not leak memory when syntax errors are encountered.
|
||||
The source file that drives Lemon is found in <b>parse.y</b>.</p>
|
||||
|
||||
<p>Because
|
||||
lemon is a program not normally found on development machines, the
|
||||
complete source code to lemon (just one C file) is included in the
|
||||
SQLite distribution in the "tool" subdirectory. Documentation on
|
||||
lemon is found in the "doc" subdirectory of the distribution.
|
||||
</p>
|
||||
|
||||
<h2>Code Generator</h2>
|
||||
|
||||
<p>After the parser assemblies tokens into complete SQL statements,
|
||||
it calls the code generator to produce virtual machine code that
|
||||
will do the work that the SQL statements request. There are six
|
||||
files in the code generator: <b>build.c</b>, <b>delete.c</b>,
|
||||
<b>expr.c</b>, <b>select.c</b>, <b>update.c</b>, and <b>where.c</b>.
|
||||
In these files is where most of the serious magic happens.</p>
|
||||
|
||||
<h2>Virtual Machine</h2>
|
||||
|
||||
<p>The program generated by the code generator is executed by
|
||||
the virtual machine. Additional information about the virtual
|
||||
machine is <a href="opcode.html">available separately</a>.
|
||||
To summarize, the virtual machine implements an abstract computing
|
||||
engine specifically designed to manipulate database files. The
|
||||
machine as a stack. Each instruction contains an opcode and
|
||||
up to three additional operands.</p>
|
||||
|
||||
<p>The virtual machine is entirely contained in a single
|
||||
source file <b>vdbe.c</b>. The virtual machine also has
|
||||
its own header file <b>vdbe.h</b> that defines an interface
|
||||
between the virtual machine and the rest of the SQLite library.</p>
|
||||
|
||||
<h2>Backend</h2>
|
||||
|
||||
<p>The last layer in the design of SQLite is the backend. The
|
||||
backend implements an interface between the virtual machine and
|
||||
the underlying data file library -- GDBM in this case. The interface
|
||||
is designed to make it easy to substitute a different database
|
||||
library, such as the Berkeley DB.
|
||||
The backend abstracts many of the low-level details to help
|
||||
reduce the complexity of the virtual machine.</p>
|
||||
|
||||
<p>The backend is contained in the single source file <b>dbbe.c</b>.
|
||||
The backend also has a header file <b>dbbe.h</b> that defines the
|
||||
interface between the backend and the rest of the SQLite library.</p>
|
||||
}
|
||||
|
||||
puts {
|
||||
<br clear="both" />
|
||||
<p><hr /></p>
|
||||
<p><a href="index.html"><img src="/goback.jpg" border=0 />
|
||||
Back to the SQLite Home Page</a>
|
||||
</p>
|
||||
|
||||
</body></html>}
|
80
www/lang.tcl
80
www/lang.tcl
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Run this Tcl script to generate the sqlite.html file.
|
||||
#
|
||||
set rcsid {$Id: lang.tcl,v 1.1 2000/06/08 21:53:06 drh Exp $}
|
||||
set rcsid {$Id: lang.tcl,v 1.2 2000/06/09 01:58:37 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head>
|
||||
@ -30,9 +30,29 @@ that are part of the syntactic markup itself are shown in black roman.</p>
|
||||
by SQLite. Many low-level productions are omitted. For detailed information
|
||||
on the language that SQLite understands, refer to the source code.</p>
|
||||
|
||||
<h2>CREATE TABLE</h2>
|
||||
|
||||
<p>The basic structure of a CREATE TABLE statement is as follows:</p>
|
||||
<p>SQLite implements the follow SQL commands:</p>
|
||||
<p><ul>
|
||||
}
|
||||
|
||||
foreach {section} [lsort -index 0 -dictionary {
|
||||
{{CREATE TABLE} createtable}
|
||||
{{CREATE INDEX} createindex}
|
||||
{VACUUM vacuum}
|
||||
{{DROP TABLE} droptable}
|
||||
{{DROP INDEX} dropindex}
|
||||
{INSERT insert}
|
||||
{DELETE delete}
|
||||
{UPDATE update}
|
||||
{SELECT select}
|
||||
{COPY copy}
|
||||
}] {
|
||||
puts "<li><a href=\"#[lindex $section 1]\">[lindex $section 0]</a></li>"
|
||||
}
|
||||
puts {</ul></p>
|
||||
|
||||
<p>Details on the implementation of each command are provided in
|
||||
the sequel.</p>
|
||||
}
|
||||
|
||||
proc Syntax {args} {
|
||||
@ -53,6 +73,20 @@ proc Syntax {args} {
|
||||
puts {</table>}
|
||||
}
|
||||
|
||||
proc Section {name {label {}}} {
|
||||
puts "\n<hr />"
|
||||
if {$label!=""} {
|
||||
puts "<a name=\"$label\">"
|
||||
}
|
||||
puts "<h1>$name</h1>\n"
|
||||
}
|
||||
|
||||
proc Example {text} {
|
||||
puts "<blockquote><pre>$text</pre></blockquote>"
|
||||
}
|
||||
|
||||
Section {CREATE TABLE} {createtable}
|
||||
|
||||
Syntax {sql-command} {
|
||||
CREATE TABLE <table-name> (
|
||||
<column-def> [, <column-def>]*
|
||||
@ -68,7 +102,8 @@ CREATE TABLE <table-name> (
|
||||
NOT NULL |
|
||||
PRIMARY KEY [<sort-order>] |
|
||||
UNIQUE |
|
||||
CHECK ( <expr> )
|
||||
CHECK ( <expr> ) |
|
||||
DEFAULT <value>
|
||||
} {constraint} {
|
||||
PRIMARY KEY ( <name> [, <name>]* ) |
|
||||
UNIQUE ( <name> [, <name>]* ) |
|
||||
@ -87,7 +122,9 @@ datatype for that column, then one or more optional column constraints.
|
||||
The datatype for the column is ignored. All information
|
||||
is stored as null-terminated strings. The constraints are also ignored,
|
||||
except that the PRIMARY KEY constraint will cause an index to be automatically
|
||||
created that implements the primary key. The name of the primary
|
||||
created that implements the primary key and the DEFAULT constraint
|
||||
which specifies a default value to use when doing an INSERT.
|
||||
The name of the primary
|
||||
key index will be the table name
|
||||
with "<b>__primary_key</b>" appended. The index used for a primary key
|
||||
does not show up in the <b>sqlite_master</b> table, but a GDBM file is
|
||||
@ -103,8 +140,7 @@ are read from the <b>sqlite_master</b> table and used to regenerate
|
||||
SQLite's internal representation of the table layout.</p>
|
||||
}
|
||||
|
||||
puts {<h2>CREATE INDEX</h2>
|
||||
}
|
||||
Section {CREATE INDEX} createindex
|
||||
|
||||
Syntax {sql-statement} {
|
||||
CREATE INDEX <index-name>
|
||||
@ -130,10 +166,11 @@ of each CREATE INDEX statement is stored in the <b>sqlite_master</b>
|
||||
table. Everytime the database is opened, all CREATE INDEX statements
|
||||
are read from the <b>sqlite_master</b> table and used to regenerate
|
||||
SQLite's internal representation of the index layout.</p>
|
||||
|
||||
<h2>DROP TABLE</h2>
|
||||
}
|
||||
|
||||
|
||||
Section {DROP TABLE} droptable
|
||||
|
||||
Syntax {sql-command} {
|
||||
DROP TABLE <table-name>
|
||||
}
|
||||
@ -142,10 +179,9 @@ puts {
|
||||
<p>The DROP TABLE statement consists of the keywords "DROP TABLE" followed
|
||||
by the name of the table. The table named is completely removed from
|
||||
the disk. The table can not be recovered. All indices associated with
|
||||
the table are also reversibly deleted.</p>
|
||||
the table are also reversibly deleted.</p>}
|
||||
|
||||
<h2>DROP INDEX</h2>
|
||||
}
|
||||
Section {DROP INDEX} dropindex
|
||||
|
||||
Syntax {sql-command} {
|
||||
DROP INDEX <index-name>
|
||||
@ -156,10 +192,10 @@ puts {
|
||||
by the name of the index. The index named is completely removed from
|
||||
the disk. The only way to recover the index is to reenter the
|
||||
appropriate CREATE INDEX command.</p>
|
||||
|
||||
<h2>VACUUM</h2>
|
||||
}
|
||||
|
||||
Section VACUUM vacuum
|
||||
|
||||
Syntax {sql-statement} {
|
||||
VACUUM [<index-or-table-name>]
|
||||
}
|
||||
@ -176,7 +212,23 @@ especially indices where a single index value refers to many
|
||||
entries in the data table. Reorganizing these indices will make
|
||||
the underlying GDBM file much smaller and will help queries to
|
||||
run much faster.</p>
|
||||
}
|
||||
|
||||
Section INSERT insert
|
||||
|
||||
Syntax {sql-statement} {
|
||||
INSERT INTO <table-name> [( <column-list> )] VALUES ( <value-list> ) |
|
||||
INSERT INTO <table-name> [( <column-list> )] <select-statement>
|
||||
}
|
||||
|
||||
puts {
|
||||
<p>The INSERT statement comes in two basic forms. The first form
|
||||
(with the "VALUES" keyword) creates a single new row in an existing table.
|
||||
If no column-list is specified then the number of values must
|
||||
be the same as the number of columns in the table. If a column-list
|
||||
is specified, then the number of values must match the number of
|
||||
specified columns
|
||||
</p>
|
||||
}
|
||||
|
||||
puts {
|
||||
|
225
www/opcode.tcl
Normal file
225
www/opcode.tcl
Normal file
@ -0,0 +1,225 @@
|
||||
#
|
||||
# Run this Tcl script to generate the sqlite.html file.
|
||||
#
|
||||
set rcsid {$Id: opcode.tcl,v 1.1 2000/06/09 01:58:37 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head>
|
||||
<title>SQLite Virtual Machine Opcodes</title>
|
||||
</head>
|
||||
<body bgcolor=white>
|
||||
<h1 align=center>
|
||||
SQLite Virtual Machine Opcodes
|
||||
</h1>}
|
||||
puts "<p align=center>
|
||||
(This page was last modified on [lrange $rcsid 3 4] GMT)
|
||||
</p>"
|
||||
|
||||
set fd [open [lindex $argv 0] r]
|
||||
set file [read $fd [file size [lindex $argv 0]]]
|
||||
close $fd
|
||||
set current_op {}
|
||||
foreach line [split $file \n] {
|
||||
set line [string trim $line]
|
||||
if {[string index $line 1]!="*"} {
|
||||
set current_op {}
|
||||
continue
|
||||
}
|
||||
if {[regexp {^/\* Opcode: } $line]} {
|
||||
set current_op [lindex $line 2]
|
||||
set Opcode($current_op:args) [lrange $line 3 end]
|
||||
lappend OpcodeList $current_op
|
||||
continue
|
||||
}
|
||||
if {$current_op==""} continue
|
||||
if {[regexp {^\*/} $line]} {
|
||||
set current_op {}
|
||||
continue
|
||||
}
|
||||
set line [string trim [string range $line 3 end]]
|
||||
if {$line==""} {
|
||||
append Opcode($current_op:text) \n<p>
|
||||
} else {
|
||||
append Opcode($current_op:text) \n$line
|
||||
}
|
||||
}
|
||||
unset file
|
||||
|
||||
puts {
|
||||
<h2>Introduction</h2>
|
||||
|
||||
<p>In order to execute an SQL statement, the SQLite library first parses
|
||||
the SQL, analyzes the statement, then generates a short program to execute
|
||||
the statement. The program is generated for a "virtual machine" implemented
|
||||
by the SQLite library. The document describes the operation of that
|
||||
virtual machine.</p>
|
||||
|
||||
<p>The source code to the virtual machine is in the <b>vdbe.c</b> source
|
||||
file. All of the opcode definitions further down in this document are
|
||||
contained in comments in the source file. In fact, the opcode table
|
||||
in this document
|
||||
was generated by scanning the <b>vdbe.c</b> source file
|
||||
and extracting the necessary information from comments. So the
|
||||
source code comments are really the canonical source of information
|
||||
about the virtual macchine. When in doubt, refer to the source code.</p>
|
||||
|
||||
<p>Each instruction in the virtual machine consists of an opcode and
|
||||
up to three operands named P1, P2 and P3. P1 may be an arbitrary
|
||||
integer. P2 must be a non-negative integer. P2 is always the
|
||||
jump destination in any operation that might cause a jump.
|
||||
P3 is a null-terminated
|
||||
string or NULL. Some operators use all three operands. Some use
|
||||
one or two. Some operators use none of the operands.<p>
|
||||
|
||||
<p>The virtual machine begins execution on instruction number 0.
|
||||
Execution continues until (1) a Halt instruction is seen, or
|
||||
(2) the program counter becomes one greater than the address of
|
||||
last instruction, or (3) there is an execution error.
|
||||
When the virtual machine halts, all memory
|
||||
that it allocated is released and all database files it may
|
||||
have had open are closed.</p>
|
||||
|
||||
<p>The virtual machine also contains an operand stack of unlimited
|
||||
depth. Many of the opcodes use operands from the stack. The details
|
||||
are described in the descriptions of each opcode.</p>
|
||||
|
||||
<p>The virtual machine can have zero or more cursors. Each cursor
|
||||
is a pointer into a single GDBM file. There can be multiple
|
||||
cursors pointing at the same file.
|
||||
All cursors operate independenly.
|
||||
The only way for the virtual machine to interact with a GDBM
|
||||
file is through a cursor.
|
||||
Instructions in the virtual
|
||||
machine can create a new cursor (Open), read data from a cursor
|
||||
(Field), advance the cursor to the next entry in the GDBM file
|
||||
(Next), and many other operations. All cursors are automatically
|
||||
closed when the virtual machine terminates.</p>
|
||||
|
||||
<p>The virtual machine contains an arbitrary number of fixed memory
|
||||
locations with addresses beginning at zero and growing upward.
|
||||
Each memory location can hold an arbitrary string. The memory
|
||||
cells are typically used to hold the result of a scalar SELECT
|
||||
that is part of a larger expression.</p>
|
||||
|
||||
<p>The virtual machine contains an arbitrary number of sorters.
|
||||
Each sorter is able to accumulate records, sort those records,
|
||||
then play the records back in sorted order. Sorters are used
|
||||
to implement the ORDER BY clause of a SELECT statement. The
|
||||
fact that the virtual machine allows multiple sorters is an
|
||||
historical accident. In practice no more than one sorter
|
||||
(sorter number 0) ever gets used.</p>
|
||||
|
||||
<p>The virtual machine may contain an arbitrary number of "Lists".
|
||||
Each list stores a list of integers. Lists are used to hold the
|
||||
GDBM keys for records of a GDBM file that needs to be modified.
|
||||
The WHERE clause of an UPDATE or DELETE statement scans through
|
||||
the table and writes the GDBM key of every record to be modified
|
||||
into a list. Then the list is played back and the table is modified
|
||||
in a separate step. It is necessary to do this in two steps since
|
||||
making a change to a GDBM file can alter the scan order.</p>
|
||||
|
||||
<p>The virtual machine can contain an arbitrary number of "Sets".
|
||||
Each set holds an arbitrary number of strings. Sets are used to
|
||||
implement the IN operator with a constant right-hand side.</p>
|
||||
|
||||
<p>The virtual machine can open a single external file for reading.
|
||||
This external read file is used to implement the COPY command.</p>
|
||||
|
||||
<p>Finally, the virtual machine can have a single set of aggregators.
|
||||
An aggregator is a device used to implement the GROUP BY clause
|
||||
of a SELECT. An aggregator has one or more slots that can hold
|
||||
values being extracted by the select. The number of slots is the
|
||||
same for all aggregators and is defined by the AggReset operation.
|
||||
At any point in time a single aggregator is current or "has focus".
|
||||
There are operations to read or write to memory slots of the aggregator
|
||||
in focus. There are also operations to change the focus aggregator
|
||||
and to scan through all aggregators.</p>
|
||||
|
||||
<h2>Viewing Programs Generated By SQLite</h2>
|
||||
|
||||
<p>Every SQL statement that SQLite interprets results in a program
|
||||
for the virtual machine. But if you precede the SQL statement with
|
||||
the keyword "EXPLAIN" the virtual machine will not execute the
|
||||
program. Instead, the instructions of the program will be returned
|
||||
like a query result. This feature is useful for debugging and
|
||||
for learning how the virtual machine operates.</p>
|
||||
|
||||
<p>You can use the <b>sqlite</b> command-line tool to see the
|
||||
instructions generated by an SQL statement. The following is
|
||||
an example:</p>}
|
||||
|
||||
|
||||
proc Code {body} {
|
||||
puts {<blockquote><pre>}
|
||||
regsub -all {&} [string trim $body] {\&} body
|
||||
regsub -all {>} $body {\>} body
|
||||
regsub -all {<} $body {\<} body
|
||||
regsub -all {\(\(\(} $body {<font color="#00671f"><i>} body
|
||||
regsub -all {\)\)\)} $body {</i></font>} body
|
||||
puts $body
|
||||
puts {</pre></blockquote>}
|
||||
}
|
||||
|
||||
Code {
|
||||
$ (((sqlite ex1)))
|
||||
sqlite> (((.explain)))
|
||||
sqlite> (((explain delete from tbl1 where two<20;)))
|
||||
addr opcode p1 p2 p3
|
||||
---- ------------ ----- ----- -------------------------------------
|
||||
0 ListOpen 0 0
|
||||
1 Open 0 1 tbl1
|
||||
2 Next 0 9
|
||||
3 Field 0 1
|
||||
4 Integer 20 0
|
||||
5 Ge 0 2
|
||||
6 Key 0 0
|
||||
7 ListWrite 0 0
|
||||
8 Goto 0 2
|
||||
9 Noop 0 0
|
||||
10 ListRewind 0 0
|
||||
11 ListRead 0 14
|
||||
12 Delete 0 0
|
||||
13 Goto 0 11
|
||||
14 ListClose 0 0
|
||||
}
|
||||
|
||||
puts {
|
||||
<p>All you have to do is add the "EXPLAIN" keyword to the front of the
|
||||
SQL statement. But if you use the ".explain" command to <b>sqlite</b>
|
||||
first, it will set up the output mode to make the program more easily
|
||||
viewable.</p>
|
||||
|
||||
<p>If <b>sqlite</b> has been compiled without the "-DNDEBUG=1" option
|
||||
(that is, with the NDEBUG preprocessor macro not defined) then you
|
||||
can put the SQLite virtual machine in a mode where it will trace its
|
||||
execution by writing messages to standard output. There are special
|
||||
comments to turn tracing on and off. Use the <b>--vdbe-trace-on--</b>
|
||||
comment to turn tracing on and the <b>--vdbe-trace-off--</b> comment
|
||||
to turn tracing back off.</p>
|
||||
|
||||
<h2>The Opcodes</h2>
|
||||
}
|
||||
|
||||
puts "<p>There are currently [llength $OpcodeList] opcodes defined by
|
||||
the virtual machine."
|
||||
puts {All currently defined opcodes are described in the table below.
|
||||
This table was generated automatically by scanning the source code
|
||||
from the file <b>vdbe.c</b>.</p>}
|
||||
|
||||
puts {
|
||||
<p><table cellspacing="1" border="1" cellpadding="10">
|
||||
<tr><th>Opcode Name</th><th>Description</th></tr>}
|
||||
foreach op [lsort -dictionary $OpcodeList] {
|
||||
puts {<tr><td valign="top" align="center">}
|
||||
puts "$op"
|
||||
puts "<td>[string trim $Opcode($op:text)]</td></tr>"
|
||||
}
|
||||
puts {</table></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>}
|
Loading…
x
Reference in New Issue
Block a user