├── Makefile.in
├── Makefile.template
├── README
├── VERSION
├── aclocal.m4
├── config.guess
├── config.sub
├── configure
├── configure.ac
├── doc
├── lemon.html
└── report1.txt
├── install-sh
├── libtool
├── ltmain.sh
├── manifest
├── manifest.uuid
├── publish.sh
├── spec.template
├── sqlite.1
├── src
├── TODO
├── btree.c
├── btree.h
├── build.c
├── delete.c
├── encode.c
├── expr.c
├── func.c
├── hash.c
├── hash.h
├── insert.c
├── main.c
├── md5.c
├── os.c
├── os.h
├── pager.c
├── pager.h
├── parse.y
├── printf.c
├── random.c
├── select.c
├── shell.c
├── shell.tcl
├── sqlite.h.in
├── sqliteInt.h
├── table.c
├── tclsqlite.c
├── test1.c
├── test2.c
├── test3.c
├── threadtest.c
├── tokenize.c
├── trigger.c
├── update.c
├── util.c
├── vdbe.c
├── vdbe.h
└── where.c
├── test
├── all.test
├── bigrow.test
├── btree.test
├── btree2.test
├── btree3.test
├── conflict.test
├── copy.test
├── delete.test
├── expr.test
├── func.test
├── in.test
├── index.test
├── insert.test
├── insert2.test
├── intpkey.test
├── ioerr.test
├── join.test
├── limit.test
├── lock.test
├── main.test
├── malloc.test
├── minmax.test
├── misc1.test
├── misuse.test
├── notnull.test
├── null.test
├── pager.test
├── pragma.test
├── printf.test
├── quick.test
├── quote.test
├── rowid.test
├── select1.test
├── select2.test
├── select3.test
├── select4.test
├── select5.test
├── select6.test
├── sort.test
├── subselect.test
├── table.test
├── tableapi.test
├── tclsqlite.test
├── temptable.test
├── tester.tcl
├── trans.test
├── trigger1.test
├── trigger2.test
├── trigger3.test
├── unique.test
├── update.test
├── vacuum.test
├── view.test
└── where.test
├── tool
├── lemon.c
├── lempar.c
├── memleak.awk
├── opNames.awk
├── opcodeDoc.awk
├── renumberOps.awk
├── report1.txt
├── speedtest.tcl
└── speedtest2.tcl
└── www
├── arch.fig
├── arch.png
├── arch.tcl
├── c_interface.tcl
├── changes.tcl
├── conflict.tcl
├── crosscompile.tcl
├── download.tcl
├── dynload.tcl
├── faq.tcl
├── formatchng.tcl
├── index.tcl
├── lang.tcl
├── mingw.tcl
├── opcode.tcl
├── speed.tcl
├── sqlite.tcl
├── tclsqlite.tcl
└── vdbe.tcl
/README:
--------------------------------------------------------------------------------
1 | This project is forked from 2.5.0 SQLite, and fixed for modern C compilers like GCC.
2 |
3 | Earlier SQLite is perfect source for code reading, and for database design and implementation.
4 | For SQLite 2.5.0, it has a core code base less than 20000 LOC in ANSI C which is easy to understand.
5 |
6 | I digged into historical versions of SQLite, and fixed this version against GCC on MacOS 10.13 and Debian 8.
7 |
8 | $sloccount SQLite-2.5.0-for-code-reading
9 | SLOC Directory SLOC-by-Language (Sorted)
10 | 20914 src_top_dir ansic=19895,yacc=584,tcl=435
11 | 6831 top_dir sh=6831
12 | 6363 www tcl=6363
13 | 4051 tool ansic=3606,tcl=372,awk=73
14 | 156 test tcl=156
15 | 0 doc (none)
16 |
17 |
18 | SQLite: An SQL Database Engine in a C Library
19 |
20 | To compile the project, first create a directory in which to place
21 | the build products. It is recommended, but not required, that the
22 | build directory be separate from the source directory. Cd into the
23 | build directory and then from the build directory run the configure
24 | script found at the root of the source tree. Then run "make".
25 |
26 | For example:
27 |
28 | tar xzf sqlite.tar.gz ;# Unpack the source tree into "sqlite"
29 | mkdir bld ;# Build will occur in a sibling directory
30 | cd bld ;# Change to the build directory
31 | ../sqlite/configure ;# Run the configure script
32 | make ;# Run the makefile.
33 |
34 | The configure script uses autoconf 2.50 and libtool. If the configure
35 | script does not work out for you, there is a generic makefile named
36 | "Makefile.template" in the top directory of the source tree that you
37 | can copy and edit to suite your needs. Comments on the generic makefile
38 | show what changes are needed.
39 |
40 | The windows binaries on the website are created using MinGW32 configured
41 | as a cross-compiler running under Linux. For details, see the ./publish.sh
42 | script at the top-level of the source tree.
43 |
44 | Contacts:
45 |
46 | http://www.hwaci.com/sw/sqlite/
47 | http://groups.yahoo.com/group/sqlite/
48 | drh@hwaci.com
49 |
--------------------------------------------------------------------------------
/VERSION:
--------------------------------------------------------------------------------
1 | 2.5.0
2 |
--------------------------------------------------------------------------------
/doc/report1.txt:
--------------------------------------------------------------------------------
1 | An SQLite (version 1.0) database was used in a large military application
2 | where the database contained 105 tables and indices. The following is
3 | a breakdown on the sizes of keys and data within these tables and indices:
4 |
5 | Entries: 967089
6 | Size: 45896104
7 | Avg Size: 48
8 | Key Size: 11112265
9 | Avg Key Size: 12
10 | Max Key Size: 99
11 |
12 | 0..8 263 0%
13 | 9..12 5560 0%
14 | 13..16 71394 7%
15 | 17..24 180717 26%
16 | 25..32 215442 48%
17 | 33..40 151118 64%
18 | 41..48 77479 72%
19 | 49..56 13983 74%
20 | 57..64 14481 75%
21 | 65..80 41342 79%
22 | 81..96 127098 92%
23 | 97..112 38054 96%
24 | 113..128 14197 98%
25 | 129..144 8208 99%
26 | 145..160 3326 99%
27 | 161..176 1242 99%
28 | 177..192 604 99%
29 | 193..208 222 99%
30 | 209..224 213 99%
31 | 225..240 132 99%
32 | 241..256 58 99%
33 | 257..288 515 99%
34 | 289..320 64 99%
35 | 321..352 39 99%
36 | 353..384 44 99%
37 | 385..416 25 99%
38 | 417..448 24 99%
39 | 449..480 26 99%
40 | 481..512 27 99%
41 | 513..1024 470 99%
42 | 1025..2048 396 99%
43 | 2049..4096 187 99%
44 | 4097..8192 78 99%
45 | 8193..16384 35 99%
46 | 16385..32768 17 99%
47 | 32769..65536 6 99%
48 | 65537..65541 3 100%
49 |
50 | If the indices are omitted, the statistics for the 49 tables
51 | become the following:
52 |
53 | Entries: 451103
54 | Size: 30930282
55 | Avg Size: 69
56 | Key Size: 1804412
57 | Avg Key Size: 4
58 | Max Key Size: 4
59 |
60 | 0..24 89 0%
61 | 25..32 9417 2%
62 | 33..40 119162 28%
63 | 41..48 68710 43%
64 | 49..56 9539 45%
65 | 57..64 12435 48%
66 | 65..80 38650 57%
67 | 81..96 126877 85%
68 | 97..112 38030 93%
69 | 113..128 14183 96%
70 | 129..144 7668 98%
71 | 145..160 3302 99%
72 | 161..176 1238 99%
73 | 177..192 597 99%
74 | 193..208 217 99%
75 | 209..224 211 99%
76 | 225..240 130 99%
77 | 241..256 57 99%
78 | 257..288 100 99%
79 | 289..320 62 99%
80 | 321..352 34 99%
81 | 353..384 43 99%
82 | 385..416 24 99%
83 | 417..448 24 99%
84 | 449..480 25 99%
85 | 481..512 27 99%
86 | 513..1024 153 99%
87 | 1025..2048 92 99%
88 | 2049..4096 7 100%
89 |
90 | The 56 indices have these statistics:
91 |
92 | Entries: 512422
93 | Size: 14879828
94 | Avg Size: 30
95 | Key Size: 9253204
96 | Avg Key Size: 19
97 | Max Key Size: 99
98 |
99 | 0..8 246 0%
100 | 9..12 5486 1%
101 | 13..16 70717 14%
102 | 17..24 178246 49%
103 | 25..32 205722 89%
104 | 33..40 31951 96%
105 | 41..48 8768 97%
106 | 49..56 4444 98%
107 | 57..64 2046 99%
108 | 65..80 2691 99%
109 | 81..96 202 99%
110 | 97..112 11 99%
111 | 113..144 527 99%
112 | 145..160 20 99%
113 | 161..288 406 99%
114 | 289..1024 316 99%
115 | 1025..2048 304 99%
116 | 2049..4096 180 99%
117 | 4097..8192 78 99%
118 | 8193..16384 35 99%
119 | 16385..32768 17 99%
120 | 32769..65536 6 99%
121 | 65537..65541 3 100%
122 |
--------------------------------------------------------------------------------
/install-sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # install - install a program, script, or datafile
4 | # This comes from X11R5 (mit/util/scripts/install.sh).
5 | #
6 | # Copyright 1991 by the Massachusetts Institute of Technology
7 | #
8 | # Permission to use, copy, modify, distribute, and sell this software and its
9 | # documentation for any purpose is hereby granted without fee, provided that
10 | # the above copyright notice appear in all copies and that both that
11 | # copyright notice and this permission notice appear in supporting
12 | # documentation, and that the name of M.I.T. not be used in advertising or
13 | # publicity pertaining to distribution of the software without specific,
14 | # written prior permission. M.I.T. makes no representations about the
15 | # suitability of this software for any purpose. It is provided "as is"
16 | # without express or implied warranty.
17 | #
18 | # Calling this script install-sh is preferred over install.sh, to prevent
19 | # `make' implicit rules from creating a file called install from it
20 | # when there is no Makefile.
21 | #
22 | # This script is compatible with the BSD install script, but was written
23 | # from scratch. It can only install one file at a time, a restriction
24 | # shared with many OS's install programs.
25 |
26 |
27 | # set DOITPROG to echo to test this script
28 |
29 | # Don't use :- since 4.3BSD and earlier shells don't like it.
30 | doit="${DOITPROG-}"
31 |
32 |
33 | # put in absolute paths if you don't have them in your path; or use env. vars.
34 |
35 | mvprog="${MVPROG-mv}"
36 | cpprog="${CPPROG-cp}"
37 | chmodprog="${CHMODPROG-chmod}"
38 | chownprog="${CHOWNPROG-chown}"
39 | chgrpprog="${CHGRPPROG-chgrp}"
40 | stripprog="${STRIPPROG-strip}"
41 | rmprog="${RMPROG-rm}"
42 | mkdirprog="${MKDIRPROG-mkdir}"
43 |
44 | transformbasename=""
45 | transform_arg=""
46 | instcmd="$mvprog"
47 | chmodcmd="$chmodprog 0755"
48 | chowncmd=""
49 | chgrpcmd=""
50 | stripcmd=""
51 | rmcmd="$rmprog -f"
52 | mvcmd="$mvprog"
53 | src=""
54 | dst=""
55 | dir_arg=""
56 |
57 | while [ x"$1" != x ]; do
58 | case $1 in
59 | -c) instcmd="$cpprog"
60 | shift
61 | continue;;
62 |
63 | -d) dir_arg=true
64 | shift
65 | continue;;
66 |
67 | -m) chmodcmd="$chmodprog $2"
68 | shift
69 | shift
70 | continue;;
71 |
72 | -o) chowncmd="$chownprog $2"
73 | shift
74 | shift
75 | continue;;
76 |
77 | -g) chgrpcmd="$chgrpprog $2"
78 | shift
79 | shift
80 | continue;;
81 |
82 | -s) stripcmd="$stripprog"
83 | shift
84 | continue;;
85 |
86 | -t=*) transformarg=`echo $1 | sed 's/-t=//'`
87 | shift
88 | continue;;
89 |
90 | -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
91 | shift
92 | continue;;
93 |
94 | *) if [ x"$src" = x ]
95 | then
96 | src=$1
97 | else
98 | # this colon is to work around a 386BSD /bin/sh bug
99 | :
100 | dst=$1
101 | fi
102 | shift
103 | continue;;
104 | esac
105 | done
106 |
107 | if [ x"$src" = x ]
108 | then
109 | echo "install: no input file specified"
110 | exit 1
111 | else
112 | true
113 | fi
114 |
115 | if [ x"$dir_arg" != x ]; then
116 | dst=$src
117 | src=""
118 |
119 | if [ -d $dst ]; then
120 | instcmd=:
121 | chmodcmd=""
122 | else
123 | instcmd=mkdir
124 | fi
125 | else
126 |
127 | # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
128 | # might cause directories to be created, which would be especially bad
129 | # if $src (and thus $dsttmp) contains '*'.
130 |
131 | if [ -f $src -o -d $src ]
132 | then
133 | true
134 | else
135 | echo "install: $src does not exist"
136 | exit 1
137 | fi
138 |
139 | if [ x"$dst" = x ]
140 | then
141 | echo "install: no destination specified"
142 | exit 1
143 | else
144 | true
145 | fi
146 |
147 | # If destination is a directory, append the input filename; if your system
148 | # does not like double slashes in filenames, you may need to add some logic
149 |
150 | if [ -d $dst ]
151 | then
152 | dst="$dst"/`basename $src`
153 | else
154 | true
155 | fi
156 | fi
157 |
158 | ## this sed command emulates the dirname command
159 | dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
160 |
161 | # Make sure that the destination directory exists.
162 | # this part is taken from Noah Friedman's mkinstalldirs script
163 |
164 | # Skip lots of stat calls in the usual case.
165 | if [ ! -d "$dstdir" ]; then
166 | defaultIFS='
167 | '
168 | IFS="${IFS-${defaultIFS}}"
169 |
170 | oIFS="${IFS}"
171 | # Some sh's can't handle IFS=/ for some reason.
172 | IFS='%'
173 | set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
174 | IFS="${oIFS}"
175 |
176 | pathcomp=''
177 |
178 | while [ $# -ne 0 ] ; do
179 | pathcomp="${pathcomp}${1}"
180 | shift
181 |
182 | if [ ! -d "${pathcomp}" ] ;
183 | then
184 | $mkdirprog "${pathcomp}"
185 | else
186 | true
187 | fi
188 |
189 | pathcomp="${pathcomp}/"
190 | done
191 | fi
192 |
193 | if [ x"$dir_arg" != x ]
194 | then
195 | $doit $instcmd $dst &&
196 |
197 | if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
198 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
199 | if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
200 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
201 | else
202 |
203 | # If we're going to rename the final executable, determine the name now.
204 |
205 | if [ x"$transformarg" = x ]
206 | then
207 | dstfile=`basename $dst`
208 | else
209 | dstfile=`basename $dst $transformbasename |
210 | sed $transformarg`$transformbasename
211 | fi
212 |
213 | # don't allow the sed command to completely eliminate the filename
214 |
215 | if [ x"$dstfile" = x ]
216 | then
217 | dstfile=`basename $dst`
218 | else
219 | true
220 | fi
221 |
222 | # Make a temp file name in the proper directory.
223 |
224 | dsttmp=$dstdir/#inst.$$#
225 |
226 | # Move or copy the file name to the temp name
227 |
228 | $doit $instcmd $src $dsttmp &&
229 |
230 | trap "rm -f ${dsttmp}" 0 &&
231 |
232 | # and set any options; do chmod last to preserve setuid bits
233 |
234 | # If any of these fail, we abort the whole thing. If we want to
235 | # ignore errors from any of these, just make sure not to ignore
236 | # errors from the above "$doit $instcmd $src $dsttmp" command.
237 |
238 | if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
239 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
240 | if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
241 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
242 |
243 | # Now rename the file to the real destination.
244 |
245 | $doit $rmcmd -f $dstdir/$dstfile &&
246 | $doit $mvcmd $dsttmp $dstdir/$dstfile
247 |
248 | fi &&
249 |
250 |
251 | exit 0
252 |
--------------------------------------------------------------------------------
/manifest.uuid:
--------------------------------------------------------------------------------
1 | 9baef3e240c4ffd90881ac4664efd205bd9e65f4
2 |
--------------------------------------------------------------------------------
/publish.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # This script is used to compile SQLite and all its documentation and
4 | # ship everything up to the SQLite website. This script will only work
5 | # on the system "zadok" at the Hwaci offices. But others might find
6 | # the script useful as an example.
7 | #
8 |
9 | # Set srcdir to the name of the directory that contains the publish.sh
10 | # script.
11 | #
12 | srcdir=`echo "$0" | sed 's%\(^.*\)/[^/][^/]*$%\1%'`
13 |
14 | # Get the makefile.
15 | #
16 | cp $srcdir/Makefile.template ./Makefile
17 |
18 | # Start building stuff.
19 | #
20 | make clean
21 | make sqlite
22 | strip sqlite
23 | mv sqlite sqlite.bin
24 | rm -f sqlite.bin.gz
25 | gzip sqlite.bin
26 |
27 | # Build the tclsqlite.so shared library for import into tclsh or wish
28 | # under Linux
29 | #
30 | make target_source
31 | rm sqlite_source.zip
32 | cd tsrc
33 | zip ../sqlite_source.zip *
34 | rm shell.c
35 | TCLDIR=/home/drh/tcltk/8.2linux
36 | TCLSTUBLIB=$TCLDIR/libtclstub8.2g.a
37 | OPTS='-DUSE_TCL_STUBS=1 -DNDEBUG=1'
38 | gcc -fPIC $OPTS -O2 -I. -I$TCLDIR -shared *.c $TCLSTUBLIB -o tclsqlite.so
39 | strip tclsqlite.so
40 | mv tclsqlite.so ..
41 | rm tclsqlite.c
42 | gcc -fPIC -DNDEBUG=1 -O2 -I. -shared *.c -o sqlite.so
43 | strip sqlite.so
44 | mv sqlite.so ..
45 | cd ..
46 | rm -f tclsqlite.so.gz sqlite.so.gz
47 | gzip tclsqlite.so
48 | gzip sqlite.so
49 |
50 | # Build the tclsqlite.dll shared library that can be imported into tclsh
51 | # or wish on windows.
52 | #
53 | make target_source
54 | cd tsrc
55 | rm shell.c
56 | TCLDIR=/home/drh/tcltk/8.2win
57 | TCLSTUBLIB=$TCLDIR/tclstub82.a
58 | PATH=$PATH:/opt/mingw/bin
59 | OPTS='-DUSE_TCL_STUBS=1 -DNDEBUG=1 -DTHREADSAFE=1'
60 | CC="i386-mingw32-gcc -O2 $OPTS -I. -I$TCLDIR"
61 | rm shell.c
62 | for i in *.c; do
63 | CMD="$CC -c $i"
64 | echo $CMD
65 | $CMD
66 | done
67 | echo 'EXPORTS' >tclsqlite.def
68 | echo 'Tclsqlite_Init' >>tclsqlite.def
69 | echo 'Sqlite_Init' >>tclsqlite.def
70 | i386-mingw32-dllwrap \
71 | --def tclsqlite.def -v --export-all \
72 | --driver-name i386-mingw32-gcc \
73 | --dlltool-name i386-mingw32-dlltool \
74 | --as i386-mingw32-as \
75 | --target i386-mingw32 \
76 | -dllname tclsqlite.dll -lmsvcrt *.o $TCLSTUBLIB
77 | i386-mingw32-strip tclsqlite.dll
78 | mv tclsqlite.dll ..
79 | rm tclsqlite.o
80 | cat >sqlite.def <<\END_OF_FILE
81 | EXPORTS
82 | sqlite_open
83 | sqlite_close
84 | sqlite_exec
85 | sqlite_last_insert_rowid
86 | sqlite_error_string
87 | sqlite_interrupt
88 | sqlite_complete
89 | sqlite_busy_handler
90 | sqlite_busy_timeout
91 | sqlite_get_table
92 | sqlite_free_table
93 | sqlite_mprintf
94 | sqlite_vmprintf
95 | sqlite_exec_printf
96 | sqlite_exec_vprintf
97 | sqlite_get_table_printf
98 | sqlite_get_table_vprintf
99 | sqlite_freemem
100 | sqlite_libversion
101 | sqlite_libencoding
102 | sqlite_changes
103 | sqliteMalloc
104 | sqliteFree
105 | sqliteRealloc
106 | END_OF_FILE
107 | i386-mingw32-dllwrap \
108 | --def sqlite.def -v --export-all \
109 | --driver-name i386-mingw32-gcc \
110 | --dlltool-name i386-mingw32-dlltool \
111 | --as i386-mingw32-as \
112 | --target i386-mingw32 \
113 | -dllname sqlite.dll -lmsvcrt *.o
114 | i386-mingw32-strip sqlite.dll
115 | mv sqlite.dll sqlite.def ..
116 | cd ..
117 | rm -f tclsqlite.zip sqlitedll.zip
118 | zip tclsqlite.zip tclsqlite.dll
119 | zip sqlitedll.zip sqlite.dll sqlite.def
120 |
121 | # Build the sqlite.exe executable for windows.
122 | #
123 | make target_source
124 | cd tsrc
125 | rm tclsqlite.c
126 | OPTS='-DSTATIC_BUILD=1 -DNDEBUG=1'
127 | i386-mingw32-gcc -O2 $OPTS -I. -I$TCLDIR *.c -o sqlite.exe
128 | mv sqlite.exe ..
129 | cd ..
130 | rm -f sqlite.zip
131 | zip sqlite.zip sqlite.exe
132 |
133 | # Construct a tarball of the source tree
134 | #
135 | ORIGIN=`pwd`
136 | cd $srcdir
137 | cd ..
138 | EXCLUDE=`find sqlite -print | grep CVS | sed 's,sqlite/, --exclude sqlite/,'`
139 | tar czf $ORIGIN/sqlite.tar.gz $EXCLUDE sqlite
140 | cd $ORIGIN
141 | vers=`cat $srcdir/VERSION`
142 | rm -f sqlite-$vers.tar.gz
143 | ln sqlite.tar.gz sqlite-$vers.tar.gz
144 |
145 | #
146 | # Build RPMS (binary) and Source RPM
147 | #
148 |
149 | # Make sure we are properly setup to build RPMs
150 | #
151 | echo "%HOME %{expand:%%(cd; pwd)}" > $HOME/.rpmmacros
152 | echo "%_topdir %{HOME}/rpm" >> $HOME/.rpmmacros
153 | mkdir $HOME/rpm
154 | mkdir $HOME/rpm/BUILD
155 | mkdir $HOME/rpm/SOURCES
156 | mkdir $HOME/rpm/RPMS
157 | mkdir $HOME/rpm/SRPMS
158 | mkdir $HOME/rpm/SPECS
159 |
160 | # create the spec file from the template
161 | sed s/SQLITE_VERSION/$vers/g $srcdir/spec.template > $HOME/rpm/SPECS/sqlite.spec
162 |
163 | # copy the source tarball to the rpm directory
164 | cp sqlite-$vers.tar.gz $HOME/rpm/SOURCES/.
165 |
166 | # build all the rpms
167 | rpm -ba $HOME/rpm/SPECS/sqlite.spec >& rpm-$vers.log
168 |
169 | # copy the RPMs into the build directory.
170 | ln $HOME/rpm/RPMS/i386/sqlite*-$vers*.rpm .
171 | ln $HOME/rpm/SRPMS/sqlite-$vers*.rpm .
172 |
173 |
174 | # Build the website
175 | #
176 | cp $srcdir/../historical/* .
177 | rm -rf doc
178 | make doc
179 | ln sqlite.bin.gz sqlite.zip sqlite*.tar.gz tclsqlite.so.gz tclsqlite.zip doc
180 | ln sqlitedll.zip sqlite.so.gz sqlite_source.zip doc
181 | ln *.rpm doc
182 |
--------------------------------------------------------------------------------
/spec.template:
--------------------------------------------------------------------------------
1 | %define name sqlite
2 | %define version SQLITE_VERSION
3 | %define release 1
4 |
5 | Name: %{name}
6 | Summary: SQLite is a C library that implements an embeddable SQL database engine
7 | Version: %{version}
8 | Release: %{release}
9 | Source: %{name}-%{version}.tar.gz
10 | Group: System/Libraries
11 | URL: http://www.hwaci.com/sw/sqlite/
12 | License: Public Domain
13 | BuildRoot: %{_tmppath}/%{name}-%{version}-root
14 |
15 | %description
16 | SQLite is a C library that implements an embeddable SQL database engine.
17 | Programs that link with the SQLite library can have SQL database access
18 | without running a separate RDBMS process. The distribution comes with a
19 | standalone command-line access program (sqlite) that can be used to
20 | administer an SQLite database and which serves as an example of how to
21 | use the SQLite library.
22 |
23 | %package -n %{name}-devel
24 | Summary: Header files and libraries for developing apps which will use sqlite
25 | Group: Development/C
26 | Requires: %{name} = %{version}-%{release}
27 |
28 | %description -n %{name}-devel
29 | The sqlite-devel package contains the header files and libraries needed
30 | to develop programs that use the sqlite database library.
31 |
32 | %prep
33 | %setup -q -n %{name}
34 |
35 | %build
36 | CFLAGS="%optflags -DNDEBUG=1" CXXFLAGS="%optflags -DNDEBUG=1" ./configure --prefix=%{_prefix}
37 |
38 | make
39 | make doc
40 |
41 | %install
42 | install -d $RPM_BUILD_ROOT/%{_prefix}
43 | install -d $RPM_BUILD_ROOT/%{_prefix}/bin
44 | install -d $RPM_BUILD_ROOT/%{_prefix}/include
45 | install -d $RPM_BUILD_ROOT/%{_prefix}/lib
46 | make install prefix=$RPM_BUILD_ROOT/%{_prefix}
47 |
48 | %clean
49 | rm -fr $RPM_BUILD_ROOT
50 |
51 | %files
52 | %defattr(-, root, root)
53 | %{_libdir}/*.so*
54 | %{_bindir}/*
55 |
56 | %files -n %{name}-devel
57 | %defattr(-, root, root)
58 | %{_libdir}/*.a
59 | %{_libdir}/*.la
60 | %{_includedir}/*
61 | %doc doc/*
62 |
--------------------------------------------------------------------------------
/src/TODO:
--------------------------------------------------------------------------------
1 | * Document all the changes and release Sqlite 2.0.
2 | * Implement CLUSTER command like in PostgreSQL.
3 | * "OPTIMIZE select" statement to automatically create indices and/or
4 | invoke a CLUSTER command.
5 | * "CREATE INDEX FOR select" to automatically generate needed indices.
6 | * Parse and use constraints.
7 |
--------------------------------------------------------------------------------
/src/btree.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** 2001 September 15
3 | **
4 | ** The author disclaims copyright to this source code. In place of
5 | ** a legal notice, here is a blessing:
6 | **
7 | ** May you do good and not evil.
8 | ** May you find forgiveness for yourself and forgive others.
9 | ** May you share freely, never taking more than you give.
10 | **
11 | *************************************************************************
12 | ** This header file defines the interface that the sqlite B-Tree file
13 | ** subsystem. See comments in the source code for a detailed description
14 | ** of what each interface routine does.
15 | **
16 | ** @(#) $Id: btree.h,v 1.24 2002/02/19 15:00:08 drh Exp $
17 | */
18 | #ifndef _BTREE_H_
19 | #define _BTREE_H_
20 |
21 | typedef struct Btree Btree;
22 | typedef struct BtCursor BtCursor;
23 |
24 | int sqliteBtreeOpen(const char *zFilename, int mode, int nPg, Btree **ppBtree);
25 | int sqliteBtreeClose(Btree*);
26 | int sqliteBtreeSetCacheSize(Btree*, int);
27 |
28 | int sqliteBtreeBeginTrans(Btree*);
29 | int sqliteBtreeCommit(Btree*);
30 | int sqliteBtreeRollback(Btree*);
31 | int sqliteBtreeBeginCkpt(Btree*);
32 | int sqliteBtreeCommitCkpt(Btree*);
33 | int sqliteBtreeRollbackCkpt(Btree*);
34 |
35 | int sqliteBtreeCreateTable(Btree*, int*);
36 | int sqliteBtreeCreateIndex(Btree*, int*);
37 | int sqliteBtreeDropTable(Btree*, int);
38 | int sqliteBtreeClearTable(Btree*, int);
39 |
40 | int sqliteBtreeCursor(Btree*, int iTable, int wrFlag, BtCursor **ppCur);
41 | int sqliteBtreeMoveto(BtCursor*, const void *pKey, int nKey, int *pRes);
42 | int sqliteBtreeDelete(BtCursor*);
43 | int sqliteBtreeInsert(BtCursor*, const void *pKey, int nKey,
44 | const void *pData, int nData);
45 | int sqliteBtreeFirst(BtCursor*, int *pRes);
46 | int sqliteBtreeLast(BtCursor*, int *pRes);
47 | int sqliteBtreeNext(BtCursor*, int *pRes);
48 | int sqliteBtreeKeySize(BtCursor*, int *pSize);
49 | int sqliteBtreeKey(BtCursor*, int offset, int amt, char *zBuf);
50 | int sqliteBtreeKeyCompare(BtCursor*, const void *pKey, int nKey,
51 | int nIgnore, int *pRes);
52 | int sqliteBtreeDataSize(BtCursor*, int *pSize);
53 | int sqliteBtreeData(BtCursor*, int offset, int amt, char *zBuf);
54 | int sqliteBtreeCloseCursor(BtCursor*);
55 |
56 | #define SQLITE_N_BTREE_META 4
57 | int sqliteBtreeGetMeta(Btree*, int*);
58 | int sqliteBtreeUpdateMeta(Btree*, int*);
59 |
60 | char *sqliteBtreeIntegrityCheck(Btree*, int*, int);
61 |
62 | #ifdef SQLITE_TEST
63 | int sqliteBtreePageDump(Btree*, int, int);
64 | int sqliteBtreeCursorDump(BtCursor*, int*);
65 | struct Pager *sqliteBtreePager(Btree*);
66 | #endif
67 |
68 | #endif /* _BTREE_H_ */
69 |
--------------------------------------------------------------------------------
/src/encode.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** 2002 April 25
3 | **
4 | ** The author disclaims copyright to this source code. In place of
5 | ** a legal notice, here is a blessing:
6 | **
7 | ** May you do good and not evil.
8 | ** May you find forgiveness for yourself and forgive others.
9 | ** May you share freely, never taking more than you give.
10 | **
11 | *************************************************************************
12 | ** This file contains helper routines used to translate binary data into
13 | ** a null-terminated string (suitable for use in SQLite) and back again.
14 | ** These are convenience routines for use by people who want to store binary
15 | ** data in an SQLite database. The code in this file is used by any other
16 | ** part of the SQLite library.
17 | **
18 | ** $Id: encode.c,v 1.2 2002/04/25 23:06:47 drh Exp $
19 | */
20 |
21 | /*
22 | ** Encode a binary buffer "in" of size n bytes so that it contains
23 | ** no instances of characters '\'' or '\000'. The output is
24 | ** null-terminated and can be used as a string value in an INSERT
25 | ** or UPDATE statement. Use sqlite_decode_binary() to convert the
26 | ** string back into its original binary.
27 | **
28 | ** The result is written into a preallocated output buffer "out".
29 | ** "out" must be able to hold at least (256*n + 1262)/253 bytes.
30 | ** In other words, the output will be expanded by as much as 3
31 | ** bytes for every 253 bytes of input plus 2 bytes of fixed overhead.
32 | ** (This is approximately 2 + 1.019*n or about a 2% size increase.)
33 | */
34 | void sqlite_encode_binary(const unsigned char *in, int n, unsigned char *out){
35 | int i, j, e, m;
36 | int cnt[256];
37 | memset(cnt, 0, sizeof(cnt));
38 | for(i=n-1; i>=0; i--){ cnt[in[i]]++; }
39 | m = n;
40 | for(i=1; i<256; i++){
41 | int sum;
42 | if( i=='\'' ) continue;
43 | sum = cnt[i] + cnt[(i+1)&0xff] + cnt[(i+'\'')&0xff];
44 | if( sum%d (max %d)", n, strlen(out)+1, m);
129 | if( strlen(out)+1>m ){
130 | printf(" ERROR output too big\n");
131 | exit(1);
132 | }
133 | for(j=0; out[j]; j++){
134 | if( out[j]=='\'' ){
135 | printf(" ERROR contains (')\n");
136 | exit(1);
137 | }
138 | }
139 | j = sqlite_decode_binary(out, out);
140 | if( j!=n ){
141 | printf(" ERROR decode size %d\n", j);
142 | exit(1);
143 | }
144 | if( memcmp(in, out, n)!=0 ){
145 | printf(" ERROR decode mismatch\n");
146 | exit(1);
147 | }
148 | printf(" OK\n");
149 | }
150 | }
151 | #endif /* ENCODER_TEST */
152 |
--------------------------------------------------------------------------------
/src/hash.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** 2001 September 22
3 | **
4 | ** The author disclaims copyright to this source code. In place of
5 | ** a legal notice, here is a blessing:
6 | **
7 | ** May you do good and not evil.
8 | ** May you find forgiveness for yourself and forgive others.
9 | ** May you share freely, never taking more than you give.
10 | **
11 | *************************************************************************
12 | ** This is the header file for the generic hash-table implemenation
13 | ** used in SQLite.
14 | **
15 | ** $Id: hash.h,v 1.5 2002/06/08 23:25:09 drh Exp $
16 | */
17 | #ifndef _SQLITE_HASH_H_
18 | #define _SQLITE_HASH_H_
19 |
20 | /* Forward declarations of structures. */
21 | typedef struct Hash Hash;
22 | typedef struct HashElem HashElem;
23 |
24 | /* A complete hash table is an instance of the following structure.
25 | ** The internals of this structure are intended to be opaque -- client
26 | ** code should not attempt to access or modify the fields of this structure
27 | ** directly. Change this structure only by using the routines below.
28 | ** However, many of the "procedures" and "functions" for modifying and
29 | ** accessing this structure are really macros, so we can't really make
30 | ** this structure opaque.
31 | */
32 | struct Hash {
33 | char keyClass; /* SQLITE_HASH_INT, _POINTER, _STRING, _BINARY */
34 | char copyKey; /* True if copy of key made on insert */
35 | int count; /* Number of entries in this table */
36 | HashElem *first; /* The first element of the array */
37 | int htsize; /* Number of buckets in the hash table */
38 | struct _ht { /* the hash table */
39 | int count; /* Number of entries with this hash */
40 | HashElem *chain; /* Pointer to first entry with this hash */
41 | } *ht;
42 | };
43 |
44 | /* Each element in the hash table is an instance of the following
45 | ** structure. All elements are stored on a single doubly-linked list.
46 | **
47 | ** Again, this structure is intended to be opaque, but it can't really
48 | ** be opaque because it is used by macros.
49 | */
50 | struct HashElem {
51 | HashElem *next, *prev; /* Next and previous elements in the table */
52 | void *data; /* Data associated with this element */
53 | void *pKey; int nKey; /* Key associated with this element */
54 | };
55 |
56 | /*
57 | ** There are 4 different modes of operation for a hash table:
58 | **
59 | ** SQLITE_HASH_INT nKey is used as the key and pKey is ignored.
60 | **
61 | ** SQLITE_HASH_POINTER pKey is used as the key and nKey is ignored.
62 | **
63 | ** SQLITE_HASH_STRING pKey points to a string that is nKey bytes long
64 | ** (including the null-terminator, if any). Case
65 | ** is ignored in comparisons.
66 | **
67 | ** SQLITE_HASH_BINARY pKey points to binary data nKey bytes long.
68 | ** memcmp() is used to compare keys.
69 | **
70 | ** A copy of the key is made for SQLITE_HASH_STRING and SQLITE_HASH_BINARY
71 | ** if the copyKey parameter to HashInit is 1.
72 | */
73 | #define SQLITE_HASH_INT 1
74 | #define SQLITE_HASH_POINTER 2
75 | #define SQLITE_HASH_STRING 3
76 | #define SQLITE_HASH_BINARY 4
77 |
78 | /*
79 | ** Access routines. To delete, insert a NULL pointer.
80 | */
81 | void sqliteHashInit(Hash*, int keytype, int copyKey);
82 | void *sqliteHashInsert(Hash*, const void *pKey, int nKey, void *pData);
83 | void *sqliteHashFind(const Hash*, const void *pKey, int nKey);
84 | void sqliteHashClear(Hash*);
85 |
86 | /*
87 | ** Macros for looping over all elements of a hash table. The idiom is
88 | ** like this:
89 | **
90 | ** Hash h;
91 | ** HashElem *p;
92 | ** ...
93 | ** for(p=sqliteHashFirst(&h); p; p=sqliteHashNext(p)){
94 | ** SomeStructure *pData = sqliteHashData(p);
95 | ** // do something with pData
96 | ** }
97 | */
98 | #define sqliteHashFirst(H) ((H)->first)
99 | #define sqliteHashNext(E) ((E)->next)
100 | #define sqliteHashData(E) ((E)->data)
101 | #define sqliteHashKey(E) ((E)->pKey)
102 | #define sqliteHashKeysize(E) ((E)->nKey)
103 |
104 | /*
105 | ** Number of entries in a hash table
106 | */
107 | #define sqliteHashCount(H) ((H)->count)
108 |
109 | #endif /* _SQLITE_HASH_H_ */
110 |
--------------------------------------------------------------------------------
/src/os.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** 2001 September 16
3 | **
4 | ** The author disclaims copyright to this source code. In place of
5 | ** a legal notice, here is a blessing:
6 | **
7 | ** May you do good and not evil.
8 | ** May you find forgiveness for yourself and forgive others.
9 | ** May you share freely, never taking more than you give.
10 | **
11 | ******************************************************************************
12 | **
13 | ** This header file (together with is companion C source-code file
14 | ** "os.c") attempt to abstract the underlying operating system so that
15 | ** the SQLite library will work on both POSIX and windows systems.
16 | */
17 | #ifndef _SQLITE_OS_H_
18 | #define _SQLITE_OS_H_
19 |
20 | #ifndef OS_UNIX
21 | # ifndef OS_WIN
22 | # if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
23 | # define OS_WIN 1
24 | # define OS_UNIX 0
25 | # else
26 | # define OS_WIN 0
27 | # define OS_UNIX 1
28 | # endif
29 | # else
30 | # define OS_UNIX 0
31 | # endif
32 | #endif
33 | #ifndef OS_WIN
34 | # define OS_WIN 0
35 | #endif
36 |
37 | /*
38 | ** A handle for an open file is stored in an OsFile object.
39 | */
40 | #if OS_UNIX
41 | typedef struct OsFile OsFile;
42 | struct OsFile {
43 | struct lockInfo *pLock; /* Information about locks on this inode */
44 | int fd; /* The file descriptor */
45 | int locked; /* True if this user holds the lock */
46 | };
47 | # define SQLITE_TEMPNAME_SIZE 200
48 | # if defined(HAVE_USLEEP) && HAVE_USLEEP
49 | # define SQLITE_MIN_SLEEP_MS 1
50 | # else
51 | # define SQLITE_MIN_SLEEP_MS 1000
52 | # endif
53 | #endif
54 |
55 | #if OS_WIN
56 | #include
57 | #include
58 | typedef struct OsFile OsFile;
59 | struct OsFile {
60 | HANDLE h;
61 | int locked;
62 | };
63 | # define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
64 | # define SQLITE_MIN_SLEEP_MS 1
65 | #endif
66 |
67 | int sqliteOsDelete(const char*);
68 | int sqliteOsFileExists(const char*);
69 | int sqliteOsOpenReadWrite(const char*, OsFile*, int*);
70 | int sqliteOsOpenExclusive(const char*, OsFile*, int);
71 | int sqliteOsOpenReadOnly(const char*, OsFile*);
72 | int sqliteOsTempFileName(char*);
73 | int sqliteOsClose(OsFile*);
74 | int sqliteOsRead(OsFile*, void*, int amt);
75 | int sqliteOsWrite(OsFile*, const void*, int amt);
76 | int sqliteOsSeek(OsFile*, int offset);
77 | int sqliteOsSync(OsFile*);
78 | int sqliteOsTruncate(OsFile*, int size);
79 | int sqliteOsFileSize(OsFile*, int *pSize);
80 | int sqliteOsReadLock(OsFile*);
81 | int sqliteOsWriteLock(OsFile*);
82 | int sqliteOsUnlock(OsFile*);
83 | int sqliteOsRandomSeed(char*);
84 | int sqliteOsSleep(int ms);
85 | void sqliteOsEnterMutex(void);
86 | void sqliteOsLeaveMutex(void);
87 |
88 |
89 |
90 | #endif /* _SQLITE_OS_H_ */
91 |
--------------------------------------------------------------------------------
/src/pager.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** 2001 September 15
3 | **
4 | ** The author disclaims copyright to this source code. In place of
5 | ** a legal notice, here is a blessing:
6 | **
7 | ** May you do good and not evil.
8 | ** May you find forgiveness for yourself and forgive others.
9 | ** May you share freely, never taking more than you give.
10 | **
11 | *************************************************************************
12 | ** This header file defines the interface that the sqlite page cache
13 | ** subsystem. The page cache subsystem reads and writes a file a page
14 | ** at a time and provides a journal for rollback.
15 | **
16 | ** @(#) $Id: pager.h,v 1.16 2002/03/05 12:41:20 drh Exp $
17 | */
18 |
19 | /*
20 | ** The size of one page
21 | **
22 | ** You can change this value to another (reasonable) power of two
23 | ** such as 512, 2048, 4096, or 8192 and things will still work. But
24 | ** experiments show that a page size of 1024 gives the best speed.
25 | ** (The speed differences are minimal.)
26 | */
27 | #define SQLITE_PAGE_SIZE 1024
28 |
29 | /*
30 | ** Maximum number of pages in one database. (This is a limitation of
31 | ** imposed by 4GB files size limits.)
32 | */
33 | #define SQLITE_MAX_PAGE 1073741823
34 |
35 | /*
36 | ** The type used to represent a page number. The first page in a file
37 | ** is called page 1. 0 is used to represent "not a page".
38 | */
39 | typedef unsigned int Pgno;
40 |
41 | /*
42 | ** Each open file is managed by a separate instance of the "Pager" structure.
43 | */
44 | typedef struct Pager Pager;
45 |
46 | /*
47 | ** See source code comments for a detailed description of the following
48 | ** routines:
49 | */
50 | int sqlitepager_open(Pager **ppPager,const char *zFilename,int nPage,int nEx);
51 | void sqlitepager_set_destructor(Pager*, void(*)(void*));
52 | void sqlitepager_set_cachesize(Pager*, int);
53 | int sqlitepager_close(Pager *pPager);
54 | int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage);
55 | void *sqlitepager_lookup(Pager *pPager, Pgno pgno);
56 | int sqlitepager_ref(void*);
57 | int sqlitepager_unref(void*);
58 | Pgno sqlitepager_pagenumber(void*);
59 | int sqlitepager_write(void*);
60 | int sqlitepager_iswriteable(void*);
61 | int sqlitepager_pagecount(Pager*);
62 | int sqlitepager_begin(void*);
63 | int sqlitepager_commit(Pager*);
64 | int sqlitepager_rollback(Pager*);
65 | int sqlitepager_isreadonly(Pager*);
66 | int sqlitepager_ckpt_begin(Pager*);
67 | int sqlitepager_ckpt_commit(Pager*);
68 | int sqlitepager_ckpt_rollback(Pager*);
69 | void sqlitepager_dont_rollback(void*);
70 | void sqlitepager_dont_write(Pager*, Pgno);
71 | int *sqlitepager_stats(Pager*);
72 |
73 | #ifdef SQLITE_TEST
74 | void sqlitepager_refdump(Pager*);
75 | int pager_refinfo_enable;
76 | #endif
77 |
--------------------------------------------------------------------------------
/src/random.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** 2001 September 15
3 | **
4 | ** The author disclaims copyright to this source code. In place of
5 | ** a legal notice, here is a blessing:
6 | **
7 | ** May you do good and not evil.
8 | ** May you find forgiveness for yourself and forgive others.
9 | ** May you share freely, never taking more than you give.
10 | **
11 | *************************************************************************
12 | ** This file contains code to implement a pseudo-random number
13 | ** generator (PRNG) for SQLite.
14 | **
15 | ** Random numbers are used by some of the database backends in order
16 | ** to generate random integer keys for tables or random filenames.
17 | **
18 | ** $Id: random.c,v 1.10 2002/02/19 13:39:23 drh Exp $
19 | */
20 | #include "sqliteInt.h"
21 | #include "os.h"
22 |
23 |
24 | /*
25 | ** Get a single 8-bit random value from the RC4 PRNG. The Mutex
26 | ** must be held while executing this routine.
27 | **
28 | ** Why not just use a library random generator like lrand48() for this?
29 | ** Because the OP_NewRecno opcode in the VDBE depends on having a very
30 | ** good source of random numbers. The lrand48() library function may
31 | ** well be good enough. But maybe not. Or maybe lrand48() has some
32 | ** subtle problems on some systems that could cause problems. It is hard
33 | ** to know. To minimize the risk of problems due to bad lrand48()
34 | ** implementations, SQLite uses this random number generator based
35 | ** on RC4, which we know works very well.
36 | */
37 | static int randomByte(){
38 | int t;
39 |
40 | /* All threads share a single random number generator.
41 | ** This structure is the current state of the generator.
42 | */
43 | static struct {
44 | int isInit; /* True if initialized */
45 | int i, j; /* State variables */
46 | int s[256]; /* State variables */
47 | } prng;
48 |
49 | /* Initialize the state of the random number generator once,
50 | ** the first time this routine is called. The seed value does
51 | ** not need to contain a lot of randomness since we are not
52 | ** trying to do secure encryption or anything like that...
53 | **
54 | ** Nothing in this file or anywhere else in SQLite does any kind of
55 | ** encryption. The RC4 algorithm is being used as a PRNG (pseudo-random
56 | ** number generator) not as an encryption device.
57 | */
58 | if( !prng.isInit ){
59 | int i;
60 | char k[256];
61 | prng.j = 0;
62 | prng.i = 0;
63 | sqliteOsRandomSeed(k);
64 | for(i=0; i<256; i++){
65 | prng.s[i] = i;
66 | }
67 | for(i=0; i<256; i++){
68 | int t;
69 | prng.j = (prng.j + prng.s[i] + k[i]) & 0xff;
70 | t = prng.s[prng.j];
71 | prng.s[prng.j] = prng.s[i];
72 | prng.s[i] = t;
73 | }
74 | prng.isInit = 1;
75 | }
76 |
77 | /* Generate and return single random byte
78 | */
79 | prng.i = (prng.i + 1) & 0xff;
80 | prng.j = (prng.j + prng.s[prng.i]) & 0xff;
81 | t = prng.s[prng.i];
82 | prng.s[prng.i] = prng.s[prng.j];
83 | prng.s[prng.j] = t;
84 | t = prng.s[prng.i] + prng.s[prng.j];
85 | return prng.s[t & 0xff];
86 | }
87 |
88 | /*
89 | ** Return an random 8-bit integer.
90 | */
91 | int sqliteRandomByte(){
92 | int r;
93 | sqliteOsEnterMutex();
94 | r = randomByte();
95 | sqliteOsLeaveMutex();
96 | return r;
97 | }
98 |
99 | /*
100 | ** Return a random 32-bit integer. The integer is generated by making
101 | ** 4 calls to sqliteRandomByte().
102 | */
103 | int sqliteRandomInteger(){
104 | int r;
105 | int i;
106 | sqliteOsEnterMutex();
107 | r = randomByte();
108 | for(i=1; i<4; i++){
109 | r = (r<<8) + randomByte();
110 | }
111 | sqliteOsLeaveMutex();
112 | return r;
113 | }
114 |
--------------------------------------------------------------------------------
/src/table.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** 2001 September 15
3 | **
4 | ** The author disclaims copyright to this source code. In place of
5 | ** a legal notice, here is a blessing:
6 | **
7 | ** May you do good and not evil.
8 | ** May you find forgiveness for yourself and forgive others.
9 | ** May you share freely, never taking more than you give.
10 | **
11 | *************************************************************************
12 | ** This file contains the sqlite_get_table() and sqlite_free_table()
13 | ** interface routines. These are just wrappers around the main
14 | ** interface routine of sqlite_exec().
15 | **
16 | ** These routines are in a separate files so that they will not be linked
17 | ** if they are not used.
18 | */
19 | #include
20 | #include
21 | #include "sqliteInt.h"
22 |
23 | /*
24 | ** This structure is used to pass data from sqlite_get_table() through
25 | ** to the callback function is uses to build the result.
26 | */
27 | typedef struct TabResult {
28 | char **azResult;
29 | char *zErrMsg;
30 | int nResult;
31 | int nAlloc;
32 | int nRow;
33 | int nColumn;
34 | int nData;
35 | int rc;
36 | } TabResult;
37 |
38 | /*
39 | ** This routine is called once for each row in the result table. Its job
40 | ** is to fill in the TabResult structure appropriately, allocating new
41 | ** memory as necessary.
42 | */
43 | static int sqlite_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
44 | TabResult *p = (TabResult*)pArg;
45 | int need;
46 | int i;
47 | char *z;
48 |
49 | /* Make sure there is enough space in p->azResult to hold everything
50 | ** we need to remember from this invocation of the callback.
51 | */
52 | if( p->nRow==0 && argv!=0 ){
53 | need = nCol*2;
54 | }else{
55 | need = nCol;
56 | }
57 | if( p->nData + need >= p->nAlloc ){
58 | char **azNew;
59 | p->nAlloc = p->nAlloc*2 + need + 1;
60 | azNew = realloc( p->azResult, sizeof(char*)*p->nAlloc );
61 | if( azNew==0 ){
62 | p->rc = SQLITE_NOMEM;
63 | return 1;
64 | }
65 | p->azResult = azNew;
66 | }
67 |
68 | /* If this is the first row, then generate an extra row containing
69 | ** the names of all columns.
70 | */
71 | if( p->nRow==0 ){
72 | p->nColumn = nCol;
73 | for(i=0; irc = SQLITE_NOMEM;
80 | return 1;
81 | }
82 | strcpy(z, colv[i]);
83 | }
84 | p->azResult[p->nData++] = z;
85 | }
86 | }else if( p->nColumn!=nCol ){
87 | sqliteSetString(&p->zErrMsg,
88 | "sqlite_get_table() called with two or more incompatible queries", 0);
89 | p->rc = SQLITE_ERROR;
90 | return 1;
91 | }
92 |
93 | /* Copy over the row data
94 | */
95 | if( argv!=0 ){
96 | for(i=0; irc = SQLITE_NOMEM;
103 | return 1;
104 | }
105 | strcpy(z, argv[i]);
106 | }
107 | p->azResult[p->nData++] = z;
108 | }
109 | p->nRow++;
110 | }
111 | return 0;
112 | }
113 |
114 | /*
115 | ** Query the database. But instead of invoking a callback for each row,
116 | ** malloc() for space to hold the result and return the entire results
117 | ** at the conclusion of the call.
118 | **
119 | ** The result that is written to ***pazResult is held in memory obtained
120 | ** from malloc(). But the caller cannot free this memory directly.
121 | ** Instead, the entire table should be passed to sqlite_free_table() when
122 | ** the calling procedure is finished using it.
123 | */
124 | int sqlite_get_table(
125 | sqlite *db, /* The database on which the SQL executes */
126 | const char *zSql, /* The SQL to be executed */
127 | char ***pazResult, /* Write the result table here */
128 | int *pnRow, /* Write the number of rows in the result here */
129 | int *pnColumn, /* Write the number of columns of result here */
130 | char **pzErrMsg /* Write error messages here */
131 | ){
132 | int rc;
133 | TabResult res;
134 | if( pazResult==0 ){ return SQLITE_ERROR; }
135 | *pazResult = 0;
136 | if( pnColumn ) *pnColumn = 0;
137 | if( pnRow ) *pnRow = 0;
138 | res.zErrMsg = 0;
139 | res.nResult = 0;
140 | res.nRow = 0;
141 | res.nColumn = 0;
142 | res.nData = 1;
143 | res.nAlloc = 20;
144 | res.rc = SQLITE_OK;
145 | res.azResult = malloc( sizeof(char*)*res.nAlloc );
146 | if( res.azResult==0 ){
147 | return SQLITE_NOMEM;
148 | }
149 | res.azResult[0] = 0;
150 | rc = sqlite_exec(db, zSql, sqlite_get_table_cb, &res, pzErrMsg);
151 | if( res.azResult ){
152 | res.azResult[0] = (char*)res.nData;
153 | }
154 | if( rc==SQLITE_ABORT ){
155 | sqlite_free_table(&res.azResult[1]);
156 | if( res.zErrMsg ){
157 | if( pzErrMsg ){
158 | free(*pzErrMsg);
159 | *pzErrMsg = res.zErrMsg;
160 | sqliteStrRealloc(pzErrMsg);
161 | }else{
162 | sqliteFree(res.zErrMsg);
163 | }
164 | }
165 | return res.rc;
166 | }
167 | sqliteFree(res.zErrMsg);
168 | if( rc!=SQLITE_OK ){
169 | sqlite_free_table(&res.azResult[1]);
170 | return rc;
171 | }
172 | if( res.nAlloc>res.nData ){
173 | char **azNew;
174 | azNew = realloc( res.azResult, sizeof(char*)*(res.nData+1) );
175 | if( res.azResult==0 ){
176 | sqlite_free_table(&res.azResult[1]);
177 | return SQLITE_NOMEM;
178 | }
179 | res.azResult = azNew;
180 | }
181 | *pazResult = &res.azResult[1];
182 | if( pnColumn ) *pnColumn = res.nColumn;
183 | if( pnRow ) *pnRow = res.nRow;
184 | return rc;
185 | }
186 |
187 | /*
188 | ** This routine frees the space the sqlite_get_table() malloced.
189 | */
190 | void sqlite_free_table(
191 | char **azResult /* Result returned from from sqlite_get_table() */
192 | ){
193 | if( azResult ){
194 | int i, n;
195 | azResult--;
196 | n = (int)azResult[0];
197 | for(i=1; i=0} continue
49 | source $testfile
50 | }
51 | if {[info exists Leak]} {
52 | lappend LeakList $Leak
53 | }
54 | }
55 |
56 | # Do one last test to look for a memory leak in the library. This will
57 | # only work if SQLite is compiled with the -DMEMORY_DEBUG=1 flag.
58 | #
59 | if {$LeakList!=""} {
60 | puts -nonewline memory-leak-test...
61 | incr ::nTest
62 | foreach x $LeakList {
63 | if {$x!=[lindex $LeakList 0]} {
64 | puts " failed!"
65 | puts "Expected: all values to be the same"
66 | puts " Got: $LeakList"
67 | incr ::nErr
68 | lappend ::failList memory-leak-test
69 | break
70 | }
71 | }
72 | puts " Ok"
73 | }
74 |
75 | # Run the malloc tests and the misuse test after memory leak detection.
76 | # Both tests leak memory.
77 | #
78 | catch {source $testdir/misuse.test}
79 | catch {source $testdir/malloc.test}
80 |
81 | really_finish_test
82 |
--------------------------------------------------------------------------------
/test/bigrow.test:
--------------------------------------------------------------------------------
1 | # 2001 September 23
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is stressing the library by putting large amounts
13 | # of data in a single row of a table.
14 | #
15 | # $Id: bigrow.test,v 1.4 2001/11/24 00:31:47 drh Exp $
16 |
17 | set testdir [file dirname $argv0]
18 | source $testdir/tester.tcl
19 |
20 | # Make a big string that we can use for test data
21 | #
22 | do_test bigrow-1.0 {
23 | set ::bigstr {}
24 | for {set i 1} {$i<=9999} {incr i} {
25 | set sep [string index "abcdefghijklmnopqrstuvwxyz" [expr {$i%26}]]
26 | append ::bigstr "$sep [format %04d $i] "
27 | }
28 | string length $::bigstr
29 | } {69993}
30 |
31 | # Make a table into which we can insert some but records.
32 | #
33 | do_test bigrow-1.1 {
34 | execsql {
35 | CREATE TABLE t1(a text, b text, c text);
36 | SELECT name FROM sqlite_master
37 | WHERE type='table' OR type='index'
38 | ORDER BY name
39 | }
40 | } {t1}
41 |
42 | do_test bigrow-1.2 {
43 | set ::big1 [string range $::bigstr 0 65519]
44 | set sql "INSERT INTO t1 VALUES('abc',"
45 | append sql "'$::big1', 'xyz');"
46 | execsql $sql
47 | execsql {SELECT a, c FROM t1}
48 | } {abc xyz}
49 | do_test bigrow-1.3 {
50 | execsql {SELECT b FROM t1}
51 | } [list $::big1]
52 | do_test bigrow-1.4 {
53 | set ::big2 [string range $::bigstr 0 65520]
54 | set sql "INSERT INTO t1 VALUES('abc2',"
55 | append sql "'$::big2', 'xyz2');"
56 | set r [catch {execsql $sql} msg]
57 | lappend r $msg
58 | } {0 {}}
59 | do_test bigrow-1.4.1 {
60 | execsql {SELECT b FROM t1 ORDER BY c}
61 | } [list $::big1 $::big2]
62 | do_test bigrow-1.4.2 {
63 | execsql {SELECT c FROM t1 ORDER BY c}
64 | } {xyz xyz2}
65 | do_test bigrow-1.4.3 {
66 | execsql {DELETE FROM t1 WHERE a='abc2'}
67 | execsql {SELECT c FROM t1}
68 | } {xyz}
69 |
70 | do_test bigrow-1.5 {
71 | execsql {
72 | UPDATE t1 SET a=b, b=a;
73 | SELECT b,c FROM t1
74 | }
75 | } {abc xyz}
76 | do_test bigrow-1.6 {
77 | execsql {
78 | SELECT * FROM t1
79 | }
80 | } [list $::big1 abc xyz]
81 | do_test bigrow-1.7 {
82 | execsql {
83 | INSERT INTO t1 VALUES('1','2','3');
84 | INSERT INTO t1 VALUES('A','B','C');
85 | SELECT b FROM t1 WHERE a=='1';
86 | }
87 | } {2}
88 | do_test bigrow-1.8 {
89 | execsql "SELECT b FROM t1 WHERE a=='$::big1'"
90 | } {abc}
91 | do_test bigrow-1.9 {
92 | execsql "SELECT b FROM t1 WHERE a!='$::big1' ORDER BY a"
93 | } {2 B}
94 |
95 | # Try doing some indexing on big columns
96 | #
97 | do_test bigrow-2.1 {
98 | execsql {
99 | CREATE INDEX i1 ON t1(a)
100 | }
101 | execsql "SELECT b FROM t1 WHERE a=='$::big1'"
102 | } {abc}
103 | do_test bigrow-2.2 {
104 | execsql {
105 | UPDATE t1 SET a=b, b=a
106 | }
107 | execsql "SELECT b FROM t1 WHERE a=='abc'"
108 | } [list $::big1]
109 | do_test bigrow-2.3 {
110 | execsql {
111 | UPDATE t1 SET a=b, b=a
112 | }
113 | execsql "SELECT b FROM t1 WHERE a=='$::big1'"
114 | } {abc}
115 | catch {unset ::bigstr}
116 | catch {unset ::big1}
117 | catch {unset ::big2}
118 |
119 | # Mosts of the tests above were created back when rows were limited in
120 | # size to 64K. Now rows can be much bigger. Test that logic. Also
121 | # make sure things work correctly at the transition boundries between
122 | # row sizes of 256 to 257 bytes and from 65536 to 65537 bytes.
123 | #
124 | # We begin by testing the 256..257 transition.
125 | #
126 | do_test bigrow-3.1 {
127 | execsql {
128 | DELETE FROM t1;
129 | INSERT INTO t1(a,b,c) VALUES('one','abcdefghijklmnopqrstuvwxyz0123','hi');
130 | }
131 | execsql {SELECT a,length(b),c FROM t1}
132 | } {one 30 hi}
133 | do_test bigrow-3.2 {
134 | execsql {
135 | UPDATE t1 SET b=b||b;
136 | UPDATE t1 SET b=b||b;
137 | UPDATE t1 SET b=b||b;
138 | }
139 | execsql {SELECT a,length(b),c FROM t1}
140 | } {one 240 hi}
141 | for {set i 1} {$i<10} {incr i} {
142 | do_test bigrow-3.3.$i {
143 | execsql "UPDATE t1 SET b=b||'$i'"
144 | execsql {SELECT a,length(b),c FROM t1}
145 | } "one [expr {240+$i}] hi"
146 | }
147 |
148 | # Now test the 65536..65537 row-size transition.
149 | #
150 | do_test bigrow-4.1 {
151 | execsql {
152 | DELETE FROM t1;
153 | INSERT INTO t1(a,b,c) VALUES('one','abcdefghijklmnopqrstuvwxyz0123','hi');
154 | }
155 | execsql {SELECT a,length(b),c FROM t1}
156 | } {one 30 hi}
157 | do_test bigrow-4.2 {
158 | execsql {
159 | UPDATE t1 SET b=b||b;
160 | UPDATE t1 SET b=b||b;
161 | UPDATE t1 SET b=b||b;
162 | UPDATE t1 SET b=b||b;
163 | UPDATE t1 SET b=b||b;
164 | UPDATE t1 SET b=b||b;
165 | UPDATE t1 SET b=b||b;
166 | UPDATE t1 SET b=b||b;
167 | UPDATE t1 SET b=b||b;
168 | UPDATE t1 SET b=b||b;
169 | UPDATE t1 SET b=b||b;
170 | UPDATE t1 SET b=b||b;
171 | }
172 | execsql {SELECT a,length(b),c FROM t1}
173 | } {one 122880 hi}
174 | do_test bigrow-4.3 {
175 | execsql {
176 | UPDATE t1 SET b=substr(b,1,65515)
177 | }
178 | execsql {SELECT a,length(b),c FROM t1}
179 | } {one 65515 hi}
180 | for {set i 1} {$i<10} {incr i} {
181 | do_test bigrow-4.4.$i {
182 | execsql "UPDATE t1 SET b=b||'$i'"
183 | execsql {SELECT a,length(b),c FROM t1}
184 | } "one [expr {65515+$i}] hi"
185 | }
186 |
187 | # Check to make sure the library recovers safely if a row contains
188 | # too much data.
189 | #
190 | do_test bigrow-5.1 {
191 | execsql {
192 | DELETE FROM t1;
193 | INSERT INTO t1(a,b,c) VALUES('one','abcdefghijklmnopqrstuvwxyz0123','hi');
194 | }
195 | execsql {SELECT a,length(b),c FROM t1}
196 | } {one 30 hi}
197 | set i 1
198 | for {set sz 60} {$sz<1048560} {incr sz $sz} {
199 | do_test bigrow-5.2.$i {
200 | execsql {
201 | UPDATE t1 SET b=b||b;
202 | SELECT a,length(b),c FROM t1;
203 | }
204 | } "one $sz hi"
205 | incr i
206 | }
207 | do_test bigrow-5.3 {
208 | set r [catch {execsql {UPDATE t1 SET b=b||b}} msg]
209 | lappend r $msg
210 | } {1 {too much data for one table row}}
211 | do_test bigrow-5.4 {
212 | execsql {DROP TABLE t1}
213 | } {}
214 |
215 | finish_test
216 |
--------------------------------------------------------------------------------
/test/btree3.test:
--------------------------------------------------------------------------------
1 | # 2001 November 22
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this script is btree database backend
13 | #
14 | # In particular, this file tests a small part of the Delete logic
15 | # for the BTree backend. When a row is deleted from a table, the
16 | # cursor is suppose to be left pointing at either the previous or
17 | # next entry in that table. If the cursor is left pointing at the
18 | # next entry, then the next Next operation is ignored. So the
19 | # sequence of operations (Delete, Next) should always leave the
20 | # cursor pointing at the first entry past the one that was deleted.
21 | # This test is designed to verify that behavior.
22 | #
23 | # $Id: btree3.test,v 1.1 2001/11/23 00:24:12 drh Exp $
24 |
25 |
26 | set testdir [file dirname $argv0]
27 | source $testdir/tester.tcl
28 |
29 | if {[info commands btree_open]!=""} {
30 |
31 | # Open a test database.
32 | #
33 | file delete -force test1.bt
34 | file delete -force test1.bt-journal
35 | set b1 [btree_open test1.bt]
36 | btree_begin_transaction $::b1
37 |
38 | # Insert a few one records
39 | #
40 | set data {abcdefghijklmnopqrstuvwxyz0123456789}
41 | append data $data
42 | append data $data
43 | append data $data
44 | append data $data
45 | for {set k 2} {$k<=10} {incr k} {
46 | for {set j 1} {$j<=$k} {incr j} {
47 | set jkey [format %02d $j]
48 | btree_clear_table $::b1 2
49 | set ::c1 [btree_cursor $::b1 2 1]
50 | for {set i 1} {$i<=$k+1} {incr i} {
51 | set key [format %02d $i]
52 | do_test btree3-$k.$j.1.$i {
53 | btree_insert $::c1 $::key $::data
54 | } {}
55 | # btree_tree_dump $::b1 2
56 | }
57 | do_test btree3-$k.$j.2 {
58 | btree_move_to $::c1 $::jkey
59 | btree_key $::c1
60 | } $::jkey
61 | do_test btree3-$k.$j.3 {
62 | btree_delete $::c1
63 | } {}
64 | do_test btree3-$k.$j.4 {
65 | btree_next $::c1
66 | btree_key $::c1
67 | } [format %02d [expr $j+1]]
68 | btree_close_cursor $::c1
69 | }
70 | }
71 |
72 | btree_rollback $::b1
73 | btree_pager_ref_dump $::b1
74 | btree_close $::b1
75 |
76 | } ;# end if( not mem: and has pager_open command );
77 |
78 | finish_test
79 |
--------------------------------------------------------------------------------
/test/copy.test:
--------------------------------------------------------------------------------
1 | # 2001 September 15
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is testing the COPY statement.
13 | #
14 | # $Id: copy.test,v 1.10 2002/02/19 13:39:23 drh Exp $
15 |
16 | set testdir [file dirname $argv0]
17 | source $testdir/tester.tcl
18 |
19 | # Create a file of data from which to copy.
20 | #
21 | set f [open data1.txt w]
22 | puts $f "11\t22\t33"
23 | puts $f "22\t33\t11"
24 | close $f
25 | set f [open data2.txt w]
26 | puts $f "11\t22\t33"
27 | puts $f "\\."
28 | puts $f "22\t33\t11"
29 | close $f
30 | set f [open data3.txt w]
31 | puts $f "11\t22\t33\t44"
32 | puts $f "22\t33\t11"
33 | close $f
34 | set f [open data4.txt w]
35 | puts $f "11 | 22 | 33"
36 | puts $f "22 | 33 | 11"
37 | close $f
38 | set f [open data5.txt w]
39 | puts $f "11|22|33"
40 | puts $f "22|33|11"
41 | close $f
42 |
43 | # Try to COPY into a non-existant table.
44 | #
45 | do_test copy-1.1 {
46 | set v [catch {execsql {COPY test1 FROM 'data1.txt'}} msg]
47 | lappend v $msg
48 | } {1 {no such table: test1}}
49 |
50 | # Try to insert into sqlite_master
51 | #
52 | do_test copy-1.2 {
53 | set v [catch {execsql {COPY sqlite_master FROM 'data2.txt'}} msg]
54 | lappend v $msg
55 | } {1 {table sqlite_master may not be modified}}
56 |
57 | # Do some actual inserts
58 | #
59 | do_test copy-1.3 {
60 | execsql {CREATE TABLE test1(one int, two int, three int)}
61 | execsql {COPY test1 FROM 'data1.txt'}
62 | execsql {SELECT * FROM test1 ORDER BY one}
63 | } {11 22 33 22 33 11}
64 |
65 | # Make sure input terminates at \.
66 | #
67 | do_test copy-1.4 {
68 | execsql {DELETE FROM test1}
69 | execsql {COPY test1 FROM 'data2.txt'}
70 | execsql {SELECT * FROM test1 ORDER BY one}
71 | } {11 22 33}
72 |
73 | # Test out the USING DELIMITERS clause
74 | #
75 | do_test copy-1.5 {
76 | execsql {DELETE FROM test1}
77 | execsql {COPY test1 FROM 'data4.txt' USING DELIMITERS ' | '}
78 | execsql {SELECT * FROM test1 ORDER BY one}
79 | } {11 22 33 22 33 11}
80 | do_test copy-1.6 {
81 | execsql {DELETE FROM test1}
82 | execsql {COPY test1 FROM 'data5.txt' USING DELIMITERS '|'}
83 | execsql {SELECT * FROM test1 ORDER BY one}
84 | } {11 22 33 22 33 11}
85 | do_test copy-1.7 {
86 | execsql {DELETE FROM test1}
87 | execsql {COPY test1 FROM 'data4.txt' USING DELIMITERS '|'}
88 | execsql {SELECT * FROM test1 ORDER BY one}
89 | } {{11 } { 22 } { 33} {22 } { 33 } { 11}}
90 |
91 | # Try copying into a table that has one or more indices.
92 | #
93 | do_test copy-1.8 {
94 | execsql {DELETE FROM test1}
95 | execsql {CREATE INDEX index1 ON test1(one)}
96 | execsql {CREATE INDEX index2 ON test1(two)}
97 | execsql {CREATE INDEX index3 ON test1(three)}
98 | execsql {COPY test1 from 'data1.txt'}
99 | execsql {SELECT * FROM test1 WHERE one=11}
100 | } {11 22 33}
101 | do_test copy-1.8b {
102 | execsql {SELECT * FROM test1 WHERE one=22}
103 | } {22 33 11}
104 | do_test copy-1.8c {
105 | execsql {SELECT * FROM test1 WHERE two=22}
106 | } {11 22 33}
107 | do_test copy-1.8d {
108 | execsql {SELECT * FROM test1 WHERE three=11}
109 | } {22 33 11}
110 |
111 |
112 | # Try inserting really long data
113 | #
114 | set x {}
115 | for {set i 0} {$i<100} {incr i} {
116 | append x "($i)-abcdefghijklmnopqrstyvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ-"
117 | }
118 | do_test copy-2.1 {
119 | execsql {CREATE TABLE test2(a int, x text)}
120 | set f [open data21.txt w]
121 | puts $f "123\t$x"
122 | close $f
123 | execsql {COPY test2 FROM 'data21.txt'}
124 | execsql {SELECT x from test2}
125 | } $x
126 | file delete -force data21.txt
127 |
128 | # Test the escape character mechanism
129 | #
130 | do_test copy-3.1 {
131 | set fd [open data6.txt w]
132 | puts $fd "hello\\\tworld\t1"
133 | puts $fd "hello\tworld\\\t2"
134 | close $fd
135 | execsql {
136 | CREATE TABLE t1(a text, b text);
137 | COPY t1 FROM 'data6.txt';
138 | SELECT * FROM t1 ORDER BY a;
139 | }
140 | } {hello {world 2} {hello world} 1}
141 | do_test copy-3.2 {
142 | set fd [open data6.txt w]
143 | puts $fd "1\thello\\\nworld"
144 | puts $fd "2\thello world"
145 | close $fd
146 | execsql {
147 | DELETE FROM t1;
148 | COPY t1 FROM 'data6.txt';
149 | SELECT * FROM t1 ORDER BY a;
150 | }
151 | } {1 {hello
152 | world} 2 {hello world}}
153 |
154 | # Test the embedded NULL logic.
155 | #
156 | do_test copy-4.1 {
157 | set fd [open data6.txt w]
158 | puts $fd "1\t\\N"
159 | puts $fd "\\N\thello world"
160 | close $fd
161 | execsql {
162 | DELETE FROM t1;
163 | COPY t1 FROM 'data6.txt';
164 | SELECT * FROM t1 WHERE a IS NULL;
165 | }
166 | } {{} {hello world}}
167 | do_test copy-4.2 {
168 | execsql {
169 | SELECT * FROM t1 WHERE b IS NULL;
170 | }
171 | } {1 {}}
172 |
173 | # Test the conflict resolution logic for COPY
174 | #
175 | do_test copy-5.1 {
176 | execsql {
177 | DROP TABLE t1;
178 | CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE, c);
179 | COPY t1 FROM 'data5.txt' USING DELIMITERS '|';
180 | SELECT * FROM t1;
181 | }
182 | } {11 22 33 22 33 11}
183 | do_test copy-5.2 {
184 | set fd [open data6.txt w]
185 | puts $fd "33|22|44"
186 | close $fd
187 | catchsql {
188 | COPY t1 FROM 'data6.txt' USING DELIMITERS '|';
189 | SELECT * FROM t1;
190 | }
191 | } {1 {constraint failed}}
192 | do_test copy-5.3 {
193 | set fd [open data6.txt w]
194 | puts $fd "33|22|44"
195 | close $fd
196 | catchsql {
197 | COPY OR IGNORE t1 FROM 'data6.txt' USING DELIMITERS '|';
198 | SELECT * FROM t1;
199 | }
200 | } {0 {11 22 33 22 33 11}}
201 | do_test copy-5.4 {
202 | set fd [open data6.txt w]
203 | puts $fd "33|22|44"
204 | close $fd
205 | catchsql {
206 | COPY OR REPLACE t1 FROM 'data6.txt' USING DELIMITERS '|';
207 | SELECT * FROM t1;
208 | }
209 | } {0 {22 33 11 33 22 44}}
210 |
211 | do_test copy-5.5 {
212 | execsql {
213 | DELETE FROM t1;
214 | PRAGMA count_changes=on;
215 | COPY t1 FROM 'data5.txt' USING DELIMITERS '|';
216 | }
217 | } {2}
218 | do_test copy-5.6 {
219 | execsql {
220 | COPY OR REPLACE t1 FROM 'data5.txt' USING DELIMITERS '|';
221 | }
222 | } {2}
223 | do_test copy-5.7 {
224 | execsql {
225 | COPY OR IGNORE t1 FROM 'data5.txt' USING DELIMITERS '|';
226 | }
227 | } {0}
228 |
229 | do_test copy-6.0 {
230 | set x [execsql {PRAGMA integrity_check}]
231 | if {$x==""} {set x ok}
232 | set x
233 | } {ok}
234 |
235 |
236 | # Cleanup
237 | #
238 | file delete -force data1.txt data2.txt data3.txt data4.txt data5.txt data6.txt
239 |
240 | finish_test
241 |
--------------------------------------------------------------------------------
/test/delete.test:
--------------------------------------------------------------------------------
1 | # 2001 September 15
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is testing the DELETE FROM statement.
13 | #
14 | # $Id: delete.test,v 1.10 2001/10/15 00:44:36 drh Exp $
15 |
16 | set testdir [file dirname $argv0]
17 | source $testdir/tester.tcl
18 |
19 | # Try to delete from a non-existant table.
20 | #
21 | do_test delete-1.1 {
22 | set v [catch {execsql {DELETE FROM test1}} msg]
23 | lappend v $msg
24 | } {1 {no such table: test1}}
25 |
26 | # Try to delete from sqlite_master
27 | #
28 | do_test delete-2.1 {
29 | set v [catch {execsql {DELETE FROM sqlite_master}} msg]
30 | lappend v $msg
31 | } {1 {table sqlite_master may not be modified}}
32 |
33 | # Delete selected entries from a table with and without an index.
34 | #
35 | do_test delete-3.1.1 {
36 | execsql {CREATE TABLE table1(f1 int, f2 int)}
37 | execsql {INSERT INTO table1 VALUES(1,2)}
38 | execsql {INSERT INTO table1 VALUES(2,4)}
39 | execsql {INSERT INTO table1 VALUES(3,8)}
40 | execsql {INSERT INTO table1 VALUES(4,16)}
41 | execsql {SELECT * FROM table1 ORDER BY f1}
42 | } {1 2 2 4 3 8 4 16}
43 | do_test delete-3.1.2 {
44 | execsql {DELETE FROM table1 WHERE f1=3}
45 | } {}
46 | do_test delete-3.1.3 {
47 | execsql {SELECT * FROM table1 ORDER BY f1}
48 | } {1 2 2 4 4 16}
49 | do_test delete-3.1.4 {
50 | execsql {CREATE INDEX index1 ON table1(f1)}
51 | execsql {PRAGMA count_changes=on}
52 | execsql {DELETE FROM 'table1' WHERE f1=3}
53 | } {0}
54 | do_test delete-3.1.5 {
55 | execsql {SELECT * FROM table1 ORDER BY f1}
56 | } {1 2 2 4 4 16}
57 | do_test delete-3.1.6 {
58 | execsql {DELETE FROM table1 WHERE f1=2}
59 | } {1}
60 | do_test delete-3.1.7 {
61 | execsql {SELECT * FROM table1 ORDER BY f1}
62 | } {1 2 4 16}
63 |
64 | # Semantic errors in the WHERE clause
65 | #
66 | do_test delete-4.1 {
67 | execsql {CREATE TABLE table2(f1 int, f2 int)}
68 | set v [catch {execsql {DELETE FROM table2 WHERE f3=5}} msg]
69 | lappend v $msg
70 | } {1 {no such column: f3}}
71 |
72 | do_test delete-4.2 {
73 | set v [catch {execsql {DELETE FROM table2 WHERE xyzzy(f1+4)}} msg]
74 | lappend v $msg
75 | } {1 {no such function: xyzzy}}
76 |
77 | # Lots of deletes
78 | #
79 | do_test delete-5.1.1 {
80 | execsql {DELETE FROM table1}
81 | } {2}
82 | do_test delete-5.1.2 {
83 | execsql {SELECT count(*) FROM table1}
84 | } {0}
85 | do_test delete-5.2.1 {
86 | execsql {BEGIN TRANSACTION}
87 | for {set i 1} {$i<=200} {incr i} {
88 | execsql "INSERT INTO table1 VALUES($i,[expr {$i*$i}])"
89 | }
90 | execsql {COMMIT}
91 | execsql {SELECT count(*) FROM table1}
92 | } {200}
93 | do_test delete-5.2.2 {
94 | execsql {DELETE FROM table1}
95 | } {200}
96 | do_test delete-5.2.3 {
97 | execsql {BEGIN TRANSACTION}
98 | for {set i 1} {$i<=200} {incr i} {
99 | execsql "INSERT INTO table1 VALUES($i,[expr {$i*$i}])"
100 | }
101 | execsql {COMMIT}
102 | execsql {SELECT count(*) FROM table1}
103 | } {200}
104 | do_test delete-5.2.4 {
105 | execsql {PRAGMA count_changes=off}
106 | execsql {DELETE FROM table1}
107 | } {}
108 | do_test delete-5.2.5 {
109 | execsql {SELECT count(*) FROM table1}
110 | } {0}
111 | do_test delete-5.2.6 {
112 | execsql {BEGIN TRANSACTION}
113 | for {set i 1} {$i<=200} {incr i} {
114 | execsql "INSERT INTO table1 VALUES($i,[expr {$i*$i}])"
115 | }
116 | execsql {COMMIT}
117 | execsql {SELECT count(*) FROM table1}
118 | } {200}
119 | do_test delete-5.3 {
120 | for {set i 1} {$i<=200} {incr i 4} {
121 | execsql "DELETE FROM table1 WHERE f1==$i"
122 | }
123 | execsql {SELECT count(*) FROM table1}
124 | } {150}
125 | do_test delete-5.4 {
126 | execsql "DELETE FROM table1 WHERE f1>50"
127 | execsql {SELECT count(*) FROM table1}
128 | } {37}
129 | do_test delete-5.5 {
130 | for {set i 1} {$i<=70} {incr i 3} {
131 | execsql "DELETE FROM table1 WHERE f1==$i"
132 | }
133 | execsql {SELECT f1 FROM table1 ORDER BY f1}
134 | } {2 3 6 8 11 12 14 15 18 20 23 24 26 27 30 32 35 36 38 39 42 44 47 48 50}
135 | do_test delete-5.6 {
136 | for {set i 1} {$i<40} {incr i} {
137 | execsql "DELETE FROM table1 WHERE f1==$i"
138 | }
139 | execsql {SELECT f1 FROM table1 ORDER BY f1}
140 | } {42 44 47 48 50}
141 | do_test delete-5.7 {
142 | execsql "DELETE FROM table1 WHERE f1!=48"
143 | execsql {SELECT f1 FROM table1 ORDER BY f1}
144 | } {48}
145 |
146 | # Delete large quantities of data. We want to test the List overflow
147 | # mechanism in the vdbe.
148 | #
149 | do_test delete-6.1 {
150 | set fd [open data1.txt w]
151 | for {set i 1} {$i<=3000} {incr i} {
152 | puts $fd "[expr {$i}]\t[expr {$i*$i}]"
153 | }
154 | close $fd
155 | execsql {DELETE FROM table1}
156 | execsql {COPY table1 FROM 'data1.txt'}
157 | execsql {DELETE FROM table2}
158 | execsql {COPY table2 FROM 'data1.txt'}
159 | file delete data1.txt
160 | execsql {SELECT count(*) FROM table1}
161 | } {3000}
162 | do_test delete-6.2 {
163 | execsql {SELECT count(*) FROM table2}
164 | } {3000}
165 | do_test delete-6.3 {
166 | execsql {SELECT f1 FROM table1 WHERE f1<10 ORDER BY f1}
167 | } {1 2 3 4 5 6 7 8 9}
168 | do_test delete-6.4 {
169 | execsql {SELECT f1 FROM table2 WHERE f1<10 ORDER BY f1}
170 | } {1 2 3 4 5 6 7 8 9}
171 | do_test delete-6.5 {
172 | execsql {DELETE FROM table1 WHERE f1>7}
173 | execsql {SELECT f1 FROM table1 ORDER BY f1}
174 | } {1 2 3 4 5 6 7}
175 | do_test delete-6.6 {
176 | execsql {DELETE FROM table2 WHERE f1>7}
177 | execsql {SELECT f1 FROM table2 ORDER BY f1}
178 | } {1 2 3 4 5 6 7}
179 | do_test delete-6.7 {
180 | execsql {DELETE FROM table1}
181 | execsql {SELECT f1 FROM table1}
182 | } {}
183 | do_test delete-6.8 {
184 | execsql {INSERT INTO table1 VALUES(2,3)}
185 | execsql {SELECT f1 FROM table1}
186 | } {2}
187 | do_test delete-6.9 {
188 | execsql {DELETE FROM table2}
189 | execsql {SELECT f1 FROM table2}
190 | } {}
191 | do_test delete-6.10 {
192 | execsql {INSERT INTO table2 VALUES(2,3)}
193 | execsql {SELECT f1 FROM table2}
194 | } {2}
195 |
196 |
197 |
198 | finish_test
199 |
--------------------------------------------------------------------------------
/test/insert.test:
--------------------------------------------------------------------------------
1 | # 2001 September 15
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is testing the INSERT statement.
13 | #
14 | # $Id: insert.test,v 1.10 2002/04/12 13:11:53 drh Exp $
15 |
16 | set testdir [file dirname $argv0]
17 | source $testdir/tester.tcl
18 |
19 | # Try to insert into a non-existant table.
20 | #
21 | do_test insert-1.1 {
22 | set v [catch {execsql {INSERT INTO test1 VALUES(1,2,3)}} msg]
23 | lappend v $msg
24 | } {1 {no such table: test1}}
25 |
26 | # Try to insert into sqlite_master
27 | #
28 | do_test insert-1.2 {
29 | set v [catch {execsql {INSERT INTO sqlite_master VALUES(1,2,3,4)}} msg]
30 | lappend v $msg
31 | } {1 {table sqlite_master may not be modified}}
32 |
33 | # Try to insert the wrong number of entries.
34 | #
35 | do_test insert-1.3 {
36 | execsql {CREATE TABLE test1(one int, two int, three int)}
37 | set v [catch {execsql {INSERT INTO test1 VALUES(1,2)}} msg]
38 | lappend v $msg
39 | } {1 {table test1 has 3 columns but 2 values were supplied}}
40 | do_test insert-1.3b {
41 | set v [catch {execsql {INSERT INTO test1 VALUES(1,2,3,4)}} msg]
42 | lappend v $msg
43 | } {1 {table test1 has 3 columns but 4 values were supplied}}
44 | do_test insert-1.3c {
45 | set v [catch {execsql {INSERT INTO test1(one,two) VALUES(1,2,3,4)}} msg]
46 | lappend v $msg
47 | } {1 {4 values for 2 columns}}
48 | do_test insert-1.3d {
49 | set v [catch {execsql {INSERT INTO test1(one,two) VALUES(1)}} msg]
50 | lappend v $msg
51 | } {1 {1 values for 2 columns}}
52 |
53 | # Try to insert into a non-existant column of a table.
54 | #
55 | do_test insert-1.4 {
56 | set v [catch {execsql {INSERT INTO test1(one,four) VALUES(1,2)}} msg]
57 | lappend v $msg
58 | } {1 {table test1 has no column named four}}
59 |
60 | # Make sure the inserts actually happen
61 | #
62 | do_test insert-1.5 {
63 | execsql {INSERT INTO test1 VALUES(1,2,3)}
64 | execsql {SELECT * FROM test1}
65 | } {1 2 3}
66 | do_test insert-1.5b {
67 | execsql {INSERT INTO test1 VALUES(4,5,6)}
68 | execsql {SELECT * FROM test1 ORDER BY one}
69 | } {1 2 3 4 5 6}
70 | do_test insert-1.5c {
71 | execsql {INSERT INTO test1 VALUES(7,8,9)}
72 | execsql {SELECT * FROM test1 ORDER BY one}
73 | } {1 2 3 4 5 6 7 8 9}
74 |
75 | do_test insert-1.6 {
76 | execsql {DELETE FROM test1}
77 | execsql {INSERT INTO test1(one,two) VALUES(1,2)}
78 | execsql {SELECT * FROM test1 ORDER BY one}
79 | } {1 2 {}}
80 | do_test insert-1.6b {
81 | execsql {INSERT INTO test1(two,three) VALUES(5,6)}
82 | execsql {SELECT * FROM test1 ORDER BY one}
83 | } {{} 5 6 1 2 {}}
84 | do_test insert-1.6c {
85 | execsql {INSERT INTO test1(three,one) VALUES(7,8)}
86 | execsql {SELECT * FROM test1 ORDER BY one}
87 | } {{} 5 6 1 2 {} 8 {} 7}
88 |
89 | # A table to use for testing default values
90 | #
91 | do_test insert-2.1 {
92 | execsql {
93 | CREATE TABLE test2(
94 | f1 int default -111,
95 | f2 real default +4.32,
96 | f3 int default +222,
97 | f4 int default 7.89
98 | )
99 | }
100 | execsql {SELECT * from test2}
101 | } {}
102 | do_test insert-2.2 {
103 | execsql {INSERT INTO test2(f1,f3) VALUES(+10,-10)}
104 | execsql {SELECT * FROM test2}
105 | } {10 4.32 -10 7.89}
106 | do_test insert-2.3 {
107 | execsql {INSERT INTO test2(f2,f4) VALUES(1.23,-3.45)}
108 | execsql {SELECT * FROM test2 WHERE f1==-111}
109 | } {-111 1.23 222 -3.45}
110 | do_test insert-2.4 {
111 | execsql {INSERT INTO test2(f1,f2,f4) VALUES(77,+1.23,3.45)}
112 | execsql {SELECT * FROM test2 WHERE f1==77}
113 | } {77 1.23 222 3.45}
114 | do_test insert-2.10 {
115 | execsql {
116 | DROP TABLE test2;
117 | CREATE TABLE test2(
118 | f1 int default 111,
119 | f2 real default -4.32,
120 | f3 text default hi,
121 | f4 text default 'abc-123',
122 | f5 varchar(10)
123 | )
124 | }
125 | execsql {SELECT * from test2}
126 | } {}
127 | do_test insert-2.11 {
128 | execsql {INSERT INTO test2(f2,f4) VALUES(-2.22,'hi!')}
129 | execsql {SELECT * FROM test2}
130 | } {111 -2.22 hi hi! {}}
131 | do_test insert-2.12 {
132 | execsql {INSERT INTO test2(f1,f5) VALUES(1,'xyzzy')}
133 | execsql {SELECT * FROM test2 ORDER BY f1}
134 | } {1 -4.32 hi abc-123 xyzzy 111 -2.22 hi hi! {}}
135 |
136 | # Do additional inserts with default values, but this time
137 | # on a table that has indices. In particular we want to verify
138 | # that the correct default values are inserted into the indices.
139 | #
140 | do_test insert-3.1 {
141 | execsql {
142 | DELETE FROM test2;
143 | CREATE INDEX index9 ON test2(f1,f2);
144 | CREATE INDEX indext ON test2(f4,f5);
145 | SELECT * from test2;
146 | }
147 | } {}
148 | do_test insert-3.2 {
149 | execsql {INSERT INTO test2(f2,f4) VALUES(-3.33,'hum')}
150 | execsql {SELECT * FROM test2 WHERE f1=111 AND f2=-3.33}
151 | } {111 -3.33 hi hum {}}
152 | do_test insert-3.3 {
153 | execsql {INSERT INTO test2(f1,f2,f5) VALUES(22,-4.44,'wham')}
154 | execsql {SELECT * FROM test2 WHERE f1=111 AND f2=-3.33}
155 | } {111 -3.33 hi hum {}}
156 | do_test insert-3.4 {
157 | execsql {SELECT * FROM test2 WHERE f1=22 AND f2=-4.44}
158 | } {22 -4.44 hi abc-123 wham}
159 | do_test insert-3.5 {
160 | set x [execsql {PRAGMA integrity_check}]
161 | if {$x==""} {set x ok}
162 | set x
163 | } {ok}
164 |
165 | # Test of expressions in the VALUES clause
166 | #
167 | do_test insert-4.1 {
168 | execsql {
169 | CREATE TABLE t3(a,b,c);
170 | INSERT INTO t3 VALUES(1+2+3,4,5);
171 | SELECT * FROM t3;
172 | }
173 | } {6 4 5}
174 | do_test insert-4.2 {
175 | execsql {
176 | INSERT INTO t3 VALUES((SELECT max(a) FROM t3)+1,5,6);
177 | SELECT * FROM t3 ORDER BY a;
178 | }
179 | } {6 4 5 7 5 6}
180 | do_test insert-4.3 {
181 | catchsql {
182 | INSERT INTO t3 VALUES((SELECT max(a) FROM t3)+1,t3.a,6);
183 | SELECT * FROM t3 ORDER BY a;
184 | }
185 | } {1 {no such column: t3.a}}
186 | do_test insert-4.4 {
187 | execsql {
188 | INSERT INTO t3 VALUES((SELECT b FROM t3 WHERE a=0),6,7);
189 | SELECT * FROM t3 ORDER BY a;
190 | }
191 | } {{} 6 7 6 4 5 7 5 6}
192 | do_test insert-4.5 {
193 | execsql {
194 | SELECT b,c FROM t3 WHERE a IS NULL;
195 | }
196 | } {6 7}
197 | do_test insert-4.6 {
198 | catchsql {
199 | INSERT INTO t3 VALUES(notafunc(2,3),2,3);
200 | }
201 | } {1 {no such function: notafunc}}
202 | do_test insert-4.7 {
203 | execsql {
204 | INSERT INTO t3 VALUES(min(1,2,3),max(1,2,3),99);
205 | SELECT * FROM t3 WHERE c=99;
206 | }
207 | } {1 3 99}
208 |
209 | # Test
210 |
211 | finish_test
212 |
--------------------------------------------------------------------------------
/test/insert2.test:
--------------------------------------------------------------------------------
1 | # 2001 September 15
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is testing the INSERT statement that takes is
13 | # result from a SELECT.
14 | #
15 | # $Id: insert2.test,v 1.9 2002/04/12 10:09:00 drh Exp $
16 |
17 | set testdir [file dirname $argv0]
18 | source $testdir/tester.tcl
19 |
20 | # Create some tables with data that we can select against
21 | #
22 | do_test insert2-1.0 {
23 | execsql {CREATE TABLE d1(n int, log int);}
24 | for {set i 1} {$i<=20} {incr i} {
25 | for {set j 0} {pow(2,$j)<$i} {incr j} {}
26 | execsql "INSERT INTO d1 VALUES($i,$j)"
27 | }
28 | execsql {SELECT * FROM d1 ORDER BY n}
29 | } {1 0 2 1 3 2 4 2 5 3 6 3 7 3 8 3 9 4 10 4 11 4 12 4 13 4 14 4 15 4 16 4 17 5 18 5 19 5 20 5}
30 |
31 | # Insert into a new table from the old one.
32 | #
33 | do_test insert2-1.1.1 {
34 | execsql {
35 | CREATE TABLE t1(log int, cnt int);
36 | PRAGMA count_changes=on;
37 | INSERT INTO t1 SELECT log, count(*) FROM d1 GROUP BY log;
38 | }
39 | } {6}
40 | do_test insert2-1.1.2 {
41 | db changes
42 | } {6}
43 | do_test insert2-1.1.3 {
44 | execsql {SELECT * FROM t1 ORDER BY log}
45 | } {0 1 1 1 2 2 3 4 4 8 5 4}
46 |
47 | do_test insert2-1.2.1 {
48 | catch {execsql {DROP TABLE t1}}
49 | execsql {
50 | CREATE TABLE t1(log int, cnt int);
51 | INSERT INTO t1
52 | SELECT log, count(*) FROM d1 GROUP BY log
53 | EXCEPT SELECT n-1,log FROM d1;
54 | }
55 | } {4}
56 | do_test insert2-1.2.2 {
57 | execsql {
58 | SELECT * FROM t1 ORDER BY log;
59 | }
60 | } {0 1 3 4 4 8 5 4}
61 | do_test insert2-1.3.1 {
62 | catch {execsql {DROP TABLE t1}}
63 | execsql {
64 | CREATE TABLE t1(log int, cnt int);
65 | PRAGMA count_changes=off;
66 | INSERT INTO t1
67 | SELECT log, count(*) FROM d1 GROUP BY log
68 | INTERSECT SELECT n-1,log FROM d1;
69 | }
70 | } {}
71 | do_test insert2-1.3.2 {
72 | execsql {
73 | SELECT * FROM t1 ORDER BY log;
74 | }
75 | } {1 1 2 2}
76 | do_test insert2-1.4 {
77 | catch {execsql {DROP TABLE t1}}
78 | set r [execsql {
79 | CREATE TABLE t1(log int, cnt int);
80 | CREATE INDEX i1 ON t1(log);
81 | CREATE INDEX i2 ON t1(cnt);
82 | INSERT INTO t1 SELECT log, count() FROM d1 GROUP BY log;
83 | SELECT * FROM t1 ORDER BY log;
84 | }]
85 | lappend r [execsql {SELECT cnt FROM t1 WHERE log=3}]
86 | lappend r [execsql {SELECT log FROM t1 WHERE cnt=4 ORDER BY log}]
87 | } {0 1 1 1 2 2 3 4 4 8 5 4 4 {3 5}}
88 |
89 | do_test insert2-2.0 {
90 | execsql {
91 | CREATE TABLE t3(a,b,c);
92 | CREATE TABLE t4(x,y);
93 | INSERT INTO t4 VALUES(1,2);
94 | SELECT * FROM t4;
95 | }
96 | } {1 2}
97 | do_test insert2-2.1 {
98 | execsql {
99 | INSERT INTO t3(a,c) SELECT * FROM t4;
100 | SELECT * FROM t3;
101 | }
102 | } {1 {} 2}
103 | do_test insert2-2.2 {
104 | execsql {
105 | DELETE FROM t3;
106 | INSERT INTO t3(c,b) SELECT * FROM t4;
107 | SELECT * FROM t3;
108 | }
109 | } {{} 2 1}
110 | do_test insert2-2.3 {
111 | execsql {
112 | DELETE FROM t3;
113 | INSERT INTO t3(c,a,b) SELECT x, 'hi', y FROM t4;
114 | SELECT * FROM t3;
115 | }
116 | } {hi 2 1}
117 |
118 | do_test insert2-3.0 {
119 | set x [execsql {PRAGMA integrity_check}]
120 | if {$x==""} {set x ok}
121 | set x
122 | } {ok}
123 |
124 | # File table t4 with lots of data
125 | #
126 | do_test insert2-3.1 {
127 | execsql {
128 | SELECT * from t4;
129 | }
130 | } {1 2}
131 | do_test insert2-3.2 {
132 | execsql {
133 | BEGIN;
134 | INSERT INTO t4 VALUES(2,4);
135 | INSERT INTO t4 VALUES(3,6);
136 | INSERT INTO t4 VALUES(4,8);
137 | INSERT INTO t4 VALUES(5,10);
138 | INSERT INTO t4 VALUES(6,12);
139 | INSERT INTO t4 VALUES(7,14);
140 | INSERT INTO t4 VALUES(8,16);
141 | INSERT INTO t4 VALUES(9,18);
142 | INSERT INTO t4 VALUES(10,20);
143 | COMMIT;
144 | }
145 | db changes
146 | } {9}
147 | do_test insert2-3.2.1 {
148 | execsql {
149 | SELECT count(*) FROM t4;
150 | }
151 | } {10}
152 | do_test insert2-3.3 {
153 | execsql {
154 | BEGIN;
155 | INSERT INTO t4 SELECT x+(SELECT max(x) FROM t4),y FROM t4;
156 | INSERT INTO t4 SELECT x+(SELECT max(x) FROM t4),y FROM t4;
157 | INSERT INTO t4 SELECT x+(SELECT max(x) FROM t4),y FROM t4;
158 | INSERT INTO t4 SELECT x+(SELECT max(x) FROM t4),y FROM t4;
159 | COMMIT;
160 | SELECT count(*) FROM t4;
161 | }
162 | } {160}
163 | do_test insert2-3.4 {
164 | execsql {
165 | BEGIN;
166 | UPDATE t4 SET y='lots of data for the row where x=' || x
167 | || ' and y=' || y || ' - even more data to fill space';
168 | COMMIT;
169 | SELECT count(*) FROM t4;
170 | }
171 | } {160}
172 | do_test insert2-3.5 {
173 | execsql {
174 | BEGIN;
175 | INSERT INTO t4 SELECT x+(SELECT max(x)+1 FROM t4),y FROM t4;
176 | SELECT count(*) from t4;
177 | ROLLBACK;
178 | }
179 | } {320}
180 | do_test insert2-3.6 {
181 | execsql {
182 | SELECT count(*) FROM t4;
183 | }
184 | } {160}
185 | do_test insert2-3.7 {
186 | execsql {
187 | BEGIN;
188 | DELETE FROM t4 WHERE x!=123;
189 | SELECT count(*) FROM t4;
190 | ROLLBACK;
191 | }
192 | } {1}
193 | do_test insert2-3.8 {
194 | db changes
195 | } {159}
196 |
197 | finish_test
198 |
--------------------------------------------------------------------------------
/test/ioerr.test:
--------------------------------------------------------------------------------
1 | # 2001 October 12
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is testing for correct handling of I/O errors
13 | # such as writes failing because the disk is full.
14 | #
15 | # The tests in this file use special facilities that are only
16 | # available in the SQLite test fixture.
17 | #
18 | # $Id: ioerr.test,v 1.1 2001/10/12 17:30:05 drh Exp $
19 |
20 | set testdir [file dirname $argv0]
21 | source $testdir/tester.tcl
22 |
23 | set ::go 1
24 | for {set n 1} {$go} {incr n} {
25 | do_test ioerr-1.$n.1 {
26 | set ::sqlite_io_error_pending 0
27 | db close
28 | catch {file delete -force test.db}
29 | sqlite db test.db
30 | execsql {SELECT * FROM sqlite_master}
31 | } {}
32 | do_test ioerr-1.$n.2 [subst {
33 | set ::sqlite_io_error_pending $n
34 | }] $n
35 | do_test ioerr-1.$n.3 {
36 | set r [catch {db eval {
37 | CREATE TABLE t1(a,b,c);
38 | SELECT * FROM sqlite_master;
39 | BEGIN TRANSACTION;
40 | INSERT INTO t1 VALUES(1,2,3);
41 | INSERT INTO t1 VALUES(4,5,6);
42 | ROLLBACK;
43 | SELECT * FROM t1;
44 | BEGIN TRANSACTION;
45 | INSERT INTO t1 VALUES(1,2,3);
46 | INSERT INTO t1 VALUES(4,5,6);
47 | COMMIT;
48 | SELECT * FROM t1;
49 | DELETE FROM t1 WHERE a<100;
50 | }} msg]
51 | # if {$r} {puts $msg}
52 | set ::go [expr {$::sqlite_io_error_pending<=0}]
53 | expr {$::sqlite_io_error_pending>0 || $r!=0}
54 | } {1}
55 | }
56 | set ::sqlite_io_error_pending 0
57 |
58 |
59 | finish_test
60 |
--------------------------------------------------------------------------------
/test/join.test:
--------------------------------------------------------------------------------
1 | # 2002 May 24
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library.
12 | #
13 | # This file implements tests for joins, including outer joins.
14 | #
15 | # $Id: join.test,v 1.2 2002/05/25 00:18:21 drh Exp $
16 |
17 | set testdir [file dirname $argv0]
18 | source $testdir/tester.tcl
19 |
20 | do_test join-1.1 {
21 | execsql {
22 | CREATE TABLE t1(a,b,c);
23 | INSERT INTO t1 VALUES(1,2,3);
24 | INSERT INTO t1 VALUES(2,3,4);
25 | INSERT INTO t1 VALUES(3,4,5);
26 | SELECT * FROM t1;
27 | }
28 | } {1 2 3 2 3 4 3 4 5}
29 | do_test join-1.2 {
30 | execsql {
31 | CREATE TABLE t2(b,c,d);
32 | INSERT INTO t2 VALUES(1,2,3);
33 | INSERT INTO t2 VALUES(2,3,4);
34 | INSERT INTO t2 VALUES(3,4,5);
35 | SELECT * FROM t2;
36 | }
37 | } {1 2 3 2 3 4 3 4 5}
38 |
39 | do_test join-1.3 {
40 | execsql2 {
41 | SELECT * FROM t1 NATURAL JOIN t2;
42 | }
43 | } {t1.a 1 t1.b 2 t1.c 3 t2.d 4 t1.a 2 t1.b 3 t1.c 4 t2.d 5}
44 | do_test join-1.3.1 {
45 | execsql2 {
46 | SELECT * FROM t2 NATURAL JOIN t1;
47 | }
48 | } {t2.b 2 t2.c 3 t2.d 4 t1.a 1 t2.b 3 t2.c 4 t2.d 5 t1.a 2}
49 | do_test join-1.4 {
50 | execsql2 {
51 | SELECT * FROM t1 INNER JOIN t2 USING(b,c);
52 | }
53 | } {t1.a 1 t1.b 2 t1.c 3 t2.d 4 t1.a 2 t1.b 3 t1.c 4 t2.d 5}
54 | do_test join-1.5 {
55 | execsql2 {
56 | SELECT * FROM t1 INNER JOIN t2 USING(b);
57 | }
58 | } {t1.a 1 t1.b 2 t1.c 3 t2.c 3 t2.d 4 t1.a 2 t1.b 3 t1.c 4 t2.c 4 t2.d 5}
59 | do_test join-1.6 {
60 | execsql2 {
61 | SELECT * FROM t1 INNER JOIN t2 USING(c);
62 | }
63 | } {t1.a 1 t1.b 2 t1.c 3 t2.b 2 t2.d 4 t1.a 2 t1.b 3 t1.c 4 t2.b 3 t2.d 5}
64 | do_test join-1.7 {
65 | execsql2 {
66 | SELECT * FROM t1 INNER JOIN t2 USING(c,b);
67 | }
68 | } {t1.a 1 t1.b 2 t1.c 3 t2.d 4 t1.a 2 t1.b 3 t1.c 4 t2.d 5}
69 |
70 | do_test join-1.8 {
71 | execsql {
72 | SELECT * FROM t1 NATURAL CROSS JOIN t2;
73 | }
74 | } {1 2 3 4 2 3 4 5}
75 | do_test join-1.9 {
76 | execsql {
77 | SELECT * FROM t1 CROSS JOIN t2 USING(b,c);
78 | }
79 | } {1 2 3 4 2 3 4 5}
80 | do_test join-1.10 {
81 | execsql {
82 | SELECT * FROM t1 NATURAL INNER JOIN t2;
83 | }
84 | } {1 2 3 4 2 3 4 5}
85 | do_test join-1.11 {
86 | execsql {
87 | SELECT * FROM t1 INNER JOIN t2 USING(b,c);
88 | }
89 | } {1 2 3 4 2 3 4 5}
90 | do_test join-1.12 {
91 | execsql {
92 | SELECT * FROM t1 natural inner join t2;
93 | }
94 | } {1 2 3 4 2 3 4 5}
95 | do_test join-1.13 {
96 | execsql2 {
97 | SELECT * FROM t1 NATURAL JOIN
98 | (SELECT b as 'c', c as 'd', d as 'e' FROM t2) as t3
99 | }
100 | } {t1.a 1 t1.b 2 t1.c 3 t3.d 4 t3.e 5}
101 | do_test join-1.14 {
102 | execsql2 {
103 | SELECT * FROM (SELECT b as 'c', c as 'd', d as 'e' FROM t2) as 'tx'
104 | NATURAL JOIN t1
105 | }
106 | } {tx.c 3 tx.d 4 tx.e 5 t1.a 1 t1.b 2}
107 |
108 | do_test join-1.15 {
109 | execsql {
110 | CREATE TABLE t3(c,d,e);
111 | INSERT INTO t3 VALUES(2,3,4);
112 | INSERT INTO t3 VALUES(3,4,5);
113 | INSERT INTO t3 VALUES(4,5,6);
114 | SELECT * FROM t3;
115 | }
116 | } {2 3 4 3 4 5 4 5 6}
117 | do_test join-1.16 {
118 | execsql {
119 | SELECT * FROM t1 natural join t2 natural join t3;
120 | }
121 | } {1 2 3 4 5 2 3 4 5 6}
122 | do_test join-1.17 {
123 | execsql2 {
124 | SELECT * FROM t1 natural join t2 natural join t3;
125 | }
126 | } {t1.a 1 t1.b 2 t1.c 3 t2.d 4 t3.e 5 t1.a 2 t1.b 3 t1.c 4 t2.d 5 t3.e 6}
127 | do_test join-1.18 {
128 | execsql {
129 | CREATE TABLE t4(d,e,f);
130 | INSERT INTO t4 VALUES(2,3,4);
131 | INSERT INTO t4 VALUES(3,4,5);
132 | INSERT INTO t4 VALUES(4,5,6);
133 | SELECT * FROM t4;
134 | }
135 | } {2 3 4 3 4 5 4 5 6}
136 | do_test join-1.19 {
137 | execsql {
138 | SELECT * FROM t1 natural join t2 natural join t4;
139 | }
140 | } {1 2 3 4 5 6}
141 | do_test join-1.19 {
142 | execsql2 {
143 | SELECT * FROM t1 natural join t2 natural join t4;
144 | }
145 | } {t1.a 1 t1.b 2 t1.c 3 t2.d 4 t4.e 5 t4.f 6}
146 | do_test join-1.20 {
147 | execsql {
148 | SELECT * FROM t1 natural join t2 natural join t3 WHERE t1.a=1
149 | }
150 | } {1 2 3 4 5}
151 |
152 | do_test join-2.1 {
153 | execsql {
154 | SELECT * FROM t1 NATURAL LEFT JOIN t2;
155 | }
156 | } {1 2 3 4 2 3 4 5 3 4 5 {}}
157 | do_test join-2.2 {
158 | execsql {
159 | SELECT * FROM t2 NATURAL LEFT OUTER JOIN t1;
160 | }
161 | } {1 2 3 {} 2 3 4 1 3 4 5 2}
162 | do_test join-2.3 {
163 | catchsql {
164 | SELECT * FROM t1 NATURAL RIGHT OUTER JOIN t2;
165 | }
166 | } {1 {RIGHT and FULL OUTER JOINs are not currently supported}}
167 |
168 | do_test join-3.1 {
169 | catchsql {
170 | SELECT * FROM t1 NATURAL JOIN t2 ON t1.a=t2.b;
171 | }
172 | } {1 {a NATURAL join may not have an ON or USING clause}}
173 | do_test join-3.2 {
174 | catchsql {
175 | SELECT * FROM t1 NATURAL JOIN t2 USING(b);
176 | }
177 | } {1 {a NATURAL join may not have an ON or USING clause}}
178 | do_test join-3.3 {
179 | catchsql {
180 | SELECT * FROM t1 JOIN t2 ON t1.a=t2.b USING(b);
181 | }
182 | } {1 {cannot have both ON and USING clauses in the same join}}
183 | do_test join-3.4 {
184 | catchsql {
185 | SELECT * FROM t1 JOIN t2 USING(a);
186 | }
187 | } {1 {cannot join using column a - column not present in both tables}}
188 | do_test join-3.5 {
189 | catchsql {
190 | SELECT * FROM t1 USING(a);
191 | }
192 | } {0 {1 2 3 2 3 4 3 4 5}}
193 | do_test join-3.6 {
194 | catchsql {
195 | SELECT * FROM t1 JOIN t2 ON t3.a=t2.b;
196 | }
197 | } {1 {no such column: t3.a}}
198 | do_test join-3.7 {
199 | catchsql {
200 | SELECT * FROM t1 INNER OUTER JOIN t2;
201 | }
202 | } {1 {unknown or unsupported join type: INNER OUTER}}
203 | do_test join-3.7 {
204 | catchsql {
205 | SELECT * FROM t1 BOGUS JOIN t2;
206 | }
207 | } {1 {unknown or unsupported join type: BOGUS}}
208 |
209 |
210 | finish_test
211 |
--------------------------------------------------------------------------------
/test/limit.test:
--------------------------------------------------------------------------------
1 | # 2001 November 6
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is testing the LIMIT ... OFFSET ... clause
13 | # of SELECT statements.
14 | #
15 | # $Id: limit.test,v 1.3 2002/06/14 22:38:43 drh Exp $
16 |
17 | set testdir [file dirname $argv0]
18 | source $testdir/tester.tcl
19 |
20 | # Build some test data
21 | #
22 | set fd [open data1.txt w]
23 | for {set i 1} {$i<=32} {incr i} {
24 | for {set j 0} {pow(2,$j)<$i} {incr j} {}
25 | puts $fd "[expr {32-$i}]\t[expr {10-$j}]"
26 | }
27 | close $fd
28 | execsql {
29 | CREATE TABLE t1(x int, y int);
30 | COPY t1 FROM 'data1.txt'
31 | }
32 | file delete data1.txt
33 |
34 | do_test limit-1.0 {
35 | execsql {SELECT count(*) FROM t1}
36 | } {32}
37 | do_test limit-1.1 {
38 | execsql {SELECT count(*) FROM t1 LIMIT 5}
39 | } {32}
40 | do_test limit-1.2 {
41 | execsql {SELECT x FROM t1 ORDER BY x LIMIT 5}
42 | } {0 1 2 3 4}
43 | do_test limit-1.3 {
44 | execsql {SELECT x FROM t1 ORDER BY x LIMIT 5 OFFSET 5}
45 | } {5 6 7 8 9}
46 | do_test limit-1.4 {
47 | execsql {SELECT x FROM t1 ORDER BY x LIMIT 50 OFFSET 30}
48 | } {30 31}
49 | do_test limit-1.5 {
50 | execsql {SELECT x FROM t1 ORDER BY x LIMIT 50 OFFSET 50}
51 | } {}
52 | do_test limit-1.6 {
53 | execsql {SELECT * FROM t1 AS a, t1 AS b ORDER BY a.x, b.x LIMIT 5}
54 | } {0 5 0 5 0 5 1 5 0 5 2 5 0 5 3 5 0 5 4 5}
55 | do_test limit-1.7 {
56 | execsql {SELECT * FROM t1 AS a, t1 AS b ORDER BY a.x, b.x LIMIT 5 OFFSET 32}
57 | } {1 5 0 5 1 5 1 5 1 5 2 5 1 5 3 5 1 5 4 5}
58 |
59 | do_test limit-2.1 {
60 | execsql {
61 | CREATE VIEW v1 AS SELECT * FROM t1 LIMIT 2;
62 | SELECT count(*) FROM (SELECT * FROM v1);
63 | }
64 | } 2
65 | do_test limit-2.2 {
66 | execsql {
67 | CREATE TABLE t2 AS SELECT * FROM t1 LIMIT 2;
68 | SELECT count(*) FROM t2;
69 | }
70 | } 2
71 | do_test limit-2.3 {
72 | execsql {
73 | SELECT count(*) FROM t1 WHERE rowid IN (SELECT rowid FROM t1 LIMIT 2);
74 | }
75 | } 2
76 |
77 |
78 | finish_test
79 |
--------------------------------------------------------------------------------
/test/main.test:
--------------------------------------------------------------------------------
1 | # 2001 September 15
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is exercising the code in main.c.
13 | #
14 | # $Id: main.test,v 1.11 2002/05/15 14:17:45 drh Exp $
15 |
16 | set testdir [file dirname $argv0]
17 | source $testdir/tester.tcl
18 |
19 | # Tests of the sqlite_complete() function.
20 | #
21 | do_test main-1.1 {
22 | db complete {This is a test}
23 | } {0}
24 | do_test main-1.2 {
25 | db complete {
26 | }
27 | } {0}
28 | do_test main-1.3 {
29 | db complete {
30 | -- a comment ;
31 | }
32 | } {0}
33 | do_test main-1.4 {
34 | db complete {
35 | -- a comment ;
36 | ;
37 | }
38 | } {1}
39 | do_test main-1.5 {
40 | db complete {DROP TABLE 'xyz;}
41 | } {0}
42 | do_test main-1.6 {
43 | db complete {DROP TABLE 'xyz';}
44 | } {1}
45 | do_test main-1.7 {
46 | db complete {DROP TABLE "xyz;}
47 | } {0}
48 | do_test main-1.8 {
49 | db complete {DROP TABLE "xyz';}
50 | } {0}
51 | do_test main-1.9 {
52 | db complete {DROP TABLE "xyz";}
53 | } {1}
54 | do_test main-1.10 {
55 | db complete {DROP TABLE xyz; hi}
56 | } {0}
57 | do_test main-1.11 {
58 | db complete {DROP TABLE xyz; }
59 | } {1}
60 | do_test main-1.12 {
61 | db complete {DROP TABLE xyz; -- hi }
62 | } {1}
63 | do_test main-1.13 {
64 | db complete {DROP TABLE xyz; -- hi
65 | }
66 | } {1}
67 | do_test main-1.14 {
68 | db complete {SELECT a-b FROM t1; }
69 | } {1}
70 | do_test main-1.15 {
71 | db complete {SELECT a-b FROM t1 }
72 | } {0}
73 | do_test main-1.16 {
74 | db complete {
75 | CREATE TABLE abc(x,y);
76 | }
77 | } {1}
78 | do_test main-1.17 {
79 | db complete {
80 | CREATE TRIGGER xyz AFTER DELETE abc BEGIN UPDATE pqr;
81 | }
82 | } {0}
83 | do_test main-1.18 {
84 | db complete {
85 | CREATE TRIGGER xyz AFTER DELETE abc BEGIN UPDATE pqr; END;
86 | }
87 | } {1}
88 | do_test main-1.19 {
89 | db complete {
90 | CREATE TRIGGER xyz AFTER DELETE abc BEGIN
91 | UPDATE pqr;
92 | unknown command;
93 | }
94 | } {0}
95 | do_test main-1.20 {
96 | db complete {
97 | CREATE TRIGGER xyz AFTER DELETE backend BEGIN
98 | UPDATE pqr;
99 | }
100 | } {0}
101 | do_test main-1.21 {
102 | db complete {
103 | CREATE TRIGGER xyz AFTER DELETE end BEGIN
104 | SELECT a, b FROM end;
105 | }
106 | } {0}
107 | do_test main-1.22 {
108 | db complete {
109 | CREATE TRIGGER xyz AFTER DELETE end BEGIN
110 | SELECT a, b FROM end;
111 | END;
112 | }
113 | } {1}
114 | do_test main-1.23 {
115 | db complete {
116 | CREATE TRIGGER xyz AFTER DELETE end BEGIN
117 | SELECT a, b FROM end;
118 | END;
119 | SELECT a, b FROM end;
120 | }
121 | } {1}
122 | do_test main-1.24 {
123 | db complete {
124 | CREATE TRIGGER xyz AFTER DELETE [;end;] BEGIN
125 | UPDATE pqr;
126 | }
127 | } {0}
128 | do_test main-1.25 {
129 | db complete {
130 | CREATE TRIGGER xyz AFTER DELETE backend BEGIN
131 | UPDATE pqr SET a=[;end;];;;
132 | }
133 | } {0}
134 | do_test main-1.26 {
135 | db complete {
136 | CREATE -- a comment
137 | TRIGGER xyz AFTER DELETE backend BEGIN
138 | UPDATE pqr SET a=5;
139 | }
140 | } {0}
141 | do_test main-1.27 {
142 | db complete {
143 | CREATE -- a comment
144 | TRIGGERX xyz AFTER DELETE backend BEGIN
145 | UPDATE pqr SET a=5;
146 | }
147 | } {1}
148 | do_test main-1.28 {
149 | db complete {
150 | CREATE TEMP TRIGGER xyz AFTER DELETE backend BEGIN
151 | UPDATE pqr SET a=5;
152 | }
153 | } {1}
154 | do_test main-1.29 {
155 | db complete {
156 | CREATE TRIGGER xyz AFTER DELETE backend BEGIN
157 | UPDATE pqr SET a=5;
158 | EXPLAIN select * from xyz;
159 | }
160 | } {0}
161 |
162 |
163 | # Try to open a database with a corrupt database file.
164 | #
165 | do_test main-2.0 {
166 | catch {db close}
167 | file delete -force test.db
168 | set fd [open test.db w]
169 | puts $fd hi!
170 | close $fd
171 | set v [catch {sqlite db test.db} msg]
172 | if {$v} {lappend v $msg} {lappend v {}}
173 | } {0 {}}
174 |
175 | # Here are some tests for tokenize.c.
176 | #
177 | do_test main-3.1 {
178 | catch {db close}
179 | foreach f [glob -nocomplain testdb/*] {file delete -force $f}
180 | file delete -force testdb
181 | sqlite db testdb
182 | set v [catch {execsql {SELECT * from T1 where x!!5}} msg]
183 | lappend v $msg
184 | } {1 {unrecognized token: "!!"}}
185 | do_test main-3.2 {
186 | catch {db close}
187 | foreach f [glob -nocomplain testdb/*] {file delete -force $f}
188 | file delete -force testdb
189 | sqlite db testdb
190 | set v [catch {execsql {SELECT * from T1 where @x}} msg]
191 | lappend v $msg
192 | } {1 {unrecognized token: "@"}}
193 |
194 | do_test main-3.3 {
195 | catch {db close}
196 | foreach f [glob -nocomplain testdb/*] {file delete -force $f}
197 | file delete -force testdb
198 | sqlite db testdb
199 | execsql {
200 | create table T1(X REAL);
201 | insert into T1 values(.5);
202 | insert into T1 values(0.5e2);
203 | insert into T1 values(0.5e-002);
204 | insert into T1 values(5e-002);
205 | insert into T1 values(-5.0e-2);
206 | insert into T1 values(-5.1e-2);
207 | insert into T1 values(.5e2);
208 | insert into T1 values(.5E+02);
209 | insert into T1 values(5E+02);
210 | insert into T1 values(5.E+03);
211 | select x*10 from T1 order by x*5;
212 | }
213 | } {-0.51 -0.5 0.05 0.5 5 500 500 500 5000 50000}
214 | do_test main-3.4 {
215 | set v [catch {execsql {create bogus}} msg]
216 | lappend v $msg
217 | } {1 {near "bogus": syntax error}}
218 | do_test main-3.5 {
219 | set v [catch {execsql {create}} msg]
220 | lappend v $msg
221 | } {1 {near "create": syntax error}}
222 |
223 | finish_test
224 |
--------------------------------------------------------------------------------
/test/minmax.test:
--------------------------------------------------------------------------------
1 | # 2001 September 15
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is testing SELECT statements that contain
13 | # aggregate min() and max() functions and which are handled as
14 | # as a special case.
15 | #
16 | # $Id: minmax.test,v 1.4 2002/05/31 15:51:26 drh Exp $
17 |
18 | set testdir [file dirname $argv0]
19 | source $testdir/tester.tcl
20 |
21 | do_test minmax-1.0 {
22 | execsql {
23 | BEGIN;
24 | CREATE TABLE t1(x, y);
25 | INSERT INTO t1 VALUES(1,1);
26 | INSERT INTO t1 VALUES(2,2);
27 | INSERT INTO t1 VALUES(3,2);
28 | INSERT INTO t1 VALUES(4,3);
29 | INSERT INTO t1 VALUES(5,3);
30 | INSERT INTO t1 VALUES(6,3);
31 | INSERT INTO t1 VALUES(7,3);
32 | INSERT INTO t1 VALUES(8,4);
33 | INSERT INTO t1 VALUES(9,4);
34 | INSERT INTO t1 VALUES(10,4);
35 | INSERT INTO t1 VALUES(11,4);
36 | INSERT INTO t1 VALUES(12,4);
37 | INSERT INTO t1 VALUES(13,4);
38 | INSERT INTO t1 VALUES(14,4);
39 | INSERT INTO t1 VALUES(15,4);
40 | INSERT INTO t1 VALUES(16,5);
41 | INSERT INTO t1 VALUES(17,5);
42 | INSERT INTO t1 VALUES(18,5);
43 | INSERT INTO t1 VALUES(19,5);
44 | INSERT INTO t1 VALUES(20,5);
45 | COMMIT;
46 | SELECT DISTINCT y FROM t1 ORDER BY y;
47 | }
48 | } {1 2 3 4 5}
49 |
50 | do_test minmax-1.1 {
51 | set sqlite_search_count 0
52 | execsql {SELECT min(x) FROM t1}
53 | } {1}
54 | do_test minmax-1.2 {
55 | set sqlite_search_count
56 | } {19}
57 | do_test minmax-1.3 {
58 | set sqlite_search_count 0
59 | execsql {SELECT max(x) FROM t1}
60 | } {20}
61 | do_test minmax-1.4 {
62 | set sqlite_search_count
63 | } {19}
64 | do_test minmax-1.5 {
65 | execsql {CREATE INDEX t1i1 ON t1(x)}
66 | set sqlite_search_count 0
67 | execsql {SELECT min(x) FROM t1}
68 | } {1}
69 | do_test minmax-1.6 {
70 | set sqlite_search_count
71 | } {1}
72 | do_test minmax-1.7 {
73 | set sqlite_search_count 0
74 | execsql {SELECT max(x) FROM t1}
75 | } {20}
76 | do_test minmax-1.8 {
77 | set sqlite_search_count
78 | } {1}
79 | do_test minmax-1.9 {
80 | set sqlite_search_count 0
81 | execsql {SELECT max(y) FROM t1}
82 | } {5}
83 | do_test minmax-1.10 {
84 | set sqlite_search_count
85 | } {19}
86 |
87 | do_test minmax-2.0 {
88 | execsql {
89 | CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
90 | INSERT INTO t2 SELECT * FROM t1;
91 | }
92 | set sqlite_search_count 0
93 | execsql {SELECT min(a) FROM t2}
94 | } {1}
95 | do_test minmax-2.1 {
96 | set sqlite_search_count
97 | } {0}
98 | do_test minmax-2.2 {
99 | set sqlite_search_count 0
100 | execsql {SELECT max(a) FROM t2}
101 | } {20}
102 | do_test minmax-2.3 {
103 | set sqlite_search_count
104 | } {0}
105 |
106 | do_test minmax-3.0 {
107 | execsql {INSERT INTO t2 VALUES((SELECT max(a) FROM t2)+1,999)}
108 | set sqlite_search_count 0
109 | execsql {SELECT max(a) FROM t2}
110 | } {21}
111 | do_test minmax-3.1 {
112 | set sqlite_search_count
113 | } {0}
114 | do_test minmax-3.2 {
115 | execsql {INSERT INTO t2 VALUES((SELECT max(a) FROM t2)+1,999)}
116 | set sqlite_search_count 0
117 | execsql {
118 | SELECT b FROM t2 WHERE a=(SELECT max(a) FROM t2)
119 | }
120 | } {999}
121 | do_test minmax-3.3 {
122 | set sqlite_search_count
123 | } {0}
124 |
125 | do_test minmax-4.1 {
126 | execsql {
127 | SELECT coalesce(min(x),-1), coalesce(max(x),-1) FROM
128 | (SELECT * FROM t1 UNION SELECT NULL as 'x', NULL as 'y')
129 | }
130 | } {1 20}
131 | do_test minmax-4.2 {
132 | execsql {
133 | SELECT y, sum(x) FROM
134 | (SELECT null, y+1 FROM t1 UNION SELECT * FROM t1)
135 | GROUP BY y ORDER BY y;
136 | }
137 | } {1 1 2 5 3 22 4 92 5 90 6 0}
138 | do_test minmax-4.3 {
139 | execsql {
140 | SELECT y, count(x), count(*) FROM
141 | (SELECT null, y+1 FROM t1 UNION SELECT * FROM t1)
142 | GROUP BY y ORDER BY y;
143 | }
144 | } {1 1 1 2 2 3 3 4 5 4 8 9 5 5 6 6 0 1}
145 |
146 | finish_test
147 |
--------------------------------------------------------------------------------
/test/misuse.test:
--------------------------------------------------------------------------------
1 | # 2002 May 10
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library.
12 | #
13 | # This file implements tests for the SQLITE_MISUSE detection logic.
14 | # This test file leaks memory and file descriptors.
15 | #
16 | # $Id: misuse.test,v 1.3 2002/05/21 11:38:12 drh Exp $
17 |
18 | set testdir [file dirname $argv0]
19 | source $testdir/tester.tcl
20 |
21 | # Make sure the test logic works
22 | #
23 | do_test misuse-1.1 {
24 | db close
25 | catch {file delete -force test2.db}
26 | set ::DB [sqlite db test2.db]
27 | execsql {
28 | CREATE TABLE t1(a,b);
29 | INSERT INTO t1 VALUES(1,2);
30 | }
31 | sqlite_exec_printf $::DB {SELECT * FROM t1} {}
32 | } {0 {a b 1 2}}
33 | do_test misuse-1.2 {
34 | sqlite_exec_printf $::DB {SELECT x_coalesce(NULL,a) AS 'xyz' FROM t1} {}
35 | } {1 {no such function: x_coalesce}}
36 | do_test misuse-1.3 {
37 | sqlite_create_function $::DB
38 | sqlite_exec_printf $::DB {SELECT x_coalesce(NULL,a) AS 'xyz' FROM t1} {}
39 | } {0 {xyz 1}}
40 |
41 | # Use the x_sqlite_exec() SQL function to simulate the effect of two
42 | # threads trying to use the same database at the same time.
43 | #
44 | do_test misuse-1.4 {
45 | sqlite_exec_printf $::DB {
46 | SELECT x_sqlite_exec('SELECT * FROM t1');
47 | } {}
48 | } {21 {library routine called out of sequence}}
49 | do_test misuse-1.5 {
50 | sqlite_exec_printf $::DB {SELECT * FROM t1} {}
51 | } {21 {library routine called out of sequence}}
52 | do_test misuse-1.6 {
53 | catchsql {
54 | SELECT * FROM t1
55 | }
56 | } {1 {library routine called out of sequence}}
57 |
58 | # Attempt to register a new SQL function while an sqlite_exec() is active.
59 | #
60 | do_test misuse-2.1 {
61 | db close
62 | set ::DB [sqlite db test2.db]
63 | execsql {
64 | SELECT * FROM t1
65 | }
66 | } {1 2}
67 | do_test misuse-2.2 {
68 | sqlite_exec_printf $::DB {SELECT * FROM t1} {}
69 | } {0 {a b 1 2}}
70 | do_test misuse-2.3 {
71 | set v [catch {
72 | db eval {SELECT * FROM t1} {} {
73 | sqlite_create_function $::DB
74 | }
75 | } msg]
76 | lappend v $msg
77 | } {1 {library routine called out of sequence}}
78 | do_test misuse-2.4 {
79 | sqlite_exec_printf $::DB {SELECT * FROM t1} {}
80 | } {21 {library routine called out of sequence}}
81 | do_test misuse-2.5 {
82 | catchsql {
83 | SELECT * FROM t1
84 | }
85 | } {1 {library routine called out of sequence}}
86 |
87 | # Attempt to register a new SQL aggregate while an sqlite_exec() is active.
88 | #
89 | do_test misuse-3.1 {
90 | db close
91 | set ::DB [sqlite db test2.db]
92 | execsql {
93 | SELECT * FROM t1
94 | }
95 | } {1 2}
96 | do_test misuse-3.2 {
97 | sqlite_exec_printf $::DB {SELECT * FROM t1} {}
98 | } {0 {a b 1 2}}
99 | do_test misuse-3.3 {
100 | set v [catch {
101 | db eval {SELECT * FROM t1} {} {
102 | sqlite_create_aggregate $::DB
103 | }
104 | } msg]
105 | lappend v $msg
106 | } {1 {library routine called out of sequence}}
107 | do_test misuse-3.4 {
108 | sqlite_exec_printf $::DB {SELECT * FROM t1} {}
109 | } {21 {library routine called out of sequence}}
110 | do_test misuse-3.5 {
111 | catchsql {
112 | SELECT * FROM t1
113 | }
114 | } {1 {library routine called out of sequence}}
115 |
116 | # Attempt to close the database from an sqlite_exec callback.
117 | #
118 | do_test misuse-4.1 {
119 | db close
120 | set ::DB [sqlite db test2.db]
121 | execsql {
122 | SELECT * FROM t1
123 | }
124 | } {1 2}
125 | do_test misuse-4.2 {
126 | sqlite_exec_printf $::DB {SELECT * FROM t1} {}
127 | } {0 {a b 1 2}}
128 | do_test misuse-4.3 {
129 | set v [catch {
130 | db eval {SELECT * FROM t1} {} {
131 | sqlite_close $::DB
132 | }
133 | } msg]
134 | lappend v $msg
135 | } {1 {library routine called out of sequence}}
136 | do_test misuse-4.4 {
137 | sqlite_exec_printf $::DB {SELECT * FROM t1} {}
138 | } {21 {library routine called out of sequence}}
139 | do_test misuse-4.5 {
140 | catchsql {
141 | SELECT * FROM t1
142 | }
143 | } {1 {library routine called out of sequence}}
144 |
145 | # Attempt to use a database after it has been closed.
146 | #
147 | do_test misuse-5.1 {
148 | db close
149 | set ::DB [sqlite db test2.db]
150 | execsql {
151 | SELECT * FROM t1
152 | }
153 | } {1 2}
154 | do_test misuse-5.2 {
155 | sqlite_exec_printf $::DB {SELECT * FROM t1} {}
156 | } {0 {a b 1 2}}
157 | do_test misuse-5.3 {
158 | db close
159 | sqlite_exec_printf $::DB {SELECT * FROM t1} {}
160 | } {21 {library routine called out of sequence}}
161 |
162 | finish_test
163 |
--------------------------------------------------------------------------------
/test/null.test:
--------------------------------------------------------------------------------
1 | # 2001 September 15
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library.
12 | #
13 | # This file implements tests for proper treatment of the special
14 | # value NULL.
15 | #
16 |
17 | set testdir [file dirname $argv0]
18 | source $testdir/tester.tcl
19 |
20 | # Create a table and some data to work with.
21 | #
22 | do_test null-1.0 {
23 | execsql {
24 | begin;
25 | create table t1(a,b,c);
26 | insert into t1 values(1,0,0);
27 | insert into t1 values(2,0,1);
28 | insert into t1 values(3,1,0);
29 | insert into t1 values(4,1,1);
30 | insert into t1 values(5,null,0);
31 | insert into t1 values(6,null,1);
32 | insert into t1 values(7,null,null);
33 | commit;
34 | select * from t1;
35 | }
36 | } {1 0 0 2 0 1 3 1 0 4 1 1 5 {} 0 6 {} 1 7 {} {}}
37 |
38 | # Check for how arithmetic expressions handle NULL
39 | #
40 | do_test null-1.1 {
41 | execsql {
42 | select ifnull(a+b,99) from t1;
43 | }
44 | } {1 2 4 5 99 99 99}
45 | do_test null-1.2 {
46 | execsql {
47 | select ifnull(b*c,99) from t1;
48 | }
49 | } {0 0 0 1 99 99 99}
50 |
51 | # Check to see how the CASE expression handles NULL values. The
52 | # first WHEN for which the test expression is TRUE is selected.
53 | # FALSE and UNKNOWN test expressions are skipped.
54 | #
55 | do_test null-2.1 {
56 | execsql {
57 | select ifnull(case when b<>0 then 1 else 0 end, 99) from t1;
58 | }
59 | } {0 0 1 1 0 0 0}
60 | do_test null-2.2 {
61 | execsql {
62 | select ifnull(case when not b<>0 then 1 else 0 end, 99) from t1;
63 | }
64 | } {1 1 0 0 0 0 0}
65 | do_test null-2.3 {
66 | execsql {
67 | select ifnull(case when b<>0 and c<>0 then 1 else 0 end, 99) from t1;
68 | }
69 | } {0 0 0 1 0 0 0}
70 | do_test null-2.4 {
71 | execsql {
72 | select ifnull(case when not (b<>0 and c<>0) then 1 else 0 end, 99) from t1;
73 | }
74 | } {1 1 1 0 1 0 0}
75 | do_test null-2.5 {
76 | execsql {
77 | select ifnull(case when b<>0 or c<>0 then 1 else 0 end, 99) from t1;
78 | }
79 | } {0 1 1 1 0 1 0}
80 | do_test null-2.6 {
81 | execsql {
82 | select ifnull(case when not (b<>0 or c<>0) then 1 else 0 end, 99) from t1;
83 | }
84 | } {1 0 0 0 0 0 0}
85 | do_test null-2.7 {
86 | execsql {
87 | select ifnull(case b when c then 1 else 0 end, 99) from t1;
88 | }
89 | } {1 0 0 1 0 0 0}
90 | do_test null-2.8 {
91 | execsql {
92 | select ifnull(case c when b then 1 else 0 end, 99) from t1;
93 | }
94 | } {1 0 0 1 0 0 0}
95 |
96 | # Check to see that NULL values are ignored in aggregate functions.
97 | #
98 | do_test null-3.1 {
99 | execsql {
100 | select count(*), count(b), count(c), sum(b), sum(c),
101 | avg(b), avg(c), min(b), max(b) from t1;
102 | }
103 | } {7 4 6 2 3 0.5 0.5 0 1}
104 |
105 | # Check to see how WHERE clauses handle NULL values. A NULL value
106 | # is the same as UNKNOWN. The WHERE clause should only select those
107 | # rows that are TRUE. FALSE and UNKNOWN rows are rejected.
108 | #
109 | do_test null-4.1 {
110 | execsql {
111 | select a from t1 where b<10
112 | }
113 | } {1 2 3 4}
114 | do_test null-4.2 {
115 | execsql {
116 | select a from t1 where not b>10
117 | }
118 | } {1 2 3 4}
119 | do_test null-4.3 {
120 | execsql {
121 | select a from t1 where b<10 or c=1;
122 | }
123 | } {1 2 3 4 6}
124 | do_test null-4.4 {
125 | execsql {
126 | select a from t1 where b<10 and c=1;
127 | }
128 | } {2 4}
129 | do_test null-4.5 {
130 | execsql {
131 | select a from t1 where not (b<10 and c=1);
132 | }
133 | } {1 3 5}
134 |
135 | # The DISTINCT keyword on a SELECT statement should treat NULL values
136 | # as distinct
137 | #
138 | do_test null-5.1 {
139 | execsql {
140 | select distinct b from t1 order by b;
141 | }
142 | } {{} 0 1}
143 |
144 | # A UNION to two queries should treat NULL values
145 | # as distinct
146 | #
147 | do_test null-6.1 {
148 | execsql {
149 | select b from t1 union select c from t1 order by c;
150 | }
151 | } {{} 0 1}
152 |
153 | # The UNIQUE constraint only applies to non-null values
154 | #
155 | do_test null-7.1 {
156 | execsql {
157 | create table t2(a, b unique on conflict ignore);
158 | insert into t2 values(1,1);
159 | insert into t2 values(2,null);
160 | insert into t2 values(3,null);
161 | insert into t2 values(4,1);
162 | select a from t2;
163 | }
164 | } {1 2 3}
165 | do_test null-7.2 {
166 | execsql {
167 | create table t3(a, b, c, unique(b,c) on conflict ignore);
168 | insert into t3 values(1,1,1);
169 | insert into t3 values(2,null,1);
170 | insert into t3 values(3,null,1);
171 | insert into t3 values(4,1,1);
172 | select a from t3;
173 | }
174 | } {1 2 3}
175 |
176 |
177 |
178 | finish_test
179 |
--------------------------------------------------------------------------------
/test/pragma.test:
--------------------------------------------------------------------------------
1 | # 2002 March 6
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library.
12 | #
13 | # This file implements tests for the PRAGMA command.
14 | #
15 | # $Id: pragma.test,v 1.1 2002/03/06 22:01:37 drh Exp $
16 |
17 | set testdir [file dirname $argv0]
18 | source $testdir/tester.tcl
19 |
20 | # Delete the preexisting database to avoid the special setup
21 | # that the "all.test" script does.
22 | #
23 | db close
24 | file delete test.db
25 | sqlite db test.db
26 |
27 | do_test pragma-1.1 {
28 | execsql {
29 | PRAGMA cache_size;
30 | PRAGMA default_cache_size;
31 | PRAGMA synchronous;
32 | PRAGMA default_synchronous;
33 | }
34 | } {2000 2000 1 1}
35 | do_test pragma-1.2 {
36 | execsql {
37 | PRAGMA cache_size=1234;
38 | PRAGMA cache_size;
39 | PRAGMA default_cache_size;
40 | PRAGMA synchronous;
41 | PRAGMA default_synchronous;
42 | }
43 | } {1234 2000 1 1}
44 | do_test pragma-1.3 {
45 | db close
46 | sqlite db test.db
47 | execsql {
48 | PRAGMA cache_size;
49 | PRAGMA default_cache_size;
50 | PRAGMA synchronous;
51 | PRAGMA default_synchronous;
52 | }
53 | } {2000 2000 1 1}
54 | do_test pragma-1.4 {
55 | execsql {
56 | PRAGMA synchronous=OFF;
57 | PRAGMA cache_size;
58 | PRAGMA default_cache_size;
59 | PRAGMA synchronous;
60 | PRAGMA default_synchronous;
61 | }
62 | } {2000 2000 0 1}
63 | do_test pragma-1.5 {
64 | execsql {
65 | PRAGMA cache_size=4321;
66 | PRAGMA cache_size;
67 | PRAGMA default_cache_size;
68 | PRAGMA synchronous;
69 | PRAGMA default_synchronous;
70 | }
71 | } {4321 2000 0 1}
72 | do_test pragma-1.6 {
73 | execsql {
74 | PRAGMA synchronous=ON;
75 | PRAGMA cache_size;
76 | PRAGMA default_cache_size;
77 | PRAGMA synchronous;
78 | PRAGMA default_synchronous;
79 | }
80 | } {4321 2000 1 1}
81 | do_test pragma-1.7 {
82 | db close
83 | sqlite db test.db
84 | execsql {
85 | PRAGMA cache_size;
86 | PRAGMA default_cache_size;
87 | PRAGMA synchronous;
88 | PRAGMA default_synchronous;
89 | }
90 | } {2000 2000 1 1}
91 | do_test pragma-1.8 {
92 | execsql {
93 | PRAGMA default_synchronous=OFF;
94 | PRAGMA cache_size;
95 | PRAGMA default_cache_size;
96 | PRAGMA synchronous;
97 | PRAGMA default_synchronous;
98 | }
99 | } {2000 2000 0 0}
100 | do_test pragma-1.9 {
101 | execsql {
102 | PRAGMA default_cache_size=123;
103 | PRAGMA cache_size;
104 | PRAGMA default_cache_size;
105 | PRAGMA synchronous;
106 | PRAGMA default_synchronous;
107 | }
108 | } {123 123 0 0}
109 | do_test pragma-1.10 {
110 | db close
111 | sqlite db test.db
112 | execsql {
113 | PRAGMA cache_size;
114 | PRAGMA default_cache_size;
115 | PRAGMA synchronous;
116 | PRAGMA default_synchronous;
117 | }
118 | } {123 123 0 0}
119 |
120 | finish_test
121 |
--------------------------------------------------------------------------------
/test/printf.test:
--------------------------------------------------------------------------------
1 | # 2001 September 15
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is testing the sqlite_*_printf() interface.
13 | #
14 | # $Id: printf.test,v 1.5 2002/06/16 04:56:37 chw Exp $
15 |
16 | set testdir [file dirname $argv0]
17 | source $testdir/tester.tcl
18 |
19 | set n 1
20 | foreach v {1 2 5 10 99 100 1000000 999999999 0 -1 -2 -5 -10 -99 -100 -9999999} {
21 | do_test printf-1.$n.1 [subst {
22 | sqlite_mprintf_int {Three integers: %d %x %o} $v $v $v
23 | }] [format {Three integers: %d %x %o} $v $v $v]
24 | do_test printf-1.$n.2 [subst {
25 | sqlite_mprintf_int {Three integers: (%6d) (%6x) (%6o)} $v $v $v
26 | }] [format {Three integers: (%6d) (%6x) (%6o)} $v $v $v]
27 | do_test printf-1.$n.3 [subst {
28 | sqlite_mprintf_int {Three integers: (%-6d) (%-6x) (%-6o)} $v $v $v
29 | }] [format {Three integers: (%-6d) (%-6x) (%-6o)} $v $v $v]
30 | do_test printf-1.$n.4 [subst {
31 | sqlite_mprintf_int {Three integers: (%+6d) (%+6x) (%+6o)} $v $v $v
32 | }] [format {Three integers: (%+6d) (%+6x) (%+6o)} $v $v $v]
33 | do_test printf-1.$n.5 [subst {
34 | sqlite_mprintf_int {Three integers: (%06d) (%06x) (%06o)} $v $v $v
35 | }] [format {Three integers: (%06d) (%06x) (%06o)} $v $v $v]
36 | do_test printf-1.$n.6 [subst {
37 | sqlite_mprintf_int {Three integers: (% 6d) (% 6x) (% 6o)} $v $v $v
38 | }] [format {Three integers: (% 6d) (% 6x) (% 6o)} $v $v $v]
39 | incr n
40 | }
41 |
42 |
43 | if {$::tcl_platform(platform)!="windows"} {
44 |
45 | set m 1
46 | foreach {a b} {1 1 5 5 10 10 10 5} {
47 | set n 1
48 | foreach x {0.001 1.0e-20 1.0 0.0 100.0 9.99999 -0.00543 -1.0 -99.99999} {
49 | do_test printf-2.$m.$n.1 [subst {
50 | sqlite_mprintf_double {A double: %*.*f} $a $b $x
51 | }] [format {A double: %*.*f} $a $b $x]
52 | do_test printf-2.$m.$n.2 [subst {
53 | sqlite_mprintf_double {A double: %*.*e} $a $b $x
54 | }] [format {A double: %*.*e} $a $b $x]
55 | do_test printf-2.$m.$n.3 [subst {
56 | sqlite_mprintf_double {A double: %*.*g} $a $b $x
57 | }] [format {A double: %*.*g} $a $b $x]
58 | do_test printf-2.$m.$n.4 [subst {
59 | sqlite_mprintf_double {A double: %d %d %g} $a $b $x
60 | }] [format {A double: %d %d %g} $a $b $x]
61 | do_test printf-2.$m.$n.5 [subst {
62 | sqlite_mprintf_double {A double: %d %d %#g} $a $b $x
63 | }] [format {A double: %d %d %#g} $a $b $x]
64 | incr n
65 | }
66 | incr m
67 | }
68 |
69 | }
70 |
71 | do_test printf-3.1 {
72 | sqlite_mprintf_str {A String: (%*.*s)} 10 10 {This is the string}
73 | } [format {A String: (%*.*s)} 10 10 {This is the string}]
74 | do_test printf-3.2 {
75 | sqlite_mprintf_str {A String: (%*.*s)} 10 5 {This is the string}
76 | } [format {A String: (%*.*s)} 10 5 {This is the string}]
77 | do_test printf-3.3 {
78 | sqlite_mprintf_str {A String: (%*.*s)} -10 5 {This is the string}
79 | } [format {A String: (%*.*s)} -10 5 {This is the string}]
80 | do_test printf-3.4 {
81 | sqlite_mprintf_str {%d %d A String: (%s)} 1 2 {This is the string}
82 | } [format {%d %d A String: (%s)} 1 2 {This is the string}]
83 | do_test printf-3.5 {
84 | sqlite_mprintf_str {%d %d A String: (%30s)} 1 2 {This is the string}
85 | } [format {%d %d A String: (%30s)} 1 2 {This is the string}]
86 | do_test printf-3.6 {
87 | sqlite_mprintf_str {%d %d A String: (%-30s)} 1 2 {This is the string}
88 | } [format {%d %d A String: (%-30s)} 1 2 {This is the string}]
89 |
90 | do_test printf-4.1 {
91 | sqlite_mprintf_str {%d %d A quoted string: '%q'} 1 2 {Hi Y'all}
92 | } {1 2 A quoted string: 'Hi Y''all'}
93 | do_test printf-4.2 {
94 | sqlite_mprintf_str {%d %d A NULL pointer in %%q: '%q'} 1 2
95 | } {1 2 A NULL pointer in %q: '(NULL)'}
96 | do_test printf-4.3 {
97 | sqlite_mprintf_str {%d %d A quoted string: %Q} 1 2 {Hi Y'all}
98 | } {1 2 A quoted string: 'Hi Y''all'}
99 | do_test printf-4.4 {
100 | sqlite_mprintf_str {%d %d A NULL pointer in %%Q: %Q} 1 2
101 | } {1 2 A NULL pointer in %Q: NULL}
102 |
103 | do_test printf-5.1 {
104 | set x [sqlite_mprintf_str {%d %d %100000s} 0 0 {Hello}]
105 | string length $x
106 | } {994}
107 | do_test printf-5.2 {
108 | sqlite_mprintf_str {%d %d (%-10.10s) %} -9 -10 {HelloHelloHello}
109 | } {-9 -10 (HelloHello) %}
110 | do_test printf-5.3 {
111 | sqlite_mprintf_str {%% %d %d (%=10s)} 5 6 Hello
112 | } {% 5 6 ( Hello )}
113 |
114 | finish_test
115 |
--------------------------------------------------------------------------------
/test/quick.test:
--------------------------------------------------------------------------------
1 | # 2001 September 15
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file runs all tests.
12 | #
13 | # $Id: quick.test,v 1.2 2001/10/22 02:58:11 drh Exp $
14 |
15 | set testdir [file dirname $argv0]
16 | source $testdir/tester.tcl
17 | rename finish_test really_finish_test
18 | proc finish_test {} {}
19 |
20 | set EXCLUDE {
21 | all.test
22 | quick.test
23 | btree2.test
24 | malloc.test
25 | }
26 |
27 | foreach testfile [lsort -dictionary [glob $testdir/*.test]] {
28 | set tail [file tail $testfile]
29 | if {[lsearch -exact $EXCLUDE $tail]>=0} continue
30 | source $testfile
31 | }
32 |
33 | really_finish_test
34 |
--------------------------------------------------------------------------------
/test/quote.test:
--------------------------------------------------------------------------------
1 | # 2001 September 15
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is the ability to specify table and column names
13 | # as quoted strings.
14 | #
15 | # $Id: quote.test,v 1.3 2002/05/21 13:43:04 drh Exp $
16 |
17 | set testdir [file dirname $argv0]
18 | source $testdir/tester.tcl
19 |
20 | # Create a table with a strange name and with strange column names.
21 | #
22 | do_test quote-1.0 {
23 | set r [catch {
24 | execsql {CREATE TABLE '@abc' ( '#xyz' int, '!pqr' text );}
25 | } msg]
26 | lappend r $msg
27 | } {0 {}}
28 |
29 | # Insert, update and query the table.
30 | #
31 | do_test quote-1.1 {
32 | set r [catch {
33 | execsql {INSERT INTO '@abc' VALUES(5,'hello')}
34 | } msg]
35 | lappend r $msg
36 | } {0 {}}
37 | do_test quote-1.2 {
38 | set r [catch {
39 | execsql {SELECT * FROM '@abc'}
40 | } msg ]
41 | lappend r $msg
42 | } {0 {5 hello}}
43 | do_test quote-1.3 {
44 | set r [catch {
45 | execsql {SELECT '@abc'.'!pqr', '@abc'.'#xyz'+5 FROM '@abc'}
46 | } msg ]
47 | lappend r $msg
48 | } {0 {hello 10}}
49 | do_test quote-1.3.1 {
50 | catchsql {
51 | SELECT '!pqr', '#xyz'+5 FROM '@abc'
52 | }
53 | } {0 {!pqr 5}}
54 | do_test quote-1.3.2 {
55 | catchsql {
56 | SELECT "!pqr", "#xyz"+5 FROM '@abc'
57 | }
58 | } {0 {hello 10}}
59 | do_test quote-1.3 {
60 | set r [catch {
61 | execsql {SELECT '@abc'.'!pqr', '@abc'.'#xyz'+5 FROM '@abc'}
62 | } msg ]
63 | lappend r $msg
64 | } {0 {hello 10}}
65 | do_test quote-1.4 {
66 | set r [catch {
67 | execsql {UPDATE '@abc' SET '#xyz'=11}
68 | } msg ]
69 | lappend r $msg
70 | } {0 {}}
71 | do_test quote-1.5 {
72 | set r [catch {
73 | execsql {SELECT '@abc'.'!pqr', '@abc'.'#xyz'+5 FROM '@abc'}
74 | } msg ]
75 | lappend r $msg
76 | } {0 {hello 16}}
77 |
78 | # Drop the table with the strange name.
79 | #
80 | do_test quote-1.6 {
81 | set r [catch {
82 | execsql {DROP TABLE '@abc'}
83 | } msg ]
84 | lappend r $msg
85 | } {0 {}}
86 |
87 |
88 | finish_test
89 |
--------------------------------------------------------------------------------
/test/select2.test:
--------------------------------------------------------------------------------
1 | # 2001 September 15
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is testing the SELECT statement.
13 | #
14 | # $Id: select2.test,v 1.18 2002/04/02 13:26:11 drh Exp $
15 |
16 | set testdir [file dirname $argv0]
17 | source $testdir/tester.tcl
18 |
19 | # Create a table with some data
20 | #
21 | execsql {CREATE TABLE tbl1(f1 int, f2 int)}
22 | set f [open ./testdata1.txt w]
23 | for {set i 0} {$i<=30} {incr i} {
24 | puts $f "[expr {$i%9}]\t[expr {$i%10}]"
25 | }
26 | close $f
27 | execsql {COPY tbl1 FROM './testdata1.txt'}
28 | file delete -force ./testdata1.txt
29 | catch {unset data}
30 |
31 | # Do a second query inside a first.
32 | #
33 | do_test select2-1.1 {
34 | set sql {SELECT DISTINCT f1 FROM tbl1 ORDER BY f1}
35 | set r {}
36 | db eval $sql data {
37 | set f1 $data(f1)
38 | lappend r $f1:
39 | set sql2 "SELECT f2 FROM tbl1 WHERE f1=$f1 ORDER BY f2"
40 | db eval $sql2 d2 {
41 | lappend r $d2(f2)
42 | }
43 | }
44 | set r
45 | } {0: 0 7 8 9 1: 0 1 8 9 2: 0 1 2 9 3: 0 1 2 3 4: 2 3 4 5: 3 4 5 6: 4 5 6 7: 5 6 7 8: 6 7 8}
46 |
47 | do_test select2-1.2 {
48 | set sql {SELECT DISTINCT f1 FROM tbl1 WHERE f1>3 AND f1<5}
49 | set r {}
50 | db eval $sql data {
51 | set f1 $data(f1)
52 | lappend r $f1:
53 | set sql2 "SELECT f2 FROM tbl1 WHERE f1=$f1 ORDER BY f2"
54 | db eval $sql2 d2 {
55 | lappend r $d2(f2)
56 | }
57 | }
58 | set r
59 | } {4: 2 3 4}
60 |
61 | # Create a largish table
62 | #
63 | do_test select2-2.0 {
64 | execsql {CREATE TABLE tbl2(f1 int, f2 int, f3 int)}
65 | set f [open ./testdata1.txt w]
66 | for {set i 1} {$i<=30000} {incr i} {
67 | puts $f "$i\t[expr {$i*2}]\t[expr {$i*3}]"
68 | }
69 | close $f
70 | # execsql {--vdbe-trace-on--}
71 | execsql {COPY tbl2 FROM './testdata1.txt'}
72 | file delete -force ./testdata1.txt
73 | } {}
74 |
75 | do_test select2-2.1 {
76 | execsql {SELECT count(*) FROM tbl2}
77 | } {30000}
78 | do_test select2-2.2 {
79 | execsql {SELECT count(*) FROM tbl2 WHERE f2>1000}
80 | } {29500}
81 |
82 | do_test select2-3.1 {
83 | execsql {SELECT f1 FROM tbl2 WHERE 1000=f2}
84 | } {500}
85 |
86 | do_test select2-3.2a {
87 | execsql {CREATE INDEX idx1 ON tbl2(f2)}
88 | } {}
89 |
90 | do_test select2-3.2b {
91 | execsql {SELECT f1 FROM tbl2 WHERE 1000=f2}
92 | } {500}
93 | do_test select2-3.2c {
94 | execsql {SELECT f1 FROM tbl2 WHERE f2=1000}
95 | } {500}
96 | do_test select2-3.2d {
97 | set sqlite_search_count 0
98 | execsql {SELECT * FROM tbl2 WHERE 1000=f2}
99 | set sqlite_search_count
100 | } {3}
101 | do_test select2-3.2e {
102 | set sqlite_search_count 0
103 | execsql {SELECT * FROM tbl2 WHERE f2=1000}
104 | set sqlite_search_count
105 | } {3}
106 |
107 | # Make sure queries run faster with an index than without
108 | #
109 | do_test select2-3.3 {
110 | execsql {DROP INDEX idx1}
111 | set sqlite_search_count 0
112 | execsql {SELECT f1 FROM tbl2 WHERE f2==2000}
113 | set sqlite_search_count
114 | } {29999}
115 |
116 | # Make sure we can optimize functions in the WHERE clause that
117 | # use fields from two or more different table. (Bug #6)
118 | #
119 | do_test select2-4.1 {
120 | execsql {
121 | CREATE TABLE aa(a);
122 | CREATE TABLE bb(b);
123 | INSERT INTO aa VALUES(1);
124 | INSERT INTO aa VALUES(3);
125 | INSERT INTO bb VALUES(2);
126 | INSERT INTO bb VALUES(4);
127 | SELECT * FROM aa, bb WHERE max(a,b)>2;
128 | }
129 | } {1 4 3 2 3 4}
130 | do_test select2-4.2 {
131 | execsql {
132 | INSERT INTO bb VALUES(0);
133 | SELECT * FROM aa, bb WHERE b;
134 | }
135 | } {1 2 1 4 3 2 3 4}
136 | do_test select2-4.3 {
137 | execsql {
138 | SELECT * FROM aa, bb WHERE NOT b;
139 | }
140 | } {1 0 3 0}
141 | do_test select2-4.4 {
142 | execsql {
143 | SELECT * FROM aa, bb WHERE min(a,b);
144 | }
145 | } {1 2 1 4 3 2 3 4}
146 | do_test select2-4.5 {
147 | execsql {
148 | SELECT * FROM aa, bb WHERE NOT min(a,b);
149 | }
150 | } {1 0 3 0}
151 | do_test select2-4.6 {
152 | execsql {
153 | SELECT * FROM aa, bb WHERE CASE WHEN a=b-1 THEN 1 END;
154 | }
155 | } {1 2 3 4}
156 | do_test select2-4.7 {
157 | execsql {
158 | SELECT * FROM aa, bb WHERE CASE WHEN a=b-1 THEN 0 ELSE 1 END;
159 | }
160 | } {1 4 1 0 3 2 3 0}
161 |
162 | finish_test
163 |
--------------------------------------------------------------------------------
/test/select3.test:
--------------------------------------------------------------------------------
1 | # 2001 September 15
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is testing aggregate functions and the
13 | # GROUP BY and HAVING clauses of SELECT statements.
14 | #
15 | # $Id: select3.test,v 1.5 2002/01/22 14:11:30 drh Exp $
16 |
17 | set testdir [file dirname $argv0]
18 | source $testdir/tester.tcl
19 |
20 | # Build some test data
21 | #
22 | do_test select3-1.0 {
23 | set fd [open data1.txt w]
24 | for {set i 1} {$i<32} {incr i} {
25 | for {set j 0} {pow(2,$j)<$i} {incr j} {}
26 | puts $fd "$i\t$j"
27 | }
28 | close $fd
29 | execsql {
30 | CREATE TABLE t1(n int, log int);
31 | COPY t1 FROM 'data1.txt'
32 | }
33 | file delete data1.txt
34 | execsql {SELECT DISTINCT log FROM t1 ORDER BY log}
35 | } {0 1 2 3 4 5}
36 |
37 | # Basic aggregate functions.
38 | #
39 | do_test select3-1.1 {
40 | execsql {SELECT count(*) FROM t1}
41 | } {31}
42 | do_test select3-1.2 {
43 | execsql {
44 | SELECT min(n),min(log),max(n),max(log),sum(n),sum(log),avg(n),avg(log)
45 | FROM t1
46 | }
47 | } {1 0 31 5 496 124 16 4}
48 | do_test select3-1.3 {
49 | execsql {SELECT max(n)/avg(n), max(log)/avg(log) FROM t1}
50 | } {1.9375 1.25}
51 |
52 | # Try some basic GROUP BY clauses
53 | #
54 | do_test select3-2.1 {
55 | execsql {SELECT log, count(*) FROM t1 GROUP BY log ORDER BY log}
56 | } {0 1 1 1 2 2 3 4 4 8 5 15}
57 | do_test select3-2.2 {
58 | execsql {SELECT log, min(n) FROM t1 GROUP BY log ORDER BY log}
59 | } {0 1 1 2 2 3 3 5 4 9 5 17}
60 | do_test select3-2.3 {
61 | execsql {SELECT log, avg(n) FROM t1 GROUP BY log ORDER BY log}
62 | } {0 1 1 2 2 3.5 3 6.5 4 12.5 5 24}
63 | do_test select3-2.3 {
64 | execsql {SELECT log, avg(n)+1 FROM t1 GROUP BY log ORDER BY log}
65 | } {0 2 1 3 2 4.5 3 7.5 4 13.5 5 25}
66 | do_test select3-2.4 {
67 | execsql {SELECT log, avg(n)-min(n) FROM t1 GROUP BY log ORDER BY log}
68 | } {0 0 1 0 2 0.5 3 1.5 4 3.5 5 7}
69 | do_test select3-2.5 {
70 | execsql {SELECT log*2+1, avg(n)-min(n) FROM t1 GROUP BY log ORDER BY log}
71 | } {1 0 3 0 5 0.5 7 1.5 9 3.5 11 7}
72 | do_test select3-2.6 {
73 | execsql {
74 | SELECT log*2+1 as x, count(*) FROM t1 GROUP BY x ORDER BY x
75 | }
76 | } {1 1 3 1 5 2 7 4 9 8 11 15}
77 | do_test select3-2.7 {
78 | execsql {
79 | SELECT log*2+1 AS x, count(*) AS y FROM t1 GROUP BY x ORDER BY y
80 | }
81 | } {1 1 3 1 5 2 7 4 9 8 11 15}
82 | do_test select3-2.8 {
83 | execsql {
84 | SELECT log*2+1 AS x, count(*) AS y FROM t1 GROUP BY x ORDER BY 10-(x+y)
85 | }
86 | } {11 15 9 8 7 4 5 2 3 1 1 1}
87 | do_test select3-2.9 {
88 | catchsql {
89 | SELECT log, count(*) FROM t1 GROUP BY 8 ORDER BY log;
90 | }
91 | } {1 {GROUP BY expressions should not be constant}}
92 |
93 | # Cannot have a HAVING without a GROUP BY
94 | #
95 | do_test select3-3.1 {
96 | set v [catch {execsql {SELECT log, count(*) FROM t1 HAVING log>=4}} msg]
97 | lappend v $msg
98 | } {1 {a GROUP BY clause is required before HAVING}}
99 |
100 | # Toss in some HAVING clauses
101 | #
102 | do_test select3-4.1 {
103 | execsql {SELECT log, count(*) FROM t1 GROUP BY log HAVING log>=4 ORDER BY log}
104 | } {4 8 5 15}
105 | do_test select3-4.2 {
106 | execsql {
107 | SELECT log, count(*) FROM t1
108 | GROUP BY log
109 | HAVING count(*)>=4
110 | ORDER BY log
111 | }
112 | } {3 4 4 8 5 15}
113 | do_test select3-4.3 {
114 | execsql {
115 | SELECT log, count(*) FROM t1
116 | GROUP BY log
117 | HAVING count(*)>=4
118 | ORDER BY max(n)
119 | }
120 | } {3 4 4 8 5 15}
121 | do_test select3-4.4 {
122 | execsql {
123 | SELECT log AS x, count(*) AS y FROM t1
124 | GROUP BY x
125 | HAVING y>=4
126 | ORDER BY max(n)
127 | }
128 | } {3 4 4 8 5 15}
129 |
130 | do_test select3-5.1 {
131 | execsql {
132 | SELECT log, count(*), avg(n), max(n+log*2) FROM t1
133 | GROUP BY log
134 | ORDER BY max(n+log*2), avg(n)
135 | }
136 | } {0 1 1 1 1 1 2 4 2 2 3.5 8 3 4 6.5 14 4 8 12.5 24 5 15 24 41}
137 | do_test select3-5.2 {
138 | execsql {
139 | SELECT log, count(*), avg(n), max(n+log*2) FROM t1
140 | GROUP BY log
141 | ORDER BY max(n+log*2), min(log,avg(n))
142 | }
143 | } {0 1 1 1 1 1 2 4 2 2 3.5 8 3 4 6.5 14 4 8 12.5 24 5 15 24 41}
144 |
145 | finish_test
146 |
--------------------------------------------------------------------------------
/test/select5.test:
--------------------------------------------------------------------------------
1 | # 2001 September 15
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is testing aggregate functions and the
13 | # GROUP BY and HAVING clauses of SELECT statements.
14 | #
15 | # $Id: select5.test,v 1.6 2001/10/15 00:44:36 drh Exp $
16 |
17 | set testdir [file dirname $argv0]
18 | source $testdir/tester.tcl
19 |
20 | # Build some test data
21 | #
22 | set fd [open data1.txt w]
23 | for {set i 1} {$i<32} {incr i} {
24 | for {set j 0} {pow(2,$j)<$i} {incr j} {}
25 | puts $fd "[expr {32-$i}]\t[expr {10-$j}]"
26 | }
27 | close $fd
28 | execsql {
29 | CREATE TABLE t1(x int, y int);
30 | COPY t1 FROM 'data1.txt'
31 | }
32 | file delete data1.txt
33 |
34 | do_test select5-1.0 {
35 | execsql {SELECT DISTINCT y FROM t1 ORDER BY y}
36 | } {5 6 7 8 9 10}
37 |
38 | # Sort by an aggregate function.
39 | #
40 | do_test select5-1.1 {
41 | execsql {SELECT y, count(*) FROM t1 GROUP BY y ORDER BY y}
42 | } {5 15 6 8 7 4 8 2 9 1 10 1}
43 | do_test select5-1.2 {
44 | execsql {SELECT y, count(*) FROM t1 GROUP BY y ORDER BY count(*), y}
45 | } {9 1 10 1 8 2 7 4 6 8 5 15}
46 | do_test select5-1.3 {
47 | execsql {SELECT count(*), y FROM t1 GROUP BY y ORDER BY count(*), y}
48 | } {1 9 1 10 2 8 4 7 8 6 15 5}
49 |
50 | # Some error messages associated with aggregates and GROUP BY
51 | #
52 | do_test select5-2.1 {
53 | set v [catch {execsql {
54 | SELECT y, count(*) FROM t1 GROUP BY z ORDER BY y
55 | }} msg]
56 | lappend v $msg
57 | } {1 {no such column: z}}
58 | do_test select5-2.2 {
59 | set v [catch {execsql {
60 | SELECT y, count(*) FROM t1 GROUP BY z(y) ORDER BY y
61 | }} msg]
62 | lappend v $msg
63 | } {1 {no such function: z}}
64 | do_test select5-2.3 {
65 | set v [catch {execsql {
66 | SELECT y, count(*) FROM t1 GROUP BY y HAVING count(*)<3 ORDER BY y
67 | }} msg]
68 | lappend v $msg
69 | } {0 {8 2 9 1 10 1}}
70 | do_test select5-2.4 {
71 | set v [catch {execsql {
72 | SELECT y, count(*) FROM t1 GROUP BY y HAVING z(y)<3 ORDER BY y
73 | }} msg]
74 | lappend v $msg
75 | } {1 {no such function: z}}
76 | do_test select5-2.5 {
77 | set v [catch {execsql {
78 | SELECT y, count(*) FROM t1 GROUP BY y HAVING count(*)100
96 | }
97 | } {{}}
98 | do_test select5-4.2 {
99 | execsql {
100 | SELECT count(x) FROM t1 WHERE x>100
101 | }
102 | } {0}
103 | do_test select5-4.3 {
104 | execsql {
105 | SELECT min(x) FROM t1 WHERE x>100
106 | }
107 | } {{}}
108 | do_test select5-4.4 {
109 | execsql {
110 | SELECT max(x) FROM t1 WHERE x>100
111 | }
112 | } {{}}
113 | do_test select5-4.5 {
114 | execsql {
115 | SELECT sum(x) FROM t1 WHERE x>100
116 | }
117 | } {0}
118 |
119 | finish_test
120 |
--------------------------------------------------------------------------------
/test/sort.test:
--------------------------------------------------------------------------------
1 | # 2001 September 15
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is testing the CREATE TABLE statement.
13 | #
14 | # $Id: sort.test,v 1.4 2002/01/22 14:11:30 drh Exp $
15 |
16 | set testdir [file dirname $argv0]
17 | source $testdir/tester.tcl
18 |
19 | # Create a bunch of data to sort against
20 | #
21 | do_test sort-1.0 {
22 | set fd [open data.txt w]
23 | puts $fd "1\tone\t0\tI\t3.141592653"
24 | puts $fd "2\ttwo\t1\tII\t2.15"
25 | puts $fd "3\tthree\t1\tIII\t4221.0"
26 | puts $fd "4\tfour\t2\tIV\t-0.0013442"
27 | puts $fd "5\tfive\t2\tV\t-11"
28 | puts $fd "6\tsix\t2\tVI\t0.123"
29 | puts $fd "7\tseven\t2\tVII\t123.0"
30 | puts $fd "8\teight\t3\tVIII\t-1.6"
31 | close $fd
32 | execsql {
33 | CREATE TABLE t1(
34 | n int,
35 | v varchar(10),
36 | log int,
37 | roman varchar(10),
38 | flt real
39 | );
40 | COPY t1 FROM 'data.txt'
41 | }
42 | file delete data.txt
43 | execsql {SELECT count(*) FROM t1}
44 | } {8}
45 |
46 | do_test sort-1.1 {
47 | execsql {SELECT n FROM t1 ORDER BY n}
48 | } {1 2 3 4 5 6 7 8}
49 | do_test sort-1.1.1 {
50 | execsql {SELECT n FROM t1 ORDER BY n ASC}
51 | } {1 2 3 4 5 6 7 8}
52 | do_test sort-1.1.1 {
53 | execsql {SELECT ALL n FROM t1 ORDER BY n ASC}
54 | } {1 2 3 4 5 6 7 8}
55 | do_test sort-1.2 {
56 | execsql {SELECT n FROM t1 ORDER BY n DESC}
57 | } {8 7 6 5 4 3 2 1}
58 | do_test sort-1.3a {
59 | execsql {SELECT v FROM t1 ORDER BY v}
60 | } {eight five four one seven six three two}
61 | do_test sort-1.3b {
62 | execsql {SELECT n FROM t1 ORDER BY v}
63 | } {8 5 4 1 7 6 3 2}
64 | do_test sort-1.4 {
65 | execsql {SELECT n FROM t1 ORDER BY v DESC}
66 | } {2 3 6 7 1 4 5 8}
67 | do_test sort-1.5 {
68 | execsql {SELECT flt FROM t1 ORDER BY flt}
69 | } {-11 -1.6 -0.0013442 0.123 2.15 3.141592653 123.0 4221.0}
70 | do_test sort-1.6 {
71 | execsql {SELECT flt FROM t1 ORDER BY flt DESC}
72 | } {4221.0 123.0 3.141592653 2.15 0.123 -0.0013442 -1.6 -11}
73 | do_test sort-1.7 {
74 | execsql {SELECT roman FROM t1 ORDER BY roman}
75 | } {I II III IV V VI VII VIII}
76 | do_test sort-1.8 {
77 | execsql {SELECT n FROM t1 ORDER BY log, flt}
78 | } {1 2 3 5 4 6 7 8}
79 | do_test sort-1.8.1 {
80 | execsql {SELECT n FROM t1 ORDER BY log asc, flt}
81 | } {1 2 3 5 4 6 7 8}
82 | do_test sort-1.8.2 {
83 | execsql {SELECT n FROM t1 ORDER BY log, flt ASC}
84 | } {1 2 3 5 4 6 7 8}
85 | do_test sort-1.8.3 {
86 | execsql {SELECT n FROM t1 ORDER BY log ASC, flt asc}
87 | } {1 2 3 5 4 6 7 8}
88 | do_test sort-1.9 {
89 | execsql {SELECT n FROM t1 ORDER BY log, flt DESC}
90 | } {1 3 2 7 6 4 5 8}
91 | do_test sort-1.9.1 {
92 | execsql {SELECT n FROM t1 ORDER BY log ASC, flt DESC}
93 | } {1 3 2 7 6 4 5 8}
94 | do_test sort-1.10 {
95 | execsql {SELECT n FROM t1 ORDER BY log DESC, flt}
96 | } {8 5 4 6 7 2 3 1}
97 | do_test sort-1.11 {
98 | execsql {SELECT n FROM t1 ORDER BY log DESC, flt DESC}
99 | } {8 7 6 4 5 3 2 1}
100 |
101 | # These tests are designed to reach some hard-to-reach places
102 | # inside the string comparison routines.
103 | #
104 | do_test sort-2.1 {
105 | execsql {
106 | UPDATE t1 SET v='x' || -flt;
107 | UPDATE t1 SET v='x-2b' where v=='x-0.123';
108 | SELECT v FROM t1 ORDER BY v;
109 | }
110 | } {x-2b x-2.15 x-3.141592653 x-123 x-4221 x0.0013442 x1.6 x11}
111 | do_test sort-2.2 {
112 | execsql {
113 | UPDATE t1 SET v='x-2_' where v=='x0.0013442';
114 | SELECT v FROM t1 ORDER BY v;
115 | }
116 | } {x-2_ x-2b x-2.15 x-3.141592653 x-123 x-4221 x1.6 x11}
117 | do_test sort-2.3 {
118 | execsql {
119 | UPDATE t1 SET v='x ' || (-1.3+0.01*n);
120 | SELECT v FROM t1 ORDER BY v;
121 | }
122 | } {{x -1.29} {x -1.28} {x -1.27} {x -1.26} {x -1.25} {x -1.24} {x -1.23} {x -1.22}}
123 |
124 | # This is a bug fix for 2.2.4.
125 | # Strings are normally mapped to upper-case for a caseless comparison.
126 | # But this can cause problems for characters in between 'Z' and 'a'.
127 | #
128 | do_test sort-3.1 {
129 | execsql {
130 | CREATE TABLE t2(a,b);
131 | INSERT INTO t2 VALUES('AGLIENTU',1);
132 | INSERT INTO t2 VALUES('AGLIE`',2);
133 | INSERT INTO t2 VALUES('AGNA',3);
134 | SELECT a, b FROM t2 ORDER BY a;
135 | }
136 | } {AGLIENTU 1 AGLIE` 2 AGNA 3}
137 | do_test sort-3.2 {
138 | execsql {
139 | SELECT a, b FROM t2 ORDER BY a DESC;
140 | }
141 | } {AGNA 3 AGLIE` 2 AGLIENTU 1}
142 | do_test sort-3.3 {
143 | execsql {
144 | DELETE FROM t2;
145 | INSERT INTO t2 VALUES('aglientu',1);
146 | INSERT INTO t2 VALUES('aglie`',2);
147 | INSERT INTO t2 VALUES('agna',3);
148 | SELECT a, b FROM t2 ORDER BY a;
149 | }
150 | } {aglie` 2 aglientu 1 agna 3}
151 | do_test sort-3.4 {
152 | execsql {
153 | SELECT a, b FROM t2 ORDER BY a DESC;
154 | }
155 | } {agna 3 aglientu 1 aglie` 2}
156 |
157 |
158 | finish_test
159 |
--------------------------------------------------------------------------------
/test/subselect.test:
--------------------------------------------------------------------------------
1 | # 2001 September 15
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is testing SELECT statements that are part of
13 | # expressions.
14 | #
15 | # $Id: subselect.test,v 1.5 2002/05/26 20:54:35 drh Exp $
16 |
17 | set testdir [file dirname $argv0]
18 | source $testdir/tester.tcl
19 |
20 | # Basic sanity checking. Try a simple subselect.
21 | #
22 | do_test subselect-1.1 {
23 | execsql {
24 | CREATE TABLE t1(a int, b int);
25 | INSERT INTO t1 VALUES(1,2);
26 | INSERT INTO t1 VALUES(3,4);
27 | INSERT INTO t1 VALUES(5,6);
28 | }
29 | execsql {SELECT * FROM t1 WHERE a = (SELECT count(*) FROM t1)}
30 | } {3 4}
31 |
32 | # Try a select with more than one result column.
33 | #
34 | do_test subselect-1.2 {
35 | set v [catch {execsql {SELECT * FROM t1 WHERE a = (SELECT * FROM t1)}} msg]
36 | lappend v $msg
37 | } {1 {only a single result allowed for a SELECT that is part of an expression}}
38 |
39 | # A subselect without an aggregate.
40 | #
41 | do_test subselect-1.3a {
42 | execsql {SELECT b from t1 where a = (SELECT a FROM t1 WHERE b=2)}
43 | } {2}
44 | do_test subselect-1.3b {
45 | execsql {SELECT b from t1 where a = (SELECT a FROM t1 WHERE b=4)}
46 | } {4}
47 | do_test subselect-1.3c {
48 | execsql {SELECT b from t1 where a = (SELECT a FROM t1 WHERE b=6)}
49 | } {6}
50 | do_test subselect-1.3c {
51 | execsql {SELECT b from t1 where a = (SELECT a FROM t1 WHERE b=8)}
52 | } {}
53 |
54 | # What if the subselect doesn't return any value. We should get
55 | # NULL as the result. Check it out.
56 | #
57 | do_test subselect-1.4 {
58 | execsql {SELECT b from t1 where a = coalesce((SELECT a FROM t1 WHERE b=5),1)}
59 | } {2}
60 |
61 | # Try multiple subselects within a single expression.
62 | #
63 | do_test subselect-1.5 {
64 | execsql {
65 | CREATE TABLE t2(x int, y int);
66 | INSERT INTO t2 VALUES(1,2);
67 | INSERT INTO t2 VALUES(2,4);
68 | INSERT INTO t2 VALUES(3,8);
69 | INSERT INTO t2 VALUES(4,16);
70 | }
71 | execsql {
72 | SELECT y from t2
73 | WHERE x = (SELECT sum(b) FROM t1 where a notnull) - (SELECT sum(a) FROM t1)
74 | }
75 | } {8}
76 |
77 | # Try something useful. Delete every entry from t2 where the
78 | # x value is less than half of the maximum.
79 | #
80 | do_test subselect-1.6 {
81 | execsql {DELETE FROM t2 WHERE x < 0.5*(SELECT max(x) FROM t2)}
82 | execsql {SELECT x FROM t2 ORDER BY x}
83 | } {2 3 4}
84 |
85 | finish_test
86 |
--------------------------------------------------------------------------------
/test/tableapi.test:
--------------------------------------------------------------------------------
1 | # 2001 September 15
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is testing the sqlite_exec_printf() and
13 | # sqlite_get_table_printf() APIs.
14 | #
15 | # $Id: tableapi.test,v 1.5 2002/03/23 00:52:01 drh Exp $
16 |
17 | set testdir [file dirname $argv0]
18 | source $testdir/tester.tcl
19 |
20 | do_test tableapi-1.0 {
21 | set ::dbx [sqlite_open testdb]
22 | catch {sqlite_exec_printf $::dbx {DROP TABLE xyz} {}}
23 | sqlite_exec_printf $::dbx {CREATE TABLE %s(a int, b text)} xyz
24 | } {0 {}}
25 | do_test tableapi-1.1 {
26 | sqlite_exec_printf $::dbx {
27 | INSERT INTO xyz VALUES(1,'%q')
28 | } {Hi Y'all}
29 | } {0 {}}
30 | do_test tableapi-1.2 {
31 | sqlite_exec_printf $::dbx {SELECT * FROM xyz} {}
32 | } {0 {a b 1 {Hi Y'all}}}
33 |
34 | do_test tableapi-2.1 {
35 | sqlite_get_table_printf $::dbx {
36 | BEGIN TRANSACTION;
37 | SELECT * FROM xyz WHERE b='%q'
38 | } {Hi Y'all}
39 | } {0 1 2 a b 1 {Hi Y'all}}
40 | do_test tableapi-2.2 {
41 | sqlite_get_table_printf $::dbx {
42 | SELECT * FROM xyz
43 | } {}
44 | } {0 1 2 a b 1 {Hi Y'all}}
45 | do_test tableapi-2.3 {
46 | for {set i 2} {$i<=50} {incr i} {
47 | sqlite_get_table_printf $::dbx \
48 | "INSERT INTO xyz VALUES($i,'(%s)')" $i
49 | }
50 | sqlite_get_table_printf $::dbx {
51 | SELECT * FROM xyz ORDER BY a
52 | } {}
53 | } {0 50 2 a b 1 {Hi Y'all} 2 (2) 3 (3) 4 (4) 5 (5) 6 (6) 7 (7) 8 (8) 9 (9) 10 (10) 11 (11) 12 (12) 13 (13) 14 (14) 15 (15) 16 (16) 17 (17) 18 (18) 19 (19) 20 (20) 21 (21) 22 (22) 23 (23) 24 (24) 25 (25) 26 (26) 27 (27) 28 (28) 29 (29) 30 (30) 31 (31) 32 (32) 33 (33) 34 (34) 35 (35) 36 (36) 37 (37) 38 (38) 39 (39) 40 (40) 41 (41) 42 (42) 43 (43) 44 (44) 45 (45) 46 (46) 47 (47) 48 (48) 49 (49) 50 (50)}
54 | do_test tableapi-2.3.1 {
55 | sqlite_get_table_printf $::dbx {
56 | SELECT * FROM xyz WHERE a>49 ORDER BY a
57 | } {}
58 | } {0 1 2 a b 50 (50)}
59 | do_test tableapi-2.3.2 {
60 | sqlite_get_table_printf $::dbx {
61 | SELECT * FROM xyz WHERE a>47 ORDER BY a
62 | } {}
63 | } {0 3 2 a b 48 (48) 49 (49) 50 (50)}
64 | do_test tableapi-2.4 {
65 | set ::big_str [sqlite_mprintf_str {%500'* Hello %500'*} 0 0 {}]
66 | sqlite_get_table_printf $::dbx {
67 | INSERT INTO xyz VALUES(51,'%q')
68 | } $::big_str
69 | } {0 0 0}
70 | do_test tableapi-2.5 {
71 | sqlite_get_table_printf $::dbx {
72 | SELECT * FROM xyz WHERE a>49 ORDER BY a;
73 | } {}
74 | } "0 2 2 a b 50 (50) 51 \173$::big_str\175"
75 | do_test tableapi-2.6 {
76 | sqlite_get_table_printf $::dbx {
77 | INSERT INTO xyz VALUES(52,NULL)
78 | } {}
79 | sqlite_get_table_printf $::dbx {
80 | SELECT * FROM xyz WHERE a IN (42,50,52) ORDER BY a DESC
81 | } {}
82 | } {0 3 2 a b 52 NULL 50 (50) 42 (42)}
83 | do_test tableapi-2.7 {
84 | sqlite_get_table_printf $::dbx {
85 | SELECT * FROM xyz WHERE a>1000
86 | } {}
87 | } {0 0 0}
88 |
89 | # Repeat all tests with the empty_result_callbacks pragma turned on
90 | #
91 | do_test tableapi-3.1 {
92 | sqlite_get_table_printf $::dbx {
93 | ROLLBACK;
94 | PRAGMA empty_result_callbacks = ON;
95 | SELECT * FROM xyz WHERE b='%q'
96 | } {Hi Y'all}
97 | } {0 1 2 a b 1 {Hi Y'all}}
98 | do_test tableapi-3.2 {
99 | sqlite_get_table_printf $::dbx {
100 | SELECT * FROM xyz
101 | } {}
102 | } {0 1 2 a b 1 {Hi Y'all}}
103 | do_test tableapi-3.3 {
104 | for {set i 2} {$i<=50} {incr i} {
105 | sqlite_get_table_printf $::dbx \
106 | "INSERT INTO xyz VALUES($i,'(%s)')" $i
107 | }
108 | sqlite_get_table_printf $::dbx {
109 | SELECT * FROM xyz ORDER BY a
110 | } {}
111 | } {0 50 2 a b 1 {Hi Y'all} 2 (2) 3 (3) 4 (4) 5 (5) 6 (6) 7 (7) 8 (8) 9 (9) 10 (10) 11 (11) 12 (12) 13 (13) 14 (14) 15 (15) 16 (16) 17 (17) 18 (18) 19 (19) 20 (20) 21 (21) 22 (22) 23 (23) 24 (24) 25 (25) 26 (26) 27 (27) 28 (28) 29 (29) 30 (30) 31 (31) 32 (32) 33 (33) 34 (34) 35 (35) 36 (36) 37 (37) 38 (38) 39 (39) 40 (40) 41 (41) 42 (42) 43 (43) 44 (44) 45 (45) 46 (46) 47 (47) 48 (48) 49 (49) 50 (50)}
112 | do_test tableapi-3.3.1 {
113 | sqlite_get_table_printf $::dbx {
114 | SELECT * FROM xyz WHERE a>49 ORDER BY a
115 | } {}
116 | } {0 1 2 a b 50 (50)}
117 | do_test tableapi-3.3.2 {
118 | sqlite_get_table_printf $::dbx {
119 | SELECT * FROM xyz WHERE a>47 ORDER BY a
120 | } {}
121 | } {0 3 2 a b 48 (48) 49 (49) 50 (50)}
122 | do_test tableapi-3.4 {
123 | set ::big_str [sqlite_mprintf_str {%500'* Hello %500'*} 0 0 {}]
124 | sqlite_get_table_printf $::dbx {
125 | INSERT INTO xyz VALUES(51,'%q')
126 | } $::big_str
127 | } {0 0 0}
128 | do_test tableapi-3.5 {
129 | sqlite_get_table_printf $::dbx {
130 | SELECT * FROM xyz WHERE a>49 ORDER BY a;
131 | } {}
132 | } "0 2 2 a b 50 (50) 51 \173$::big_str\175"
133 | do_test tableapi-3.6 {
134 | sqlite_get_table_printf $::dbx {
135 | INSERT INTO xyz VALUES(52,NULL)
136 | } {}
137 | sqlite_get_table_printf $::dbx {
138 | SELECT * FROM xyz WHERE a IN (42,50,52) ORDER BY a DESC
139 | } {}
140 | } {0 3 2 a b 52 NULL 50 (50) 42 (42)}
141 | do_test tableapi-3.7 {
142 | sqlite_get_table_printf $::dbx {
143 | SELECT * FROM xyz WHERE a>1000
144 | } {}
145 | } {0 0 2 a b}
146 |
147 | do_test tableapi-4.1 {
148 | set rc [catch {
149 | sqlite_get_table_printf $::dbx {
150 | SELECT * FROM xyz; SELECT * FROM sqlite_master
151 | } {}
152 | } msg]
153 | concat $rc $msg
154 | } {0 1 {sqlite_get_table() called with two or more incompatible queries}}
155 |
156 | do_test tableapi-99.0 {
157 | sqlite_close $::dbx
158 | } {}
159 |
160 | finish_test
161 |
--------------------------------------------------------------------------------
/test/tclsqlite.test:
--------------------------------------------------------------------------------
1 | # 2001 September 15
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for TCL interface to the
12 | # SQLite library.
13 | #
14 | # Actually, all tests are based on the TCL interface, so the main
15 | # interface is pretty well tested. This file contains some addition
16 | # tests for fringe issues that the main test suite does not cover.
17 | #
18 | # $Id: tclsqlite.test,v 1.6 2002/04/12 10:09:00 drh Exp $
19 |
20 | set testdir [file dirname $argv0]
21 | source $testdir/tester.tcl
22 |
23 | # Check the error messages generated by tclsqlite
24 | #
25 | do_test tcl-1.1 {
26 | set v [catch {sqlite bogus} msg]
27 | lappend v $msg
28 | } {1 {wrong # args: should be "sqlite HANDLE FILENAME ?MODE?"}}
29 | do_test tcl-1.2 {
30 | set v [catch {db bogus} msg]
31 | lappend v $msg
32 | } {1 {bad option "bogus": must be busy, changes, close, complete, eval, last_insert_rowid, or timeout}}
33 | do_test tcl-1.3 {
34 | execsql {CREATE TABLE t1(a int, b int)}
35 | execsql {INSERT INTO t1 VALUES(10,20)}
36 | set v [catch {
37 | db eval {SELECT * FROM t1} data {
38 | error "The error message"
39 | }
40 | } msg]
41 | lappend v $msg
42 | } {1 {The error message}}
43 | do_test tcl-1.4 {
44 | set v [catch {
45 | db eval {SELECT * FROM t2} data {
46 | error "The error message"
47 | }
48 | } msg]
49 | lappend v $msg
50 | } {1 {no such table: t2}}
51 | do_test tcl-1.5 {
52 | set v [catch {
53 | db eval {SELECT * FROM t1} data {
54 | break
55 | }
56 | } msg]
57 | lappend v $msg
58 | } {0 {}}
59 | do_test tcl-1.6 {
60 | set v [catch {
61 | db eval {SELECT * FROM t1} data {
62 | expr x*
63 | }
64 | } msg]
65 | regsub {:.*$} $msg {} msg
66 | lappend v $msg
67 | } {1 {syntax error in expression "x*"}}
68 |
69 | if {[sqlite -encoding]=="UTF-8" && [sqlite -tcl-uses-utf]} {
70 | do_test tcl-2.1 {
71 | execsql "CREATE TABLE t\u0123x(a int, b\u1235 float)"
72 | execsql "PRAGMA table_info(t\u0123x)"
73 | } "0 a int 0 {} 1 b\u1235 float 0 {}"
74 | do_test tcl-2.2 {
75 | execsql "INSERT INTO t\u0123x VALUES(1,2.3)"
76 | db eval "SELECT * FROM t\u0123x" result break
77 | set result(*)
78 | } "a b\u1235"
79 | }
80 |
81 | if {[sqlite -encoding]=="iso8859" && [sqlite -tcl-uses-utf]} {
82 | do_test tcl-2.1 {
83 | execsql "CREATE TABLE t\251x(a int, b\306 float)"
84 | execsql "PRAGMA table_info(t\251x)"
85 | } "0 a int 0 {} 1 b\306 float 0 {}"
86 | do_test tcl-2.2 {
87 | execsql "INSERT INTO t\251x VALUES(1,2.3)"
88 | db eval "SELECT * FROM t\251x" result break
89 | set result(*)
90 | } "a b\306"
91 | }
92 |
93 |
94 | finish_test
95 |
--------------------------------------------------------------------------------
/test/tester.tcl:
--------------------------------------------------------------------------------
1 | # 2001 September 15
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements some common TCL routines used for regression
12 | # testing the SQLite library
13 | #
14 | # $Id: tester.tcl,v 1.22 2002/03/06 22:01:37 drh Exp $
15 |
16 | # Make sure tclsqlite was compiled correctly. Abort now with an
17 | # error message if not.
18 | #
19 | if {[sqlite -tcl-uses-utf]} {
20 | if {"\u1234"=="u1234"} {
21 | puts stderr "***** BUILD PROBLEM *****"
22 | puts stderr "$argv0 was linked against an older version"
23 | puts stderr "of TCL that does not support Unicode, but uses a header"
24 | puts stderr "file (\"tcl.h\") from a new TCL version that does support"
25 | puts stderr "Unicode. This combination causes internal errors."
26 | puts stderr "Recompile using a TCL library and header file that match"
27 | puts stderr "and try again.\n**************************"
28 | exit 1
29 | }
30 | } else {
31 | if {"\u1234"!="u1234"} {
32 | puts stderr "***** BUILD PROBLEM *****"
33 | puts stderr "$argv0 was linked against an newer version"
34 | puts stderr "of TCL that supports Unicode, but uses a header file"
35 | puts stderr "(\"tcl.h\") from a old TCL version that does not support"
36 | puts stderr "Unicode. This combination causes internal errors."
37 | puts stderr "Recompile using a TCL library and header file that match"
38 | puts stderr "and try again.\n**************************"
39 | exit 1
40 | }
41 | }
42 |
43 | # Create a test database
44 | #
45 | catch {db close}
46 | file delete -force test.db
47 | file delete -force test.db-journal
48 | sqlite db ./test.db
49 | if {[info exists ::SETUP_SQL]} {
50 | db eval $::SETUP_SQL
51 | }
52 |
53 | # Abort early if this script has been run before.
54 | #
55 | if {[info exists nTest]} return
56 |
57 | # Set the test counters to zero
58 | #
59 | set nErr 0
60 | set nTest 0
61 | set nProb 0
62 | set skip_test 0
63 | set failList {}
64 |
65 | # Invoke the do_test procedure to run a single test
66 | #
67 | proc do_test {name cmd expected} {
68 | global argv nErr nTest skip_test
69 | if {$skip_test} {
70 | set skip_test 0
71 | return
72 | }
73 | if {[llength $argv]==0} {
74 | set go 1
75 | } else {
76 | set go 0
77 | foreach pattern $argv {
78 | if {[string match $pattern $name]} {
79 | set go 1
80 | break
81 | }
82 | }
83 | }
84 | if {!$go} return
85 | incr nTest
86 | puts -nonewline $name...
87 | flush stdout
88 | if {[catch {uplevel #0 "$cmd;\n"} result]} {
89 | puts "\nError: $result"
90 | incr nErr
91 | lappend ::failList $name
92 | if {$nErr>10} {puts "*** Giving up..."; finalize_testing}
93 | } elseif {[string compare $result $expected]} {
94 | puts "\nExpected: \[$expected\]\n Got: \[$result\]"
95 | incr nErr
96 | lappend ::failList $name
97 | if {$nErr>10} {puts "*** Giving up..."; finalize_testing}
98 | } else {
99 | puts " Ok"
100 | }
101 | }
102 |
103 | # Invoke this procedure on a test that is probabilistic
104 | # and might fail sometimes.
105 | #
106 | proc do_probtest {name cmd expected} {
107 | global argv nProb nTest skip_test
108 | if {$skip_test} {
109 | set skip_test 0
110 | return
111 | }
112 | if {[llength $argv]==0} {
113 | set go 1
114 | } else {
115 | set go 0
116 | foreach pattern $argv {
117 | if {[string match $pattern $name]} {
118 | set go 1
119 | break
120 | }
121 | }
122 | }
123 | if {!$go} return
124 | incr nTest
125 | puts -nonewline $name...
126 | flush stdout
127 | if {[catch {uplevel #0 "$cmd;\n"} result]} {
128 | puts "\nError: $result"
129 | incr nErr
130 | } elseif {[string compare $result $expected]} {
131 | puts "\nExpected: \[$expected\]\n Got: \[$result\]"
132 | puts "NOTE: The results of the previous test depend on system load"
133 | puts "and processor speed. The test may sometimes fail even if the"
134 | puts "library is working correctly."
135 | incr nProb
136 | } else {
137 | puts " Ok"
138 | }
139 | }
140 |
141 | # The procedure uses the special "sqlite_malloc_stat" command
142 | # (which is only available if SQLite is compiled with -DMEMORY_DEBUG=1)
143 | # to see how many malloc()s have not been free()ed. The number
144 | # of surplus malloc()s is stored in the global variable $::Leak.
145 | # If the value in $::Leak grows, it may mean there is a memory leak
146 | # in the library.
147 | #
148 | proc memleak_check {} {
149 | if {[info command sqlite_malloc_stat]!=""} {
150 | set r [sqlite_malloc_stat]
151 | set ::Leak [expr {[lindex $r 0]-[lindex $r 1]}]
152 | }
153 | }
154 |
155 | # Run this routine last
156 | #
157 | proc finish_test {} {
158 | finalize_testing
159 | }
160 | proc finalize_testing {} {
161 | global nTest nErr nProb
162 | if {$nErr==0} memleak_check
163 | catch {db close}
164 | puts "$nErr errors out of $nTest tests"
165 | puts "Failures on these tests: $::failList"
166 | if {$nProb>0} {
167 | puts "$nProb probabilistic tests also failed, but this does"
168 | puts "not necessarily indicate a malfunction."
169 | }
170 | exit [expr {$nErr>0}]
171 | }
172 |
173 | # A procedure to execute SQL
174 | #
175 | proc execsql {sql {db db}} {
176 | # puts "SQL = $sql"
177 | return [$db eval $sql]
178 | }
179 |
180 | # Execute SQL and catch exceptions.
181 | #
182 | proc catchsql {sql {db db}} {
183 | # puts "SQL = $sql"
184 | set r [catch {$db eval $sql} msg]
185 | lappend r $msg
186 | return $r
187 | }
188 |
189 | # Do an VDBE code dump on the SQL given
190 | #
191 | proc explain {sql {db db}} {
192 | puts ""
193 | puts "addr opcode p1 p2 p3 "
194 | puts "---- ------------ ------ ------ ---------------"
195 | $db eval "explain $sql" {} {
196 | puts [format {%-4d %-12.12s %-6d %-6d %s} $addr $opcode $p1 $p2 $p3]
197 | }
198 | }
199 |
200 | # Another procedure to execute SQL. This one includes the field
201 | # names in the returned list.
202 | #
203 | proc execsql2 {sql} {
204 | set result {}
205 | db eval $sql data {
206 | foreach f $data(*) {
207 | lappend result $f $data($f)
208 | }
209 | }
210 | return $result
211 | }
212 |
213 | # Delete a file or directory
214 | #
215 | proc forcedelete {filename} {
216 | if {[catch {file delete -force $filename}]} {
217 | exec rm -rf $filename
218 | }
219 | }
220 |
--------------------------------------------------------------------------------
/test/trigger1.test:
--------------------------------------------------------------------------------
1 | # The author disclaims copyright to this source code. In place of
2 | # a legal notice, here is a blessing:
3 | #
4 | # May you do good and not evil.
5 | # May you find forgiveness for yourself and forgive others.
6 | # May you share freely, never taking more than you give.
7 | #
8 | #***********************************************************************
9 | #
10 | # This file tests creating and dropping triggers, and interaction thereof
11 | # with the database COMMIT/ROLLBACK logic.
12 | #
13 | # 1. CREATE and DROP TRIGGER tests
14 | # trig-1.1: Error if table does not exist
15 | # trig-1.2: Error if trigger already exists
16 | # trig-1.3: Created triggers are deleted if the transaction is rolled back
17 | # trig-1.4: DROP TRIGGER removes trigger
18 | # trig-1.5: Dropped triggers are restored if the transaction is rolled back
19 | # trig-1.6: Error if dropped trigger doesn't exist
20 | # trig-1.7: Dropping the table automatically drops all triggers
21 | # trig-1.8: A trigger created on a TEMP table is not inserted into sqlite_master
22 | # trig-1.9: Ensure that we cannot create a trigger on sqlite_master
23 | # trig-1.10:
24 | # trig-1.11:
25 | # trig-1.12: Ensure that INSTEAD OF triggers cannot be created on tables
26 | # trig-1.13: Ensure that AFTER triggers cannot be created on views
27 | # trig-1.14: Ensure that BEFORE triggers cannot be created on views
28 | #
29 |
30 | set testdir [file dirname $argv0]
31 | source $testdir/tester.tcl
32 |
33 | do_test trig_cd-1.1 {
34 | catchsql {
35 | CREATE TRIGGER trig UPDATE ON no_such_table BEGIN
36 | SELECT * from sqlite_master;
37 | END;
38 | }
39 | } {1 {no such table: no_such_table}}
40 |
41 | execsql {
42 | CREATE TABLE t1(a);
43 | }
44 | execsql {
45 | CREATE TRIGGER tr1 INSERT ON t1 BEGIN
46 | INSERT INTO t1 values(1);
47 | END;
48 | }
49 | do_test trig_cd-1.2 {
50 | catchsql {
51 | CREATE TRIGGER tr1 DELETE ON t1 BEGIN
52 | SELECT * FROM sqlite_master;
53 | END
54 | }
55 | } {1 {trigger tr1 already exists}}
56 |
57 | do_test trig_cd-1.3 {
58 | catchsql {
59 | BEGIN;
60 | CREATE TRIGGER tr2 INSERT ON t1 BEGIN
61 | SELECT * from sqlite_master; END;
62 | ROLLBACK;
63 | CREATE TRIGGER tr2 INSERT ON t1 BEGIN
64 | SELECT * from sqlite_master; END;
65 | }
66 | } {0 {}}
67 |
68 | do_test trig_cd-1.4 {
69 | catchsql {
70 | DROP TRIGGER tr1;
71 | CREATE TRIGGER tr1 DELETE ON t1 BEGIN
72 | SELECT * FROM sqlite_master;
73 | END
74 | }
75 | } {0 {}}
76 |
77 | do_test trig_cd-1.5 {
78 | execsql {
79 | BEGIN;
80 | DROP TRIGGER tr2;
81 | ROLLBACK;
82 | DROP TRIGGER tr2;
83 | }
84 | } {}
85 |
86 | do_test trig_cd-1.6 {
87 | catchsql {
88 | DROP TRIGGER biggles;
89 | }
90 | } {1 {no such trigger: biggles}}
91 |
92 | do_test trig_cd-1.7 {
93 | catchsql {
94 | DROP TABLE t1;
95 | DROP TRIGGER tr1;
96 | }
97 | } {1 {no such trigger: tr1}}
98 |
99 | execsql {
100 | CREATE TEMP TABLE temp_table(a);
101 | }
102 | do_test trig_cd-1.8 {
103 | execsql {
104 | CREATE TRIGGER temp_trig UPDATE ON temp_table BEGIN
105 | SELECT * from sqlite_master;
106 | END;
107 | SELECT count(*) FROM sqlite_master WHERE name = 'temp_trig';
108 | }
109 | } {0}
110 |
111 | do_test trig_cd-1.9 {
112 | catchsql {
113 | CREATE TRIGGER tr1 AFTER UPDATE ON sqlite_master BEGIN
114 | SELECT * FROM sqlite_master;
115 | END;
116 | }
117 | } {1 {cannot create trigger on system table: sqlite_master}}
118 |
119 | # Check to make sure that a DELETE statement within the body of
120 | # a trigger does not mess up the DELETE that caused the trigger to
121 | # run in the first place.
122 | #
123 | do_test trig_cd-1.10 {
124 | execsql {
125 | create table t1(a,b);
126 | insert into t1 values(1,'a');
127 | insert into t1 values(2,'b');
128 | insert into t1 values(3,'c');
129 | insert into t1 values(4,'d');
130 | create trigger r1 after delete on t1 for each row begin
131 | delete from t1 WHERE a=old.a+2;
132 | end;
133 | delete from t1 where a in (1,3);
134 | select * from t1;
135 | drop table t1;
136 | }
137 | } {2 b 4 d}
138 | do_test trig_cd-1.11 {
139 | execsql {
140 | create table t1(a,b);
141 | insert into t1 values(1,'a');
142 | insert into t1 values(2,'b');
143 | insert into t1 values(3,'c');
144 | insert into t1 values(4,'d');
145 | create trigger r1 after update on t1 for each row begin
146 | delete from t1 WHERE a=old.a+2;
147 | end;
148 | update t1 set b='x-' || b where a in (1,3);
149 | select * from t1;
150 | drop table t1;
151 | }
152 | } {1 x-a 2 b 4 d}
153 |
154 | # Ensure that we cannot create INSTEAD OF triggers on tables
155 | do_test trig_cd-1.12 {
156 | catchsql {
157 | create table t1(a,b);
158 | create trigger t1t instead of update on t1 for each row begin
159 | delete from t1 WHERE a=old.a+2;
160 | end;
161 | }
162 | } {1 {cannot create INSTEAD OF trigger on table: t1}}
163 | # Ensure that we cannot create BEFORE triggers on views
164 | do_test trig_cd-1.13 {
165 | catchsql {
166 | create view v1 as select * from t1;
167 | create trigger v1t before update on v1 for each row begin
168 | delete from t1 WHERE a=old.a+2;
169 | end;
170 | }
171 | } {1 {cannot create BEFORE trigger on view: v1}}
172 | # Ensure that we cannot create AFTER triggers on views
173 | do_test trig_cd-1.14 {
174 | catchsql {
175 | create table t1(a,b);
176 | create view v1 as select * from t1;
177 | create trigger v1t AFTER update on v1 for each row begin
178 | delete from t1 WHERE a=old.a+2;
179 | end;
180 | }
181 | } {1 {cannot create AFTER trigger on view: v1}}
182 |
183 | finish_test
184 |
--------------------------------------------------------------------------------
/test/trigger3.test:
--------------------------------------------------------------------------------
1 | # The author disclaims copyright to this source code. In place of
2 | # a legal notice, here is a blessing:
3 | #
4 | # May you do good and not evil.
5 | # May you find forgiveness for yourself and forgive others.
6 | # May you share freely, never taking more than you give.
7 | #
8 | #***********************************************************************
9 | #
10 | # This file tests the RAISE() function.
11 | #
12 |
13 | set testdir [file dirname $argv0]
14 | source $testdir/tester.tcl
15 |
16 | # Test that we can cause ROLLBACK, FAIL and ABORT correctly
17 | # catchsql { DROP TABLE tbl; }
18 | catchsql { CREATE TABLE tbl (a, b, c) }
19 |
20 | execsql {
21 | CREATE TRIGGER before_tbl_insert BEFORE INSERT ON tbl BEGIN SELECT CASE
22 | WHEN (new.a = 4) THEN RAISE(IGNORE) END;
23 | END;
24 |
25 | CREATE TRIGGER after_tbl_insert AFTER INSERT ON tbl BEGIN SELECT CASE
26 | WHEN (new.a = 1) THEN RAISE(ABORT, 'Trigger abort')
27 | WHEN (new.a = 2) THEN RAISE(FAIL, 'Trigger fail')
28 | WHEN (new.a = 3) THEN RAISE(ROLLBACK, 'Trigger rollback') END;
29 | END;
30 | }
31 | # ABORT
32 | do_test trig-raise-1.1 {
33 | catchsql {
34 | BEGIN;
35 | INSERT INTO tbl VALUES (5, 5, 6);
36 | INSERT INTO tbl VALUES (1, 5, 6);
37 | }
38 | } {1 {Trigger abort}}
39 |
40 | do_test trig-raise-1.2 {
41 | execsql {
42 | SELECT * FROM tbl;
43 | ROLLBACK;
44 | }
45 | } {5 5 6}
46 |
47 | # FAIL
48 | do_test trig-raise-2.1 {
49 | catchsql {
50 | BEGIN;
51 | INSERT INTO tbl VALUES (5, 5, 6);
52 | INSERT INTO tbl VALUES (2, 5, 6);
53 | }
54 | } {1 {Trigger fail}}
55 | do_test trig-raise-2.2 {
56 | execsql {
57 | SELECT * FROM tbl;
58 | ROLLBACK;
59 | }
60 | } {5 5 6 2 5 6}
61 | # ROLLBACK
62 | do_test trig-raise-3.1 {
63 | catchsql {
64 | BEGIN;
65 | INSERT INTO tbl VALUES (5, 5, 6);
66 | INSERT INTO tbl VALUES (3, 5, 6);
67 | }
68 | } {1 {Trigger rollback}}
69 | do_test trig-raise-3.2 {
70 | execsql {
71 | SELECT * FROM tbl;
72 | ROLLBACK;
73 | }
74 | } {}
75 | # IGNORE
76 | do_test trig-raise-4.1 {
77 | catchsql {
78 | BEGIN;
79 | INSERT INTO tbl VALUES (5, 5, 6);
80 | INSERT INTO tbl VALUES (4, 5, 6);
81 | }
82 | } {0 {}}
83 | do_test trig-raise-4.2 {
84 | execsql {
85 | SELECT * FROM tbl;
86 | ROLLBACK;
87 | }
88 | } {5 5 6}
89 |
90 | # Check that we can also do RAISE(IGNORE) for UPDATE and DELETE
91 | execsql {DROP TABLE tbl;}
92 | execsql {CREATE TABLE tbl (a, b, c);}
93 | execsql {INSERT INTO tbl VALUES(1, 2, 3);}
94 | execsql {INSERT INTO tbl VALUES(4, 5, 6);}
95 | execsql {
96 | CREATE TRIGGER before_tbl_update BEFORE UPDATE ON tbl BEGIN
97 | SELECT CASE WHEN (old.a = 1) THEN RAISE(IGNORE) END;
98 | END;
99 |
100 | CREATE TRIGGER before_tbl_delete BEFORE DELETE ON tbl BEGIN
101 | SELECT CASE WHEN (old.a = 1) THEN RAISE(IGNORE) END;
102 | END;
103 | }
104 | do_test trig-raise-5.1 {
105 | execsql {
106 | UPDATE tbl SET c = 10;
107 | SELECT * FROM tbl;
108 | }
109 | } {1 2 3 4 5 10}
110 | do_test trig-raise-5.2 {
111 | execsql {
112 | DELETE FROM tbl;
113 | SELECT * FROM tbl;
114 | }
115 | } {1 2 3}
116 |
117 | # Check that RAISE(IGNORE) works correctly for nested triggers:
118 | execsql {CREATE TABLE tbl2(a, b, c)}
119 | execsql {
120 | CREATE TRIGGER after_tbl2_insert AFTER INSERT ON tbl2 BEGIN
121 | UPDATE tbl SET c = 10;
122 | INSERT INTO tbl2 VALUES (new.a, new.b, new.c);
123 | END;
124 | }
125 | do_test trig-raise-6 {
126 | execsql {
127 | INSERT INTO tbl2 VALUES (1, 2, 3);
128 | SELECT * FROM tbl2;
129 | SELECT * FROM tbl;
130 | }
131 | } {1 2 3 1 2 3 1 2 3}
132 |
133 | # Check that things also work for view-triggers
134 | execsql {CREATE VIEW tbl_view AS SELECT * FROM tbl}
135 | execsql {
136 | CREATE TRIGGER tbl_view_insert INSTEAD OF INSERT ON tbl_view BEGIN
137 | SELECT CASE WHEN (new.a = 1) THEN RAISE(ROLLBACK, 'View rollback')
138 | WHEN (new.a = 2) THEN RAISE(IGNORE)
139 | WHEN (new.a = 3) THEN RAISE(ABORT, 'View abort') END;
140 | END;
141 | }
142 |
143 | do_test trig-raise-7.1 {
144 | catchsql {
145 | INSERT INTO tbl_view VALUES(1, 2, 3);
146 | }
147 | } {1 {View rollback}}
148 | do_test trig-raise-7.2 {
149 | catchsql {
150 | INSERT INTO tbl_view VALUES(2, 2, 3);
151 | }
152 | } {0 {}}
153 | do_test trig-raise-7.3 {
154 | catchsql {
155 | INSERT INTO tbl_view VALUES(3, 2, 3);
156 | }
157 | } {1 {View abort}}
158 |
159 | catchsql { DROP TABLE tbl; }
160 | catchsql { DROP TABLE tbl2; }
161 | catchsql { DROP VIEW tbl_view; }
162 |
163 |
164 |
--------------------------------------------------------------------------------
/test/unique.test:
--------------------------------------------------------------------------------
1 | # 2001 September 27
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is testing the CREATE UNIQUE INDEX statement,
13 | # and primary keys, and the UNIQUE constraint on table columns
14 | #
15 | # $Id: unique.test,v 1.4 2002/05/26 20:54:35 drh Exp $
16 |
17 | set testdir [file dirname $argv0]
18 | source $testdir/tester.tcl
19 |
20 | # Try to create a table with two primary keys.
21 | # (This is allowed in SQLite even that it is not valid SQL)
22 | #
23 | do_test unique-1.1 {
24 | catchsql {
25 | CREATE TABLE t1(
26 | a int PRIMARY KEY,
27 | b int PRIMARY KEY,
28 | c text
29 | );
30 | }
31 | } {1 {table "t1" has more than one primary key}}
32 | do_test unique-1.1b {
33 | catchsql {
34 | CREATE TABLE t1(
35 | a int PRIMARY KEY,
36 | b int UNIQUE,
37 | c text
38 | );
39 | }
40 | } {0 {}}
41 | do_test unique-1.2 {
42 | catchsql {
43 | INSERT INTO t1(a,b,c) VALUES(1,2,3)
44 | }
45 | } {0 {}}
46 | do_test unique-1.3 {
47 | catchsql {
48 | INSERT INTO t1(a,b,c) VALUES(1,3,4)
49 | }
50 | } {1 {constraint failed}}
51 | do_test unique-1.4 {
52 | execsql {
53 | SELECT * FROM t1 ORDER BY a;
54 | }
55 | } {1 2 3}
56 | do_test unique-1.5 {
57 | catchsql {
58 | INSERT INTO t1(a,b,c) VALUES(3,2,4)
59 | }
60 | } {1 {constraint failed}}
61 | do_test unique-1.6 {
62 | execsql {
63 | SELECT * FROM t1 ORDER BY a;
64 | }
65 | } {1 2 3}
66 | do_test unique-1.7 {
67 | catchsql {
68 | INSERT INTO t1(a,b,c) VALUES(3,4,5)
69 | }
70 | } {0 {}}
71 | do_test unique-1.8 {
72 | execsql {
73 | SELECT * FROM t1 ORDER BY a;
74 | }
75 | } {1 2 3 3 4 5}
76 |
77 | do_test unique-2.0 {
78 | execsql {
79 | DROP TABLE t1;
80 | CREATE TABLE t2(a int, b int);
81 | INSERT INTO t2(a,b) VALUES(1,2);
82 | INSERT INTO t2(a,b) VALUES(3,4);
83 | SELECT * FROM t2 ORDER BY a;
84 | }
85 | } {1 2 3 4}
86 | do_test unique-2.1 {
87 | catchsql {
88 | CREATE UNIQUE INDEX i2 ON t2(a)
89 | }
90 | } {0 {}}
91 | do_test unique-2.2 {
92 | catchsql {
93 | SELECT * FROM t2 ORDER BY a
94 | }
95 | } {0 {1 2 3 4}}
96 | do_test unique-2.3 {
97 | catchsql {
98 | INSERT INTO t2 VALUES(1,5);
99 | }
100 | } {1 {constraint failed}}
101 | do_test unique-2.4 {
102 | catchsql {
103 | SELECT * FROM t2 ORDER BY a
104 | }
105 | } {0 {1 2 3 4}}
106 | do_test unique-2.5 {
107 | catchsql {
108 | DROP INDEX i2;
109 | SELECT * FROM t2 ORDER BY a;
110 | }
111 | } {0 {1 2 3 4}}
112 | do_test unique-2.6 {
113 | catchsql {
114 | INSERT INTO t2 VALUES(1,5)
115 | }
116 | } {0 {}}
117 | do_test unique-2.7 {
118 | catchsql {
119 | SELECT * FROM t2 ORDER BY a, b;
120 | }
121 | } {0 {1 2 1 5 3 4}}
122 | do_test unique-2.8 {
123 | catchsql {
124 | CREATE UNIQUE INDEX i2 ON t2(a);
125 | }
126 | } {1 {constraint failed}}
127 | do_test unique-2.9 {
128 | catchsql {
129 | CREATE INDEX i2 ON t2(a);
130 | }
131 | } {0 {}}
132 |
133 | # Test the UNIQUE keyword as used on two or more fields.
134 | #
135 | do_test unique-3.1 {
136 | catchsql {
137 | CREATE TABLE t3(
138 | a int,
139 | b int,
140 | c int,
141 | d int,
142 | unique(a,c,d)
143 | );
144 | }
145 | } {0 {}}
146 | do_test unique-3.2 {
147 | catchsql {
148 | INSERT INTO t3(a,b,c,d) VALUES(1,2,3,4);
149 | SELECT * FROM t3 ORDER BY a,b,c,d;
150 | }
151 | } {0 {1 2 3 4}}
152 | do_test unique-3.3 {
153 | catchsql {
154 | INSERT INTO t3(a,b,c,d) VALUES(1,2,3,5);
155 | SELECT * FROM t3 ORDER BY a,b,c,d;
156 | }
157 | } {0 {1 2 3 4 1 2 3 5}}
158 | do_test unique-3.4 {
159 | catchsql {
160 | INSERT INTO t3(a,b,c,d) VALUES(1,4,3,5);
161 | SELECT * FROM t3 ORDER BY a,b,c,d;
162 | }
163 | } {1 {constraint failed}}
164 |
165 | # Make sure NULLs are distinct as far as the UNIQUE tests are
166 | # concerned.
167 | #
168 | do_test unique-4.1 {
169 | execsql {
170 | CREATE TABLE t4(a UNIQUE, b, c, UNIQUE(b,c));
171 | INSERT INTO t4 VALUES(1,2,3);
172 | INSERT INTO t4 VALUES(NULL, 2, NULL);
173 | SELECT * FROM t4;
174 | }
175 | } {1 2 3 {} 2 {}}
176 | do_test unique-4.2 {
177 | catchsql {
178 | INSERT INTO t4 VALUES(NULL, 3, 4);
179 | }
180 | } {0 {}}
181 | do_test unique-4.3 {
182 | execsql {
183 | SELECT * FROM t4
184 | }
185 | } {1 2 3 {} 2 {} {} 3 4}
186 | do_test unique-4.4 {
187 | catchsql {
188 | INSERT INTO t4 VALUES(2, 2, NULL);
189 | }
190 | } {0 {}}
191 | do_test unique-4.5 {
192 | execsql {
193 | SELECT * FROM t4
194 | }
195 | } {1 2 3 {} 2 {} {} 3 4 2 2 {}}
196 |
197 |
198 | finish_test
199 |
--------------------------------------------------------------------------------
/test/vacuum.test:
--------------------------------------------------------------------------------
1 | # 2001 September 15
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is testing the VACUUM statement.
13 | #
14 | # $Id: vacuum.test,v 1.7 2002/03/03 02:49:52 drh Exp $
15 |
16 | set testdir [file dirname $argv0]
17 | source $testdir/tester.tcl
18 |
19 | # The vacuum command no longer functions. There is
20 | # nothing to test.
21 |
22 | # finish_test
23 |
--------------------------------------------------------------------------------
/test/view.test:
--------------------------------------------------------------------------------
1 | # 2002 February 26
2 | #
3 | # The author disclaims copyright to this source code. In place of
4 | # a legal notice, here is a blessing:
5 | #
6 | # May you do good and not evil.
7 | # May you find forgiveness for yourself and forgive others.
8 | # May you share freely, never taking more than you give.
9 | #
10 | #***********************************************************************
11 | # This file implements regression tests for SQLite library. The
12 | # focus of this file is testing VIEW statements.
13 | #
14 | # $Id: view.test,v 1.5 2002/05/08 21:30:16 drh Exp $
15 | set testdir [file dirname $argv0]
16 | source $testdir/tester.tcl
17 |
18 | do_test view-1.0 {
19 | execsql {
20 | CREATE TABLE t1(a,b,c);
21 | INSERT INTO t1 VALUES(1,2,3);
22 | INSERT INTO t1 VALUES(4,5,6);
23 | INSERT INTO t1 VALUES(7,8,9);
24 | SELECT * FROM t1;
25 | }
26 | } {1 2 3 4 5 6 7 8 9}
27 |
28 | do_test view-1.1 {
29 | execsql {
30 | BEGIN;
31 | CREATE VIEW v1 AS SELECT a,b FROM t1;
32 | SELECT * FROM v1 ORDER BY a;
33 | }
34 | } {1 2 4 5 7 8}
35 | do_test view-1.2 {
36 | catchsql {
37 | ROLLBACK;
38 | SELECT * FROM v1 ORDER BY a;
39 | }
40 | } {1 {no such table: v1}}
41 | do_test view-1.3 {
42 | execsql {
43 | CREATE VIEW v1 AS SELECT a,b FROM t1;
44 | SELECT * FROM v1 ORDER BY a;
45 | }
46 | } {1 2 4 5 7 8}
47 | do_test view-1.3.1 {
48 | db close
49 | sqlite db test.db
50 | execsql {
51 | SELECT * FROM v1 ORDER BY a;
52 | }
53 | } {1 2 4 5 7 8}
54 | do_test view-1.4 {
55 | catchsql {
56 | DROP VIEW v1;
57 | SELECT * FROM v1 ORDER BY a;
58 | }
59 | } {1 {no such table: v1}}
60 | do_test view-1.5 {
61 | execsql {
62 | CREATE VIEW v1 AS SELECT a,b FROM t1;
63 | SELECT * FROM v1 ORDER BY a;
64 | }
65 | } {1 2 4 5 7 8}
66 | do_test view-1.6 {
67 | catchsql {
68 | DROP TABLE t1;
69 | SELECT * FROM v1 ORDER BY a;
70 | }
71 | } {1 {no such table: t1}}
72 | do_test view-1.7 {
73 | execsql {
74 | CREATE TABLE t1(x,a,b,c);
75 | INSERT INTO t1 VALUES(1,2,3,4);
76 | INSERT INTO t1 VALUES(4,5,6,7);
77 | INSERT INTO t1 VALUES(7,8,9,10);
78 | SELECT * FROM v1 ORDER BY a;
79 | }
80 | } {2 3 5 6 8 9}
81 | do_test view-1.8 {
82 | db close
83 | sqlite db test.db
84 | execsql {
85 | SELECT * FROM v1 ORDER BY a;
86 | }
87 | } {2 3 5 6 8 9}
88 |
89 | do_test view-2.1 {
90 | execsql {
91 | CREATE VIEW v2 AS SELECT * FROM t1 WHERE a>5
92 | }; # No semicolon
93 | execsql2 {
94 | SELECT * FROM v2;
95 | }
96 | } {x 7 a 8 b 9 c 10}
97 | do_test view-2.2 {
98 | catchsql {
99 | INSERT INTO v2 VALUES(1,2,3,4);
100 | }
101 | } {1 {view v2 may not be modified}}
102 | do_test view-2.3 {
103 | catchsql {
104 | UPDATE v2 SET a=10 WHERE a=5;
105 | }
106 | } {1 {view v2 may not be modified}}
107 | do_test view-2.4 {
108 | catchsql {
109 | DELETE FROM v2;
110 | }
111 | } {1 {view v2 may not be modified}}
112 | do_test view-2.5 {
113 | execsql {
114 | INSERT INTO t1 VALUES(11,12,13,14);
115 | SELECT * FROM v2 ORDER BY x;
116 | }
117 | } {7 8 9 10 11 12 13 14}
118 | do_test view-2.6 {
119 | execsql {
120 | SELECT x FROM v2 WHERE a>10
121 | }
122 | } {11}
123 |
124 | # Test that column name of views are generated correctly.
125 | #
126 | do_test view-3.1 {
127 | execsql2 {
128 | SELECT * FROM v1 LIMIT 1
129 | }
130 | } {a 2 b 3}
131 | do_test view-3.2 {
132 | execsql2 {
133 | SELECT * FROM v2 LIMIT 1
134 | }
135 | } {x 7 a 8 b 9 c 10}
136 | do_test view-3.3 {
137 | execsql2 {
138 | DROP VIEW v1;
139 | CREATE VIEW v1 AS SELECT a AS 'xyz', b+c AS 'pqr', c-b FROM t1;
140 | SELECT * FROM v1 LIMIT 1
141 | }
142 | } {xyz 2 pqr 7 c-b 1}
143 | do_test view-3.4 {
144 | execsql2 {
145 | CREATE VIEW v3 AS SELECT a FROM t1 UNION SELECT b FROM t1 ORDER BY b;
146 | SELECT * FROM v3 LIMIT 4;
147 | }
148 | } {b 2 b 3 b 5 b 6}
149 | do_test view-3.5 {
150 | execsql2 {
151 | CREATE VIEW v4 AS
152 | SELECT a, b FROM t1
153 | UNION
154 | SELECT b AS 'x', a AS 'y' FROM t1
155 | ORDER BY x, y;
156 | SELECT y FROM v4 ORDER BY y LIMIT 4;
157 | }
158 | } {y 2 y 3 y 5 y 6}
159 |
160 |
161 | finish_test
162 |
--------------------------------------------------------------------------------
/tool/memleak.awk:
--------------------------------------------------------------------------------
1 | #
2 | # This script looks for memory leaks by analyzing the output of "sqlite"
3 | # when compiled with the MEMORY_DEBUG=2 option.
4 | #
5 | /^malloc / {
6 | mem[$5] = $0
7 | }
8 | /^realloc / {
9 | mem[$7] = "";
10 | mem[$9] = $0
11 | }
12 | /^free / {
13 | mem[$5] = "";
14 | str[$5] = ""
15 | }
16 | /^string at / {
17 | addr = $3
18 | sub("string at " addr " is ","")
19 | str[addr] = $0
20 | }
21 | END {
22 | for(addr in mem){
23 | if( mem[addr]=="" ) continue
24 | print mem[addr], str[addr]
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tool/opNames.awk:
--------------------------------------------------------------------------------
1 | # Read the sqliteVdbe.h file and generate a table of opcode names.
2 | #
3 | BEGIN {
4 | printf "static char *zOpName[] = { 0,\n"
5 | n = 0
6 | }
7 | /^#define OP_MAX/ {
8 | next
9 | }
10 | /^#define OP_/ {
11 | name = "\"" substr($2,4) "\","
12 | if( n<3 ){
13 | printf " %-19s", name
14 | n++
15 | } else {
16 | printf " %s\n", name
17 | n = 0
18 | }
19 | }
20 | END {
21 | if( n ){ printf "\n" }
22 | printf "};\n"
23 | }
24 |
--------------------------------------------------------------------------------
/tool/opcodeDoc.awk:
--------------------------------------------------------------------------------
1 | #
2 | # Extract opcode documentation for sqliteVdbe.c and generate HTML
3 | #
4 | BEGIN {
5 | print ""
6 | print "SQLite Virtual Database Engine Opcodes
"
7 | print ""
8 | }
9 | / Opcode: /,/\*\// {
10 | if( $2=="Opcode:" ){
11 | printf "%s %s %s %s | \n\n", $3, $4, $5, $6
12 | }else if( $1=="*/" ){
13 | printf " |
\n"
14 | }else if( NF>1 ){
15 | sub(/^ *\*\* /,"")
16 | gsub(/,"<")
17 | gsub(/&/,"&")
18 | print
19 | }
20 | }
21 | END {
22 | print "
"
23 | }
24 |
--------------------------------------------------------------------------------
/tool/renumberOps.awk:
--------------------------------------------------------------------------------
1 | # Run this script on sqliteVdbe.h to renumber the opcodes sequentially.
2 | #
3 | BEGIN { cnt = 1 }
4 | /^#define OP_MAX/ {
5 | printf "#define %-20s %3d\n",$2, cnt-1
6 | next
7 | }
8 | /^#define OP_/ {
9 | printf "#define %-20s %3d\n",$2, cnt++
10 | next
11 | }
12 | { print }
13 |
--------------------------------------------------------------------------------
/tool/report1.txt:
--------------------------------------------------------------------------------
1 | The SQL database used for ACD contains 113 tables and indices implemented
2 | in GDBM. The following are statistics on the sizes of keys and data
3 | within these tables and indices.
4 |
5 | Entries: 962080
6 | Size: 45573853
7 | Avg Size: 48
8 | Key Size: 11045299
9 | Avg Key Size: 12
10 | Max Key Size: 99
11 |
12 |
13 | Size of key Cummulative
14 | and data Instances Percentage
15 | ------------ ---------- -----------
16 | 0..8 266 0%
17 | 9..12 5485 0%
18 | 13..16 73633 8%
19 | 17..24 180918 27%
20 | 25..32 209823 48%
21 | 33..40 148995 64%
22 | 41..48 76304 72%
23 | 49..56 14346 73%
24 | 57..64 15725 75%
25 | 65..80 44916 80%
26 | 81..96 127815 93%
27 | 97..112 34769 96%
28 | 113..128 13314 98%
29 | 129..144 8098 99%
30 | 145..160 3355 99%
31 | 161..176 1159 99%
32 | 177..192 629 99%
33 | 193..208 221 99%
34 | 209..224 210 99%
35 | 225..240 129 99%
36 | 241..256 57 99%
37 | 257..288 496 99%
38 | 289..320 60 99%
39 | 321..352 37 99%
40 | 353..384 46 99%
41 | 385..416 22 99%
42 | 417..448 24 99%
43 | 449..480 26 99%
44 | 481..512 27 99%
45 | 513..1024 471 99%
46 | 1025..2048 389 99%
47 | 2049..4096 182 99%
48 | 4097..8192 74 99%
49 | 8193..16384 34 99%
50 | 16385..32768 17 99%
51 | 32769..65536 5 99%
52 | 65537..131073 3 100%
53 |
54 |
55 | This information is gathered to help design the new built-in
56 | backend for sqlite 2.0. Note in particular that 99% of all
57 | database entries have a combined key and data size of less than
58 | 144 bytes. So if a leaf node in the new database is able to
59 | store 144 bytes of combined key and data, only 1% of the leaves
60 | will require overflow pages. Furthermore, note that no key
61 | is larger than 99 bytes, so if the key will never be on an
62 | overflow page.
63 |
64 | The average combined size of key+data is 48. Add in 16 bytes of
65 | overhead for a total of 64. That means that a 1K page will
66 | store (on average) about 16 entries.
67 |
--------------------------------------------------------------------------------
/tool/speedtest2.tcl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/tclsh
2 | #
3 | # Run this script using TCLSH to do a speed comparison between
4 | # various versions of SQLite and PostgreSQL and MySQL
5 | #
6 |
7 | # Run a test
8 | #
9 | set cnt 1
10 | proc runtest {title} {
11 | global cnt
12 | set sqlfile test$cnt.sql
13 | puts "Test $cnt: $title
"
14 | incr cnt
15 | set fd [open $sqlfile r]
16 | set sql [string trim [read $fd [file size $sqlfile]]]
17 | close $fd
18 | set sx [split $sql \n]
19 | set n [llength $sx]
20 | if {$n>8} {
21 | set sql {}
22 | for {set i 0} {$i<3} {incr i} {append sql [lindex $sx $i]
\n}
23 | append sql "... [expr {$n-6}] lines omitted
\n"
24 | for {set i [expr {$n-3}]} {$i<$n} {incr i} {
25 | append sql [lindex $sx $i]
\n
26 | }
27 | } else {
28 | regsub -all \n [string trim $sql]
sql
29 | }
30 | puts ""
31 | puts "$sql"
32 | puts "
"
33 | set format {%s | %.3f |
}
34 | set delay 1000
35 | exec sync; after $delay;
36 | set t [time "exec psql drh <$sqlfile" 1]
37 | set t [expr {[lindex $t 0]/1000000.0}]
38 | puts [format $format PostgreSQL: $t]
39 | exec sync; after $delay;
40 | set t [time "exec mysql -f drh <$sqlfile" 1]
41 | set t [expr {[lindex $t 0]/1000000.0}]
42 | puts [format $format MySQL: $t]
43 | # set t [time "exec ./sqlite232 s232.db <$sqlfile" 1]
44 | # set t [expr {[lindex $t 0]/1000000.0}]
45 | # puts [format $format {SQLite 2.3.2:} $t]
46 | # set t [time "exec ./sqlite-100 s100.db <$sqlfile" 1]
47 | # set t [expr {[lindex $t 0]/1000000.0}]
48 | # puts [format $format {SQLite 2.4 (cache=100):} $t]
49 | exec sync; after $delay;
50 | set t [time "exec ./sqlite240 s2k.db <$sqlfile" 1]
51 | set t [expr {[lindex $t 0]/1000000.0}]
52 | puts [format $format {SQLite 2.4:} $t]
53 | exec sync; after $delay;
54 | set t [time "exec ./sqlite240 sns.db <$sqlfile" 1]
55 | set t [expr {[lindex $t 0]/1000000.0}]
56 | puts [format $format {SQLite 2.4 (nosync):} $t]
57 | # set t [time "exec ./sqlite-t1 st1.db <$sqlfile" 1]
58 | # set t [expr {[lindex $t 0]/1000000.0}]
59 | # puts [format $format {SQLite 2.4 (test):} $t]
60 | puts "
"
61 | }
62 |
63 | # Initialize the environment
64 | #
65 | expr srand(1)
66 | catch {exec /bin/sh -c {rm -f s*.db}}
67 | set fd [open clear.sql w]
68 | puts $fd {
69 | drop table t1;
70 | drop table t2;
71 | }
72 | close $fd
73 | catch {exec psql drh =1000} {
96 | set txt "[number_name [expr {$n/1000}]] thousand"
97 | set n [expr {$n%1000}]
98 | } else {
99 | set txt {}
100 | }
101 | if {$n>=100} {
102 | append txt " [lindex $::ones [expr {$n/100}]] hundred"
103 | set n [expr {$n%100}]
104 | }
105 | if {$n>=20} {
106 | append txt " [lindex $::tens [expr {$n/10}]]"
107 | set n [expr {$n%10}]
108 | }
109 | if {$n>0} {
110 | append txt " [lindex $::ones $n]"
111 | }
112 | set txt [string trim $txt]
113 | if {$txt==""} {set txt zero}
114 | return $txt
115 | }
116 |
117 |
118 | set fd [open test$cnt.sql w]
119 | puts $fd "BEGIN;"
120 | puts $fd "CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100));"
121 | for {set i 1} {$i<=25000} {incr i} {
122 | set r [expr {int(rand()*500000)}]
123 | puts $fd "INSERT INTO t1 VALUES($i,$r,'[number_name $r]');"
124 | }
125 | puts $fd "COMMIT;"
126 | close $fd
127 | runtest {25000 INSERTs in a transaction}
128 |
129 |
130 | set fd [open test$cnt.sql w]
131 | puts $fd "DELETE FROM t1;"
132 | close $fd
133 | runtest {DELETE everything}
134 |
135 |
136 | set fd [open test$cnt.sql w]
137 | puts $fd "BEGIN;"
138 | for {set i 1} {$i<=25000} {incr i} {
139 | set r [expr {int(rand()*500000)}]
140 | puts $fd "INSERT INTO t1 VALUES($i,$r,'[number_name $r]');"
141 | }
142 | puts $fd "COMMIT;"
143 | close $fd
144 | runtest {25000 INSERTs in a transaction}
145 |
146 |
147 | set fd [open test$cnt.sql w]
148 | puts $fd "DELETE FROM t1;"
149 | close $fd
150 | runtest {DELETE everything}
151 |
152 |
153 | set fd [open test$cnt.sql w]
154 | puts $fd "BEGIN;"
155 | for {set i 1} {$i<=25000} {incr i} {
156 | set r [expr {int(rand()*500000)}]
157 | puts $fd "INSERT INTO t1 VALUES($i,$r,'[number_name $r]');"
158 | }
159 | puts $fd "COMMIT;"
160 | close $fd
161 | runtest {25000 INSERTs in a transaction}
162 |
163 |
164 | set fd [open test$cnt.sql w]
165 | puts $fd "DELETE FROM t1;"
166 | close $fd
167 | runtest {DELETE everything}
168 |
169 |
170 | set fd [open test$cnt.sql w]
171 | puts $fd "BEGIN;"
172 | for {set i 1} {$i<=25000} {incr i} {
173 | set r [expr {int(rand()*500000)}]
174 | puts $fd "INSERT INTO t1 VALUES($i,$r,'[number_name $r]');"
175 | }
176 | puts $fd "COMMIT;"
177 | close $fd
178 | runtest {25000 INSERTs in a transaction}
179 |
180 |
181 | set fd [open test$cnt.sql w]
182 | puts $fd "DELETE FROM t1;"
183 | close $fd
184 | runtest {DELETE everything}
185 |
186 |
187 | set fd [open test$cnt.sql w]
188 | puts $fd "BEGIN;"
189 | for {set i 1} {$i<=25000} {incr i} {
190 | set r [expr {int(rand()*500000)}]
191 | puts $fd "INSERT INTO t1 VALUES($i,$r,'[number_name $r]');"
192 | }
193 | puts $fd "COMMIT;"
194 | close $fd
195 | runtest {25000 INSERTs in a transaction}
196 |
197 |
198 | set fd [open test$cnt.sql w]
199 | puts $fd "DELETE FROM t1;"
200 | close $fd
201 | runtest {DELETE everything}
202 |
203 |
204 | set fd [open test$cnt.sql w]
205 | puts $fd {DROP TABLE t1;}
206 | close $fd
207 | runtest {DROP TABLE}
208 |
--------------------------------------------------------------------------------
/www/arch.fig:
--------------------------------------------------------------------------------
1 | #FIG 3.2
2 | Portrait
3 | Center
4 | Inches
5 | Letter
6 | 100.00
7 | Single
8 | -2
9 | 1200 2
10 | 2 1 0 3 0 7 100 0 -1 0.000 0 0 -1 1 0 2
11 | 1 1 3.00 75.00 135.00
12 | 3675 8550 3675 9075
13 | 2 1 0 3 0 7 100 0 -1 0.000 0 0 -1 1 0 2
14 | 1 1 3.00 75.00 135.00
15 | 3675 7200 3675 7725
16 | 2 1 0 3 0 7 100 0 -1 0.000 0 0 -1 1 0 2
17 | 1 1 3.00 75.00 135.00
18 | 3675 5775 3675 6300
19 | 2 1 0 3 0 7 100 0 -1 0.000 0 0 -1 1 0 2
20 | 1 1 3.00 75.00 135.00
21 | 3675 3975 3675 4500
22 | 2 1 0 3 0 7 100 0 -1 0.000 0 0 -1 1 0 2
23 | 1 1 3.00 75.00 135.00
24 | 3675 2625 3675 3150
25 | 2 1 0 3 0 7 100 0 -1 0.000 0 0 -1 1 0 2
26 | 1 1 3.00 75.00 135.00
27 | 3675 1275 3675 1800
28 | 2 1 0 3 0 7 100 0 -1 0.000 0 0 -1 1 0 2
29 | 1 1 3.00 75.00 135.00
30 | 3675 9900 3675 10425
31 | 2 2 0 1 0 11 100 0 20 0.000 0 0 7 0 0 5
32 | 2550 10425 4875 10425 4875 11250 2550 11250 2550 10425
33 | 2 2 0 1 0 11 100 0 20 0.000 0 0 7 0 0 5
34 | 2550 9075 4875 9075 4875 9900 2550 9900 2550 9075
35 | 2 2 0 1 0 11 100 0 20 0.000 0 0 7 0 0 5
36 | 2550 7725 4875 7725 4875 8550 2550 8550 2550 7725
37 | 2 2 0 1 0 11 100 0 20 0.000 0 0 7 0 0 5
38 | 2550 6300 4875 6300 4875 7200 2550 7200 2550 6300
39 | 2 2 0 1 0 11 100 0 20 0.000 0 0 7 0 0 5
40 | 2550 4500 4875 4500 4875 5775 2550 5775 2550 4500
41 | 2 2 0 1 0 11 100 0 20 0.000 0 0 7 0 0 5
42 | 2550 3150 4875 3150 4875 3975 2550 3975 2550 3150
43 | 2 2 0 1 0 11 100 0 20 0.000 0 0 7 0 0 5
44 | 2550 1800 4875 1800 4875 2625 2550 2625 2550 1800
45 | 2 2 0 1 0 11 100 0 20 0.000 0 0 7 0 0 5
46 | 2550 450 4875 450 4875 1275 2550 1275 2550 450
47 | 4 1 0 100 0 0 20 0.0000 4 195 1020 3675 750 Interface\001
48 | 4 1 0 100 0 0 14 0.0000 4 195 2040 3675 1125 main.c table.c tclsqlite.c\001
49 | 4 1 0 100 0 0 20 0.0000 4 195 1920 3675 6675 Virtual Machine\001
50 | 4 1 0 100 0 0 14 0.0000 4 150 570 3675 7050 vdbe.c\001
51 | 4 1 0 100 0 0 20 0.0000 4 195 1830 3675 4875 Code Generator\001
52 | 4 1 0 100 0 0 14 0.0000 4 195 1860 3675 5175 build.c delete.c expr.c\001
53 | 4 1 0 100 0 0 14 0.0000 4 195 2115 3675 5400 insert.c select.c update.c\001
54 | 4 1 0 100 0 0 14 0.0000 4 150 705 3675 5625 where.c\001
55 | 4 1 0 100 0 0 20 0.0000 4 195 735 3675 3450 Parser\001
56 | 4 1 0 100 0 0 20 0.0000 4 195 1140 3675 2100 Tokenizer\001
57 | 4 1 0 100 0 0 14 0.0000 4 150 870 3675 2475 tokenize.c\001
58 | 4 1 0 100 0 0 20 0.0000 4 255 1350 3675 9375 Page Cache\001
59 | 4 1 0 100 0 0 14 0.0000 4 150 630 3675 3825 parse.y\001
60 | 4 1 0 100 0 0 14 0.0000 4 150 600 3675 8400 btree.c\001
61 | 4 1 0 100 0 0 14 0.0000 4 150 645 3675 9750 pager.c\001
62 | 4 1 0 100 0 0 20 0.0000 4 195 1620 3675 8025 B-tree Driver\001
63 | 4 1 0 100 0 0 14 0.0000 4 105 345 3675 11100 os.c\001
64 | 4 1 0 100 0 0 20 0.0000 4 195 1470 3675 10725 OS Interface\001
65 |
--------------------------------------------------------------------------------
/www/arch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davideuler/SQLite-2.5.0-for-code-reading/95c98088ffd4fff76aea62a4f79b7d08bf9a3b7d/www/arch.png
--------------------------------------------------------------------------------
/www/conflict.tcl:
--------------------------------------------------------------------------------
1 | #
2 | # Run this Tcl script to generate the constraint.html file.
3 | #
4 | set rcsid {$Id: conflict.tcl,v 1.2 2002/02/03 00:56:11 drh Exp $ }
5 |
6 | puts {
7 |
8 | Constraint Conflict Resolution in SQLite
9 |
10 |
11 |
12 | Constraint Conflict Resolution in SQLite
13 |
}
14 | puts "
15 | (This page was last modified on [lrange $rcsid 3 4] UTC)
16 |
"
17 |
18 | puts {
19 | Introduction
20 |
21 |
22 | In most SQL databases, if you have a UNIQUE constraint on
23 | a table and you try to do an UPDATE or INSERT that violates
24 | that constraint, the database will aborts the operation in
25 | progress, back out any prior changes associated with that
26 | one UPDATE or INSERT command, and return an error.
27 | This is the default behavior of SQLite.
28 | Beginning with version 2.3.0, though, SQLite allows you to
29 | define alternative ways for dealing with constraint violations.
30 | This article describes those alternatives and how to use them.
31 |
32 |
33 | Conflict Resolution Algorithms
34 |
35 |
36 | SQLite defines five constraint conflict resolution algorithms
37 | as follows:
38 |
39 |
40 |
41 | - ROLLBACK
42 | When a constraint violation occurs, an immediate ROLLBACK
43 | occurs, thus ending the current transaction, and the command aborts
44 | with a return code of SQLITE_CONSTRAINT. If no transaction is
45 | active (other than the implied transaction that is created on every
46 | command) then this algorithm works the same as ABORT.
47 |
48 | - ABORT
49 | When a constraint violation occurs, the command backs out
50 | any prior changes it might have made and aborts with a return code
51 | of SQLITE_CONSTRAINT. But no ROLLBACK is executed so changes
52 | from prior commands within the same transaction
53 | are preserved. This is the default behavior for SQLite.
54 |
55 | - FAIL
56 | When a constraint violation occurs, the command aborts with a
57 | return code SQLITE_CONSTRAINT. But any changes to the database that
58 | the command made prior to encountering the constraint violation
59 | are preserved and are not backed out. For example, if an UPDATE
60 | statement encountered a constraint violation on the 100th row that
61 | it attempts to update, then the first 99 row changes are preserved
62 | by change to rows 100 and beyond never occur.
63 |
64 | - IGNORE
65 | When a constraint violation occurs, the one row that contains
66 | the constraint violation is not inserted or changed. But the command
67 | continues executing normally. Other rows before and after the row that
68 | contained the constraint violation continue to be inserted or updated
69 | normally. No error is returned.
70 |
71 | - REPLACE
72 | When a UNIQUE constraint violation occurs, the pre-existing row
73 | that caused the constraint violation is removed prior to inserting
74 | or updating the current row. Thus the insert or update always occurs.
75 | The command continues executing normally. No error is returned.
76 |
77 |
78 | Why So Many Choices?
79 |
80 | SQLite provides multiple conflict resolution algorithms for a
81 | couple of reasons. First, SQLite tries to be roughly compatible with as
82 | many other SQL databases as possible, but different SQL database
83 | engines exhibit different conflict resolution strategies. For
84 | example, PostgreSQL always uses ROLLBACK, Oracle always uses ABORT, and
85 | MySQL usually uses FAIL but can be instructed to use IGNORE or REPLACE.
86 | By supporting all five alternatives, SQLite provides maximum
87 | portability.
88 |
89 | Another reason for supporing multiple algorithms is that sometimes
90 | it is useful to use an algorithm other than the default.
91 | Suppose, for example, you are
92 | inserting 1000 records into a database, all within a single
93 | transaction, but one of those records is malformed and causes
94 | a constraint error. Under PostgreSQL or Oracle, none of the
95 | 1000 records would get inserted. In MySQL, some subset of the
96 | records that appeared before the malformed record would be inserted
97 | but the rest would not. Neither behavior is espeically helpful.
98 | What you really want is to use the IGNORE algorithm to insert
99 | all but the malformed record.
100 |
101 | }
102 |
103 | puts {
104 |
105 |
106 | Back to the SQLite Home Page
107 |
108 |
109 | }
110 |
--------------------------------------------------------------------------------
/www/crosscompile.tcl:
--------------------------------------------------------------------------------
1 | #
2 | # Run this Tcl script to generate the crosscompile.html file.
3 | #
4 | set rcsid {$Id: crosscompile.tcl,v 1.5 2001/11/24 13:23:05 drh Exp $}
5 |
6 | puts {
7 |
8 | Notes On How To Compile SQLite Using The MinGW Cross-Compiler
9 |
10 |
11 |
12 | Notes On How To Compile SQLite Using The MinGW Cross-Compiler
13 |
}
14 | puts "
15 | (This page was last modified on [lrange $rcsid 3 4] UTC)
16 |
"
17 |
18 | puts {
19 | MinGW or
20 | Minimalist GNU For Windows
21 | is a version of the popular GCC compiler that builds Win95/Win98/WinNT
22 | binaries. See the website for details.
23 |
24 | This page describes how you can use MinGW configured as a
25 | cross-compiler running under RedHat 6.0 Linux to generate a
26 | binary for SQLite that runs under WinNT.
27 | Some additional steps (described below)
28 | are needed to target Win95/98.
29 | }
30 |
31 | proc Code {body} {
32 | puts {}
33 | regsub -all {&} [string trim $body] {\&} body
34 | regsub -all {>} $body {\>} body
35 | regsub -all {<} $body {\<} body
36 | regsub -all {\(\(\(} $body {} body
37 | regsub -all {\)\)\)} $body {} body
38 | puts $body
39 | puts {
}
40 | }
41 |
42 | puts {
43 | Here are the steps:
44 |
45 |
46 | -
47 |
Get a copy of the MinGW compiler and all
48 | its associated tools that run under Linux. No binary versions of
49 | MinGW in this configuration are available for net downloads, as far
50 | as I know. You will probably have to download the source code and
51 | compile it all yourself.
52 | A separate bulletin describes how this
53 | can be done.
54 | When you are done, make sure the compiler and all its associated tools
55 | are located somewhere on your PATH environment variable.
56 |
57 |
58 |
59 | -
60 |
61 | Download the Win32 port of GDBM from
62 | Roth Consulting. You can FTP a ZIP archive of the sources directly
63 | from
64 | ftp://ftp.roth.net/pub/ntperl/gdbm/source/Win32_GDBM_Source.zip.
65 |
66 |
67 |
68 | -
69 |
Make a directory and unpack the Win32 port of GDBM.
70 |
71 | mkdir roth
72 | cd roth
73 | unzip ../Win32_GDBM_Source.zip
74 |
75 |
76 |
77 | -
78 |
Manually build the GDBM library as follows:
79 |
80 | i386-mingw32-gcc -DWIN32=1 -O2 -c *.c
81 | i386-mingw32-ar cr libgdbm.a *.o
82 | i386-mingw32-ranlib libgdbm.a
83 | cd ..
84 |
85 |
86 |
87 | -
88 |
89 | Download the SQLite tarball from
90 |
91 | http://www.hwaci.com/sw/sqlite/sqlite.tar.gz.
92 | Unpack the tarball and create a separate directory in which
93 | to build the executable and library.
94 |
95 |
96 | tar xzf sqlite.tar.gz
97 | mkdir sqlite-bld
98 | cd sqlite-bld
99 |
100 |
101 |
102 | -
103 |
104 | Create a "hints" file that will tell the SQLite configuration script
105 | to use the MinGW cross-compiler rather than the native linux compiler.
106 | The hints file should looks something like this:
107 |
108 | cat >mingw.hints <<\END
109 | config_TARGET_CC=i386-mingw32-gcc
110 | config_TARGET_CFLAGS='-O2'
111 | config_TARGET_GDBM_LIBS=../roth/libgdbm.a
112 | config_TARGET_GDBM_INC=-I../roth
113 | config_TARGET_AR='i386-mingw32-ar cr'
114 | config_TARGET_RANLIB=i386-mingw32-ranlib
115 | config_TARGET_EXEEXT='.exe'
116 | END
117 |
118 |
119 |
120 | -
121 |
Configure and build SQLite:
122 |
123 | ../sqlite/configure --with-hints=./mingw.hints
124 | make
125 |
126 |
127 |
128 |
129 |
130 | Targetting Windows95/98 instead of WindowsNT
131 |
132 | A small amount of additional work is needed to get SQLite running
133 | under Windows95/98. The first problem is that the LockFile() and
134 | UnlockFile() API that the Roth GDBM port uses does not work under
135 | Windows95. The easiest workaround is to just disable file locking
136 | in the GDBM library. You can do so by appending a few lines of code
137 | to the end of one of the GDBM source files and compiling the library
138 | using a special command-line option. Replace step (4) above as
139 | follows:
140 |
141 |
142 |
143 | Append text to the systems.h source file as follows:
144 |
145 |
146 | cat >>systems.h <<\END
147 | #ifdef NO_LOCKS
148 | #undef UNLOCK_FILE
149 | #define UNLOCK_FILE(x)
150 | #undef READLOCK_FILE
151 | #define READLOCK_FILE(x) lock_val=0;
152 | #undef WRITELOCK_FILE
153 | #define WRITELOCK_FILE(x) lock_val=0;
154 | #endif
155 | END
156 |
157 |
158 | Then manually build the GDBM library with the extra
159 | "NO_LOCKS" define as follows:
160 |
161 | i386-mingw32-gcc -DWIN32=1 -DNO_LOCKS -O2 -c *.c
162 | i386-mingw32-ar cr libgdbm.a *.o
163 | i386-mingw32-ranlib libgdbm.a
164 | cd ..
165 |
166 |
167 |
168 |
169 | Note that the locking problem has been reported and may actually
170 | be fixed in the Roth GDBM distribution by the time you read this.
171 | You should probably check before you make the above changes.
172 |
173 | The above is all you have to do to get SQLite to work on Windows95.
174 | But one more step is required to get it to work well. It
175 | turns out that SQLite make heavy use of malloc() and
176 | free() and the implementation of this functions
177 | on Windows95 is particular poor. Large database queries will run
178 | more than 10 times faster if you substitute a better memory allocator
179 | such as the one by
180 | Doug Lea.
181 | A copy of Doug's allocator is included in the contrib
182 | directory of the source tree. Speed improvements are also reported
183 | on WindowsNT when alternative memory allocators are used, though
184 | the speedup is not as dramatic as it is with WIndows95.
185 |
186 | }
187 | puts {
188 |
189 |
190 | Back to the SQLite Home Page
191 |
192 |
193 | }
194 |
--------------------------------------------------------------------------------
/www/download.tcl:
--------------------------------------------------------------------------------
1 | #
2 | # Run this TCL script to generate HTML for the download.html file.
3 | #
4 | set rcsid {$Id: download.tcl,v 1.5 2002/03/30 14:15:52 drh Exp $}
5 |
6 | puts {
7 | SQLite Download Page
8 |
9 | SQLite Download Page
}
10 | #}
11 | #puts "This page was last modified on [lrange $rcsid 3 4] UTC
"
12 | #set vers [lindex $argv 0]
13 | #puts "The latest SQLite version is $vers"
14 | #puts " created on [exec cat last_change] UTC"
15 | #puts {
}
16 |
17 | puts {Precompiled Binaries For Linux
}
18 |
19 | proc Product {file desc} {
20 | if {![file exists $file]} return
21 | set size [file size $file]
22 | puts [subst {
23 |
24 |
25 |
26 | $file ($size bytes)
27 | |
28 | [string trim $desc] |
29 |
30 |
}]
31 | }
32 |
33 | Product sqlite.bin.gz {
34 | A command-line program for accessing and modifing SQLite databases.
35 | See the documentation for additional information.
36 | }
37 |
38 | Product tclsqlite.so.gz {
39 | Bindings for TCL. You can import this shared library into either
40 | tclsh or wish to get SQLite database access from Tcl/Tk.
41 | See the documentation for details.
42 | }
43 |
44 | Product sqlite.so.gz {
45 | A precompiled shared-library for Linux. This is the same as
46 | tclsqlite.so.gz but without the TCL bindings.
47 | }
48 |
49 | foreach name [lsort -dict [glob -nocomplain sqlite-*.i386.rpm]] {
50 | if {[regexp -- -devel- $name]} {
51 | Product $name {
52 | RPM containing documentation, header files, and static library.
53 | }
54 | } else {
55 | Product $name {
56 | RPM containing shared libraries and the sqlite command-line
57 | program.
58 | }
59 | }
60 | }
61 |
62 | puts {Precompiled Binaries For Windows
}
63 |
64 | Product sqlite.zip {
65 | A command-line program for accessing and modifing SQLite databases.
66 | See the documentation for additional information.
67 | }
68 | Product tclsqlite.zip {
69 | Bindings for TCL. You can import this shared library into either
70 | tclsh or wish to get SQLite database access from Tcl/Tk.
71 | See the documentation for details.
72 | }
73 | Product sqlitedll.zip {
74 | This is a DLL of the SQLite library without the TCL bindings.
75 | The only external dependency is MSVCRT.DLL.
76 | }
77 |
78 | puts {Source Code
}
79 |
80 | Product {sqlite_source.zip} {
81 | This ZIP archive contains pure C source code for the SQLite library.
82 | Unlike the tarballs below, all of the preprocessing has already been
83 | done on these C source code, so you can just hand the files directly to
84 | your favorite C compiler. This file is provided as a service to
85 | MS-Windows users who lack the build support infrastructure of Unix.
86 | }
87 |
88 | foreach name [lsort -dict [glob -nocomplain sqlite-*.src.rpm]] {
89 | Product $name "RPM containing complete source code"
90 | }
91 |
92 | foreach name [lsort -dict -decreasing [glob -nocomplain sqlite-*.tar.gz]] {
93 | regexp {sqlite-(.*)\.tar\.gz} $name match vers
94 | Product $name "
95 | Version $vers of the source tree including all documentation.
96 | "
97 | }
98 |
99 | puts {
100 |
101 |
102 |
103 | Back to the SQLite home page
104 |
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/www/dynload.tcl:
--------------------------------------------------------------------------------
1 | #
2 | # Run this Tcl script to generate the dynload.html file.
3 | #
4 | set rcsid {$Id: dynload.tcl,v 1.1 2001/02/11 16:58:22 drh Exp $}
5 |
6 | puts {
7 |
8 | How to build a dynamically loaded Tcl extension for SQLite
9 |
10 |
11 |
12 | How To Build A Dynamically Loaded Tcl Extension
13 |
}
14 | puts {
15 | This note was contributed by
16 | Bill Saunders. Thanks, Bill!
17 |
18 |
19 | To compile the SQLite Tcl extension into a dynamically loaded module
20 | I did the following:
21 |
22 |
23 |
24 | Do a standard compile
25 | (I had a dir called bld at the same level as sqlite ie
26 | /root/bld
27 | /root/sqlite
28 | I followed the directions and did a standard build in the bld
29 | directory)
30 |
31 |
32 | Now do the following in the bld directory
33 |
34 | gcc -shared -I. -lgdbm ../sqlite/src/tclsqlite.c libsqlite.a -o sqlite.so
35 |
36 |
37 |
38 | This should produce the file sqlite.so in the bld directory
39 |
40 |
41 | Create a pkgIndex.tcl file that contains this line
42 |
43 |
44 | package ifneeded sqlite 1.0 [list load [file join $dir sqlite.so]]
45 |
46 |
47 |
48 | To use this put sqlite.so and pkgIndex.tcl in the same directory
49 |
50 |
51 | From that directory start wish
52 |
53 |
54 | Execute the following tcl command (tells tcl where to fine loadable
55 | modules)
56 |
57 | lappend auto_path [exec pwd]
58 |
59 |
60 |
61 | Load the package
62 |
63 | package require sqlite
64 |
65 |
66 |
67 | Have fun....
68 |
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/www/formatchng.tcl:
--------------------------------------------------------------------------------
1 | #
2 | # Run this Tcl script to generate the formatchng.html file.
3 | #
4 | set rcsid {$Id: formatchng.tcl,v 1.4 2002/03/11 02:06:14 drh Exp $ }
5 |
6 | puts {
7 |
8 | File Format Changes in SQLite
9 |
10 |
11 |
12 | File Format Changes in SQLite
13 |
}
14 | puts "
15 | (This page was last modified on [lrange $rcsid 3 4] UTC)
16 |
"
17 |
18 | puts {
19 |
20 | From time to time, enhancements or bug fixes require a change to
21 | the underlying file format for SQLite. When this happens and you
22 | want to upgrade your library, you must convert the contents of your
23 | databases into a portable ASCII representation using the old version
24 | of the library then reload the data using the new version of the
25 | library.
26 |
27 |
28 |
29 | You can tell if you should reload your databases by comparing the
30 | version numbers of the old and new libraries. If either of the
31 | first two digits in the version number change, then a reload is
32 | either required or recommended. For example, upgrading from
33 | version 1.0.32 to 2.0.0 requires a reload. So does going from
34 | version 2.0.8 to 2.1.0.
35 |
36 |
37 |
38 | The following table summarizes the SQLite file format changes that have
39 | occurred since version 1.0.0:
40 |
41 |
42 |
43 |
44 |
45 | Version Change |
46 | Approx. Date |
47 | Description Of File Format Change |
48 |
49 |
50 | 1.0.32 to 2.0.0 |
51 | 2001-Sep-20 |
52 | Version 1.0.X of SQLite used the GDBM library as its backend
53 | interface to the disk. Beginning in version 2.0.0, GDBM was replaced
54 | by a custom B-Tree library written especially for SQLite. The new
55 | B-Tree backend is twice as fast as GDBM, supports atomic commits and
56 | rollback, and stores an entire database in a single disk file instead
57 | using a separate file for each table as GDBM does. The two
58 | file formats are not even remotely similar. |
59 |
60 |
61 | 2.0.8 to 2.1.0 |
62 | 2001-Nov-12 |
63 | The same basic B-Tree format is used but the details of the
64 | index keys were changed in order to provide better query
65 | optimization opportunities. Some of the headers were also changed in order
66 | to increase the maximum size of a row from 64KB to 24MB. |
67 |
68 |
69 | 2.1.7 to 2.2.0 |
70 | 2001-Dec-21 |
71 | Beginning with version 2.2.0, SQLite no longer builds an index for
72 | an INTEGER PRIMARY KEY column. Instead, it uses that column as the actual
73 | B-Tree key for the main table. Version 2.2.0 and later of the library
74 | will automatically detect when it is reading a 2.1.x database and will
75 | disable the new INTEGER PRIMARY KEY feature. In other words, version
76 | 2.2.x is backwards compatible to version 2.1.x. But version 2.1.x is not
77 | forward compatible with version 2.2.x. If you try to open
78 | a 2.2.x database with an older 2.1.x library and that database contains
79 | an INTEGER PRIMARY KEY, you will likely get a coredump. If the database
80 | schema does not contain any INTEGER PRIMARY KEYs, then the version 2.1.x
81 | and version 2.2.x database files will be identical and completely
82 | interchangeable.
83 | |
84 |
85 | 2.2.5 to 2.3.0 |
86 | 2002-Jan-30 |
87 | Beginning with version 2.3.0, SQLite supports some additional syntax
88 | (the "ON CONFLICT" clause) in the CREATE TABLE and CREATE INDEX statements
89 | that are stored in the SQLITE_MASTER table. If you create a database that
90 | contains this new syntax, then try to read that database using version 2.2.5
91 | or earlier, the parser will not understand the new syntax and you will get
92 | an error. Otherwise, databases for 2.2.x and 2.3.x are interchangeable. |
93 |
94 |
95 | 2.3.3 to 2.4.0 |
96 | 2002-Mar-10 |
97 | Beginning with version 2.4.0, SQLite added support for views.
98 | Information about views is stored in the SQLITE_MASTER table. If an older
99 | version of SQLite attempts to read a database that contains VIEW information
100 | in the SQLITE_MASTER table, the parser will not understand the new syntax
101 | and you will get an error. Also, the
102 | way SQLite keeps track of unused disk blocks in the database file
103 | changed slightly.
104 | If an older version of SQLite attempts to write a database that
105 | was previously written by version 2.4.0 or later, then it may leak disk
106 | blocks. |
107 |
108 |
109 |
110 |
111 |
112 | To perform a database reload, have ready versions of the
113 | sqlite command-line utility for both the old and new
114 | version of SQLite. Call these two executables "sqlite-old"
115 | and "sqlite-new". Suppose the name of your old database
116 | is "old.db" and you want to create a new database with
117 | the same information named "new.db". The command to do
118 | this is as follows:
119 |
120 |
121 |
122 | echo .dump | sqlite-old old.db | sqlite-new new.db
123 |
124 | }
125 |
126 | puts {
127 |
128 |
129 | Back to the SQLite Home Page
130 |
131 |
132 | }
133 |
--------------------------------------------------------------------------------
/www/mingw.tcl:
--------------------------------------------------------------------------------
1 | #
2 | # Run this Tcl script to generate the crosscompile.html file.
3 | #
4 | set rcsid {$Id: mingw.tcl,v 1.3 2001/11/24 13:23:05 drh Exp $}
5 |
6 | puts {
7 |
8 | Notes On How To Build MinGW As A Cross-Compiler
9 |
10 |
11 |
12 | Notes On How To Build MinGW As A Cross-Compiler
13 |
}
14 | puts "
15 | (This page was last modified on [lrange $rcsid 3 4] UTC)
16 |
"
17 |
18 | puts {
19 | MinGW or
20 | Minimalist GNU For Windows
21 | is a version of the popular GCC compiler that builds Win95/Win98/WinNT
22 | binaries. See the website for details.
23 |
24 | This page describes how you can build MinGW
25 | from sources as a cross-compiler
26 | running under Linux. Doing so will allow you to construct
27 | WinNT binaries from the comfort and convenience of your
28 | Unix desktop.
29 | }
30 |
31 | proc Link {path {file {}}} {
32 | if {$file!=""} {
33 | set path $path/$file
34 | } else {
35 | set file $path
36 | }
37 | puts "$file"
38 | }
39 |
40 | puts {
41 | Here are the steps:
42 |
43 |
44 | -
45 |
Get a copy of source code. You will need the binutils, the
46 | compiler, and the MinGW runtime. Each are available separately.
47 | As of this writing, Mumit Khan has collected everything you need
48 | together in one FTP site:
49 | }
50 | set ftpsite \
51 | ftp://ftp.nanotech.wisc.edu/pub/khan/gnu-win32/mingw32/snapshots/gcc-2.95.2-1
52 | Link $ftpsite
53 | puts {
54 | The three files you will need are:
55 |
56 | - }
57 | Link $ftpsite binutils-19990818-1-src.tar.gz
58 | puts
-
59 | Link $ftpsite gcc-2.95.2-1-src.tar.gz
60 | puts
-
61 | Link $ftpsite mingw-20000203.zip
62 | puts {
63 |
64 |
65 | Put all the downloads in a directory out of the way. The sequel
66 | will assume all downloads are in a directory named
67 | ~/mingw/download.
68 |
69 |
70 | -
71 |
72 | Create a directory in which to install the new compiler suite and make
73 | the new directory writable.
74 | Depending on what directory you choose, you might need to become
75 | root. The example shell commands that follow
76 | will assume the installation directory is
77 | /opt/mingw and that your user ID is drh.
78 |
79 | su
80 | mkdir /opt/mingw
81 | chown drh /opt/mingw
82 | exit
83 |
84 |
85 |
86 | -
87 |
Unpack the source tarballs into a separate directory.
88 |
89 | mkdir ~/mingw/src
90 | cd ~/mingw/src
91 | tar xzf ../download/binutils-*.tar.gz
92 | tar xzf ../download/gcc-*.tar.gz
93 | unzip ../download/mingw-*.zip
94 |
95 |
96 |
97 | -
98 |
Create a directory in which to put all the build products.
99 |
100 | mkdir ~/mingw/bld
101 |
102 |
103 |
104 | -
105 |
Configure and build binutils and add the results to your PATH.
106 |
107 | mkdir ~/mingw/bld/binutils
108 | cd ~/mingw/bld/binutils
109 | ../../src/binutils/configure --prefix=/opt/mingw --target=i386-mingw32 -v
110 | make 2>&1 | tee make.out
111 | make install 2>&1 | tee make-install.out
112 | export PATH=$PATH:/opt/mingw/bin
113 |
114 |
115 |
116 | -
117 |
Manually copy the runtime include files into the installation directory
118 | before trying to build the compiler.
119 |
120 | mkdir /opt/mingw/i386-mingw32/include
121 | cd ~/mingw/src/mingw-runtime*/mingw/include
122 | cp -r * /opt/mingw/i386-mingw32/include
123 |
124 |
125 |
126 | -
127 |
Configure and build the compiler
128 |
129 | mkdir ~/mingw/bld/gcc
130 | cd ~/mingw/bld/gcc
131 | ../../src/gcc-*/configure --prefix=/opt/mingw --target=i386-mingw32 -v
132 | cd gcc
133 | make installdirs
134 | cd ..
135 | make 2>&1 | tee make.out
136 | make install
137 |
138 |
139 |
140 | -
141 |
Configure and build the MinGW runtime
142 |
143 | mkdir ~/mingw/bld/runtime
144 | cd ~/mingw/bld/runtime
145 | ../../src/mingw-runtime*/configure --prefix=/opt/mingw --target=i386-mingw32 -v
146 | make install-target-w32api
147 | make install
148 |
149 |
150 |
151 |
152 | And you are done...
153 | }
154 | puts {
155 |
156 |
157 | Back to the SQLite Home Page
158 |
159 |
160 | }
161 |
--------------------------------------------------------------------------------