mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
:-) (CVS 87)
FossilOrigin-Name: 3661b5ff93b01da7fea9f85370ecdda1402b7164
This commit is contained in:
13
Makefile.in
13
Makefile.in
@@ -188,6 +188,16 @@ fileformat.html: $(TOP)/www/fileformat.tcl
|
|||||||
lang.html: $(TOP)/www/lang.tcl
|
lang.html: $(TOP)/www/lang.tcl
|
||||||
tclsh $(TOP)/www/lang.tcl >lang.html
|
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.
|
# Files to be published on the website.
|
||||||
#
|
#
|
||||||
PUBLISH = \
|
PUBLISH = \
|
||||||
@@ -197,6 +207,9 @@ PUBLISH = \
|
|||||||
changes.html \
|
changes.html \
|
||||||
fileformat.html \
|
fileformat.html \
|
||||||
lang.html \
|
lang.html \
|
||||||
|
opcode.html \
|
||||||
|
arch.html \
|
||||||
|
arch.png \
|
||||||
c_interface.html
|
c_interface.html
|
||||||
|
|
||||||
website: $(PUBLISH)
|
website: $(PUBLISH)
|
||||||
|
20
manifest
20
manifest
@@ -1,7 +1,7 @@
|
|||||||
C :-)\s(CVS\s86)
|
C :-)\s(CVS\s87)
|
||||||
D 2000-06-08T21:53:06
|
D 2000-06-09T01:58:36
|
||||||
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
|
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
|
||||||
F Makefile.in c98978c886b94cf0d0ed414d6384501390cf0030
|
F Makefile.in a0cc8da380c65002af452dfb72b3e82e1d33b04d
|
||||||
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
|
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
|
||||||
F configure 00a5b5c82147a576fa6e82d7c1b0d55c321d6d2c x
|
F configure 00a5b5c82147a576fa6e82d7c1b0d55c321d6d2c x
|
||||||
F configure.in 6ccfd5fc80517f7cfe605a7fc7e0f62d962a233c
|
F configure.in 6ccfd5fc80517f7cfe605a7fc7e0f62d962a233c
|
||||||
@@ -22,7 +22,7 @@ F src/tclsqlite.c 9f358618ae803bedf4fb96da5154fd45023bc1f7
|
|||||||
F src/tokenize.c 344754f81b55da5b19ea9504dfa16a9de68cd5ba
|
F src/tokenize.c 344754f81b55da5b19ea9504dfa16a9de68cd5ba
|
||||||
F src/update.c d8d90df714bac99c68446a0c49f3d957ca6fc3c8
|
F src/update.c d8d90df714bac99c68446a0c49f3d957ca6fc3c8
|
||||||
F src/util.c 38e4bb5edf6fa92e677698c45785bf73c69b9e9f
|
F src/util.c 38e4bb5edf6fa92e677698c45785bf73c69b9e9f
|
||||||
F src/vdbe.c cc5598c00935ec9ec349467487182ddce9c00bce
|
F src/vdbe.c b7fb724aa69f4b4a488109c92cc8d64ce483821f
|
||||||
F src/vdbe.h 8f79f57c66ce1030f6371ff067b326d627a52c6d
|
F src/vdbe.h 8f79f57c66ce1030f6371ff067b326d627a52c6d
|
||||||
F src/where.c c9b90e7672f4662a83ef9a27a193020d69fe034c
|
F src/where.c c9b90e7672f4662a83ef9a27a193020d69fe034c
|
||||||
F test/all.test 0950c135cab7e60c07bd745ccfad1476211e5bd7
|
F test/all.test 0950c135cab7e60c07bd745ccfad1476211e5bd7
|
||||||
@@ -53,13 +53,17 @@ F tool/memleak.awk a0a11dd84bf4582acc81c3c61271021ae49b3f15
|
|||||||
F tool/opNames.awk 2bd9071a138e4e2be13dc98fe066398a61219e1e
|
F tool/opNames.awk 2bd9071a138e4e2be13dc98fe066398a61219e1e
|
||||||
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
|
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
|
||||||
F tool/renumberOps.awk 6d067177ad5f8d711b79577b462da9b3634bd0a9
|
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/c_interface.tcl 9ac800854272db5fe439e07b7435b243a5422293
|
||||||
F www/changes.tcl 04e66b4257589ff78a7e1de93e9dda4725fb03d6
|
F www/changes.tcl 04e66b4257589ff78a7e1de93e9dda4725fb03d6
|
||||||
F www/fileformat.tcl b11435fcd2cf2238a1c5e6d16fe5e83bcd14d434
|
F www/fileformat.tcl b11435fcd2cf2238a1c5e6d16fe5e83bcd14d434
|
||||||
F www/index.tcl b2c288000f14383501b157a57ee4506561d62f45
|
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
|
F www/sqlite.tcl 5420eab24b539928f80ea9b3088e2549d34f438d
|
||||||
P 8b1c151b7b2243672a0bf0ac8377e82c568bacfb
|
P 049abcb37def4200fb8f4ad7cea60a1d53ee3219
|
||||||
R 6dab3d7551f8822711ca5b84a3310ca7
|
R cbc86aaf3901beefb4f0dfae3fd3db17
|
||||||
U drh
|
U drh
|
||||||
Z 1919fdb42862a0c5cf9947137480de24
|
Z 0d4f983c5b2e1877564119b56f0ca7bf
|
||||||
|
@@ -1 +1 @@
|
|||||||
049abcb37def4200fb8f4ad7cea60a1d53ee3219
|
3661b5ff93b01da7fea9f85370ecdda1402b7164
|
34
src/vdbe.c
34
src/vdbe.c
@@ -41,7 +41,7 @@
|
|||||||
** But other routines are also provided to help in building up
|
** But other routines are also provided to help in building up
|
||||||
** a program instruction by instruction.
|
** 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 "sqliteInt.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -946,7 +946,7 @@ int sqliteVdbeExec(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: NULL * * *
|
/* Opcode: Null * * *
|
||||||
**
|
**
|
||||||
** Push a NULL value onto the stack.
|
** 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
|
** 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
|
** 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
|
** data off of the key rather than the data. This is useful for
|
||||||
** outer joins and stuff...
|
** processing compound selects.
|
||||||
*/
|
*/
|
||||||
case OP_KeyAsData: {
|
case OP_KeyAsData: {
|
||||||
int i = pOp->p1;
|
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 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,
|
** 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
|
** or when P1 is closed. Make a copy of the string (using
|
||||||
** to persist longer than that.
|
** "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: {
|
case OP_Field: {
|
||||||
int *pAddr;
|
int *pAddr;
|
||||||
@@ -2756,8 +2760,11 @@ int sqliteVdbeExec(
|
|||||||
** with the given key exists, create one and make it current but
|
** with the given key exists, create one and make it current but
|
||||||
** do not jump.
|
** do not jump.
|
||||||
**
|
**
|
||||||
** This opcode should not be executed after an AggNext but before
|
** The order of aggregator opcodes is important. The order is:
|
||||||
** the next AggReset.
|
** 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: {
|
case OP_AggFocus: {
|
||||||
int tos = p->tos;
|
int tos = p->tos;
|
||||||
@@ -2852,7 +2859,7 @@ int sqliteVdbeExec(
|
|||||||
/* Opcode: AggGet * P2 *
|
/* Opcode: AggGet * P2 *
|
||||||
**
|
**
|
||||||
** Push a new entry onto the stack which is a copy of the P2-th field
|
** 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
|
** of the current aggregate. Strings are not duplicated so
|
||||||
** string values will be ephemeral.
|
** string values will be ephemeral.
|
||||||
*/
|
*/
|
||||||
case OP_AggGet: {
|
case OP_AggGet: {
|
||||||
@@ -2876,8 +2883,11 @@ int sqliteVdbeExec(
|
|||||||
** aggregate is deleted. If all aggregate values have been consumed,
|
** aggregate is deleted. If all aggregate values have been consumed,
|
||||||
** jump to P2.
|
** jump to P2.
|
||||||
**
|
**
|
||||||
** Do not execute an AggFocus after this opcode until after the
|
** The order of aggregator opcodes is important. The order is:
|
||||||
** next AggReset.
|
** 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: {
|
case OP_AggNext: {
|
||||||
if( p->agg.nHash ){
|
if( p->agg.nHash ){
|
||||||
@@ -2905,7 +2915,7 @@ int sqliteVdbeExec(
|
|||||||
|
|
||||||
/* Opcode: SetClear P1 * *
|
/* Opcode: SetClear P1 * *
|
||||||
**
|
**
|
||||||
** Remove all elements from the given Set.
|
** Remove all elements from the P1-th Set.
|
||||||
*/
|
*/
|
||||||
case OP_SetClear: {
|
case OP_SetClear: {
|
||||||
int i = pOp->p1;
|
int i = pOp->p1;
|
||||||
@@ -2917,7 +2927,7 @@ int sqliteVdbeExec(
|
|||||||
|
|
||||||
/* Opcode: SetInsert P1 * P3
|
/* 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
|
** P3 into that set. If P3 is NULL, then insert the top of the
|
||||||
** stack into the set.
|
** 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.
|
# 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>
|
puts {<html>
|
||||||
<head>
|
<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
|
by SQLite. Many low-level productions are omitted. For detailed information
|
||||||
on the language that SQLite understands, refer to the source code.</p>
|
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} {
|
proc Syntax {args} {
|
||||||
@@ -53,6 +73,20 @@ proc Syntax {args} {
|
|||||||
puts {</table>}
|
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} {
|
Syntax {sql-command} {
|
||||||
CREATE TABLE <table-name> (
|
CREATE TABLE <table-name> (
|
||||||
<column-def> [, <column-def>]*
|
<column-def> [, <column-def>]*
|
||||||
@@ -68,7 +102,8 @@ CREATE TABLE <table-name> (
|
|||||||
NOT NULL |
|
NOT NULL |
|
||||||
PRIMARY KEY [<sort-order>] |
|
PRIMARY KEY [<sort-order>] |
|
||||||
UNIQUE |
|
UNIQUE |
|
||||||
CHECK ( <expr> )
|
CHECK ( <expr> ) |
|
||||||
|
DEFAULT <value>
|
||||||
} {constraint} {
|
} {constraint} {
|
||||||
PRIMARY KEY ( <name> [, <name>]* ) |
|
PRIMARY KEY ( <name> [, <name>]* ) |
|
||||||
UNIQUE ( <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
|
The datatype for the column is ignored. All information
|
||||||
is stored as null-terminated strings. The constraints are also ignored,
|
is stored as null-terminated strings. The constraints are also ignored,
|
||||||
except that the PRIMARY KEY constraint will cause an index to be automatically
|
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
|
key index will be the table name
|
||||||
with "<b>__primary_key</b>" appended. The index used for a primary key
|
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
|
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>
|
SQLite's internal representation of the table layout.</p>
|
||||||
}
|
}
|
||||||
|
|
||||||
puts {<h2>CREATE INDEX</h2>
|
Section {CREATE INDEX} createindex
|
||||||
}
|
|
||||||
|
|
||||||
Syntax {sql-statement} {
|
Syntax {sql-statement} {
|
||||||
CREATE INDEX <index-name>
|
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
|
table. Everytime the database is opened, all CREATE INDEX statements
|
||||||
are read from the <b>sqlite_master</b> table and used to regenerate
|
are read from the <b>sqlite_master</b> table and used to regenerate
|
||||||
SQLite's internal representation of the index layout.</p>
|
SQLite's internal representation of the index layout.</p>
|
||||||
|
|
||||||
<h2>DROP TABLE</h2>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Section {DROP TABLE} droptable
|
||||||
|
|
||||||
Syntax {sql-command} {
|
Syntax {sql-command} {
|
||||||
DROP TABLE <table-name>
|
DROP TABLE <table-name>
|
||||||
}
|
}
|
||||||
@@ -142,10 +179,9 @@ puts {
|
|||||||
<p>The DROP TABLE statement consists of the keywords "DROP TABLE" followed
|
<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
|
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 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} {
|
Syntax {sql-command} {
|
||||||
DROP INDEX <index-name>
|
DROP INDEX <index-name>
|
||||||
@@ -156,10 +192,10 @@ puts {
|
|||||||
by the name of the index. The index named is completely removed from
|
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
|
the disk. The only way to recover the index is to reenter the
|
||||||
appropriate CREATE INDEX command.</p>
|
appropriate CREATE INDEX command.</p>
|
||||||
|
|
||||||
<h2>VACUUM</h2>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Section VACUUM vacuum
|
||||||
|
|
||||||
Syntax {sql-statement} {
|
Syntax {sql-statement} {
|
||||||
VACUUM [<index-or-table-name>]
|
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
|
entries in the data table. Reorganizing these indices will make
|
||||||
the underlying GDBM file much smaller and will help queries to
|
the underlying GDBM file much smaller and will help queries to
|
||||||
run much faster.</p>
|
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 {
|
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>}
|
Reference in New Issue
Block a user