SQLite

Check-in Differences
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Difference From 2a832b19b657ba02 To 09b4f19f100fe82a

2009-11-11
13:17
Allow media sector sizes as small as 32. The former minimum size was 512. (check-in: 5a32bfc17e user: drh tags: trunk)
04:17
Modified CLI to raise an error when extra command line options are passed. Added tests to verify correct handling, as well as other basic handling of command line options. Ticket [f5cb008a65]. (check-in: 09b4f19f10 user: shaneh tags: trunk)
01:14
Additional test cases for the coalesce() and ifnull() functions. (check-in: d0591258b6 user: drh tags: trunk)
2009-10-30
13:26
Version 3.6.16.1 (Leaf check-in: 2a832b19b6 user: drh tags: release, branch_3_6_16)
2009-10-29
18:38
Fix a 16-bit integer overflow that might occur in statements that use both an EXISTS clause and IN operator with a RHS holding in excess of 32K entries. (check-in: 65a1f1334d user: drh tags: branch_3_6_16)

Changes to Makefile.in.
161
162
163
164
165
166
167
168

169
170
171
172
173
174
175
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175







-
+







# You should not have to change anything below this line
###############################################################################

# Object files for the SQLite library (non-amalgamation).
#
OBJS0 = alter.lo analyze.lo attach.lo auth.lo backup.lo bitvec.lo btmutex.lo \
        btree.lo build.lo callback.lo complete.lo date.lo \
        delete.lo expr.lo fault.lo func.lo global.lo \
        delete.lo expr.lo fault.lo fkey.lo func.lo global.lo \
        hash.lo journal.lo insert.lo legacy.lo loadext.lo \
        main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
        memjournal.lo \
        mutex.lo mutex_noop.lo mutex_os2.lo mutex_unix.lo mutex_w32.lo \
        notify.lo opcodes.lo os.lo os_unix.lo os_win.lo os_os2.lo \
        pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
        random.lo resolve.lo rowset.lo select.lo status.lo \
204
205
206
207
208
209
210

211
212
213
214
215
216
217
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218







+







  $(TOP)/src/build.c \
  $(TOP)/src/callback.c \
  $(TOP)/src/complete.c \
  $(TOP)/src/date.c \
  $(TOP)/src/delete.c \
  $(TOP)/src/expr.c \
  $(TOP)/src/fault.c \
  $(TOP)/src/fkey.c \
  $(TOP)/src/func.c \
  $(TOP)/src/global.c \
  $(TOP)/src/hash.c \
  $(TOP)/src/hash.h \
  $(TOP)/src/hwtime.h \
  $(TOP)/src/insert.c \
  $(TOP)/src/journal.c \
231
232
233
234
235
236
237
238
239
240



241
242
243
244
245
246
247
232
233
234
235
236
237
238



239
240
241
242
243
244
245
246
247
248







-
-
-
+
+
+







  $(TOP)/src/mutex_os2.c \
  $(TOP)/src/mutex_unix.c \
  $(TOP)/src/mutex_w32.c \
  $(TOP)/src/notify.c \
  $(TOP)/src/os.c \
  $(TOP)/src/os.h \
  $(TOP)/src/os_common.h \
  $(TOP)/src/os_unix.c \
  $(TOP)/src/os_win.c \
  $(TOP)/src/os_os2.c \
  $(TOP)/src/os_os2.c \
  $(TOP)/src/os_unix.c \
  $(TOP)/src/os_win.c \
  $(TOP)/src/pager.c \
  $(TOP)/src/pager.h \
  $(TOP)/src/parse.y \
  $(TOP)/src/pcache.c \
  $(TOP)/src/pcache.h \
  $(TOP)/src/pcache1.c \
  $(TOP)/src/pragma.c \
334
335
336
337
338
339
340
341

342
343
344
345
346
347
348
335
336
337
338
339
340
341

342
343
344
345
346
347
348
349







-
+







  $(TOP)/src/bitvec.c \
  $(TOP)/src/btree.c \
  $(TOP)/src/build.c \
  $(TOP)/src/date.c \
  $(TOP)/src/expr.c \
  $(TOP)/src/func.c \
  $(TOP)/src/insert.c \
  $(TOP)/src/malloc.c \
  $(TOP)/src/mem5.c \
  $(TOP)/src/os.c \
  $(TOP)/src/os_os2.c \
  $(TOP)/src/os_unix.c \
  $(TOP)/src/os_win.c \
  $(TOP)/src/pager.c \
  $(TOP)/src/pcache.c \
  $(TOP)/src/pcache1.c \
377
378
379
380
381
382
383
384
385
386




387
388
389
390
391
392
393
394


395
396
397
398
399
400
401
378
379
380
381
382
383
384



385
386
387
388
389
390
391
392
393
394
395

396
397
398
399
400
401
402
403
404







-
-
-
+
+
+
+







-
+
+







  $(TOP)/src/test_async.c \
  $(TOP)/src/test_backup.c \
  $(TOP)/src/test_btree.c \
  $(TOP)/src/test_config.c \
  $(TOP)/src/test_devsym.c \
  $(TOP)/src/test_func.c \
  $(TOP)/src/test_hexio.c \
  $(TOP)/src/test_journal.c \
  $(TOP)/src/test_malloc.c \
  $(TOP)/src/test_md5.c \
  $(TOP)/src/test_init.c \
  $(TOP)/src/test_intarray.c \
  $(TOP)/src/test_journal.c \
  $(TOP)/src/test_malloc.c \
  $(TOP)/src/test_mutex.c \
  $(TOP)/src/test_onefile.c \
  $(TOP)/src/test_osinst.c \
  $(TOP)/src/test_pcache.c \
  $(TOP)/src/test_schema.c \
  $(TOP)/src/test_server.c \
  $(TOP)/src/test_tclvar.c \
  $(TOP)/src/test_thread.c
  $(TOP)/src/test_thread.c \
  $(TOP)/src/test_wsd.c

# Header files used by all library source files.
#
HDR = \
   sqlite3.h  \
   $(TOP)/src/btree.h \
   $(TOP)/src/btreeInt.h \
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
453
454
455
456
457
458
459







460
461
462
463
464
465
466







-
-
-
-
-
-
-








Makefile: $(TOP)/Makefile.in
	./config.status

sqlite3.pc: $(TOP)/sqlite3.pc.in
	./config.status

# Generate the file "last_change" which contains the date of change
# of the most recently modified source code file
#
last_change:	$(SRC)
	cat $(SRC) | grep '$$Id: ' | sort -k 5 | tail -1 \
          | $(NAWK) '{print $$5,$$6}' >last_change

libsqlite3.la:	$(LIBOBJ)
	$(LTLINK) -o $@ $(LIBOBJ) $(TLIBS) \
		${ALLOWRELEASE} -rpath "$(libdir)" -version-info "8:6:8"

libtclsqlite3.la:	tclsqlite.lo libsqlite3.la
	$(LTLINK) -o $@ tclsqlite.lo \
		libsqlite3.la @TCL_STUB_LIB_SPEC@ $(TLIBS) \
493
494
495
496
497
498
499
500

501
502

503
504
505
506
507
508
509
489
490
491
492
493
494
495

496
497

498
499
500
501
502
503
504
505







-
+

-
+







	touch .target_source

sqlite3.c:	.target_source $(TOP)/tool/mksqlite3c.tcl
	$(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl

# Rules to build the LEMON compiler generator
#
lemon$(BEXE):	$(TOP)/tool/lemon.c $(TOP)/tool/lempar.c
lemon$(BEXE):	$(TOP)/tool/lemon.c $(TOP)/src/lempar.c
	$(BCC) -o $@ $(TOP)/tool/lemon.c
	cp $(TOP)/tool/lempar.c .
	cp $(TOP)/src/lempar.c .


# Rule to build the amalgamation
#
sqlite3.lo:	sqlite3.c
	$(LTCOMPILE) $(TEMP_STORE) -c sqlite3.c

550
551
552
553
554
555
556



557
558
559
560
561
562
563
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562







+
+
+








expr.lo:	$(TOP)/src/expr.c $(HDR)
	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/expr.c

fault.lo:	$(TOP)/src/fault.c $(HDR)
	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fault.c

fkey.lo:	$(TOP)/src/fkey.c $(HDR)
	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fkey.c

func.lo:	$(TOP)/src/func.c $(HDR)
	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/func.c

global.lo:	$(TOP)/src/global.c $(HDR)
	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/global.c

hash.lo:	$(TOP)/src/hash.c $(HDR)
678
679
680
681
682
683
684
685

686
687

688
689
690
691
692
693
694
677
678
679
680
681
682
683

684


685
686
687
688
689
690
691
692







-
+
-
-
+








select.lo:	$(TOP)/src/select.c $(HDR)
	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/select.c

status.lo:	$(TOP)/src/status.c $(HDR)
	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/status.c

sqlite3.h:	$(TOP)/src/sqlite.h.in 
sqlite3.h:	$(TOP)/src/sqlite.h.in $(TOP)/manifest.uuid $(TOP)/VERSION
	sed -e s/--VERS--/$(RELEASE)/ $(TOP)/src/sqlite.h.in | \
	sed -e s/--VERSION-NUMBER--/$(VERSION_NUMBER)/ >sqlite3.h
	tclsh $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h

table.lo:	$(TOP)/src/table.c $(HDR)
	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/table.c

tclsqlite.lo:	$(TOP)/src/tclsqlite.c $(HDR)
	$(LTCOMPILE) -DUSE_TCL_STUBS=1 -c $(TOP)/src/tclsqlite.c

Changes to Makefile.vxworks.
485
486
487
488
489
490
491
492

493
494

495
496
497
498
499
500
501
485
486
487
488
489
490
491

492
493

494
495
496
497
498
499
500
501







-
+

-
+







	tclsh $(TOP)/ext/fts2/mkfts2amal.tcl

fts3amal.c:	target_source $(TOP)/ext/fts3/mkfts3amal.tcl
	tclsh $(TOP)/ext/fts3/mkfts3amal.tcl

# Rules to build the LEMON compiler generator
#
lemon:	$(TOP)/tool/lemon.c $(TOP)/tool/lempar.c
lemon:	$(TOP)/tool/lemon.c $(TOP)/src/lempar.c
	$(BCC) -o lemon $(TOP)/tool/lemon.c
	cp $(TOP)/tool/lempar.c .
	cp $(TOP)/src/lempar.c .

# Rules to build individual *.o files from generated *.c files. This
# applies to:
#
#     parse.o
#     opcodes.o
#
Changes to README.
20
21
22
23
24
25
26
27

28
29
30








31
32
33
34
20
21
22
23
24
25
26

27



28
29
30
31
32
33
34
35
36
37
38
39







-
+
-
-
-
+
+
+
+
+
+
+
+




The configure script uses autoconf 2.61 and libtool.  If the configure
script does not work out for you, there is a generic makefile named
"Makefile.linux-gcc" in the top directory of the source tree that you
can copy and edit to suit your needs.  Comments on the generic makefile
show what changes are needed.

The linux binaries on the website are created using the generic makefile,
not the configure script.
not the configure script.  The windows binaries on the website are created
The windows binaries on the website are created using MinGW32 configured
as a cross-compiler running under Linux.  For details, see the ./publish.sh
script at the top-level of the source tree.
using MinGW32 configured as a cross-compiler running under Linux.  For 
details, see the ./publish.sh script at the top-level of the source tree.
The developers do not use teh configure script.

SQLite does not require TCL to run, but a TCL installation is required
by the makefiles.  SQLite contains a lot of generated code and TCL is
used to do much of that code generation.  The makefile also requires
AWK.

Contacts:

   http://www.sqlite.org/
Changes to VERSION.
1


1
-
+
3.6.16.1
3.6.20
Changes to addopcodes.awk.
15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
30


31
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34







+









+
+

}
END {
  printf "#define TK_%-29s %4d\n", "TO_TEXT",         ++max
  printf "#define TK_%-29s %4d\n", "TO_BLOB",         ++max
  printf "#define TK_%-29s %4d\n", "TO_NUMERIC",      ++max
  printf "#define TK_%-29s %4d\n", "TO_INT",          ++max
  printf "#define TK_%-29s %4d\n", "TO_REAL",         ++max
  printf "#define TK_%-29s %4d\n", "ISNOT",           ++max
  printf "#define TK_%-29s %4d\n", "END_OF_FILE",     ++max
  printf "#define TK_%-29s %4d\n", "ILLEGAL",         ++max
  printf "#define TK_%-29s %4d\n", "SPACE",           ++max
  printf "#define TK_%-29s %4d\n", "UNCLOSED_STRING", ++max
  printf "#define TK_%-29s %4d\n", "FUNCTION",        ++max
  printf "#define TK_%-29s %4d\n", "COLUMN",          ++max
  printf "#define TK_%-29s %4d\n", "AGG_FUNCTION",    ++max
  printf "#define TK_%-29s %4d\n", "AGG_COLUMN",      ++max
  printf "#define TK_%-29s %4d\n", "CONST_FUNC",      ++max
  printf "#define TK_%-29s %4d\n", "UMINUS",          ++max
  printf "#define TK_%-29s %4d\n", "UPLUS",           ++max
}
Added art/src_logo.gif.

cannot compute difference between binary files

Changes to configure.
1
2
3

4
5
6
7
8
9
10
1
2

3
4
5
6
7
8
9
10


-
+







#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.62 for sqlite 3.6.16.
# Generated by GNU Autoconf 2.62 for sqlite 3.6.20.
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## --------------------- ##
## M4sh Initialization.  ##
739
740
741
742
743
744
745
746
747


748
749
750
751
752
753
754
739
740
741
742
743
744
745


746
747
748
749
750
751
752
753
754







-
-
+
+







MFLAGS=
MAKEFLAGS=
SHELL=${CONFIG_SHELL-/bin/sh}

# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.6.16'
PACKAGE_STRING='sqlite 3.6.16'
PACKAGE_VERSION='3.6.20'
PACKAGE_STRING='sqlite 3.6.20'
PACKAGE_BUGREPORT=''

# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
1483
1484
1485
1486
1487
1488
1489
1490

1491
1492
1493
1494
1495
1496
1497
1483
1484
1485
1486
1487
1488
1489

1490
1491
1492
1493
1494
1495
1496
1497







-
+







#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
  # Omit some internal or obsolete options to make the list less imposing.
  # This message is too long to be a string in the A/UX 3.1 sh.
  cat <<_ACEOF
\`configure' configures sqlite 3.6.16 to adapt to many kinds of systems.
\`configure' configures sqlite 3.6.20 to adapt to many kinds of systems.

Usage: $0 [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.
1548
1549
1550
1551
1552
1553
1554
1555

1556
1557
1558
1559
1560
1561
1562
1548
1549
1550
1551
1552
1553
1554

1555
1556
1557
1558
1559
1560
1561
1562







-
+







  --build=BUILD     configure for building on BUILD [guessed]
  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
_ACEOF
fi

if test -n "$ac_init_help"; then
  case $ac_init_help in
     short | recursive ) echo "Configuration of sqlite 3.6.16:";;
     short | recursive ) echo "Configuration of sqlite 3.6.20:";;
   esac
  cat <<\_ACEOF

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
1666
1667
1668
1669
1670
1671
1672
1673

1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687

1688
1689
1690
1691
1692
1693
1694
1666
1667
1668
1669
1670
1671
1672

1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686

1687
1688
1689
1690
1691
1692
1693
1694







-
+













-
+







    cd "$ac_pwd" || { ac_status=$?; break; }
  done
fi

test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
  cat <<\_ACEOF
sqlite configure 3.6.16
sqlite configure 3.6.20
generated by GNU Autoconf 2.62

Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
  exit
fi
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by sqlite $as_me 3.6.16, which was
It was created by sqlite $as_me 3.6.20, which was
generated by GNU Autoconf 2.62.  Invocation command line was

  $ $0 $@

_ACEOF
exec 5>>config.log
{
2061
2062
2063
2064
2065
2066
2067
2068

2069
2070
2071
2072
2073
2074
2075
2061
2062
2063
2064
2065
2066
2067

2068
2069
2070
2071
2072
2073
2074
2075







-
+







 configure \$PACKAGE_VERSION = $PACKAGE_VERSION
 top level VERSION file     = $sqlite_version_sanity_check
please regen with autoconf" >&2;}
   { (exit 1); exit 1; }; }
fi

# The following RCS revision string applies to configure.in
# $Revision: 1.73 $
# $Revision: 1.56 $

#########
# Programs needed
#
case `pwd` in
  *\ * | *\	*)
    { $as_echo "$as_me:$LINENO: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
13968
13969
13970
13971
13972
13973
13974
13975

13976
13977
13978
13979
13980
13981
13982
13968
13969
13970
13971
13972
13973
13974

13975
13976
13977
13978
13979
13980
13981
13982







-
+








exec 6>&1

# Save the log message, to keep $[0] and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by sqlite $as_me 3.6.16, which was
This file was extended by sqlite $as_me 3.6.20, which was
generated by GNU Autoconf 2.62.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@
14021
14022
14023
14024
14025
14026
14027
14028

14029
14030
14031
14032
14033
14034
14035
14021
14022
14023
14024
14025
14026
14027

14028
14029
14030
14031
14032
14033
14034
14035







-
+







$config_commands

Report bugs to <bug-autoconf@gnu.org>."

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
sqlite config.status 3.6.16
sqlite config.status 3.6.20
configured by $0, generated by GNU Autoconf 2.62,
  with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"

Copyright (C) 2008 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."

Deleted doc/report1.txt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

























































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
An SQLite (version 1.0) database was used in a large military application
where the database contained 105 tables and indices.  The following is
a breakdown on the sizes of keys and data within these tables and indices:

Entries:      967089
Size:         45896104
Avg Size:     48
Key Size:     11112265
Avg Key Size: 12
Max Key Size: 99

    0..8            263    0%
    9..12          5560    0%
   13..16         71394    7%
   17..24        180717   26%
   25..32        215442   48%
   33..40        151118   64%
   41..48         77479   72%
   49..56         13983   74%
   57..64         14481   75%
   65..80         41342   79%
   81..96        127098   92%
   97..112        38054   96%
  113..128        14197   98%
  129..144         8208   99%
  145..160         3326   99%
  161..176         1242   99%
  177..192          604   99%
  193..208          222   99%
  209..224          213   99%
  225..240          132   99%
  241..256           58   99%
  257..288          515   99%
  289..320           64   99%
  321..352           39   99%
  353..384           44   99%
  385..416           25   99%
  417..448           24   99%
  449..480           26   99%
  481..512           27   99%
  513..1024         470   99%
 1025..2048         396   99%
 2049..4096         187   99%
 4097..8192          78   99%
 8193..16384         35   99%
16385..32768         17   99%
32769..65536          6   99%
65537..65541          3  100%

If the indices are omitted, the statistics for the 49 tables
become the following:

Entries:      451103
Size:         30930282
Avg Size:     69
Key Size:     1804412
Avg Key Size: 4
Max Key Size: 4

    0..24            89    0%
   25..32          9417    2%
   33..40        119162   28%
   41..48         68710   43%
   49..56          9539   45%
   57..64         12435   48%
   65..80         38650   57%
   81..96        126877   85%
   97..112        38030   93%
  113..128        14183   96%
  129..144         7668   98%
  145..160         3302   99%
  161..176         1238   99%
  177..192          597   99%
  193..208          217   99%
  209..224          211   99%
  225..240          130   99%
  241..256           57   99%
  257..288          100   99%
  289..320           62   99%
  321..352           34   99%
  353..384           43   99%
  385..416           24   99%
  417..448           24   99%
  449..480           25   99%
  481..512           27   99%
  513..1024         153   99%
 1025..2048          92   99%
 2049..4096           7  100%

The 56 indices have these statistics:

Entries:      512422
Size:         14879828
Avg Size:     30
Key Size:     9253204
Avg Key Size: 19
Max Key Size: 99

    0..8            246    0%
    9..12          5486    1%
   13..16         70717   14%
   17..24        178246   49%
   25..32        205722   89%
   33..40         31951   96%
   41..48          8768   97%
   49..56          4444   98%
   57..64          2046   99%
   65..80          2691   99%
   81..96           202   99%
   97..112           11   99%
  113..144          527   99%
  145..160           20   99%
  161..288          406   99%
  289..1024         316   99%
 1025..2048         304   99%
 2049..4096         180   99%
 4097..8192          78   99%
 8193..16384         35   99%
16385..32768         17   99%
32769..65536          6   99%
65537..65541          3  100%
Changes to ext/async/sqlite3async.c.
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
20












-
+







/*
** 2005 December 14
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** $Id: sqlite3async.c,v 1.6 2009/04/30 17:45:34 shane Exp $
** $Id: sqlite3async.c,v 1.7 2009/07/18 11:52:04 danielk1977 Exp $
**
** This file contains the implementation of an asynchronous IO backend 
** for SQLite.
*/

#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ASYNCIO)

664
665
666
667
668
669
670
671
672

673
674
675
676
677
678
679
680
681
682
683
684
685

686
687
688
689
690

691
692
693
694
695
696
697
698
699
700
701
702
703
704
705








706
707
708
709
710
711
712
713

714
715
716
717
718
719
720
664
665
666
667
668
669
670

671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690

691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716


717
718

719
720
721
722
723
724
725
726
727







-

+













+




-
+















+
+
+
+
+
+
+
+


-
-


-

+







  void *zOut, 
  int iAmt, 
  sqlite3_int64 iOffset
){
  AsyncFileData *p = ((AsyncFile *)pFile)->pData;
  int rc = SQLITE_OK;
  sqlite3_int64 filesize;
  int nRead;
  sqlite3_file *pBase = p->pBaseRead;
  sqlite3_int64 iAmt64 = (sqlite3_int64)iAmt;

  /* Grab the write queue mutex for the duration of the call */
  async_mutex_enter(ASYNC_MUTEX_QUEUE);

  /* If an I/O error has previously occurred in this virtual file 
  ** system, then all subsequent operations fail.
  */
  if( async.ioError!=SQLITE_OK ){
    rc = async.ioError;
    goto asyncread_out;
  }

  if( pBase->pMethods ){
    sqlite3_int64 nRead;
    rc = pBase->pMethods->xFileSize(pBase, &filesize);
    if( rc!=SQLITE_OK ){
      goto asyncread_out;
    }
    nRead = (int)MIN(filesize - iOffset, iAmt);
    nRead = MIN(filesize - iOffset, iAmt64);
    if( nRead>0 ){
      rc = pBase->pMethods->xRead(pBase, zOut, nRead, iOffset);
      ASYNC_TRACE(("READ %s %d bytes at %d\n", p->zName, nRead, iOffset));
    }
  }

  if( rc==SQLITE_OK ){
    AsyncWrite *pWrite;
    char *zName = p->zName;

    for(pWrite=async.pQueueFirst; pWrite; pWrite = pWrite->pNext){
      if( pWrite->op==ASYNC_WRITE && (
        (pWrite->pFileData==p) ||
        (zName && pWrite->pFileData->zName==zName)
      )){
        sqlite3_int64 nCopy;
        sqlite3_int64 nByte64 = (sqlite3_int64)pWrite->nByte;

        /* Set variable iBeginIn to the offset in buffer pWrite->zBuf[] from
        ** which data should be copied. Set iBeginOut to the offset within
        ** the output buffer to which data should be copied. If either of
        ** these offsets is a negative number, set them to 0.
        */
        sqlite3_int64 iBeginOut = (pWrite->iOffset-iOffset);
        sqlite3_int64 iBeginIn = -iBeginOut;
        int nCopy;

        if( iBeginIn<0 ) iBeginIn = 0;
        if( iBeginOut<0 ) iBeginOut = 0;
        nCopy = (int)MIN(pWrite->nByte-iBeginIn, iAmt-iBeginOut);

        nCopy = MIN(nByte64-iBeginIn, iAmt64-iBeginOut);
        if( nCopy>0 ){
          memcpy(&((char *)zOut)[iBeginOut], &pWrite->zBuf[iBeginIn], nCopy);
          ASYNC_TRACE(("OVERREAD %d bytes at %d\n", nCopy, iBeginOut+iOffset));
        }
      }
    }
  }
1061
1062
1063
1064
1065
1066
1067

1068



1069
1070
1071
1072
1073
1074
1075
1068
1069
1070
1071
1072
1073
1074
1075

1076
1077
1078
1079
1080
1081
1082
1083
1084
1085







+
-
+
+
+







    pData->nName = nName;
    memcpy(pData->zName, zName, nName);
  }

  if( !isAsyncOpen ){
    int flagsout;
    rc = pVfs->xOpen(pVfs, pData->zName, pData->pBaseRead, flags, &flagsout);
    if( rc==SQLITE_OK 
    if( rc==SQLITE_OK && (flagsout&SQLITE_OPEN_READWRITE) ){
     && (flagsout&SQLITE_OPEN_READWRITE) 
     && (flags&SQLITE_OPEN_EXCLUSIVE)==0
    ){
      rc = pVfs->xOpen(pVfs, pData->zName, pData->pBaseWrite, flags, 0);
    }
    if( pOutFlags ){
      *pOutFlags = flagsout;
    }
  }

Changes to ext/fts3/fts3_expr.c.
417
418
419
420
421
422
423
424



425
426
427
428
429
430
431
417
418
419
420
421
422
423

424
425
426
427
428
429
430
431
432
433







-
+
+
+







  ** limitation.
  */
  iCol = pParse->iDefaultCol;
  iColLen = 0;
  for(ii=0; ii<pParse->nCol; ii++){
    const char *zStr = pParse->azCol[ii];
    int nStr = strlen(zStr);
    if( nInput>nStr && zInput[nStr]==':' && memcmp(zStr, zInput, nStr)==0 ){
    if( nInput>nStr && zInput[nStr]==':' 
     && sqlite3_strnicmp(zStr, zInput, nStr)==0 
    ){
      iCol = ii;
      iColLen = ((zInput - z) + nStr + 1);
      break;
    }
  }
  rc = getNextToken(pParse, iCol, &z[iColLen], n-iColLen, ppExpr, pnConsumed);
  *pnConsumed += iColLen;
534
535
536
537
538
539
540
541
542

543
544

545
546
547
548
549
550
551
536
537
538
539
540
541
542


543
544
545
546
547
548
549
550
551
552
553







-
-
+


+







          rc = SQLITE_NOMEM;
          goto exprparse_out;
        }
        memset(pNot, 0, sizeof(Fts3Expr));
        pNot->eType = FTSQUERY_NOT;
        pNot->pRight = p;
        if( pNotBranch ){
          pNotBranch->pLeft = p;
          pNot->pRight = pNotBranch;
          pNot->pLeft = pNotBranch;
        }
        pNotBranch = pNot;
        p = pPrev;
      }else{
        int eType = p->eType;
        assert( eType!=FTSQUERY_PHRASE || !p->pPhrase->isNot );
        isPhrase = (eType==FTSQUERY_PHRASE || p->pLeft);

        /* The isRequirePhrase variable is set to true if a phrase or
        ** an expression contained in parenthesis is required. If a
619
620
621
622
623
624
625




626

627
628
629
630
631
632
633
621
622
623
624
625
626
627
628
629
630
631

632
633
634
635
636
637
638
639







+
+
+
+
-
+








  if( rc==SQLITE_DONE ){
    rc = SQLITE_OK;
    if( !sqlite3_fts3_enable_parentheses && pNotBranch ){
      if( !pRet ){
        rc = SQLITE_ERROR;
      }else{
        Fts3Expr *pIter = pNotBranch;
        while( pIter->pLeft ){
          pIter = pIter->pLeft;
        }
        pNotBranch->pLeft = pRet;
        pIter->pLeft = pRet;
        pRet = pNotBranch;
      }
    }
  }
  *pnConsumed = n - nIn;

exprparse_out:
Changes to ext/rtree/rtree.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code for implementations of the r-tree and r*-tree
** algorithms packaged as an SQLite virtual table module.
**
** $Id: rtree.c,v 1.12 2008/12/22 15:04:32 danielk1977 Exp $
*/

#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE)

/*
** This file contains an implementation of a couple of different variants
** of the r-tree algorithm. See the README file for further details. The 
1482
1483
1484
1485
1486
1487
1488
1489
1490


1491
1492
1493
1494
1495
1496
1497
1498
1499
1500


1501
1502
1503
1504
1505
1506
1507
1480
1481
1482
1483
1484
1485
1486


1487
1488
1489
1490
1491
1492
1493
1494
1495
1496


1497
1498
1499
1500
1501
1502
1503
1504
1505







-
-
+
+








-
-
+
+








  /* Pick two "seed" cells from the array of cells. The algorithm used
  ** here is the LinearPickSeeds algorithm from Gutman[1984]. The 
  ** indices of the two seed cells in the array are stored in local
  ** variables iLeftSeek and iRightSeed.
  */
  for(i=0; i<pRtree->nDim; i++){
    float x1 = aCell[0].aCoord[i*2];
    float x2 = aCell[0].aCoord[i*2+1];
    float x1 = DCOORD(aCell[0].aCoord[i*2]);
    float x2 = DCOORD(aCell[0].aCoord[i*2+1]);
    float x3 = x1;
    float x4 = x2;
    int jj;

    int iCellLeft = 0;
    int iCellRight = 0;

    for(jj=1; jj<nCell; jj++){
      float left = aCell[jj].aCoord[i*2];
      float right = aCell[jj].aCoord[i*2+1];
      float left = DCOORD(aCell[jj].aCoord[i*2]);
      float right = DCOORD(aCell[jj].aCoord[i*2+1]);

      if( left<x1 ) x1 = left;
      if( right>x4 ) x4 = right;
      if( left>x3 ){
        x3 = left;
        iCellRight = jj;
      }
1851
1852
1853
1854
1855
1856
1857



1858
1859
1860
1861
1862
1863
1864
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865







+
+
+







){
  int iLeftSeed = 0;
  int iRightSeed = 1;
  int *aiUsed;
  int i;

  aiUsed = sqlite3_malloc(sizeof(int)*nCell);
  if( !aiUsed ){
    return SQLITE_NOMEM;
  }
  memset(aiUsed, 0, sizeof(int)*nCell);

  PickSeeds(pRtree, aCell, nCell, &iLeftSeed, &iRightSeed);

  memcpy(pBboxLeft, &aCell[iLeftSeed], sizeof(RtreeCell));
  memcpy(pBboxRight, &aCell[iRightSeed], sizeof(RtreeCell));
  nodeInsertCell(pRtree, pLeft, &aCell[iLeftSeed]);
2338
2339
2340
2341
2342
2343
2344
2345

2346
2347
2348
2349
2350
2351
2352
2339
2340
2341
2342
2343
2344
2345

2346
2347
2348
2349
2350
2351
2352
2353







-
+







  return 1;
}
#endif

/*
** The xUpdate method for rtree module virtual tables.
*/
int rtreeUpdate(
static int rtreeUpdate(
  sqlite3_vtab *pVtab, 
  int nData, 
  sqlite3_value **azData, 
  sqlite_int64 *pRowid
){
  Rtree *pRtree = (Rtree *)pVtab;
  int rc = SQLITE_OK;
2733
2734
2735
2736
2737
2738
2739
2740

2741


2742
2743
2744
2745
2746
2747
2748
2734
2735
2736
2737
2738
2739
2740

2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751







-
+

+
+







      sqlite3_free(zTmp);
    }
    if( zSql ){
      zTmp = zSql;
      zSql = sqlite3_mprintf("%s);", zTmp);
      sqlite3_free(zTmp);
    }
    if( !zSql || sqlite3_declare_vtab(db, zSql) ){
    if( !zSql ){
      rc = SQLITE_NOMEM;
    }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){
      *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
    }
    sqlite3_free(zSql);
  }

  if( rc==SQLITE_OK ){
    *ppVtab = (sqlite3_vtab *)pRtree;
  }else{
Changes to ext/rtree/rtree1.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







# 2008 Feb 19
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# The focus of this file is testing the r-tree extension.
#
# $Id: rtree1.test,v 1.6 2008/12/22 15:04:32 danielk1977 Exp $
#

if {![info exists testdir]} {
  set testdir [file join [file dirname $argv0] .. .. test]
}
source [file join [file dirname [info script]] rtree_util.tcl]
source $testdir/tester.tcl

388
389
390
391
392
393
394
395








396
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402








+
+
+
+
+
+
+
+

} {1600}
do_test rtree-9.3 {
  execsql {
    SELECT count(*) FROM bar b1, bar b2, foo s1 
    WHERE b1.minX <= b2.maxX AND s1.id = b1.id;
  }
} {1600}

#-------------------------------------------------------------------------
# Ticket #3970: Check that the error message is meaningful when a 
# keyword is used as a column name.
#
do_test rtree-10.1 {
  catchsql { CREATE VIRTUAL TABLE t7 USING rtree(index, x1, y1, x2, y2) }
} {1 {near "index": syntax error}}

finish_test
Changes to ext/rtree/rtree2.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







# 2008 Feb 19
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# The focus of this file is testing the r-tree extension.
#
# $Id: rtree2.test,v 1.4 2008/07/14 15:37:01 danielk1977 Exp $
#

if {![info exists testdir]} {
  set testdir [file join [file dirname $argv0] .. .. test]
} 
source [file join [file dirname [info script]] rtree_util.tcl]
source $testdir/tester.tcl

Changes to ext/rtree/rtree3.test.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
8
9
10
11
12
13
14


15
16
17
18
19
20
21







-
-







#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# The focus of this file is testing that the r-tree correctly handles
# out-of-memory conditions.
#
# $Id: rtree3.test,v 1.2 2008/06/23 15:55:52 danielk1977 Exp $
#

if {![info exists testdir]} {
  set testdir [file join [file dirname $argv0] .. .. test]
} 
source $testdir/tester.tcl

ifcapable !rtree {
67
68
69
70
71
72
73
74
65
66
67
68
69
70
71








-
    set f [expr rand()]
    db eval { DELETE FROM rt WHERE x1<($f*10.0) AND x1>($f*10.5) }
  }
  db eval COMMIT
} 

finish_test

Changes to ext/rtree/rtree4.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







# 2008 May 23
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Randomized test cases for the rtree extension.
#
# $Id: rtree4.test,v 1.3 2008/06/23 15:55:52 danielk1977 Exp $
#

if {![info exists testdir]} {
  set testdir [file join [file dirname $argv0] .. .. test]
} 
source $testdir/tester.tcl

ifcapable !rtree {
Changes to ext/rtree/rtree5.test.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
8
9
10
11
12
13
14


15
16
17
18
19
20
21







-
-







#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# The focus of this file is testing the r-tree extension when it is
# configured to store values as 32 bit integers.
#
# $Id: rtree5.test,v 1.1 2008/07/14 15:37:01 danielk1977 Exp $
#

if {![info exists testdir]} {
  set testdir [file join [file dirname $argv0] .. .. test]
} 
source $testdir/tester.tcl

ifcapable !rtree {
Changes to ext/rtree/rtree6.test.
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
1
2
3
4
5
6
7
8
9
10

11

12
13
14
15
16
17
18










-
+
-







# 2008 Sep 1
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# 
# $Id: rtree6.test,v 1.1 2008/09/01 12:47:00 danielk1977 Exp $
#

if {![info exists testdir]} {
  set testdir [file join [file dirname $argv0] .. .. test]
} 
source $testdir/tester.tcl

92
93
94
95
96
97
98
99
100

101
102
103
104
105
106
107
108
109
110
111
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109








-

+










-
  {TABLE t2}                          \
  {TABLE t1 VIRTUAL TABLE INDEX 1:}   \
]

do_test rtree6.2.4 {
  query_plan {SELECT * FROM t1,t2 WHERE v=10 and x1<10 and x2>10}
} [list \
  {TABLE t2}                              \
  {TABLE t1 VIRTUAL TABLE INDEX 2:CaEb}   \
  {TABLE t2}                              \
]

do_test rtree6.2.5 {
  query_plan {SELECT * FROM t1,t2 WHERE k=ii AND x1<v}
} [list \
  {TABLE t2}                              \
  {TABLE t1 VIRTUAL TABLE INDEX 1:}   \
]

finish_test

Changes to ext/rtree/rtree_perf.tcl.
68
69
70
71
72
73
74
75
76
68
69
70
71
72
73
74









-
-
flush stdout
set rtree_select_time [time {
  foreach {x1 x2 y1 y2} [lrange $data 0 [expr $NQUERY*4-1]] {
    db eval {SELECT * FROM rtree WHERE x1<$x1 AND x2>$x2 AND y1<$y1 AND y2>$y2}
  }
}]
puts "$rtree_select_time"


Changes to ext/rtree/rtree_util.tcl.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
9
10
11
12
13
14
15


16
17
18
19
20
21
22







-
-







#
#***********************************************************************
#
# This file contains Tcl code that may be useful for testing or
# analyzing r-tree structures created with this module. It is
# used by both test procedures and the r-tree viewer application.
#
# $Id: rtree_util.tcl,v 1.1 2008/05/26 18:41:54 danielk1977 Exp $
#


#--------------------------------------------------------------------------
# PUBLIC API:
#
#   rtree_depth
#   rtree_ndim
188
189
190
191
192
193
194
195
186
187
188
189
190
191
192








-
  set ret
}

proc rtree_treedump {db zTab} {
  set d [rtree_depth $db $zTab]
  rtree_nodetreedump $db $zTab "" $d 1
}

Changes to ext/rtree/tkt3363.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







# 2008 Sep 08
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# The focus of this file is testing that ticket #3363 is fixed.
#
# $Id: tkt3363.test,v 1.1 2008/09/08 11:07:03 danielk1977 Exp $
#

if {![info exists testdir]} {
  set testdir [file join [file dirname $argv0] .. .. test]
}
source [file join [file dirname [info script]] rtree_util.tcl]
source $testdir/tester.tcl

46
47
48
49
50
51
52
53
54
44
45
46
47
48
49
50









-
-
do_test tkt3363.1.4 {
  execsql { 
    SELECT count(*) FROM t1 WHERE y2>4000425.0;
  }
} {7}

finish_test


Changes to ext/rtree/viewrtree.tcl.
182
183
184
185
186
187
188
189
182
183
184
185
186
187
188








-
  }

  return $zReport
}

view_node
bind .c <Configure> view_node

Changes to main.mk.
48
49
50
51
52
53
54
55

56
57
58
59
60
61
62
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62







-
+







TCCX += -I$(TOP)/ext/rtree -I$(TOP)/ext/icu -I$(TOP)/ext/fts3
TCCX += -I$(TOP)/ext/async

# Object files for the SQLite library.
#
LIBOBJ+= alter.o analyze.o attach.o auth.o \
         backup.o bitvec.o btmutex.o btree.o build.o \
         callback.o complete.o date.o delete.o expr.o fault.o \
         callback.o complete.o date.o delete.o expr.o fault.o fkey.o \
         fts3.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \
         fts3_tokenizer.o fts3_tokenizer1.o \
         func.o global.o hash.o \
         icu.o insert.o journal.o legacy.o loadext.o \
         main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \
         memjournal.o \
         mutex.o mutex_noop.o mutex_os2.o mutex_unix.o mutex_w32.o \
86
87
88
89
90
91
92

93
94
95
96
97
98
99
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100







+







  $(TOP)/src/build.c \
  $(TOP)/src/callback.c \
  $(TOP)/src/complete.c \
  $(TOP)/src/date.c \
  $(TOP)/src/delete.c \
  $(TOP)/src/expr.c \
  $(TOP)/src/fault.c \
  $(TOP)/src/fkey.c \
  $(TOP)/src/func.c \
  $(TOP)/src/global.c \
  $(TOP)/src/hash.c \
  $(TOP)/src/hash.h \
  $(TOP)/src/hwtime.h \
  $(TOP)/src/insert.c \
  $(TOP)/src/journal.c \
188
189
190
191
192
193
194
195

196
197
198
199
200
201
202
189
190
191
192
193
194
195

196
197
198
199
200
201
202
203







-
+







  $(TOP)/ext/fts3/fts3_icu.c \
  $(TOP)/ext/fts3/fts3_porter.c \
  $(TOP)/ext/fts3/fts3_tokenizer.h \
  $(TOP)/ext/fts3/fts3_tokenizer.c \
  $(TOP)/ext/fts3/fts3_tokenizer1.c
SRC += \
  $(TOP)/ext/icu/sqliteicu.h \
  $(TOP)/ext/icu/icu.c 
  $(TOP)/ext/icu/icu.c
SRC += \
  $(TOP)/ext/rtree/rtree.h \
  $(TOP)/ext/rtree/rtree.c


# Generated source code files
#
225
226
227
228
229
230
231
232
233
234




235
236
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251


252
253
254
255
256
257
258
226
227
228
229
230
231
232



233
234
235
236
237
238
239
240
241
242
243
244

245
246
247
248
249
250
251
252

253
254
255
256
257
258
259
260
261







-
-
-
+
+
+
+








-
+







-
+
+







  $(TOP)/src/test_async.c \
  $(TOP)/src/test_backup.c \
  $(TOP)/src/test_btree.c \
  $(TOP)/src/test_config.c \
  $(TOP)/src/test_devsym.c \
  $(TOP)/src/test_func.c \
  $(TOP)/src/test_hexio.c \
  $(TOP)/src/test_journal.c \
  $(TOP)/src/test_malloc.c \
  $(TOP)/src/test_md5.c \
  $(TOP)/src/test_init.c \
  $(TOP)/src/test_intarray.c \
  $(TOP)/src/test_journal.c \
  $(TOP)/src/test_malloc.c \
  $(TOP)/src/test_mutex.c \
  $(TOP)/src/test_onefile.c \
  $(TOP)/src/test_osinst.c \
  $(TOP)/src/test_pcache.c \
  $(TOP)/src/test_schema.c \
  $(TOP)/src/test_server.c \
  $(TOP)/src/test_tclvar.c \
  $(TOP)/src/test_thread.c \
  $(TOP)/src/test_wsd.c \
  $(TOP)/src/test_wsd.c

#TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c
#TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c

TESTSRC2 = \
  $(TOP)/src/attach.c $(TOP)/src/backup.c $(TOP)/src/btree.c                   \
  $(TOP)/src/build.c $(TOP)/src/date.c                                         \
  $(TOP)/src/expr.c $(TOP)/src/func.c $(TOP)/src/insert.c $(TOP)/src/os.c      \
  $(TOP)/src/expr.c $(TOP)/src/func.c $(TOP)/src/insert.c $(TOP)/src/mem5.c    \
  $(TOP)/src/os.c                                                              \
  $(TOP)/src/os_os2.c $(TOP)/src/os_unix.c $(TOP)/src/os_win.c                 \
  $(TOP)/src/pager.c $(TOP)/src/pragma.c $(TOP)/src/prepare.c                  \
  $(TOP)/src/printf.c $(TOP)/src/random.c $(TOP)/src/pcache.c                  \
  $(TOP)/src/pcache1.c $(TOP)/src/select.c $(TOP)/src/tokenize.c               \
  $(TOP)/src/utf.c $(TOP)/src/util.c $(TOP)/src/vdbeapi.c $(TOP)/src/vdbeaux.c \
  $(TOP)/src/vdbe.c $(TOP)/src/vdbemem.c $(TOP)/src/where.c parse.c            \
  $(TOP)/ext/fts3/fts3.c $(TOP)/ext/fts3/fts3_expr.c                           \
341
342
343
344
345
346
347
348

349
350

351
352
353
354
355
356
357
344
345
346
347
348
349
350

351
352

353
354
355
356
357
358
359
360







-
+

-
+







	tclsh $(TOP)/ext/fts2/mkfts2amal.tcl

fts3amal.c:	target_source $(TOP)/ext/fts3/mkfts3amal.tcl
	tclsh $(TOP)/ext/fts3/mkfts3amal.tcl

# Rules to build the LEMON compiler generator
#
lemon:	$(TOP)/tool/lemon.c $(TOP)/tool/lempar.c
lemon:	$(TOP)/tool/lemon.c $(TOP)/src/lempar.c
	$(BCC) -o lemon $(TOP)/tool/lemon.c
	cp $(TOP)/tool/lempar.c .
	cp $(TOP)/src/lempar.c .

# Rules to build individual *.o files from generated *.c files. This
# applies to:
#
#     parse.o
#     opcodes.o
#
384
385
386
387
388
389
390
391

392
393
394

395
396
397
398
399
400
401
387
388
389
390
391
392
393

394



395
396
397
398
399
400
401
402







-
+
-
-
-
+







parse.c:	$(TOP)/src/parse.y lemon $(TOP)/addopcodes.awk
	cp $(TOP)/src/parse.y .
	rm -f parse.h
	./lemon $(OPTS) parse.y
	mv parse.h parse.h.temp
	awk -f $(TOP)/addopcodes.awk parse.h.temp >parse.h

sqlite3.h:	$(TOP)/src/sqlite.h.in 
sqlite3.h:	$(TOP)/src/sqlite.h.in $(TOP)/manifest.uuid $(TOP)/VERSION
	sed -e s/--VERS--/`cat ${TOP}/VERSION`/ \
	    -e s/--VERSION-NUMBER--/`cat ${TOP}/VERSION | sed 's/[^0-9]/ /g' | $(NAWK) '{printf "%d%03d%03d",$$1,$$2,$$3}'`/ \
                 $(TOP)/src/sqlite.h.in >sqlite3.h
	tclsh $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h

keywordhash.h:	$(TOP)/tool/mkkeywordhash.c
	$(BCC) -o mkkeywordhash $(OPTS) $(TOP)/tool/mkkeywordhash.c
	./mkkeywordhash >keywordhash.h



Changes to mkopcodeh.awk.
21
22
23
24
25
26
27
28

29
30
31
32



33
34
35
36
37
38
39
40
41
42
43
44
45
21
22
23
24
25
26
27

28
29



30
31
32






33
34
35
36
37
38
39







-
+

-
-
-
+
+
+
-
-
-
-
-
-







# OP_Add and OP_Divide.  By making TK_ADD==OP_Add and TK_DIVIDE==OP_Divide,
# code to translate from one to the other is avoided.  This makes the
# code generator run (infinitesimally) faster and more importantly it makes
# the library footprint smaller.
#
# This script also scans for lines of the form:
#
#       case OP_aaaa:       /* no-push */
#       case OP_aaaa:       /* jump, in1, in2, in3, out2-prerelease, out3 */
#
# When the no-push comment is found on an opcode, it means that that
# opcode does not leave a result on the stack.  By identifying which
# opcodes leave results on the stack it is possible to determine a
# When such comments are found on an opcode, it means that certain
# properties apply to that opcode.  Set corresponding flags using the
# OPFLG_INITIALIZER macro.
# much smaller upper bound on the size of the stack.  This allows
# a smaller stack to be allocated, which is important to embedded
# systems with limited memory space.  This script generates a series
# of "NOPUSH_MASK" defines that contain bitmaps of opcodes that leave
# results on the stack.  The NOPUSH_MASK defines are used in vdbeaux.c
# to help determine the maximum stack size.
#


# Remember the TK_ values from the parse.h file
/^#define TK_/ {
  tk[$2] = 0+$3
}
76
77
78
79
80
81
82

83
84
85
86
87
88
89
90
91

92


93

94
95
96
97
98
99
100
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98







+









+

+
+
-
+







      in2[name] = 1
    }else if(x=="in3"){
      in3[name] = 1
    }else if(x=="out3"){
      out3[name] = 1
    }
  }
  order[n_op++] = name;
}

# Assign numbers to all opcodes and output the result.
END {
  cnt = 0
  max = 0
  print "/* Automatically generated.  Do not edit */"
  print "/* See the mkopcodeh.awk script for details */"
  op["OP_Noop"] = -1;
  order[n_op++] = "OP_Noop";
  op["OP_Explain"] = -1;
  order[n_op++] = "OP_Explain";
  for(i=0; i<n_op; i++){
  for(name in op){
    name = order[i];
    if( op[name]<0 ){
      cnt++
      while( used[cnt] ) cnt++
      op[name] = cnt
    }
    used[op[name]] = 1;
    if( op[name]>max ) max = op[name]
119
120
121
122
123
124
125

126

127
128
129
130
131
132
133
117
118
119
120
121
122
123
124

125
126
127
128
129
130
131
132







+
-
+







  # Generate the bitvectors:
  #
  #  bit 0:     jump
  #  bit 1:     pushes a result onto stack
  #  bit 2:     output to p1.  release p1 before opcode runs
  #
  for(i=0; i<=max; i++) bv[i] = 0;
  for(i=0; i<n_op; i++){
  for(name in op){
    name = order[i];
    x = op[name]
    a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0
    # a8 = a9 = a10 = a11 = a12 = a13 = a14 = a15 = 0
    if( jump[name] ) a0 = 1;
    if( out2_prerelease[name] ) a1 = 2;
    if( in1[name] ) a2 = 4;
    if( in2[name] ) a3 = 8;
Changes to publish.sh.
88
89
90
91
92
93
94

95
96
97

98
99
100
101
102
103
104
88
89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105







+


-
+







zip doc/sqlite-$VERSW.zip sqlite3.exe

# Construct a tarball of the source tree
#
echo '***** BUILDING source archive'
ORIGIN=`pwd`
cd $srcdir
chmod +x configure
cd ..
mv sqlite sqlite-$VERS
EXCLUDE=`find sqlite-$VERS -print | egrep '(CVS|www/|art/|doc/|contrib/|_FOSSIL_|manifest)' | sed 's,^, --exclude ,'`
EXCLUDE=`find sqlite-$VERS -print | egrep '(www/|art/|doc/|contrib/|_FOSSIL_)' | sed 's,^, --exclude ,'`
echo "tar czf $ORIGIN/doc/sqlite-$VERS.tar.gz $EXCLUDE sqlite-$VERS"
tar czf $ORIGIN/doc/sqlite-$VERS.tar.gz $EXCLUDE sqlite-$VERS
mv sqlite-$VERS sqlite
cd $ORIGIN

#
# Build RPMS (binary) and Source RPM
Changes to src/alter.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2005 February 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that used to generate VDBE code
** that implements the ALTER TABLE command.
**
** $Id: alter.c,v 1.61 2009/06/03 11:25:07 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** The code in this file only exists if we are not omitting the
** ALTER TABLE logic from the build.
*/
81
82
83
84
85
86
87































































88
89
90
91
92
93
94
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








    zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, 
       zTableName, tname.z+tname.n);
    sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
  }
}

/*
** This C function implements an SQL user function that is used by SQL code
** generated by the ALTER TABLE ... RENAME command to modify the definition
** of any foreign key constraints that use the table being renamed as the 
** parent table. It is passed three arguments:
**
**   1) The complete text of the CREATE TABLE statement being modified,
**   2) The old name of the table being renamed, and
**   3) The new name of the table being renamed.
**
** It returns the new CREATE TABLE statement. For example:
**
**   sqlite_rename_parent('CREATE TABLE t1(a REFERENCES t2)', 't2', 't3')
**       -> 'CREATE TABLE t1(a REFERENCES t3)'
*/
#ifndef SQLITE_OMIT_FOREIGN_KEY
static void renameParentFunc(
  sqlite3_context *context,
  int NotUsed,
  sqlite3_value **argv
){
  sqlite3 *db = sqlite3_context_db_handle(context);
  char *zOutput = 0;
  char *zResult;
  unsigned char const *zInput = sqlite3_value_text(argv[0]);
  unsigned char const *zOld = sqlite3_value_text(argv[1]);
  unsigned char const *zNew = sqlite3_value_text(argv[2]);

  unsigned const char *z;         /* Pointer to token */
  int n;                          /* Length of token z */
  int token;                      /* Type of token */

  UNUSED_PARAMETER(NotUsed);
  for(z=zInput; *z; z=z+n){
    n = sqlite3GetToken(z, &token);
    if( token==TK_REFERENCES ){
      char *zParent;
      do {
        z += n;
        n = sqlite3GetToken(z, &token);
      }while( token==TK_SPACE );

      zParent = sqlite3DbStrNDup(db, (const char *)z, n);
      if( zParent==0 ) break;
      sqlite3Dequote(zParent);
      if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){
        char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"", 
            (zOutput?zOutput:""), z-zInput, zInput, (const char *)zNew
        );
        sqlite3DbFree(db, zOutput);
        zOutput = zOut;
        zInput = &z[n];
      }
      sqlite3DbFree(db, zParent);
    }
  }

  zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput), 
  sqlite3_result_text(context, zResult, -1, SQLITE_DYNAMIC);
  sqlite3DbFree(db, zOutput);
}
#endif

#ifndef SQLITE_OMIT_TRIGGER
/* This function is used by SQL generated to implement the
** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER 
** statement. The second is a table name. The table name in the CREATE 
** TRIGGER statement is replaced with the third argument and the result 
** returned. This is analagous to renameTableFunc() above, except for CREATE
** TRIGGER, not CREATE INDEX and CREATE TABLE.
168
169
170
171
172
173
174




175












































176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202

203
204
205
206
207
208
209
210
211
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294

295
296
297
298
299
300
301
302
303
304
305





306


307
308
309
310
311
312
313







+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+










-











-
-
-
-
-
+
-
-







void sqlite3AlterFunctions(sqlite3 *db){
  sqlite3CreateFunc(db, "sqlite_rename_table", 2, SQLITE_UTF8, 0,
                         renameTableFunc, 0, 0);
#ifndef SQLITE_OMIT_TRIGGER
  sqlite3CreateFunc(db, "sqlite_rename_trigger", 2, SQLITE_UTF8, 0,
                         renameTriggerFunc, 0, 0);
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
  sqlite3CreateFunc(db, "sqlite_rename_parent", 3, SQLITE_UTF8, 0,
                         renameParentFunc, 0, 0);
#endif
}

/*
** This function is used to create the text of expressions of the form:
**
**   name=<constant1> OR name=<constant2> OR ...
**
** If argument zWhere is NULL, then a pointer string containing the text 
** "name=<constant>" is returned, where <constant> is the quoted version
** of the string passed as argument zConstant. The returned buffer is
** allocated using sqlite3DbMalloc(). It is the responsibility of the
** caller to ensure that it is eventually freed.
**
** If argument zWhere is not NULL, then the string returned is 
** "<where> OR name=<constant>", where <where> is the contents of zWhere.
** In this case zWhere is passed to sqlite3DbFree() before returning.
** 
*/
static char *whereOrName(sqlite3 *db, char *zWhere, char *zConstant){
  char *zNew;
  if( !zWhere ){
    zNew = sqlite3MPrintf(db, "name=%Q", zConstant);
  }else{
    zNew = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, zConstant);
    sqlite3DbFree(db, zWhere);
  }
  return zNew;
}

#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
/*
** Generate the text of a WHERE expression which can be used to select all
** tables that have foreign key constraints that refer to table pTab (i.e.
** constraints for which pTab is the parent table) from the sqlite_master
** table.
*/
static char *whereForeignKeys(Parse *pParse, Table *pTab){
  FKey *p;
  char *zWhere = 0;
  for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
    zWhere = whereOrName(pParse->db, zWhere, p->pFrom->zName);
  }
  return zWhere;
}
#endif

/*
** Generate the text of a WHERE expression which can be used to select all
** temporary triggers on table pTab from the sqlite_temp_master table. If
** table pTab has no temporary triggers, or is itself stored in the 
** temporary database, NULL is returned.
*/
static char *whereTempTriggers(Parse *pParse, Table *pTab){
  Trigger *pTrig;
  char *zWhere = 0;
  char *tmp = 0;
  const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */

  /* If the table is not located in the temp-db (in which case NULL is 
  ** returned, loop through the tables list of triggers. For each trigger
  ** that is not part of the temp-db schema, add a clause to the WHERE 
  ** expression being built up in zWhere.
  */
  if( pTab->pSchema!=pTempSchema ){
    sqlite3 *db = pParse->db;
    for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
      if( pTrig->pSchema==pTempSchema ){
        if( !zWhere ){
          zWhere = sqlite3MPrintf(db, "name=%Q", pTrig->name);
        }else{
          tmp = zWhere;
          zWhere = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, pTrig->name);
        zWhere = whereOrName(db, zWhere, pTrig->zName);
          sqlite3DbFree(db, tmp);
        }
      }
    }
  }
  return zWhere;
}

/*
231
232
233
234
235
236
237
238

239
240
241
242

243
244
245
246
247
248
249
333
334
335
336
337
338
339

340
341
342
343

344
345
346
347
348
349
350
351







-
+



-
+







  assert( iDb>=0 );

#ifndef SQLITE_OMIT_TRIGGER
  /* Drop any table triggers from the internal schema. */
  for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
    int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
    assert( iTrigDb==iDb || iTrigDb==1 );
    sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->name, 0);
    sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->zName, 0);
  }
#endif

  /* Drop the table and index from the internal schema */
  /* Drop the table and index from the internal schema.  */
  sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);

  /* Reload the table, index and permanent trigger schemas. */
  zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName);
  if( !zWhere ) return;
  sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC);

273
274
275
276
277
278
279
280

281
282
283
284
285
286
287
375
376
377
378
379
380
381

382
383
384
385
386
387
388
389







-
+







  sqlite3 *db = pParse->db; /* Database connection */
  int nTabName;             /* Number of UTF-8 characters in zTabName */
  const char *zTabName;     /* Original name of the table */
  Vdbe *v;
#ifndef SQLITE_OMIT_TRIGGER
  char *zWhere = 0;         /* Where clause to locate temp triggers */
#endif
  int isVirtualRename = 0;  /* True if this is a v-table with an xRename() */
  VTable *pVTab = 0;        /* Non-zero if this is a v-tab with an xRename() */
  
  if( NEVER(db->mallocFailed) ) goto exit_rename_table;
  assert( pSrc->nSrc==1 );
  assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );

  pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
  if( !pTab ) goto exit_rename_table;
328
329
330
331
332
333
334
335
336





337
338
339
340
341
342
343
344
345
346
347
348
349

350
351
352
353
354
355
356
357
358

359
360
361


362
363
364
365
366
367















368
369
370
371
372
373
374
430
431
432
433
434
435
436


437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453

454
455
456
457
458
459
460
461
462

463
464
465

466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495







-
-
+
+
+
+
+












-
+








-
+


-
+
+






+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







  }
#endif

#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( sqlite3ViewGetColumnNames(pParse, pTab) ){
    goto exit_rename_table;
  }
  if( IsVirtual(pTab) && pTab->pMod->pModule->xRename ){
    isVirtualRename = 1;
  if( IsVirtual(pTab) ){
    pVTab = sqlite3GetVTable(db, pTab);
    if( pVTab->pVtab->pModule->xRename==0 ){
      pVTab = 0;
    }
  }
#endif

  /* Begin a transaction and code the VerifyCookie for database iDb. 
  ** Then modify the schema cookie (since the ALTER TABLE modifies the
  ** schema). Open a statement transaction if the table is a virtual
  ** table.
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ){
    goto exit_rename_table;
  }
  sqlite3BeginWriteOperation(pParse, isVirtualRename, iDb);
  sqlite3BeginWriteOperation(pParse, pVTab!=0, iDb);
  sqlite3ChangeCookie(pParse, iDb);

  /* If this is a virtual table, invoke the xRename() function if
  ** one is defined. The xRename() callback will modify the names
  ** of any resources used by the v-table implementation (including other
  ** SQLite tables) that are identified by the name of the virtual table.
  */
#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( isVirtualRename ){
  if( pVTab ){
    int i = ++pParse->nMem;
    sqlite3VdbeAddOp4(v, OP_String8, 0, i, 0, zName, 0);
    sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pTab->pVtab, P4_VTAB);
    sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);
    sqlite3MayAbort(pParse);
  }
#endif

  /* figure out how many UTF-8 characters are in zName */
  zTabName = pTab->zName;
  nTabName = sqlite3Utf8CharLen(zTabName, -1);

#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
  if( db->flags&SQLITE_ForeignKeys ){
    /* If foreign-key support is enabled, rewrite the CREATE TABLE 
    ** statements corresponding to all child tables of foreign key constraints
    ** for which the renamed table is the parent table.  */
    if( (zWhere=whereForeignKeys(pParse, pTab))!=0 ){
      sqlite3NestedParse(pParse, 
          "UPDATE sqlite_master SET "
              "sql = sqlite_rename_parent(sql, %Q, %Q) "
              "WHERE %s;", zTabName, zName, zWhere);
      sqlite3DbFree(db, zWhere);
    }
  }
#endif

  /* Modify the sqlite_master table to use the new table name. */
  sqlite3NestedParse(pParse,
      "UPDATE %Q.%s SET "
#ifdef SQLITE_OMIT_TRIGGER
          "sql = sqlite_rename_table(sql, %Q), "
#else
410
411
412
413
414
415
416












417
418
419
420
421
422
423
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556







+
+
+
+
+
+
+
+
+
+
+
+







  if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
    sqlite3NestedParse(pParse, 
        "UPDATE sqlite_temp_master SET "
            "sql = sqlite_rename_trigger(sql, %Q), "
            "tbl_name = %Q "
            "WHERE %s;", zName, zName, zWhere);
    sqlite3DbFree(db, zWhere);
  }
#endif

#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
  if( db->flags&SQLITE_ForeignKeys ){
    FKey *p;
    for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
      Table *pFrom = p->pFrom;
      if( pFrom!=pTab ){
        reloadTableSchema(pParse, p->pFrom, pFrom->zName);
      }
    }
  }
#endif

  /* Drop and reload the internal table schema. */
  reloadTableSchema(pParse, pTab, zName);

exit_rename_table:
506
507
508
509
510
511
512





513
514
515
516
517
518
519
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657







+
+
+
+
+







  if( pCol->isPrimKey ){
    sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
    return;
  }
  if( pNew->pIndex ){
    sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
    return;
  }
  if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){
    sqlite3ErrorMsg(pParse, 
        "Cannot add a REFERENCES column with non-NULL default value");
    return;
  }
  if( pCol->notNull && !pDflt ){
    sqlite3ErrorMsg(pParse, 
        "Cannot add a NOT NULL column with default value NULL");
    return;
  }

Changes to src/analyze.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21




22
23

24
25







26
27
28
29
30
31
32














33
34
35
36
37
38
39
40
41
42
43




44
45
46
47
48
49
50







51
52
53
54
55
56
57







58
59
60
61
62
63
64








65
66
67
68



69
70
71
72
73
74
75
76



77
78
79




80
81
82
83
84
85
86
87
88
89
90
91

92
93


94
95
96
97
98
99
100





















101
102
103
104
105
106
107
108


109
110
111
112

113
114
115
116
117
118
119
120
121

122
123

124
125
126


127
128
129
130



131
132

133
134
135
136
137
138
139
140
141

























142
143





144


145

146

147
148
149
150
151
152








153
154
155


156
157
158
159
160
161
162
163
164
165


166
167
168
169

170
171

































172
173
174







175
176
177
178

179
180
181


182
183
184
185
186

187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208

209
210
211

212
213
214
215
216

217
218

219
220
221
222
223
224
225
1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17


18
19
20
21
22
23
24


25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54



55

56
57
58
59
60
61
62
63







64
65
66
67
68
69
70







71
72
73
74
75
76
77







78
79
80
81
82
83
84
85




86
87
88







89
90
91
92



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109


110
111







112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138


139
140
141
142
143

144
145
146
147
148
149
150
151
152
153
154
155

156



157
158




159
160
161


162

163
164
165





166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197

198
199
200
201

202






203
204
205
206
207
208
209
210
211


212
213
214
215
216
217
218
219
220
221


222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276

277
278
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305




306
307
308

309
310
311
312
313

314
315

316
317
318
319
320
321
322
323












-
-





-
-
+
+
+
+


+
-
-
+
+
+
+
+
+
+







+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-
-

-




+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
-
-
-
-
-
-
-

+
+
+
-
-
-
+
+
+
+












+
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






-
-
+
+



-
+









+

-
+
-
-
-
+
+
-
-
-
-
+
+
+
-
-
+
-



-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
+
+
+
+
-
+
+

+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+

-
-
+
+








-
-
+
+




+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



+
+
+
+
+
+
+



-
+



+
+




-
+


















-
-
-
-
+


-
+




-
+

-
+







/*
** 2005 July 8
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code associated with the ANALYZE command.
**
** @(#) $Id: analyze.c,v 1.52 2009/04/16 17:45:48 drh Exp $
*/
#ifndef SQLITE_OMIT_ANALYZE
#include "sqliteInt.h"

/*
** This routine generates code that opens the sqlite_stat1 table on cursor
** iStatCur.
** This routine generates code that opens the sqlite_stat1 table for
** writing with cursor iStatCur. If the library was built with the
** SQLITE_ENABLE_STAT2 macro defined, then the sqlite_stat2 table is
** opened for writing using cursor (iStatCur+1)
**
** If the sqlite_stat1 tables does not previously exist, it is created.
** Similarly, if the sqlite_stat2 table does not exist and the library
** If it does previously exist, all entires associated with table zWhere
** are removed.  If zWhere==0 then all entries are removed.
** is compiled with SQLITE_ENABLE_STAT2 defined, it is created. 
**
** Argument zWhere may be a pointer to a buffer containing a table name,
** or it may be a NULL pointer. If it is not NULL, then all entries in
** the sqlite_stat1 and (if applicable) sqlite_stat2 tables associated
** with the named table are deleted. If zWhere==0, then code is generated
** to delete all stat table entries.
*/
static void openStatTable(
  Parse *pParse,          /* Parsing context */
  int iDb,                /* The database we are looking in */
  int iStatCur,           /* Open the sqlite_stat1 table on this cursor */
  const char *zWhere      /* Delete entries associated with this table */
){
  static struct {
    const char *zName;
    const char *zCols;
  } aTable[] = {
    { "sqlite_stat1", "tbl,idx,stat" },
#ifdef SQLITE_ENABLE_STAT2
    { "sqlite_stat2", "tbl,idx,sampleno,sample" },
#endif
  };

  int aRoot[] = {0, 0};
  u8 aCreateTbl[] = {0, 0};

  int i;
  sqlite3 *db = pParse->db;
  Db *pDb;
  int iRootPage;
  u8 createStat1 = 0;
  Table *pStat;
  Vdbe *v = sqlite3GetVdbe(pParse);

  if( v==0 ) return;
  assert( sqlite3BtreeHoldsAllMutexes(db) );
  assert( sqlite3VdbeDb(v)==db );
  pDb = &db->aDb[iDb];

  for(i=0; i<ArraySize(aTable); i++){
    const char *zTab = aTable[i].zName;
    Table *pStat;
  if( (pStat = sqlite3FindTable(db, "sqlite_stat1", pDb->zName))==0 ){
    /* The sqlite_stat1 tables does not exist.  Create it.  
    ** Note that a side-effect of the CREATE TABLE statement is to leave
    ** the rootpage of the new table in register pParse->regRoot.  This is
    ** important because the OpenWrite opcode below will be needing it. */
    sqlite3NestedParse(pParse,
      "CREATE TABLE %Q.sqlite_stat1(tbl,idx,stat)",
    if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){
      /* The sqlite_stat[12] table does not exist. Create it. Note that a 
      ** side-effect of the CREATE TABLE statement is to leave the rootpage 
      ** of the new table in register pParse->regRoot. This is important 
      ** because the OpenWrite opcode below will be needing it. */
      sqlite3NestedParse(pParse,
          "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols
      pDb->zName
    );
    iRootPage = pParse->regRoot;
    createStat1 = 1;  /* Cause rootpage to be taken from top of stack */
  }else if( zWhere ){
    /* The sqlite_stat1 table exists.  Delete all entries associated with
    ** the table zWhere. */
      );
      aRoot[i] = pParse->regRoot;
      aCreateTbl[i] = 1;
    }else{
      /* The table already exists. If zWhere is not NULL, delete all entries 
      ** associated with the table zWhere. If zWhere is NULL, delete the
      ** entire contents of the table. */
    sqlite3NestedParse(pParse,
       "DELETE FROM %Q.sqlite_stat1 WHERE tbl=%Q",
       pDb->zName, zWhere
    );
    iRootPage = pStat->tnum;
  }else{
    /* The sqlite_stat1 table already exists.  Delete all rows. */
      aRoot[i] = pStat->tnum;
      sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
      if( zWhere ){
        sqlite3NestedParse(pParse,
           "DELETE FROM %Q.%s WHERE tbl=%Q", pDb->zName, zTab, zWhere
        );
      }else{
        /* The sqlite_stat[12] table already exists.  Delete all rows. */
    iRootPage = pStat->tnum;
    sqlite3VdbeAddOp2(v, OP_Clear, pStat->tnum, iDb);
  }

        sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
      }
    }
  /* Open the sqlite_stat1 table for writing. Unless it was created
  ** by this vdbe program, lock it for writing at the shared-cache level. 
  ** If this vdbe did create the sqlite_stat1 table, then it must have 
  ** already obtained a schema-lock, making the write-lock redundant.
  */
  if( !createStat1 ){
    sqlite3TableLock(pParse, iDb, iRootPage, 1, "sqlite_stat1");
  }

  /* Open the sqlite_stat[12] tables for writing. */
  for(i=0; i<ArraySize(aTable); i++){
  sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur, iRootPage, iDb);
  sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
  sqlite3VdbeChangeP5(v, createStat1);
    sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
    sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
    sqlite3VdbeChangeP5(v, aCreateTbl[i]);
  }
}

/*
** Generate code to do an analysis of all indices associated with
** a single table.
*/
static void analyzeOneTable(
  Parse *pParse,   /* Parser context */
  Table *pTab,     /* Table whose indices are to be analyzed */
  int iStatCur,    /* Index of VdbeCursor that writes the sqlite_stat1 table */
  int iMem         /* Available memory locations begin here */
){
  sqlite3 *db = pParse->db;    /* Database handle */
  Index *pIdx;     /* An index to being analyzed */
  int iIdxCur;     /* Index of VdbeCursor for index being analyzed */
  Index *pIdx;                 /* An index to being analyzed */
  int iIdxCur;                 /* Cursor open on index being analyzed */
  int nCol;        /* Number of columns in the index */
  Vdbe *v;         /* The virtual machine being built up */
  int i;           /* Loop counter */
  int topOfLoop;   /* The top of the loop */
  int endOfLoop;   /* The end of the loop */
  int addr;        /* The address of an instruction */
  int iDb;         /* Index of database containing pTab */
  Vdbe *v;                     /* The virtual machine being built up */
  int i;                       /* Loop counter */
  int topOfLoop;               /* The top of the loop */
  int endOfLoop;               /* The end of the loop */
  int addr;                    /* The address of an instruction */
  int iDb;                     /* Index of database containing pTab */
  int regTabname = iMem++;     /* Register containing table name */
  int regIdxname = iMem++;     /* Register containing index name */
  int regSampleno = iMem++;    /* Register containing next sample number */
  int regCol = iMem++;         /* Content of a column analyzed table */
  int regRec = iMem++;         /* Register holding completed record */
  int regTemp = iMem++;        /* Temporary use register */
  int regRowid = iMem++;       /* Rowid for the inserted record */

#ifdef SQLITE_ENABLE_STAT2
  int regTemp2 = iMem++;       /* Temporary use register */
  int regSamplerecno = iMem++; /* Index of next sample to record */
  int regRecno = iMem++;       /* Current sample index */
  int regLast = iMem++;        /* Index of last sample to record */
  int regFirst = iMem++;       /* Index of first sample to record */
#endif

  v = sqlite3GetVdbe(pParse);
  if( v==0 || NEVER(pTab==0) || pTab->pIndex==0 ){
    /* Do no analysis for tables that have no indices */
    return;
  }
  assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
  assert( sqlite3BtreeHoldsAllMutexes(db) );
  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  assert( iDb>=0 );
#ifndef SQLITE_OMIT_AUTHORIZATION
  if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
      pParse->db->aDb[iDb].zName ) ){
      db->aDb[iDb].zName ) ){
    return;
  }
#endif

  /* Establish a read-lock on the table at the shared-cache level. */
  sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);

  iIdxCur = pParse->nTab++;
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    int nCol = pIdx->nColumn;
    KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
    int regFields;    /* Register block for building records */

    int regRec;       /* Register holding completed record */
    int regTemp;      /* Temporary use register */
    int regCol;       /* Content of a column from the table being analyzed */
    if( iMem+1+(nCol*2)>pParse->nMem ){
      pParse->nMem = iMem+1+(nCol*2);
    int regRowid;     /* Rowid for the inserted record */
    int regF2;

    /* Open a cursor to the index to be analyzed
    }

    /* Open a cursor to the index to be analyzed. */
    */
    assert( iDb==sqlite3SchemaToIndex(pParse->db, pIdx->pSchema) );
    assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) );
    nCol = pIdx->nColumn;
    sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb,
        (char *)pKey, P4_KEYINFO_HANDOFF);
    VdbeComment((v, "%s", pIdx->zName));
    regFields = iMem+nCol*2;
    regTemp = regRowid = regCol = regFields+3;
    regRec = regCol+1;
    if( regRec>pParse->nMem ){
      pParse->nMem = regRec;

    /* Populate the registers containing the table and index names. */
    if( pTab->pIndex==pIdx ){
      sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
    }
    sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0);

#ifdef SQLITE_ENABLE_STAT2

    /* If this iteration of the loop is generating code to analyze the
    ** first index in the pTab->pIndex list, then register regLast has
    ** not been populated. In this case populate it now.  */
    if( pTab->pIndex==pIdx ){
      sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES, regSamplerecno);
      sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES*2-1, regTemp);
      sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES*2, regTemp2);

      sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regLast);
      sqlite3VdbeAddOp2(v, OP_Null, 0, regFirst);
      addr = sqlite3VdbeAddOp3(v, OP_Lt, regSamplerecno, 0, regLast);
      sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regLast, regFirst);
      sqlite3VdbeAddOp3(v, OP_Multiply, regLast, regTemp, regLast);
      sqlite3VdbeAddOp2(v, OP_AddImm, regLast, SQLITE_INDEX_SAMPLES*2-2);
      sqlite3VdbeAddOp3(v, OP_Divide,  regTemp2, regLast, regLast);
      sqlite3VdbeJumpHere(v, addr);
    }

    /* Zero the regSampleno and regRecno registers. */
    sqlite3VdbeAddOp2(v, OP_Integer, 0, regSampleno);
    sqlite3VdbeAddOp2(v, OP_Integer, 0, regRecno);
    sqlite3VdbeAddOp2(v, OP_Copy, regFirst, regSamplerecno);
#endif
    /* Memory cells are used as follows:

    /* The block of memory cells initialized here is used as follows.
    **
    **    iMem:                
    **    mem[iMem]:             The total number of rows in the table.
    **        The total number of rows in the table.
    **    mem[iMem+1]:           Number of distinct values in column 1
    **    ...
    **    mem[iMem+nCol]:        Number of distinct values in column N
    **    mem[iMem+nCol+1]       Last observed value of column 1
    **    ...
    **    mem[iMem+nCol+nCol]:   Last observed value of column N
    **
    **    iMem+1 .. iMem+nCol: 
    **        Number of distinct entries in index considering the 
    **        left-most N columns only, where N is between 1 and nCol, 
    **        inclusive.
    **
    **    iMem+nCol+1 .. Mem+2*nCol:  
    **        Previous value of indexed columns, from left to right.
    **
    ** Cells iMem through iMem+nCol are initialized to 0.  The others
    ** are initialized to NULL.
    ** Cells iMem through iMem+nCol are initialized to 0. The others are 
    ** initialized to contain an SQL NULL.
    */
    for(i=0; i<=nCol; i++){
      sqlite3VdbeAddOp2(v, OP_Integer, 0, iMem+i);
    }
    for(i=0; i<nCol; i++){
      sqlite3VdbeAddOp2(v, OP_Null, 0, iMem+nCol+i+1);
    }

    /* Do the analysis.
    */
    /* Start the analysis loop. This loop runs through all the entries in
    ** the index b-tree.  */
    endOfLoop = sqlite3VdbeMakeLabel(v);
    sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop);
    topOfLoop = sqlite3VdbeCurrentAddr(v);
    sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1);

    for(i=0; i<nCol; i++){
      sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regCol);
#ifdef SQLITE_ENABLE_STAT2
      if( i==0 ){
        /* Check if the record that cursor iIdxCur points to contains a
        ** value that should be stored in the sqlite_stat2 table. If so,
        ** store it.  */
        int ne = sqlite3VdbeAddOp3(v, OP_Ne, regRecno, 0, regSamplerecno);
        assert( regTabname+1==regIdxname 
             && regTabname+2==regSampleno
             && regTabname+3==regCol
        );
        sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
        sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 4, regRec, "aaab", 0);
        sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regRowid);
        sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regRowid);

        /* Calculate new values for regSamplerecno and regSampleno.
        **
        **   sampleno = sampleno + 1
        **   samplerecno = samplerecno+(remaining records)/(remaining samples)
        */
        sqlite3VdbeAddOp2(v, OP_AddImm, regSampleno, 1);
        sqlite3VdbeAddOp3(v, OP_Subtract, regRecno, regLast, regTemp);
        sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
        sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES, regTemp2);
        sqlite3VdbeAddOp3(v, OP_Subtract, regSampleno, regTemp2, regTemp2);
        sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regTemp, regTemp);
        sqlite3VdbeAddOp3(v, OP_Add, regSamplerecno, regTemp, regSamplerecno);

        sqlite3VdbeJumpHere(v, ne);
        sqlite3VdbeAddOp2(v, OP_AddImm, regRecno, 1);
      }
#endif

      sqlite3VdbeAddOp3(v, OP_Ne, regCol, 0, iMem+nCol+i+1);
      /**** TODO:  add collating sequence *****/
      sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
    }
    if( db->mallocFailed ){
      /* If a malloc failure has occurred, then the result of the expression 
      ** passed as the second argument to the call to sqlite3VdbeJumpHere() 
      ** below may be negative. Which causes an assert() to fail (or an
      ** out-of-bounds write if SQLITE_DEBUG is not defined).  */
      return;
    }
    sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop);
    for(i=0; i<nCol; i++){
      sqlite3VdbeJumpHere(v, topOfLoop + 2*(i + 1));
      sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-(nCol*2));
      sqlite3VdbeAddOp2(v, OP_AddImm, iMem+i+1, 1);
      sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1);
    }

    /* End of the analysis loop. */
    sqlite3VdbeResolveLabel(v, endOfLoop);
    sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, topOfLoop);
    sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);

    /* Store the results.  
    /* Store the results in sqlite_stat1.
    **
    ** The result is a single row of the sqlite_stat1 table.  The first
    ** two columns are the names of the table and index.  The third column
    ** is a string composed of a list of integer statistics about the
    ** index.  The first integer in the list is the total number of entries
    ** in the index.  There is one additional integer in the list for each
    ** column of the table.  This additional integer is a guess of how many
    ** rows of the table the index will select.  If D is the count of distinct
    ** values and K is the total number of rows, then the integer is computed
    ** as:
    **
    **        I = (K+D-1)/D
    **
    ** If K==0 then no entry is made into the sqlite_stat1 table.  
    ** If K>0 then it is always the case the D>0 so division by zero
    ** is never possible.
    */
    addr = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
    sqlite3VdbeAddOp4(v, OP_String8, 0, regFields, 0, pTab->zName, 0);
    sqlite3VdbeAddOp4(v, OP_String8, 0, regFields+1, 0, pIdx->zName, 0);
    regF2 = regFields+2;
    sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regF2);
    sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regSampleno);
    for(i=0; i<nCol; i++){
      sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0);
      sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regF2, regF2);
      sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regSampleno, regSampleno);
      sqlite3VdbeAddOp3(v, OP_Add, iMem, iMem+i+1, regTemp);
      sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
      sqlite3VdbeAddOp3(v, OP_Divide, iMem+i+1, regTemp, regTemp);
      sqlite3VdbeAddOp1(v, OP_ToInt, regTemp);
      sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regF2, regF2);
      sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regSampleno, regSampleno);
    }
    sqlite3VdbeAddOp4(v, OP_MakeRecord, regFields, 3, regRec, "aaa", 0);
    sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
    sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regRowid);
    sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regRowid);
    sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
    sqlite3VdbeJumpHere(v, addr);
  }
}

241
242
243
244
245
246
247
248


249
250
251
252
253
254
255
339
340
341
342
343
344
345

346
347
348
349
350
351
352
353
354







-
+
+







  sqlite3 *db = pParse->db;
  Schema *pSchema = db->aDb[iDb].pSchema;    /* Schema of database iDb */
  HashElem *k;
  int iStatCur;
  int iMem;

  sqlite3BeginWriteOperation(pParse, 0, iDb);
  iStatCur = pParse->nTab++;
  iStatCur = pParse->nTab;
  pParse->nTab += 2;
  openStatTable(pParse, iDb, iStatCur, 0);
  iMem = pParse->nMem+1;
  for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
    Table *pTab = (Table*)sqliteHashData(k);
    analyzeOneTable(pParse, pTab, iStatCur, iMem);
  }
  loadAnalysis(pParse, iDb);
263
264
265
266
267
268
269
270


271
272
273
274
275
276
277
362
363
364
365
366
367
368

369
370
371
372
373
374
375
376
377







-
+
+







  int iDb;
  int iStatCur;

  assert( pTab!=0 );
  assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
  sqlite3BeginWriteOperation(pParse, 0, iDb);
  iStatCur = pParse->nTab++;
  iStatCur = pParse->nTab;
  pParse->nTab += 2;
  openStatTable(pParse, iDb, iStatCur, pTab->zName);
  analyzeOneTable(pParse, pTab, iStatCur, pParse->nMem+1);
  loadAnalysis(pParse, iDb);
}

/*
** Generate code for the ANALYZE command.  The parser calls this routine
383
384
385
386
387
388
389























390


















391
392
393
394
395
396
397
398
399
400
401
402
403
404
405

406
407
408

409
410
411
412

413
414
415
416
417
418


419
420
421
422
423
424
425














































































426


427
428
429
430
431
432
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512

513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548

549
550
551
552

553
554
555

556


557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643

644
645
646
647
648
649
650
651







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+















+


-
+



-
+


-

-
-
+
+







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+






    pIndex->aiRowEst[i] = v;
    if( *z==' ' ) z++;
  }
  return 0;
}

/*
** If the Index.aSample variable is not NULL, delete the aSample[] array
** and its contents.
*/
void sqlite3DeleteIndexSamples(Index *pIdx){
#ifdef SQLITE_ENABLE_STAT2
  if( pIdx->aSample ){
    int j;
    sqlite3 *dbMem = pIdx->pTable->dbMem;
    for(j=0; j<SQLITE_INDEX_SAMPLES; j++){
      IndexSample *p = &pIdx->aSample[j];
      if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){
        sqlite3DbFree(pIdx->pTable->dbMem, p->u.z);
      }
    }
    sqlite3DbFree(dbMem, pIdx->aSample);
    pIdx->aSample = 0;
  }
#else
  UNUSED_PARAMETER(pIdx);
#endif
}

/*
** Load the content of the sqlite_stat1 table into the index hash tables.
** Load the content of the sqlite_stat1 and sqlite_stat2 tables. The
** contents of sqlite_stat1 are used to populate the Index.aiRowEst[]
** arrays. The contents of sqlite_stat2 are used to populate the
** Index.aSample[] arrays.
**
** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR
** is returned. In this case, even if SQLITE_ENABLE_STAT2 was defined 
** during compilation and the sqlite_stat2 table is present, no data is 
** read from it.
**
** If SQLITE_ENABLE_STAT2 was defined during compilation and the 
** sqlite_stat2 table is not present in the database, SQLITE_ERROR is
** returned. However, in this case, data is read from the sqlite_stat1
** table (if it is present) before returning.
**
** If an OOM error occurs, this function always sets db->mallocFailed.
** This means if the caller does not care about other errors, the return
** code may be ignored.
*/
int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
  analysisInfo sInfo;
  HashElem *i;
  char *zSql;
  int rc;

  assert( iDb>=0 && iDb<db->nDb );
  assert( db->aDb[iDb].pBt!=0 );
  assert( sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );

  /* Clear any prior statistics */
  for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
    Index *pIdx = sqliteHashData(i);
    sqlite3DefaultRowEst(pIdx);
    sqlite3DeleteIndexSamples(pIdx);
  }

  /* Check to make sure the sqlite_stat1 table existss */
  /* Check to make sure the sqlite_stat1 table exists */
  sInfo.db = db;
  sInfo.zDatabase = db->aDb[iDb].zName;
  if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){
     return SQLITE_ERROR;
    return SQLITE_ERROR;
  }


  /* Load new statistics out of the sqlite_stat1 table */
  zSql = sqlite3MPrintf(db, "SELECT idx, stat FROM %Q.sqlite_stat1",
                        sInfo.zDatabase);
  zSql = sqlite3MPrintf(db, 
      "SELECT idx, stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
  if( zSql==0 ){
    rc = SQLITE_NOMEM;
  }else{
    (void)sqlite3SafetyOff(db);
    rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
    (void)sqlite3SafetyOn(db);
    sqlite3DbFree(db, zSql);
  }


  /* Load the statistics from the sqlite_stat2 table. */
#ifdef SQLITE_ENABLE_STAT2
  if( rc==SQLITE_OK && !sqlite3FindTable(db, "sqlite_stat2", sInfo.zDatabase) ){
    rc = SQLITE_ERROR;
  }
  if( rc==SQLITE_OK ){
    sqlite3_stmt *pStmt = 0;

    zSql = sqlite3MPrintf(db, 
        "SELECT idx,sampleno,sample FROM %Q.sqlite_stat2", sInfo.zDatabase);
    if( !zSql ){
      rc = SQLITE_NOMEM;
    }else{
      (void)sqlite3SafetyOff(db);
      rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
      (void)sqlite3SafetyOn(db);
      sqlite3DbFree(db, zSql);
    }

    if( rc==SQLITE_OK ){
      (void)sqlite3SafetyOff(db);
      while( sqlite3_step(pStmt)==SQLITE_ROW ){
        char *zIndex = (char *)sqlite3_column_text(pStmt, 0);
        Index *pIdx = sqlite3FindIndex(db, zIndex, sInfo.zDatabase);
        if( pIdx ){
          int iSample = sqlite3_column_int(pStmt, 1);
          sqlite3 *dbMem = pIdx->pTable->dbMem;
          assert( dbMem==db || dbMem==0 );
          if( iSample<SQLITE_INDEX_SAMPLES && iSample>=0 ){
            int eType = sqlite3_column_type(pStmt, 2);

            if( pIdx->aSample==0 ){
              static const int sz = sizeof(IndexSample)*SQLITE_INDEX_SAMPLES;
              pIdx->aSample = (IndexSample *)sqlite3DbMallocZero(dbMem, sz);
              if( pIdx->aSample==0 ){
                db->mallocFailed = 1;
                break;
              }
            }

            assert( pIdx->aSample );
            {
              IndexSample *pSample = &pIdx->aSample[iSample];
              pSample->eType = (u8)eType;
              if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
                pSample->u.r = sqlite3_column_double(pStmt, 2);
              }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
                const char *z = (const char *)(
                    (eType==SQLITE_BLOB) ?
                    sqlite3_column_blob(pStmt, 2):
                    sqlite3_column_text(pStmt, 2)
                );
                int n = sqlite3_column_bytes(pStmt, 2);
                if( n>24 ){
                  n = 24;
                }
                pSample->nByte = (u8)n;
                pSample->u.z = sqlite3DbMallocRaw(dbMem, n);
                if( pSample->u.z ){
                  memcpy(pSample->u.z, z, n);
                }else{
                  db->mallocFailed = 1;
                  break;
                }
              }
            }
          }
        }
      }
      rc = sqlite3_finalize(pStmt);
      (void)sqlite3SafetyOn(db);
    }
  }
#endif

    if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
  if( rc==SQLITE_NOMEM ){
    db->mallocFailed = 1;
  }
  return rc;
}


#endif /* SQLITE_OMIT_ANALYZE */
Changes to src/attach.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19












-
-







/*
** 2003 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.93 2009/05/31 21:21:41 drh Exp $
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_ATTACH
/*
** Resolve an expression that was part of an ATTACH or DETACH statement. This
** is slightly different from resolving a normal SQL expression, because simple
147
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

172
173
174
175
176
177

178
179
180
181
182
183
184
145
146
147
148
149
150
151

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168

169
170
171
172
173
174

175
176
177
178
179
180
181
182







-
+
















-
+





-
+







    sqlite3PagerLockingMode(pPager, db->dfltLockMode);
    sqlite3PagerJournalMode(pPager, db->dfltJournalMode);
  }
  aNew->zName = sqlite3DbStrDup(db, zName);
  aNew->safety_level = 3;

#if SQLITE_HAS_CODEC
  {
  if( rc==SQLITE_OK ){
    extern int sqlite3CodecAttach(sqlite3*, int, const void*, int);
    extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
    int nKey;
    char *zKey;
    int t = sqlite3_value_type(argv[2]);
    switch( t ){
      case SQLITE_INTEGER:
      case SQLITE_FLOAT:
        zErrDyn = sqlite3DbStrDup(db, "Invalid key value");
        rc = SQLITE_ERROR;
        break;
        
      case SQLITE_TEXT:
      case SQLITE_BLOB:
        nKey = sqlite3_value_bytes(argv[2]);
        zKey = (char *)sqlite3_value_blob(argv[2]);
        sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
        rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
        break;

      case SQLITE_NULL:
        /* No key specified.  Use the key from the main database */
        sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
        sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
        rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
        break;
    }
  }
#endif

  /* If the file was opened successfully, read the schema for the new database.
  ** If this fails, or if opening the file failed, then close the file and 
Changes to src/auth.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
9
10
11
12
13
14
15


16
17
18
19
20
21
22







-
-







**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the sqlite3_set_authorizer()
** API.  This facility is an optional feature of the library.  Embedded
** systems that do not need this facility may omit it by recompiling
** the library with -DSQLITE_OMIT_AUTHORIZATION=1
**
** $Id: auth.c,v 1.31 2009/05/04 18:01:40 drh Exp $
*/
#include "sqliteInt.h"

/*
** All of the code in this file may be omitted by defining a single
** macro.
*/
86
87
88
89
90
91
92

































93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

117
118
119
120
121
122
123
124
125





126

127
128

129
130
131
132


133
134
135
136
137
138
139
140
141




142
143
144
145




146
147
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

141
142
143


144
145
146
147

148
149
150
151
152
153
154
155
156
157
158

159
160

161




162
163









164
165
166
167
168



169
170
171
172
173
174
175
176
177
178
179


180


181










182
183
184
185
186
187
188







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

















-



-
-

+


-






+
+
+
+
+
-
+

-
+
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+

-
-
-
+
+
+
+







-
-
+
-
-

-
-
-
-
-
-
-
-
-
-







** Write an error message into pParse->zErrMsg that explains that the
** user-supplied authorization function returned an illegal value.
*/
static void sqliteAuthBadReturnCode(Parse *pParse){
  sqlite3ErrorMsg(pParse, "authorizer malfunction");
  pParse->rc = SQLITE_ERROR;
}

/*
** Invoke the authorization callback for permission to read column zCol from
** table zTab in database zDb. This function assumes that an authorization
** callback has been registered (i.e. that sqlite3.xAuth is not NULL).
**
** If SQLITE_IGNORE is returned and pExpr is not NULL, then pExpr is changed
** to an SQL NULL expression. Otherwise, if pExpr is NULL, then SQLITE_IGNORE
** is treated as SQLITE_DENY. In this case an error is left in pParse.
*/
int sqlite3AuthReadCol(
  Parse *pParse,                  /* The parser context */
  const char *zTab,               /* Table name */
  const char *zCol,               /* Column name */
  int iDb                         /* Index of containing database. */
){
  sqlite3 *db = pParse->db;       /* Database handle */
  char *zDb = db->aDb[iDb].zName; /* Name of attached database */
  int rc;                         /* Auth callback return code */

  rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext);
  if( rc==SQLITE_DENY ){
    if( db->nDb>2 || iDb!=0 ){
      sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol);
    }else{
      sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited", zTab, zCol);
    }
    pParse->rc = SQLITE_AUTH;
  }else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){
    sqliteAuthBadReturnCode(pParse);
  }
  return rc;
}

/*
** The pExpr should be a TK_COLUMN expression.  The table referred to
** is in pTabList or else it is the NEW or OLD table of a trigger.  
** Check to see if it is OK to read this particular column.
**
** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN 
** instruction into a TK_NULL.  If the auth function returns SQLITE_DENY,
** then generate an error.
*/
void sqlite3AuthRead(
  Parse *pParse,        /* The parser context */
  Expr *pExpr,          /* The expression to check authorization on */
  Schema *pSchema,      /* The schema of the expression */
  SrcList *pTabList     /* All table that pExpr might refer to */
){
  sqlite3 *db = pParse->db;
  int rc;
  Table *pTab = 0;      /* The table being read */
  const char *zCol;     /* Name of the column of the table */
  int iSrc;             /* Index in pTabList->a[] of table being read */
  const char *zDBase;   /* Name of database being accessed */
  TriggerStack *pStack; /* The stack of current triggers */
  int iDb;              /* The index of the database the expression refers to */
  int iCol;             /* Index of column in table */

  if( db->xAuth==0 ) return;
  assert( pExpr->op==TK_COLUMN );
  iDb = sqlite3SchemaToIndex(pParse->db, pSchema);
  if( iDb<0 ){
    /* An attempt to read a column out of a subquery or other
    ** temporary table. */
    return;
  }

  assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
  if( pExpr->op==TK_TRIGGER ){
    pTab = pParse->pTriggerTab;
  }else{
  if( pTabList ){
    assert( pTabList );
    for(iSrc=0; ALWAYS(iSrc<pTabList->nSrc); iSrc++){
      if( pExpr->iTable==pTabList->a[iSrc].iCursor ) break;
      if( pExpr->iTable==pTabList->a[iSrc].iCursor ){
    }
    assert( iSrc<pTabList->nSrc );
    pTab = pTabList->a[iSrc].pTab;
  }else{
        pTab = pTabList->a[iSrc].pTab;
        break;
    pStack = pParse->trigStack;
    if( ALWAYS(pStack) ){
      /* This must be an attempt to read the NEW or OLD pseudo-tables
      ** of a trigger.
      */
      assert( pExpr->iTable==pStack->newIdx || pExpr->iTable==pStack->oldIdx );
      pTab = pStack->pTab;
    }
  }
      }
    }
  }
  iCol = pExpr->iColumn;
  if( NEVER(pTab==0) ) return;
  if( pExpr->iColumn>=0 ){
    assert( pExpr->iColumn<pTab->nCol );
    zCol = pTab->aCol[pExpr->iColumn].zName;

  if( iCol>=0 ){
    assert( iCol<pTab->nCol );
    zCol = pTab->aCol[iCol].zName;
  }else if( pTab->iPKey>=0 ){
    assert( pTab->iPKey<pTab->nCol );
    zCol = pTab->aCol[pTab->iPKey].zName;
  }else{
    zCol = "ROWID";
  }
  assert( iDb>=0 && iDb<db->nDb );
  zDBase = db->aDb[iDb].zName;
  rc = db->xAuth(db->pAuthArg, SQLITE_READ, pTab->zName, zCol, zDBase, 
  if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){
                 pParse->zAuthContext);
  if( rc==SQLITE_IGNORE ){
    pExpr->op = TK_NULL;
  }else if( rc==SQLITE_DENY ){
    if( db->nDb>2 || iDb!=0 ){
      sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited", 
         zDBase, pTab->zName, zCol);
    }else{
      sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited",pTab->zName,zCol);
    }
    pParse->rc = SQLITE_AUTH;
  }else if( rc!=SQLITE_OK ){
    sqliteAuthBadReturnCode(pParse);
  }
}

/*
** Do an authorization check using the code and arguments given.  Return
** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY.  If SQLITE_DENY
** is returned, then the error count and error message in pParse are
Changes to src/backup.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2009 January 28
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the implementation of the sqlite3_backup_XXX() 
** API functions and the related features.
**
** $Id: backup.c,v 1.17 2009/06/03 11:25:07 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "btreeInt.h"

/* Macro to find the minimum of two numeric values.
*/
#ifndef MIN
314
315
316
317
318
319
320
321

322
323
324
325
326
327
328
312
313
314
315
316
317
318

319
320
321
322
323
324
325
326







-
+







    }

    /* Lock the destination database, if it is not locked already. */
    if( SQLITE_OK==rc && p->bDestLocked==0
     && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) 
    ){
      p->bDestLocked = 1;
      rc = sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema);
      sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema);
    }

    /* If there is no open read-transaction on the source database, open
    ** one now. If a transaction is opened here, then it will be closed
    ** before this function exits.
    */
    if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){
354
355
356
357
358
359
360





361



362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
352
353
354
355
356
357
358
359
360
361
362
363

364
365
366
367
368
369
370






371
372
373
374
375
376
377







+
+
+
+
+
-
+
+
+




-
-
-
-
-
-







      if( p->iNext>(Pgno)nSrcPage ){
        rc = SQLITE_DONE;
      }else if( !p->isAttached ){
        attachBackupObject(p);
      }
    }
  
    /* Update the schema version field in the destination database. This
    ** is to make sure that the schema-version really does change in
    ** the case where the source and destination databases have the
    ** same schema version.
    */
    if( rc==SQLITE_DONE ){
    if( rc==SQLITE_DONE 
     && (rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1))==SQLITE_OK
    ){
      const int nSrcPagesize = sqlite3BtreeGetPageSize(p->pSrc);
      const int nDestPagesize = sqlite3BtreeGetPageSize(p->pDest);
      int nDestTruncate;
  
      /* Update the schema version field in the destination database. This
      ** is to make sure that the schema-version really does change in
      ** the case where the source and destination databases have the
      ** same schema version.
      */
      sqlite3BtreeUpdateMeta(p->pDest, 1, p->iDestSchema+1);
      if( p->pDestDb ){
        sqlite3ResetInternalSchema(p->pDestDb, 0);
      }

      /* Set nDestTruncate to the final number of pages in the destination
      ** database. The complication here is that the destination page
      ** size may be different to the source page size. 
Changes to src/bitvec.c.
29
30
31
32
33
34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
29
30
31
32
33
34
35


36
37
38
39

40
41
42
43
44
45
46
47







-
-




-
+







** Test operations are about 100 times more common that set operations.
** Clear operations are exceedingly rare.  There are usually between
** 5 and 500 set operations per Bitvec object, though the number of sets can
** sometimes grow into tens of thousands or larger.  The size of the
** Bitvec object is the number of pages in the database file at the
** start of a transaction, and is thus usually less than a few thousand,
** but can be as large as 2 billion for a really big database.
**
** @(#) $Id: bitvec.c,v 1.15 2009/06/02 21:31:39 drh Exp $
*/
#include "sqliteInt.h"

/* Size of the Bitvec structure in bytes. */
#define BITVEC_SZ        512
#define BITVEC_SZ        (sizeof(void*)*128)  /* 512 on 32bit.  1024 on 64bit */

/* Round the union size down to the nearest pointer boundary, since that's how 
** it will be aligned within the Bitvec struct. */
#define BITVEC_USIZE     (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*))

/* Type of the array "element" for the bitmap representation. 
** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE. 
142
143
144
145
146
147
148
149
150

151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170

171
172
173
174
175
176
177
140
141
142
143
144
145
146


147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
174







-
-
+



















-
+







  }
  if( p->iSize<=BITVEC_NBIT ){
    return (p->u.aBitmap[i/BITVEC_SZELEM] & (1<<(i&(BITVEC_SZELEM-1))))!=0;
  } else{
    u32 h = BITVEC_HASH(i++);
    while( p->u.aHash[h] ){
      if( p->u.aHash[h]==i ) return 1;
      h++;
      if( h>=BITVEC_NINT ) h = 0;
      h = (h+1) % BITVEC_NINT;
    }
    return 0;
  }
}

/*
** Set the i-th bit.  Return 0 on success and an error code if
** anything goes wrong.
**
** This routine might cause sub-bitmaps to be allocated.  Failing
** to get the memory needed to hold the sub-bitmap is the only
** that can go wrong with an insert, assuming p and i are valid.
**
** The calling function must ensure that p is a valid Bitvec object
** and that the value for "i" is within range of the Bitvec object.
** Otherwise the behavior is undefined.
*/
int sqlite3BitvecSet(Bitvec *p, u32 i){
  u32 h;
  assert( p!=0 );
  if( p==0 ) return SQLITE_OK;
  assert( i>0 );
  assert( i<=p->iSize );
  i--;
  while((p->iSize > BITVEC_NBIT) && p->iDivisor) {
    u32 bin = i/p->iDivisor;
    i = i%p->iDivisor;
    if( p->u.apSub[bin]==0 ){
233
234
235
236
237
238
239
240

241
242
243
244
245
246
247
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244







-
+







/*
** Clear the i-th bit.
**
** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage
** that BitvecClear can use to rebuilt its hash table.
*/
void sqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){
  assert( p!=0 );
  if( p==0 ) return;
  assert( i>0 );
  i--;
  while( p->iDivisor ){
    u32 bin = i/p->iDivisor;
    i = i%p->iDivisor;
    p = p->u.apSub[bin];
    if (!p) {
344
345
346
347
348
349
350




351
352
353
354
355
356
357
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358







+
+
+
+







  ** bits to act as the reference */
  pBitvec = sqlite3BitvecCreate( sz );
  pV = sqlite3_malloc( (sz+7)/8 + 1 );
  pTmpSpace = sqlite3_malloc(BITVEC_SZ);
  if( pBitvec==0 || pV==0 || pTmpSpace==0  ) goto bitvec_end;
  memset(pV, 0, (sz+7)/8 + 1);

  /* NULL pBitvec tests */
  sqlite3BitvecSet(0, 1);
  sqlite3BitvecClear(0, 1, pTmpSpace);

  /* Run the program */
  pc = 0;
  while( (op = aOp[pc])!=0 ){
    switch( op ){
      case 1:
      case 2:
      case 5: {
Changes to src/btmutex.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19












-
-







/*
** 2007 August 27
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** $Id: btmutex.c,v 1.15 2009/04/10 12:55:17 danielk1977 Exp $
**
** This file contains code used to implement mutexes on Btree objects.
** This code really belongs in btree.c.  But btree.c is getting too
** big and we want to break it down some.  This packaged seemed like
** a good breakout.
*/
#include "btreeInt.h"
#ifndef SQLITE_OMIT_SHARED_CACHE
193
194
195
196
197
198
199


200

201
202
203
204
205
206
207
191
192
193
194
195
196
197
198
199

200
201
202
203
204
205
206
207







+
+
-
+







    p = db->aDb[i].pBt;
    assert( !p || (p->locked==0 && p->sharable) || p->pBt->db==p->db );
    if( p && p->sharable ){
      p->wantToLock++;
      if( !p->locked ){
        assert( p->wantToLock==1 );
        while( p->pPrev ) p = p->pPrev;
        /* Reason for ALWAYS:  There must be at least on unlocked Btree in
        ** the chain.  Otherwise the !p->locked test above would have failed */
        while( p->locked && p->pNext ) p = p->pNext;
        while( p->locked && ALWAYS(p->pNext) ) p = p->pNext;
        for(pLater = p->pNext; pLater; pLater=pLater->pNext){
          if( pLater->locked ){
            unlockBtreeMutex(pLater);
          }
        }
        while( p ){
          lockBtreeMutex(p);
304
305
306
307
308
309
310




311
312

313
314
315
316
317
318
319
320
321
322
323
324
325
326
327

328
329
330
331
332
333
334

335
336
337
338
339
340
341
304
305
306
307
308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323
324
325
326
327
328
329
330

331
332
333
334
335
336
337

338
339
340
341
342
343
344
345







+
+
+
+

-
+














-
+






-
+







    /* Some basic sanity checking */
    assert( i==0 || pArray->aBtree[i-1]->pBt<p->pBt );
    assert( !p->locked || p->wantToLock>0 );

    /* We should already hold a lock on the database connection */
    assert( sqlite3_mutex_held(p->db->mutex) );

    /* The Btree is sharable because only sharable Btrees are entered
    ** into the array in the first place. */
    assert( p->sharable );

    p->wantToLock++;
    if( !p->locked && p->sharable ){
    if( !p->locked ){
      lockBtreeMutex(p);
    }
  }
}

/*
** Leave the mutex of every btree in the group.
*/
void sqlite3BtreeMutexArrayLeave(BtreeMutexArray *pArray){
  int i;
  for(i=0; i<pArray->nMutex; i++){
    Btree *p = pArray->aBtree[i];
    /* Some basic sanity checking */
    assert( i==0 || pArray->aBtree[i-1]->pBt<p->pBt );
    assert( p->locked || !p->sharable );
    assert( p->locked );
    assert( p->wantToLock>0 );

    /* We should already hold a lock on the database connection */
    assert( sqlite3_mutex_held(p->db->mutex) );

    p->wantToLock--;
    if( p->wantToLock==0 && p->locked ){
    if( p->wantToLock==0 ){
      unlockBtreeMutex(p);
    }
  }
}

#else
void sqlite3BtreeEnter(Btree *p){
Changes to src/btree.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11


12
13
14
15
16
17
18











-
-







/*
** 2004 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.645 2009/06/26 16:32:13 shane Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"

/*
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88



89
90
91


92





















































































































93

94
95
96
97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165



















166
167
168
169
170
171
172
173
174
175
176
177
178









179
180


181
182
183
184
185
186
187
188
189
190
191
192
193
194
195

196
197
198
199



200
201
202
203
204
205

206
207
208
209
210





211
212
213
214
215
216
217
61
62
63
64
65
66
67





68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
236
237
238
239
240
241








































242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281


282
283
284
285
286
287
288
289
290
291
292
293





294




295
296
297






298





299
300
301
302
303
304
305
306
307
308
309
310







-
-
-
-
-














+
+
+



+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+











+








-
+












-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-












+
+
+
+
+
+
+
+
+
-
-
+
+










-
-
-
-
-
+
-
-
-
-
+
+
+
-
-
-
-
-
-
+
-
-
-
-
-
+
+
+
+
+







int sqlite3_enable_shared_cache(int enable){
  sqlite3GlobalConfig.sharedCacheEnabled = enable;
  return SQLITE_OK;
}
#endif


/*
** Forward declaration
*/
static int checkForReadConflicts(Btree*, Pgno, BtCursor*, i64);


#ifdef SQLITE_OMIT_SHARED_CACHE
  /*
  ** The functions querySharedCacheTableLock(), setSharedCacheTableLock(),
  ** and clearAllSharedCacheTableLocks()
  ** manipulate entries in the BtShared.pLock linked list used to store
  ** shared-cache table level locks. If the library is compiled with the
  ** shared-cache feature disabled, then there is only ever one user
  ** of each BtShared structure and so this locking is not necessary. 
  ** So define the lock related functions as no-ops.
  */
  #define querySharedCacheTableLock(a,b,c) SQLITE_OK
  #define setSharedCacheTableLock(a,b,c) SQLITE_OK
  #define clearAllSharedCacheTableLocks(a)
  #define downgradeAllSharedCacheTableLocks(a)
  #define hasSharedCacheTableLock(a,b,c,d) 1
  #define hasReadConflicts(a, b) 0
#endif

#ifndef SQLITE_OMIT_SHARED_CACHE

#ifdef SQLITE_DEBUG
/*
**** This function is only used as part of an assert() statement. ***
**
** Check to see if pBtree holds the required locks to read or write to the 
** table with root page iRoot.   Return 1 if it does and 0 if not.
**
** For example, when writing to a table with root-page iRoot via 
** Btree connection pBtree:
**
**    assert( hasSharedCacheTableLock(pBtree, iRoot, 0, WRITE_LOCK) );
**
** When writing to an index that resides in a sharable database, the 
** caller should have first obtained a lock specifying the root page of
** the corresponding table. This makes things a bit more complicated,
** as this module treats each table as a separate structure. To determine
** the table corresponding to the index being written, this
** function has to search through the database schema.
**
** Instead of a lock on the table/index rooted at page iRoot, the caller may
** hold a write-lock on the schema table (root page 1). This is also
** acceptable.
*/
static int hasSharedCacheTableLock(
  Btree *pBtree,         /* Handle that must hold lock */
  Pgno iRoot,            /* Root page of b-tree */
  int isIndex,           /* True if iRoot is the root of an index b-tree */
  int eLockType          /* Required lock type (READ_LOCK or WRITE_LOCK) */
){
  Schema *pSchema = (Schema *)pBtree->pBt->pSchema;
  Pgno iTab = 0;
  BtLock *pLock;

  /* If this database is not shareable, or if the client is reading
  ** and has the read-uncommitted flag set, then no lock is required. 
  ** Return true immediately.
  */
  if( (pBtree->sharable==0)
   || (eLockType==READ_LOCK && (pBtree->db->flags & SQLITE_ReadUncommitted))
  ){
    return 1;
  }

  /* If the client is reading  or writing an index and the schema is
  ** not loaded, then it is too difficult to actually check to see if
  ** the correct locks are held.  So do not bother - just return true.
  ** This case does not come up very often anyhow.
  */
  if( isIndex && (!pSchema || (pSchema->flags&DB_SchemaLoaded)==0) ){
    return 1;
  }

  /* Figure out the root-page that the lock should be held on. For table
  ** b-trees, this is just the root page of the b-tree being read or
  ** written. For index b-trees, it is the root page of the associated
  ** table.  */
  if( isIndex ){
    HashElem *p;
    for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){
      Index *pIdx = (Index *)sqliteHashData(p);
      if( pIdx->tnum==(int)iRoot ){
        iTab = pIdx->pTable->tnum;
      }
    }
  }else{
    iTab = iRoot;
  }

  /* Search for the required lock. Either a write-lock on root-page iTab, a 
  ** write-lock on the schema table, or (if the client is reading) a
  ** read-lock on iTab will suffice. Return 1 if any of these are found.  */
  for(pLock=pBtree->pBt->pLock; pLock; pLock=pLock->pNext){
    if( pLock->pBtree==pBtree 
     && (pLock->iTable==iTab || (pLock->eLock==WRITE_LOCK && pLock->iTable==1))
     && pLock->eLock>=eLockType 
    ){
      return 1;
    }
  }

  /* Failed to find the required lock. */
  return 0;
}
#endif /* SQLITE_DEBUG */

#ifdef SQLITE_DEBUG
/*
**** This function may be used as part of assert() statements only. ****
**
** Return true if it would be illegal for pBtree to write into the
** table or index rooted at iRoot because other shared connections are
** simultaneously reading that same table or index.
**
** It is illegal for pBtree to write if some other Btree object that
** shares the same BtShared object is currently reading or writing
** the iRoot table.  Except, if the other Btree object has the
** read-uncommitted flag set, then it is OK for the other object to
** have a read cursor.
**
** For example, before writing to any part of the table or index
** rooted at page iRoot, one should call:
**
**    assert( !hasReadConflicts(pBtree, iRoot) );
*/
static int hasReadConflicts(Btree *pBtree, Pgno iRoot){
  BtCursor *p;
  for(p=pBtree->pBt->pCursor; p; p=p->pNext){
    if( p->pgnoRoot==iRoot 
     && p->pBtree!=pBtree
     && 0==(p->pBtree->db->flags & SQLITE_ReadUncommitted)
    ){
      return 1;
    }
  }
  return 0;
}
#endif    /* #ifdef SQLITE_DEBUG */

/*
** Query to see if btree handle p may obtain a lock of type eLock 
** Query to see if Btree handle p may obtain a lock of type eLock 
** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return
** SQLITE_OK if the lock may be obtained (by calling
** setSharedCacheTableLock()), or SQLITE_LOCKED if not.
*/
static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){
  BtShared *pBt = p->pBt;
  BtLock *pIter;

  assert( sqlite3BtreeHoldsMutex(p) );
  assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
  assert( p->db!=0 );
  assert( !(p->db->flags&SQLITE_ReadUncommitted)||eLock==WRITE_LOCK||iTab==1 );
  
  /* If requesting a write-lock, then the Btree must have an open write
  ** transaction on this file. And, obviously, for this to be so there 
  ** must be an open write transaction on the file itself.
  */
  assert( eLock==READ_LOCK || (p==pBt->pWriter && p->inTrans==TRANS_WRITE) );
  assert( eLock==READ_LOCK || pBt->inTransaction==TRANS_WRITE );
  
  /* This is a no-op if the shared-cache is not enabled */
  /* This routine is a no-op if the shared-cache is not enabled */
  if( !p->sharable ){
    return SQLITE_OK;
  }

  /* If some other connection is holding an exclusive lock, the
  ** requested lock may not be obtained.
  */
  if( pBt->pWriter!=p && pBt->isExclusive ){
    sqlite3ConnectionBlocked(p->db, pBt->pWriter->db);
    return SQLITE_LOCKED_SHAREDCACHE;
  }

  /* This (along with setSharedCacheTableLock()) is where
  ** the ReadUncommitted flag is dealt with.
  ** If the caller is querying for a read-lock on any table
  ** other than the sqlite_master table (table 1) and if the ReadUncommitted
  ** flag is set, then the lock granted even if there are write-locks
  ** on the table. If a write-lock is requested, the ReadUncommitted flag
  ** is not considered.
  **
  ** In function setSharedCacheTableLock(), if a read-lock is demanded and the 
  ** ReadUncommitted flag is set, no entry is added to the locks list 
  ** (BtShared.pLock).
  **
  ** To summarize: If the ReadUncommitted flag is set, then read cursors
  ** on non-schema tables do not create or respect table locks. The locking
  ** procedure for a write-cursor does not change.
  */
  if( 
    0==(p->db->flags&SQLITE_ReadUncommitted) || 
    eLock==WRITE_LOCK ||
    iTab==MASTER_ROOT
  ){
    for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
      /* The condition (pIter->eLock!=eLock) in the following if(...) 
      ** statement is a simplification of:
      **
      **   (eLock==WRITE_LOCK || pIter->eLock==WRITE_LOCK)
      **
      ** since we know that if eLock==WRITE_LOCK, then no other connection
      ** may hold a WRITE_LOCK on any table in this file (since there can
      ** only be a single writer).
      */
      assert( pIter->eLock==READ_LOCK || pIter->eLock==WRITE_LOCK );
      assert( eLock==READ_LOCK || pIter->pBtree==p || pIter->eLock==READ_LOCK);
      if( pIter->pBtree!=p && pIter->iTable==iTab && pIter->eLock!=eLock ){
        sqlite3ConnectionBlocked(p->db, pIter->pBtree->db);
        if( eLock==WRITE_LOCK ){
          assert( p==pBt->pWriter );
          pBt->isPending = 1;
        }
        return SQLITE_LOCKED_SHAREDCACHE;
  for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
    /* The condition (pIter->eLock!=eLock) in the following if(...) 
    ** statement is a simplification of:
    **
    **   (eLock==WRITE_LOCK || pIter->eLock==WRITE_LOCK)
    **
    ** since we know that if eLock==WRITE_LOCK, then no other connection
    ** may hold a WRITE_LOCK on any table in this file (since there can
    ** only be a single writer).
    */
    assert( pIter->eLock==READ_LOCK || pIter->eLock==WRITE_LOCK );
    assert( eLock==READ_LOCK || pIter->pBtree==p || pIter->eLock==READ_LOCK);
    if( pIter->pBtree!=p && pIter->iTable==iTab && pIter->eLock!=eLock ){
      sqlite3ConnectionBlocked(p->db, pIter->pBtree->db);
      if( eLock==WRITE_LOCK ){
        assert( p==pBt->pWriter );
        pBt->isPending = 1;
      }
      return SQLITE_LOCKED_SHAREDCACHE;
      }
    }
  }
  return SQLITE_OK;
}
#endif /* !SQLITE_OMIT_SHARED_CACHE */

#ifndef SQLITE_OMIT_SHARED_CACHE
/*
** Add a lock on the table with root-page iTable to the shared-btree used
** by Btree handle p. Parameter eLock must be either READ_LOCK or 
** WRITE_LOCK.
**
** This function assumes the following:
**
**   (a) The specified Btree object p is connected to a sharable
**       database (one with the BtShared.sharable flag set), and
**
**   (b) No other Btree objects hold a lock that conflicts
**       with the requested lock (i.e. querySharedCacheTableLock() has
**       already been called and returned SQLITE_OK).
**
** SQLITE_OK is returned if the lock is added successfully. SQLITE_BUSY and
** SQLITE_NOMEM may also be returned.
** SQLITE_OK is returned if the lock is added successfully. SQLITE_NOMEM 
** is returned if a malloc attempt fails.
*/
static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){
  BtShared *pBt = p->pBt;
  BtLock *pLock = 0;
  BtLock *pIter;

  assert( sqlite3BtreeHoldsMutex(p) );
  assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
  assert( p->db!=0 );

  /* This is a no-op if the shared-cache is not enabled */
  if( !p->sharable ){
    return SQLITE_OK;
  }

  /* A connection with the read-uncommitted flag set will never try to
  assert( SQLITE_OK==querySharedCacheTableLock(p, iTable, eLock) );

  /* If the read-uncommitted flag is set and a read-lock is requested on
  ** a non-schema table, then the lock is always granted.  Return early
  ** obtain a read-lock using this function. The only read-lock obtained
  ** by a connection in read-uncommitted mode is on the sqlite_master 
  ** table, and that lock is obtained in BtreeBeginTrans().  */
  ** without adding an entry to the BtShared.pLock list. See
  ** comment in function querySharedCacheTableLock() for more info
  ** on handling the ReadUncommitted flag.
  */
  if( 
    (p->db->flags&SQLITE_ReadUncommitted) && 
  assert( 0==(p->db->flags&SQLITE_ReadUncommitted) || eLock==WRITE_LOCK );
    (eLock==READ_LOCK) &&
    iTable!=MASTER_ROOT
  ){
    return SQLITE_OK;
  }

  /* This function should only be called on a sharable b-tree after it 
  ** has been determined that no other b-tree holds a conflicting lock.  */
  assert( p->sharable );
  assert( SQLITE_OK==querySharedCacheTableLock(p, iTable, eLock) );

  /* First search the list for an existing lock on this table. */
  for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
    if( pIter->iTable==iTable && pIter->pBtree==p ){
      pLock = pIter;
      break;
    }
243
244
245
246
247
248
249
250

251
252

253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269


270


271
272
273
274
275
276
277
278
279
280
281
282

283
284
285
286
287
288
289
290
291
292
293


















294
295
296
297
298


299

300
301

302
303
304
305
306
307
308
336
337
338
339
340
341
342

343
344

345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364

365
366
367
368
369
370
371
372
373
374
375
376
377

378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414

415
416

417
418
419
420
421
422
423
424







-
+

-
+

















+
+
-
+
+











-
+











+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+





+
+
-
+

-
+







  return SQLITE_OK;
}
#endif /* !SQLITE_OMIT_SHARED_CACHE */

#ifndef SQLITE_OMIT_SHARED_CACHE
/*
** Release all the table locks (locks obtained via calls to
** the setSharedCacheTableLock() procedure) held by Btree handle p.
** the setSharedCacheTableLock() procedure) held by Btree object p.
**
** This function assumes that handle p has an open read or write 
** This function assumes that Btree p has an open read or write 
** transaction. If it does not, then the BtShared.isPending variable
** may be incorrectly cleared.
*/
static void clearAllSharedCacheTableLocks(Btree *p){
  BtShared *pBt = p->pBt;
  BtLock **ppIter = &pBt->pLock;

  assert( sqlite3BtreeHoldsMutex(p) );
  assert( p->sharable || 0==*ppIter );
  assert( p->inTrans>0 );

  while( *ppIter ){
    BtLock *pLock = *ppIter;
    assert( pBt->isExclusive==0 || pBt->pWriter==pLock->pBtree );
    assert( pLock->pBtree->inTrans>=pLock->eLock );
    if( pLock->pBtree==p ){
      *ppIter = pLock->pNext;
      assert( pLock->iTable!=1 || pLock==&p->lock );
      if( pLock->iTable!=1 ){
      sqlite3_free(pLock);
        sqlite3_free(pLock);
      }
    }else{
      ppIter = &pLock->pNext;
    }
  }

  assert( pBt->isPending==0 || pBt->pWriter );
  if( pBt->pWriter==p ){
    pBt->pWriter = 0;
    pBt->isExclusive = 0;
    pBt->isPending = 0;
  }else if( pBt->nTransaction==2 ){
    /* This function is called when connection p is concluding its 
    /* This function is called when Btree p is concluding its 
    ** transaction. If there currently exists a writer, and p is not
    ** that writer, then the number of locks held by connections other
    ** than the writer must be about to drop to zero. In this case
    ** set the isPending flag to 0.
    **
    ** If there is not currently a writer, then BtShared.isPending must
    ** be zero already. So this next line is harmless in that case.
    */
    pBt->isPending = 0;
  }
}

/*
** This function changes all write-locks held by Btree p into read-locks.
*/
static void downgradeAllSharedCacheTableLocks(Btree *p){
  BtShared *pBt = p->pBt;
  if( pBt->pWriter==p ){
    BtLock *pLock;
    pBt->pWriter = 0;
    pBt->isExclusive = 0;
    pBt->isPending = 0;
    for(pLock=pBt->pLock; pLock; pLock=pLock->pNext){
      assert( pLock->eLock==READ_LOCK || pLock->pBtree==p );
      pLock->eLock = READ_LOCK;
    }
  }
}

#endif /* SQLITE_OMIT_SHARED_CACHE */

static void releasePage(MemPage *pPage);  /* Forward reference */

/*
***** This routine is used inside of assert() only ****
**
** Verify that the cursor holds a mutex on the BtShared
** Verify that the cursor holds the mutex on its BtShared
*/
#ifndef NDEBUG
#ifdef SQLITE_DEBUG
static int cursorHoldsMutex(BtCursor *p){
  return sqlite3_mutex_held(p->pBt->mutex);
}
#endif


#ifndef SQLITE_OMIT_INCRBLOB
322
323
324
325
326
327
328





























329

330
331

332

333
334
335
336
337
338
339
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478

479
480
481
482
483
484
485
486







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+


+
-
+







static void invalidateAllOverflowCache(BtShared *pBt){
  BtCursor *p;
  assert( sqlite3_mutex_held(pBt->mutex) );
  for(p=pBt->pCursor; p; p=p->pNext){
    invalidateOverflowCache(p);
  }
}

/*
** This function is called before modifying the contents of a table
** to invalidate any incrblob cursors that are open on the
** row or one of the rows being modified.
**
** If argument isClearTable is true, then the entire contents of the
** table is about to be deleted. In this case invalidate all incrblob
** cursors open on any row within the table with root-page pgnoRoot.
**
** Otherwise, if argument isClearTable is false, then the row with
** rowid iRow is being replaced or deleted. In this case invalidate
** only those incrblob cursors open on that specific row.
*/
static void invalidateIncrblobCursors(
  Btree *pBtree,          /* The database file to check */
  i64 iRow,               /* The rowid that might be changing */
  int isClearTable        /* True if all rows are being deleted */
){
  BtCursor *p;
  BtShared *pBt = pBtree->pBt;
  assert( sqlite3BtreeHoldsMutex(pBtree) );
  for(p=pBt->pCursor; p; p=p->pNext){
    if( p->isIncrblobHandle && (isClearTable || p->info.nKey==iRow) ){
      p->eState = CURSOR_INVALID;
    }
  }
}

#else
  /* Stub functions when INCRBLOB is omitted */
  #define invalidateOverflowCache(x)
  #define invalidateAllOverflowCache(x)
  #define invalidateIncrblobCursors(x,y,z)
#endif
#endif /* SQLITE_OMIT_INCRBLOB */

/*
** Set bit pgno of the BtShared.pHasContent bitvec. This is called 
** when a page that previously contained data becomes a free-list leaf 
** page.
**
** The BtShared.pHasContent bitvec exists to work around an obscure
358
359
360
361
362
363
364
365

366
367
368
369
370
371
372
373
374
375
376
377







378
379
380
381
382
383
384
385
505
506
507
508
509
510
511

512
513
514
515
516
517
518






519
520
521
522
523
524
525

526
527
528
529
530
531
532







-
+






-
-
-
-
-
-
+
+
+
+
+
+
+
-







** is extracted from the free-list and reused, then the original data
** may be lost. In the event of a rollback, it may not be possible
** to restore the database to its original configuration.
**
** The solution is the BtShared.pHasContent bitvec. Whenever a page is 
** moved to become a free-list leaf page, the corresponding bit is
** set in the bitvec. Whenever a leaf page is extracted from the free-list,
** optimization 2 above is ommitted if the corresponding bit is already
** optimization 2 above is omitted if the corresponding bit is already
** set in BtShared.pHasContent. The contents of the bitvec are cleared
** at the end of every transaction.
*/
static int btreeSetHasContent(BtShared *pBt, Pgno pgno){
  int rc = SQLITE_OK;
  if( !pBt->pHasContent ){
    int nPage;
    rc = sqlite3PagerPagecount(pBt->pPager, &nPage);
    if( rc==SQLITE_OK ){
      pBt->pHasContent = sqlite3BitvecCreate((u32)nPage);
      if( !pBt->pHasContent ){
        rc = SQLITE_NOMEM;
    int nPage = 100;
    sqlite3PagerPagecount(pBt->pPager, &nPage);
    /* If sqlite3PagerPagecount() fails there is no harm because the
    ** nPage variable is unchanged from its default value of 100 */
    pBt->pHasContent = sqlite3BitvecCreate((u32)nPage);
    if( !pBt->pHasContent ){
      rc = SQLITE_NOMEM;
      }
    }
  }
  if( rc==SQLITE_OK && pgno<=sqlite3BitvecSize(pBt->pHasContent) ){
    rc = sqlite3BitvecSet(pBt->pHasContent, pgno);
  }
  return rc;
}
404
405
406
407
408
409
410



411
412
413
414
415
416
417
418
419

420
421
422
423
424
425
426
427

428
429
430
431
432
433
434
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577

578
579
580
581
582
583
584
585







+
+
+









+







-
+







  sqlite3BitvecDestroy(pBt->pHasContent);
  pBt->pHasContent = 0;
}

/*
** Save the current cursor position in the variables BtCursor.nKey 
** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
**
** The caller must ensure that the cursor is valid (has eState==CURSOR_VALID)
** prior to calling this routine.  
*/
static int saveCursorPosition(BtCursor *pCur){
  int rc;

  assert( CURSOR_VALID==pCur->eState );
  assert( 0==pCur->pKey );
  assert( cursorHoldsMutex(pCur) );

  rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
  assert( rc==SQLITE_OK );  /* KeySize() cannot fail */

  /* If this is an intKey table, then the above call to BtreeKeySize()
  ** stores the integer key in pCur->nKey. In this case this value is
  ** all that is required. Otherwise, if pCur is not open on an intKey
  ** table, then malloc space for and store the pCur->nKey bytes of key 
  ** data.
  */
  if( rc==SQLITE_OK && 0==pCur->apPage[0]->intKey){
  if( 0==pCur->apPage[0]->intKey ){
    void *pKey = sqlite3Malloc( (int)pCur->nKey );
    if( pKey ){
      rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey);
      if( rc==SQLITE_OK ){
        pCur->pKey = pKey;
      }else{
        sqlite3_free(pKey);
450
451
452
453
454
455
456
457
458


459
460
461
462
463
464
465
601
602
603
604
605
606
607


608
609
610
611
612
613
614
615
616







-
-
+
+







  }

  invalidateOverflowCache(pCur);
  return rc;
}

/*
** Save the positions of all cursors except pExcept open on the table 
** with root-page iRoot. Usually, this is called just before cursor
** Save the positions of all cursors (except pExcept) that are open on
** the table  with root-page iRoot. Usually, this is called just before cursor
** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()).
*/
static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
  BtCursor *p;
  assert( sqlite3_mutex_held(pBt->mutex) );
  assert( pExcept==0 || pExcept->pBt==pBt );
  for(p=pBt->pCursor; p; p=p->pNext){
479
480
481
482
483
484
485































486
487
488
489
490
491
492
493
494

495
496
497
498
499

500
501
502

503
504
505
506
507
508
509
510
511
512
513

514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532

533
534
535
536
537
538
539
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675

676
677
678
679
680

681
682
683

684
685
686
687
688
689
690
691
692
693
694

695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713

714
715
716
717
718
719
720
721







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








-
+




-
+


-
+










-
+


















-
+







*/
void sqlite3BtreeClearCursor(BtCursor *pCur){
  assert( cursorHoldsMutex(pCur) );
  sqlite3_free(pCur->pKey);
  pCur->pKey = 0;
  pCur->eState = CURSOR_INVALID;
}

/*
** In this version of BtreeMoveto, pKey is a packed index record
** such as is generated by the OP_MakeRecord opcode.  Unpack the
** record and then call BtreeMovetoUnpacked() to do the work.
*/
static int btreeMoveto(
  BtCursor *pCur,     /* Cursor open on the btree to be searched */
  const void *pKey,   /* Packed key if the btree is an index */
  i64 nKey,           /* Integer key for tables.  Size of pKey for indices */
  int bias,           /* Bias search to the high end */
  int *pRes           /* Write search results here */
){
  int rc;                    /* Status code */
  UnpackedRecord *pIdxKey;   /* Unpacked index key */
  char aSpace[150];          /* Temp space for pIdxKey - to avoid a malloc */

  if( pKey ){
    assert( nKey==(i64)(int)nKey );
    pIdxKey = sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey,
                                      aSpace, sizeof(aSpace));
    if( pIdxKey==0 ) return SQLITE_NOMEM;
  }else{
    pIdxKey = 0;
  }
  rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes);
  if( pKey ){
    sqlite3VdbeDeleteUnpackedRecord(pIdxKey);
  }
  return rc;
}

/*
** Restore the cursor to the position it was in (or as close to as possible)
** when saveCursorPosition() was called. Note that this call deletes the 
** saved position info stored by saveCursorPosition(), so there can be
** at most one effective restoreCursorPosition() call after each 
** saveCursorPosition().
*/
int sqlite3BtreeRestoreCursorPosition(BtCursor *pCur){
static int btreeRestoreCursorPosition(BtCursor *pCur){
  int rc;
  assert( cursorHoldsMutex(pCur) );
  assert( pCur->eState>=CURSOR_REQUIRESEEK );
  if( pCur->eState==CURSOR_FAULT ){
    return pCur->skip;
    return pCur->skipNext;
  }
  pCur->eState = CURSOR_INVALID;
  rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skip);
  rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skipNext);
  if( rc==SQLITE_OK ){
    sqlite3_free(pCur->pKey);
    pCur->pKey = 0;
    assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
  }
  return rc;
}

#define restoreCursorPosition(p) \
  (p->eState>=CURSOR_REQUIRESEEK ? \
         sqlite3BtreeRestoreCursorPosition(p) : \
         btreeRestoreCursorPosition(p) : \
         SQLITE_OK)

/*
** Determine whether or not a cursor has moved from the position it
** was last placed at.  Cursors can move when the row they are pointing
** at is deleted out from under them.
**
** This routine returns an error code if something goes wrong.  The
** integer *pHasMoved is set to one if the cursor has moved and 0 if not.
*/
int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){
  int rc;

  rc = restoreCursorPosition(pCur);
  if( rc ){
    *pHasMoved = 1;
    return rc;
  }
  if( pCur->eState!=CURSOR_VALID || pCur->skip!=0 ){
  if( pCur->eState!=CURSOR_VALID || pCur->skipNext!=0 ){
    *pHasMoved = 1;
  }else{
    *pHasMoved = 0;
  }
  return SQLITE_OK;
}

557
558
559
560
561
562
563

564



565
566

567
568
569
570
571



572
573
574
575
576
577
578
579


580
581
582
583

584

585
586
587
588


589
590
591
592
593
594

595
596
597
598
599
600

601
602
603
604
605
606
607
608
609
739
740
741
742
743
744
745
746

747
748
749
750

751
752
753
754
755

756
757
758
759
760
761
762
763
764
765

766
767
768
769
770
771
772

773
774
775
776

777
778
779
780
781
782
783

784
785
786
787
788
789
790
791
792

793
794
795
796
797
798
799







+
-
+
+
+

-
+




-
+
+
+







-
+
+




+
-
+



-
+
+





-
+






+

-







}

/*
** Write an entry into the pointer map.
**
** This routine updates the pointer map entry for page number 'key'
** so that it maps to type 'eType' and parent page number 'pgno'.
**
** An error code is returned if something goes wrong, otherwise SQLITE_OK.
** If *pRC is initially non-zero (non-SQLITE_OK) then this routine is
** a no-op.  If an error occurs, the appropriate error code is written
** into *pRC.
*/
static int ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent){
static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){
  DbPage *pDbPage;  /* The pointer map page */
  u8 *pPtrmap;      /* The pointer map data */
  Pgno iPtrmap;     /* The pointer map page number */
  int offset;       /* Offset in pointer map page */
  int rc;
  int rc;           /* Return code from subfunctions */

  if( *pRC ) return;

  assert( sqlite3_mutex_held(pBt->mutex) );
  /* The master-journal page number must never be used as a pointer map page */
  assert( 0==PTRMAP_ISPAGE(pBt, PENDING_BYTE_PAGE(pBt)) );

  assert( pBt->autoVacuum );
  if( key==0 ){
    return SQLITE_CORRUPT_BKPT;
    *pRC = SQLITE_CORRUPT_BKPT;
    return;
  }
  iPtrmap = PTRMAP_PAGENO(pBt, key);
  rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
  if( rc!=SQLITE_OK ){
    *pRC = rc;
    return rc;
    return;
  }
  offset = PTRMAP_PTROFFSET(iPtrmap, key);
  if( offset<0 ){
    return SQLITE_CORRUPT_BKPT;
    *pRC = SQLITE_CORRUPT_BKPT;
    goto ptrmap_exit;
  }
  pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);

  if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
    TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent));
    rc = sqlite3PagerWrite(pDbPage);
    *pRC= rc = sqlite3PagerWrite(pDbPage);
    if( rc==SQLITE_OK ){
      pPtrmap[offset] = eType;
      put4byte(&pPtrmap[offset+1], parent);
    }
  }

ptrmap_exit:
  sqlite3PagerUnref(pDbPage);
  return rc;
}

/*
** Read an entry from the pointer map.
**
** This routine retrieves the pointer map entry for page 'key', writing
** the type and parent page number to *pEType and *pPgno respectively.
632
633
634
635
636
637
638
639

640

641
642
643
644
645
646
647
648
649
650
651
652
653
654
655

656
657
658
659
660
661
662
822
823
824
825
826
827
828

829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845

846
847
848
849
850
851
852
853







-
+

+














-
+








  sqlite3PagerUnref(pDbPage);
  if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_BKPT;
  return SQLITE_OK;
}

#else /* if defined SQLITE_OMIT_AUTOVACUUM */
  #define ptrmapPut(w,x,y,z) SQLITE_OK
  #define ptrmapPut(w,x,y,z,rc)
  #define ptrmapGet(w,x,y,z) SQLITE_OK
  #define ptrmapPutOvflPtr(x, y, rc)
#endif

/*
** Given a btree page and a cell index (0 means the first cell on
** the page, 1 means the second cell, and so forth) return a pointer
** to the cell content.
**
** This routine works only for pages that do not contain overflow cells.
*/
#define findCell(P,I) \
  ((P)->aData + ((P)->maskPage & get2byte(&(P)->aData[(P)->cellOffset+2*(I)])))

/*
** This a more complex version of findCell() that works for
** pages that do contain overflow cells.  See insert
** pages that do contain overflow cells.
*/
static u8 *findOverflowCell(MemPage *pPage, int iCell){
  int i;
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  for(i=pPage->nOverflow-1; i>=0; i--){
    int k;
    struct _OvflCell *pOvfl;
670
671
672
673
674
675
676
677
678


679
680
681
682

683
684

685
686
687
688
689
690
691
861
862
863
864
865
866
867


868
869
870
871
872

873
874

875
876
877
878
879
880
881
882







-
-
+
+



-
+

-
+







    }
  }
  return findCell(pPage, iCell);
}

/*
** Parse a cell content block and fill in the CellInfo structure.  There
** are two versions of this function.  sqlite3BtreeParseCell() takes a 
** cell index as the second argument and sqlite3BtreeParseCellPtr() 
** are two versions of this function.  btreeParseCell() takes a 
** cell index as the second argument and btreeParseCellPtr() 
** takes a pointer to the body of the cell as its second argument.
**
** Within this file, the parseCell() macro can be called instead of
** sqlite3BtreeParseCellPtr(). Using some compilers, this will be faster.
** btreeParseCellPtr(). Using some compilers, this will be faster.
*/
void sqlite3BtreeParseCellPtr(
static void btreeParseCellPtr(
  MemPage *pPage,         /* Page containing the cell */
  u8 *pCell,              /* Pointer to the cell text. */
  CellInfo *pInfo         /* Fill in this structure */
){
  u16 n;                  /* Number bytes in cell content header */
  u32 nPayload;           /* Number of bytes of cell payload */

706
707
708
709
710
711
712


713
714
715
716
717
718
719
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912







+
+







  }else{
    pInfo->nData = 0;
    n += getVarint32(&pCell[n], nPayload);
    pInfo->nKey = nPayload;
  }
  pInfo->nPayload = nPayload;
  pInfo->nHeader = n;
  testcase( nPayload==pPage->maxLocal );
  testcase( nPayload==pPage->maxLocal+1 );
  if( likely(nPayload<=pPage->maxLocal) ){
    /* This is the (easy) common case where the entire payload fits
    ** on the local page.  No overflow is required.
    */
    int nSize;          /* Total size of cell content in bytes */
    nSize = nPayload + n;
    pInfo->nLocal = (u16)nPayload;
735
736
737
738
739
740
741


742
743
744
745
746
747
748
749
750
751
752
753


754
755
756
757
758
759
760
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946


947
948
949
950
951
952
953
954
955







+
+










-
-
+
+







    int minLocal;  /* Minimum amount of payload held locally */
    int maxLocal;  /* Maximum amount of payload held locally */
    int surplus;   /* Overflow payload available for local storage */

    minLocal = pPage->minLocal;
    maxLocal = pPage->maxLocal;
    surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize - 4);
    testcase( surplus==maxLocal );
    testcase( surplus==maxLocal+1 );
    if( surplus <= maxLocal ){
      pInfo->nLocal = (u16)surplus;
    }else{
      pInfo->nLocal = (u16)minLocal;
    }
    pInfo->iOverflow = (u16)(pInfo->nLocal + n);
    pInfo->nSize = pInfo->iOverflow + 4;
  }
}
#define parseCell(pPage, iCell, pInfo) \
  sqlite3BtreeParseCellPtr((pPage), findCell((pPage), (iCell)), (pInfo))
void sqlite3BtreeParseCell(
  btreeParseCellPtr((pPage), findCell((pPage), (iCell)), (pInfo))
static void btreeParseCell(
  MemPage *pPage,         /* Page containing the cell */
  int iCell,              /* The cell index.  First cell is 0 */
  CellInfo *pInfo         /* Fill in this structure */
){
  parseCell(pPage, iCell, pInfo);
}

770
771
772
773
774
775
776
777

778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796


797
798
799


800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815




816
817
818
819
820
821
822
823
824
825
826
827

828

829
830

831
832
833
834

835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858



859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874


875
876
877
878






879

880
881


882
883





884

885
886

887



888
889
890
891

892
893
894
895
896
897

898
899

900
901
902
903
904
905
906
907
908



909
910

911
912
913
914
915




916
917
918

919
920

921
922
923
924



925
926
927
928
929
930
931

932
933
934

935
936
937
938







939
940
941

942
943




944
945
946
947
948
949
950
951
952


953
954
955
956
957
958
959
960
961
962
963


964
965
966
967












968
969




970
971

972


973

974
975
976
977
978
979
980
981
982
983
984
985

986
987
988
989
990

991
992
993
994
995
996
997
998
999
1000
1001









1002
1003


1004
1005
1006

1007
1008
1009
1010
1011

1012
1013
1014
1015
1016
1017
1018
1019
1020
1021

1022
1023
1024
1025
1026
1027
1028
1029
1030

1031
1032
1033

1034
1035
1036
1037
1038
1039
1040
965
966
967
968
969
970
971

972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013

1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028

1029
1030
1031
1032

1033
1034
1035
1036

1037
1038

1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051

1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090

1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102

1103
1104
1105
1106

1107
1108
1109
1110
1111
1112

1113
1114
1115
1116
1117


1118
1119

1120
1121
1122
1123
1124
1125
1126
1127


1128
1129
1130
1131

1132





1133
1134
1135
1136



1137
1138

1139
1140
1141
1142

1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154


1155




1156
1157
1158
1159
1160
1161
1162
1163

1164
1165


1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190

1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209

1210
1211
1212
1213
1214

1215
1216
1217
1218

1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236

1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247

1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261


1262
1263
1264
1265
1266

1267
1268
1269
1270
1271
1272
1273
1274
1275
1276

1277
1278
1279
1280
1281
1282
1283
1284
1285

1286
1287
1288

1289
1290
1291
1292
1293
1294
1295
1296







-
+



















+
+



+
+















-
+
+
+
+











-
+

+

-
+



-
+

-













-








+
+
+
















+
+




+
+
+
+
+
+
-
+


+
+


+
+
+
+
+
-
+


+
-
+
+
+



-
+




-
-
+

-
+







-
-
+
+
+

-
+
-
-
-
-
-
+
+
+
+
-
-
-
+

-
+



-
+
+
+







+

-
-
+
-
-
-
-
+
+
+
+
+
+
+

-

+
-
-
+
+
+
+









+
+










-
+
+




+
+
+
+
+
+
+
+
+
+
+
+

-
+
+
+
+

-
+

+
+
-
+












+




-
+










-
+
+
+
+
+
+
+
+
+


+
+

-
-
+




-
+









-
+








-
+


-
+








#ifdef SQLITE_DEBUG
  /* The value returned by this function should always be the same as
  ** the (CellInfo.nSize) value found by doing a full parse of the
  ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
  ** this function verifies that this invariant is not violated. */
  CellInfo debuginfo;
  sqlite3BtreeParseCellPtr(pPage, pCell, &debuginfo);
  btreeParseCellPtr(pPage, pCell, &debuginfo);
#endif

  if( pPage->intKey ){
    u8 *pEnd;
    if( pPage->hasData ){
      pIter += getVarint32(pIter, nSize);
    }else{
      nSize = 0;
    }

    /* pIter now points at the 64-bit integer key value, a variable length 
    ** integer. The following block moves pIter to point at the first byte
    ** past the end of the key value. */
    pEnd = &pIter[9];
    while( (*pIter++)&0x80 && pIter<pEnd );
  }else{
    pIter += getVarint32(pIter, nSize);
  }

  testcase( nSize==pPage->maxLocal );
  testcase( nSize==pPage->maxLocal+1 );
  if( nSize>pPage->maxLocal ){
    int minLocal = pPage->minLocal;
    nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4);
    testcase( nSize==pPage->maxLocal );
    testcase( nSize==pPage->maxLocal+1 );
    if( nSize>pPage->maxLocal ){
      nSize = minLocal;
    }
    nSize += 4;
  }
  nSize += (u32)(pIter - pCell);

  /* The minimum size of any cell is 4 bytes. */
  if( nSize<4 ){
    nSize = 4;
  }

  assert( nSize==debuginfo.nSize );
  return (u16)nSize;
}
#ifndef NDEBUG

#ifdef SQLITE_DEBUG
/* This variation on cellSizePtr() is used inside of assert() statements
** only. */
static u16 cellSize(MemPage *pPage, int iCell){
  return cellSizePtr(pPage, findCell(pPage, iCell));
}
#endif

#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** If the cell pCell, part of page pPage contains a pointer
** to an overflow page, insert an entry into the pointer-map
** for the overflow page.
*/
static int ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell){
static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
  CellInfo info;
  if( *pRC ) return;
  assert( pCell!=0 );
  sqlite3BtreeParseCellPtr(pPage, pCell, &info);
  btreeParseCellPtr(pPage, pCell, &info);
  assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
  if( info.iOverflow ){
    Pgno ovfl = get4byte(&pCell[info.iOverflow]);
    return ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno);
    ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
  }
  return SQLITE_OK;
}
#endif


/*
** Defragment the page given.  All Cells are moved to the
** end of the page and all free space is collected into one
** big FreeBlk that occurs in between the header and cell
** pointer array and the cell content area.
*/
static int defragmentPage(MemPage *pPage){
  int i;                     /* Loop counter */
  int pc;                    /* Address of a i-th cell */
  int addr;                  /* Offset of first byte after cell pointer array */
  int hdr;                   /* Offset to the page header */
  int size;                  /* Size of a cell */
  int usableSize;            /* Number of usable bytes on a page */
  int cellOffset;            /* Offset to the cell pointer array */
  int cbrk;                  /* Offset to the cell content area */
  int nCell;                 /* Number of cells on the page */
  unsigned char *data;       /* The page data */
  unsigned char *temp;       /* Temp area for cell content */
  int iCellFirst;            /* First allowable cell index */
  int iCellLast;             /* Last possible cell index */


  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  assert( pPage->pBt!=0 );
  assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
  assert( pPage->nOverflow==0 );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  temp = sqlite3PagerTempSpace(pPage->pBt->pPager);
  data = pPage->aData;
  hdr = pPage->hdrOffset;
  cellOffset = pPage->cellOffset;
  nCell = pPage->nCell;
  assert( nCell==get2byte(&data[hdr+3]) );
  usableSize = pPage->pBt->usableSize;
  cbrk = get2byte(&data[hdr+5]);
  memcpy(&temp[cbrk], &data[cbrk], usableSize - cbrk);
  cbrk = usableSize;
  iCellFirst = cellOffset + 2*nCell;
  iCellLast = usableSize - 4;
  for(i=0; i<nCell; i++){
    u8 *pAddr;     /* The i-th cell pointer */
    pAddr = &data[cellOffset + i*2];
    pc = get2byte(pAddr);
    testcase( pc==iCellFirst );
    testcase( pc==iCellLast );
#if !defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
    /* These conditions have already been verified in btreeInitPage()
    ** if SQLITE_ENABLE_OVERSIZE_CELL_CHECK is defined 
    */
    if( pc>=usableSize ){
    if( pc<iCellFirst || pc>iCellLast ){
      return SQLITE_CORRUPT_BKPT;
    }
#endif
    assert( pc>=iCellFirst && pc<=iCellLast );
    size = cellSizePtr(pPage, &temp[pc]);
    cbrk -= size;
#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
    if( cbrk<iCellFirst ){
      return SQLITE_CORRUPT_BKPT;
    }
#else
    if( cbrk<cellOffset+2*nCell || pc+size>usableSize ){
    if( cbrk<iCellFirst || pc+size>usableSize ){
      return SQLITE_CORRUPT_BKPT;
    }
#endif
    assert( cbrk+size<=usableSize && cbrk>=0 );
    assert( cbrk+size<=usableSize && cbrk>=iCellFirst );
    testcase( cbrk+size==usableSize );
    testcase( pc+size==usableSize );
    memcpy(&data[cbrk], &temp[pc], size);
    put2byte(pAddr, cbrk);
  }
  assert( cbrk>=cellOffset+2*nCell );
  assert( cbrk>=iCellFirst );
  put2byte(&data[hdr+5], cbrk);
  data[hdr+1] = 0;
  data[hdr+2] = 0;
  data[hdr+7] = 0;
  addr = cellOffset+2*nCell;
  memset(&data[addr], 0, cbrk-addr);
  memset(&data[iCellFirst], 0, cbrk-iCellFirst);
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  if( cbrk-addr!=pPage->nFree ){
  if( cbrk-iCellFirst!=pPage->nFree ){
    return SQLITE_CORRUPT_BKPT;
  }
  return SQLITE_OK;
}

/*
** Allocate nByte bytes of space from within the B-Tree page passed
** as the first argument. Return the index into pPage->aData[] of the 
** first byte of allocated space. 
** as the first argument. Write into *pIdx the index into pPage->aData[]
** of the first byte of allocated space. Return either SQLITE_OK or
** an error code (usually SQLITE_CORRUPT).
**
** The caller guarantees that the space between the end of the cell-offset 
** The caller guarantees that there is sufficient space to make the
** array and the start of the cell-content area is at least nByte bytes
** in size. So this routine can never fail.
**
** If there are already 60 or more bytes of fragments within the page,
** the page is defragmented before returning. If this were not done there
** allocation.  This routine might need to defragment in order to bring
** all the space together, however.  This routine will avoid using
** the first two bytes past the cell pointer area since presumably this
** allocation is being made in order to insert a new cell, so we will
** is a chance that the number of fragmented bytes could eventually 
** overflow the single-byte field of the page-header in which this value
** is stored.
** also end up needing a new cell pointer.
*/
static int allocateSpace(MemPage *pPage, int nByte){
static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
  const int hdr = pPage->hdrOffset;    /* Local cache of pPage->hdrOffset */
  u8 * const data = pPage->aData;      /* Local cache of pPage->aData */
  int nFrag;                           /* Number of fragmented bytes on pPage */
  int top;
  int top;                             /* First byte of cell content area */
  int gap;        /* First byte of gap between cell pointers and cell content */
  int rc;         /* Integer return code */
  
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  assert( pPage->pBt );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  assert( nByte>=0 );  /* Minimum cell size is 4 */
  assert( pPage->nFree>=nByte );
  assert( pPage->nOverflow==0 );
  assert( nByte<pPage->pBt->usableSize-8 );

  /* Assert that the space between the cell-offset array and the 
  ** cell-content area is greater than nByte bytes.
  nFrag = data[hdr+7];
  */
  assert( nByte <= (
      get2byte(&data[hdr+5])-(hdr+8+(pPage->leaf?0:4)+2*get2byte(&data[hdr+3]))
  ));
  assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf );
  gap = pPage->cellOffset + 2*pPage->nCell;
  top = get2byte(&data[hdr+5]);
  if( gap>top ) return SQLITE_CORRUPT_BKPT;
  testcase( gap+2==top );
  testcase( gap+1==top );
  testcase( gap==top );

  nFrag = data[hdr+7];
  if( nFrag>=60 ){
    /* Always defragment highly fragmented pages */
    defragmentPage(pPage);
  }else{
    rc = defragmentPage(pPage);
    if( rc ) return rc;
    top = get2byte(&data[hdr+5]);
  }else if( gap+2<=top ){
    /* Search the freelist looking for a free slot big enough to satisfy 
    ** the request. The allocation is made from the first free slot in 
    ** the list that is large enough to accomadate it.
    */
    int pc, addr;
    for(addr=hdr+1; (pc = get2byte(&data[addr]))>0; addr=pc){
      int size = get2byte(&data[pc+2]);     /* Size of free slot */
      if( size>=nByte ){
        int x = size - nByte;
        testcase( x==4 );
        testcase( x==3 );
        if( x<4 ){
          /* Remove the slot from the free-list. Update the number of
          ** fragmented bytes within the page. */
          memcpy(&data[addr], &data[pc], 2);
          data[hdr+7] = (u8)(nFrag + x);
        }else{
          /* The slot remains on the free-list. Reduce its size to account
          ** for the portion used by the new allocation. */
          put2byte(&data[pc+2], x);
        }
        return pc + x;
        *pIdx = pc + x;
        return SQLITE_OK;
      }
    }
  }

  /* Check to make sure there is enough space in the gap to satisfy
  ** the allocation.  If not, defragment.
  */
  testcase( gap+2+nByte==top );
  if( gap+2+nByte>top ){
    rc = defragmentPage(pPage);
    if( rc ) return rc;
    top = get2byte(&data[hdr+5]);
    assert( gap+nByte<=top );
  }


  /* Allocate memory from the gap in between the cell pointer array
  ** and the cell content area.
  ** and the cell content area.  The btreeInitPage() call has already
  ** validated the freelist.  Given that the freelist is valid, there
  ** is no way that the allocation can extend off the end of the page.
  ** The assert() below verifies the previous sentence.
  */
  top = get2byte(&data[hdr+5]) - nByte;
  top -= nByte;
  put2byte(&data[hdr+5], top);
  assert( top+nByte <= pPage->pBt->usableSize );
  *pIdx = top;
  return top;
  return SQLITE_OK;
}

/*
** Return a section of the pPage->aData to the freelist.
** The first byte of the new free block is pPage->aDisk[start]
** and the size of the block is "size" bytes.
**
** Most of the effort here is involved in coalesing adjacent
** free blocks into a single big free block.
*/
static int freeSpace(MemPage *pPage, int start, int size){
  int addr, pbegin, hdr;
  int iLast;                        /* Largest possible freeblock offset */
  unsigned char *data = pPage->aData;

  assert( pPage->pBt!=0 );
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  assert( start>=pPage->hdrOffset+6+(pPage->leaf?0:4) );
  assert( start>=pPage->hdrOffset+6+pPage->childPtrSize );
  assert( (start + size)<=pPage->pBt->usableSize );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  assert( size>=0 );   /* Minimum cell size is 4 */

#ifdef SQLITE_SECURE_DELETE
  /* Overwrite deleted information with zeros when the SECURE_DELETE 
  ** option is enabled at compile-time */
  memset(&data[start], 0, size);
#endif

  /* Add the space back into the linked list of freeblocks */
  /* Add the space back into the linked list of freeblocks.  Note that
  ** even though the freeblock list was checked by btreeInitPage(),
  ** btreeInitPage() did not detect overlapping cells or
  ** freeblocks that overlapped cells.   Nor does it detect when the
  ** cell content area exceeds the value in the page header.  If these
  ** situations arise, then subsequent insert operations might corrupt
  ** the freelist.  So we do need to check for corruption while scanning
  ** the freelist.
  */
  hdr = pPage->hdrOffset;
  addr = hdr + 1;
  iLast = pPage->pBt->usableSize - 4;
  assert( start<=iLast );
  while( (pbegin = get2byte(&data[addr]))<start && pbegin>0 ){
    assert( pbegin<=pPage->pBt->usableSize-4 );
    if( pbegin<=addr ) {
    if( pbegin<addr+4 ){
      return SQLITE_CORRUPT_BKPT;
    }
    addr = pbegin;
  }
  if ( pbegin>pPage->pBt->usableSize-4 ) {
  if( pbegin>iLast ){
    return SQLITE_CORRUPT_BKPT;
  }
  assert( pbegin>addr || pbegin==0 );
  put2byte(&data[addr], start);
  put2byte(&data[start], pbegin);
  put2byte(&data[start+2], size);
  pPage->nFree = pPage->nFree + (u16)size;

  /* Coalesce adjacent free blocks */
  addr = pPage->hdrOffset + 1;
  addr = hdr + 1;
  while( (pbegin = get2byte(&data[addr]))>0 ){
    int pnext, psize, x;
    assert( pbegin>addr );
    assert( pbegin<=pPage->pBt->usableSize-4 );
    pnext = get2byte(&data[pbegin]);
    psize = get2byte(&data[pbegin+2]);
    if( pbegin + psize + 3 >= pnext && pnext>0 ){
      int frag = pnext - (pbegin+psize);
      if( (frag<0) || (frag>(int)data[pPage->hdrOffset+7]) ){
      if( (frag<0) || (frag>(int)data[hdr+7]) ){
        return SQLITE_CORRUPT_BKPT;
      }
      data[pPage->hdrOffset+7] -= (u8)frag;
      data[hdr+7] -= (u8)frag;
      x = get2byte(&data[pnext]);
      put2byte(&data[pbegin], x);
      x = pnext + get2byte(&data[pnext+2]) - pbegin;
      put2byte(&data[pbegin+2], x);
    }else{
      addr = pbegin;
    }
1094
1095
1096
1097
1098
1099
1100
1101

1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117


1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134

1135
1136

1137
1138
1139
1140
1141
1142


1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154


1155
1156
1157
1158

1159
1160
1161
1162

1163
1164
1165
1166
1167
1168
1169
1170
1171
1172


1173
1174
1175
1176
1177
1178



1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196

1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1350
1351
1352
1353
1354
1355
1356

1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394

1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405


1406
1407
1408


1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431


1432
1433
1434
1435
1436
1437


1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456


1457




















1458
1459
1460
1461
1462
1463
1464







-
+
















+
+

















+

-
+






+
+


-
-



-
-



+
+




+




+








-
-
+
+




-
-
+
+
+
















-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







**
** Return SQLITE_OK on success.  If we see that the page does
** not contain a well-formed database page, then return 
** SQLITE_CORRUPT.  Note that a return of SQLITE_OK does not
** guarantee that the page is well-formed.  It only shows that
** we failed to detect any corruption.
*/
int sqlite3BtreeInitPage(MemPage *pPage){
static int btreeInitPage(MemPage *pPage){

  assert( pPage->pBt!=0 );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
  assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) );
  assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) );

  if( !pPage->isInit ){
    u16 pc;            /* Address of a freeblock within pPage->aData[] */
    u8 hdr;            /* Offset to beginning of page header */
    u8 *data;          /* Equal to pPage->aData */
    BtShared *pBt;        /* The main btree structure */
    u16 usableSize;    /* Amount of usable space on each page */
    u16 cellOffset;    /* Offset from start of page to first cell pointer */
    u16 nFree;         /* Number of unused bytes on the page */
    u16 top;           /* First byte of the cell content area */
    int iCellFirst;    /* First allowable cell or freeblock offset */
    int iCellLast;     /* Last possible cell or freeblock offset */

    pBt = pPage->pBt;

    hdr = pPage->hdrOffset;
    data = pPage->aData;
    if( decodeFlags(pPage, data[hdr]) ) return SQLITE_CORRUPT_BKPT;
    assert( pBt->pageSize>=512 && pBt->pageSize<=32768 );
    pPage->maskPage = pBt->pageSize - 1;
    pPage->nOverflow = 0;
    usableSize = pBt->usableSize;
    pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf;
    top = get2byte(&data[hdr+5]);
    pPage->nCell = get2byte(&data[hdr+3]);
    if( pPage->nCell>MX_CELL(pBt) ){
      /* To many cells for a single page.  The page must be corrupt */
      return SQLITE_CORRUPT_BKPT;
    }
    testcase( pPage->nCell==MX_CELL(pBt) );

    /* A malformed database page might cause use to read past the end
    /* A malformed database page might cause us to read past the end
    ** of page when parsing a cell.  
    **
    ** The following block of code checks early to see if a cell extends
    ** past the end of a page boundary and causes SQLITE_CORRUPT to be 
    ** returned if it does.
    */
    iCellFirst = cellOffset + 2*pPage->nCell;
    iCellLast = usableSize - 4;
#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
    {
      int iCellFirst;   /* First allowable cell index */
      int iCellLast;    /* Last possible cell index */
      int i;            /* Index into the cell pointer array */
      int sz;           /* Size of a cell */

      iCellFirst = cellOffset + 2*pPage->nCell;
      iCellLast = usableSize - 4;
      if( !pPage->leaf ) iCellLast--;
      for(i=0; i<pPage->nCell; i++){
        pc = get2byte(&data[cellOffset+i*2]);
        testcase( pc==iCellFirst );
        testcase( pc==iCellLast );
        if( pc<iCellFirst || pc>iCellLast ){
          return SQLITE_CORRUPT_BKPT;
        }
        sz = cellSizePtr(pPage, &data[pc]);
        testcase( pc+sz==usableSize );
        if( pc+sz>usableSize ){
          return SQLITE_CORRUPT_BKPT;
        }
      }
      if( !pPage->leaf ) iCellLast++;
    }  
#endif

    /* Compute the total free space on the page */
    pc = get2byte(&data[hdr+1]);
    nFree = data[hdr+7] + top;
    while( pc>0 ){
      u16 next, size;
      if( pc>usableSize-4 ){
        /* Free block is off the page */
      if( pc<iCellFirst || pc>iCellLast ){
        /* Start of free block is off the page */
        return SQLITE_CORRUPT_BKPT; 
      }
      next = get2byte(&data[pc]);
      size = get2byte(&data[pc+2]);
      if( next>0 && next<=pc+size+3 ){
        /* Free blocks must be in accending order */
      if( (next>0 && next<=pc+size+3) || pc+size>usableSize ){
        /* Free blocks must be in ascending order. And the last byte of
	** the free-block must lie on the database page.  */
        return SQLITE_CORRUPT_BKPT; 
      }
      nFree = nFree + size;
      pc = next;
    }

    /* At this point, nFree contains the sum of the offset to the start
    ** of the cell-content area plus the number of free bytes within
    ** the cell-content area. If this is greater than the usable-size
    ** of the page, then the page must be corrupted. This check also
    ** serves to verify that the offset to the start of the cell-content
    ** area, according to the page header, lies within the page.
    */
    if( nFree>usableSize ){
      return SQLITE_CORRUPT_BKPT; 
    }
    pPage->nFree = nFree - (cellOffset + 2*pPage->nCell);

    pPage->nFree = (u16)(nFree - iCellFirst);
#if 0
  /* Check that all the offsets in the cell offset array are within range. 
  ** 
  ** Omitting this consistency check and using the pPage->maskPage mask
  ** to prevent overrunning the page buffer in findCell() results in a
  ** 2.5% performance gain.
  */
  {
    u8 *pOff;        /* Iterator used to check all cell offsets are in range */
    u8 *pEnd;        /* Pointer to end of cell offset array */
    u8 mask;         /* Mask of bits that must be zero in MSB of cell offsets */
    mask = ~(((u8)(pBt->pageSize>>8))-1);
    pEnd = &data[cellOffset + pPage->nCell*2];
    for(pOff=&data[cellOffset]; pOff!=pEnd && !((*pOff)&mask); pOff+=2);
    if( pOff!=pEnd ){
      return SQLITE_CORRUPT_BKPT;
    }
  }
#endif

    pPage->isInit = 1;
  }
  return SQLITE_OK;
}

/*
** Set up a raw page so that it looks like a database page holding
1273
1274
1275
1276
1277
1278
1279
1280

1281
1282
1283
1284
1285
1286
1287
1514
1515
1516
1517
1518
1519
1520

1521
1522
1523
1524
1525
1526
1527
1528







-
+







** If the noContent flag is set, it means that we do not care about
** the content of the page at this time.  So do not go to the disk
** to fetch the content.  Just fill in the content with zeros for now.
** If in the future we call sqlite3PagerWrite() on this page, that
** means we have started to be concerned about content and the disk
** read should occur at that point.
*/
int sqlite3BtreeGetPage(
static int btreeGetPage(
  BtShared *pBt,       /* The btree */
  Pgno pgno,           /* Number of the page to fetch */
  MemPage **ppPage,    /* Return the page in this parameter */
  int noContent        /* Do not load page content if true */
){
  int rc;
  DbPage *pDbPage;
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327






1328
1329
1330
1331
1332
1333
1334
1335
1336

1337
1338
1339
1340
1341


1342
1343
1344
1345
1346
1347
1348
1349
1350
1351




1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364







1365
1366


1367
1368
1369
1370
1371
1372

1373
1374
1375
1376
1377
1378
1379
1559
1560
1561
1562
1563
1564
1565



1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578


1579
1580




1581
1582










1583
1584
1585
1586



1587



1588





1589
1590
1591
1592
1593
1594
1595


1596
1597
1598
1599
1600
1601
1602

1603
1604
1605
1606
1607
1608
1609
1610







-
-
-
+
+
+
+
+
+







-
-
+

-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-

-
-
-

-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+





-
+







  assert( pBt->pPage1 );
  rc = sqlite3PagerPagecount(pBt->pPager, &nPage);
  assert( rc==SQLITE_OK || nPage==-1 );
  return (Pgno)nPage;
}

/*
** Get a page from the pager and initialize it.  This routine
** is just a convenience wrapper around separate calls to
** sqlite3BtreeGetPage() and sqlite3BtreeInitPage().
** Get a page from the pager and initialize it.  This routine is just a
** convenience wrapper around separate calls to btreeGetPage() and 
** btreeInitPage().
**
** If an error occurs, then the value *ppPage is set to is undefined. It
** may remain unchanged, or it may be set to an invalid value.
*/
static int getAndInitPage(
  BtShared *pBt,          /* The database file */
  Pgno pgno,           /* Number of the page to get */
  MemPage **ppPage     /* Write the page pointer here */
){
  int rc;
  MemPage *pPage;

  TESTONLY( Pgno iLastPg = pagerPagecount(pBt); )
  assert( sqlite3_mutex_held(pBt->mutex) );
  if( pgno==0 ){
    return SQLITE_CORRUPT_BKPT; 
  }


  rc = btreeGetPage(pBt, pgno, ppPage, 0);
  /* It is often the case that the page we want is already in cache.
  ** If so, get it directly.  This saves us from having to call
  ** pagerPagecount() to make sure pgno is within limits, which results
  ** in a measureable performance improvements.
  */
  *ppPage = pPage = btreePageLookup(pBt, pgno);
  if( pPage ){
    /* Page is already in cache */
    rc = SQLITE_OK;
  }else{
  if( rc==SQLITE_OK ){
    rc = btreeInitPage(*ppPage);
    if( rc!=SQLITE_OK ){
      releasePage(*ppPage);
    /* Page not in cache.  Acquire it. */
    if( pgno>pagerPagecount(pBt) ){
      return SQLITE_CORRUPT_BKPT; 
    }
    rc = sqlite3BtreeGetPage(pBt, pgno, ppPage, 0);
    if( rc ) return rc;
    pPage = *ppPage;
  }
  if( !pPage->isInit ){
    rc = sqlite3BtreeInitPage(pPage);
  }
  if( rc!=SQLITE_OK ){
    releasePage(pPage);

  /* If the requested page number was either 0 or greater than the page
  ** number of the last page in the database, this function should return
  ** SQLITE_CORRUPT or some other error (i.e. SQLITE_FULL). Check that this
  ** is the case.  */
  assert( (pgno>0 && pgno<=iLastPg) || rc!=SQLITE_OK );
  testcase( pgno==0 );
    *ppPage = 0;
  }
  testcase( pgno==iLastPg );

  return rc;
}

/*
** Release a MemPage.  This should be called once for each prior
** call to sqlite3BtreeGetPage.
** call to btreeGetPage.
*/
static void releasePage(MemPage *pPage){
  if( pPage ){
    assert( pPage->nOverflow==0 || sqlite3PagerPageRefcount(pPage->pDbPage)>1 );
    assert( pPage->aData );
    assert( pPage->pBt );
    assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
1397
1398
1399
1400
1401
1402
1403
1404

1405
1406

1407
1408

1409
1410
1411
1412
1413
1414
1415
1628
1629
1630
1631
1632
1633
1634

1635
1636

1637
1638

1639
1640
1641
1642
1643
1644
1645
1646







-
+

-
+

-
+







  assert( sqlite3PagerPageRefcount(pData)>0 );
  if( pPage->isInit ){
    assert( sqlite3_mutex_held(pPage->pBt->mutex) );
    pPage->isInit = 0;
    if( sqlite3PagerPageRefcount(pData)>1 ){
      /* pPage might not be a btree page;  it might be an overflow page
      ** or ptrmap page or a free page.  In those cases, the following
      ** call to sqlite3BtreeInitPage() will likely return SQLITE_CORRUPT.
      ** call to btreeInitPage() will likely return SQLITE_CORRUPT.
      ** But no harm is done by this.  And it is very important that
      ** sqlite3BtreeInitPage() be called on every btree page so we make
      ** btreeInitPage() be called on every btree page so we make
      ** the call for every page that comes in for re-initing. */
      sqlite3BtreeInitPage(pPage);
      btreeInitPage(pPage);
    }
  }
}

/*
** Invoke the busy handler for a btree.
*/
1469
1470
1471
1472
1473
1474
1475




1476
1477
1478
1479
1480
1481
1482
1483

1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717

1718
1719
1720
1721
1722

1723
1724
1725
1726
1727
1728
1729







+
+
+
+







-
+




-







  pVfs = db->pVfs;
  p = sqlite3MallocZero(sizeof(Btree));
  if( !p ){
    return SQLITE_NOMEM;
  }
  p->inTrans = TRANS_NONE;
  p->db = db;
#ifndef SQLITE_OMIT_SHARED_CACHE
  p->lock.pBtree = p;
  p->lock.iTable = 1;
#endif

#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
  /*
  ** If this Btree is a candidate for shared cache, try to find an
  ** existing BtShared object that we can share with
  */
  if( isMemdb==0 && zFilename && zFilename[0] ){
    if( sqlite3GlobalConfig.sharedCacheEnabled ){
    if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
      int nFullPathname = pVfs->mxPathname+1;
      char *zFullPathname = sqlite3Malloc(nFullPathname);
      sqlite3_mutex *mutexShared;
      p->sharable = 1;
      db->flags |= SQLITE_SharedCache;
      if( !zFullPathname ){
        sqlite3_free(p);
        return SQLITE_NOMEM;
      }
      sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);
      mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN);
      sqlite3_mutex_enter(mutexOpen);
1544
1545
1546
1547
1548
1549
1550
1551

1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1778
1779
1780
1781
1782
1783
1784

1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795

1796
1797
1798
1799
1800
1801
1802







-
+










-







  
    pBt = sqlite3MallocZero( sizeof(*pBt) );
    if( pBt==0 ){
      rc = SQLITE_NOMEM;
      goto btree_open_out;
    }
    rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename,
                          EXTRA_SIZE, flags, vfsFlags);
                          EXTRA_SIZE, flags, vfsFlags, pageReinit);
    if( rc==SQLITE_OK ){
      rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
    }
    if( rc!=SQLITE_OK ){
      goto btree_open_out;
    }
    pBt->db = db;
    sqlite3PagerSetBusyhandler(pBt->pPager, btreeInvokeBusyHandler, pBt);
    p->pBt = pBt;
  
    sqlite3PagerSetReiniter(pBt->pPager, pageReinit);
    pBt->pCursor = 0;
    pBt->pPage1 = 0;
    pBt->readOnly = sqlite3PagerIsreadonly(pBt->pPager);
    pBt->pageSize = get2byte(&zDbHeader[16]);
    if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE
         || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){
      pBt->pageSize = 0;
1980
1981
1982
1983
1984
1985
1986


1987

1988
1989
1990
1991
1992
1993
1994
2213
2214
2215
2216
2217
2218
2219
2220
2221

2222
2223
2224
2225
2226
2227
2228
2229







+
+
-
+







static int lockBtree(BtShared *pBt){
  int rc;
  MemPage *pPage1;
  int nPage;

  assert( sqlite3_mutex_held(pBt->mutex) );
  assert( pBt->pPage1==0 );
  rc = sqlite3PagerSharedLock(pBt->pPager);
  if( rc!=SQLITE_OK ) return rc;
  rc = sqlite3BtreeGetPage(pBt, 1, &pPage1, 0);
  rc = btreeGetPage(pBt, 1, &pPage1, 0);
  if( rc!=SQLITE_OK ) return rc;

  /* Do some checking to help insure the file we opened really is
  ** a valid database file. 
  */
  rc = sqlite3PagerPagecount(pBt->pPager, &nPage);
  if( rc!=SQLITE_OK ){
2033
2034
2035
2036
2037
2038
2039
2040
2041

2042
2043
2044
2045
2046
2047
2048
2268
2269
2270
2271
2272
2273
2274


2275
2276
2277
2278
2279
2280
2281
2282







-
-
+







      */
      releasePage(pPage1);
      pBt->usableSize = (u16)usableSize;
      pBt->pageSize = (u16)pageSize;
      freeTempSpace(pBt);
      rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize,
                                   pageSize-usableSize);
      if( rc ) goto page1_init_failed;
      return SQLITE_OK;
      return rc;
    }
    if( usableSize<480 ){
      goto page1_init_failed;
    }
    pBt->pageSize = (u16)pageSize;
    pBt->usableSize = (u16)usableSize;
#ifndef SQLITE_OMIT_AUTOVACUUM
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115

2116

2117
2118
2119
2120
2121
2122
2123
2124
2125

2126
2127


2128
2129
2130
2131
2132
2133
2134
2135



2136
2137

2138
2139
2140
2141
2142
2143
2144
2308
2309
2310
2311
2312
2313
2314























2315
2316
2317
2318
2319
2320


2321
2322
2323
2324
2325

2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336


2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350

2351
2352
2353
2354
2355
2356
2357
2358







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-






-
-




+
-
+









+
-
-
+
+








+
+
+

-
+








page1_init_failed:
  releasePage(pPage1);
  pBt->pPage1 = 0;
  return rc;
}

/*
** This routine works like lockBtree() except that it also invokes the
** busy callback if there is lock contention.
*/
static int lockBtreeWithRetry(Btree *pRef){
  int rc = SQLITE_OK;

  assert( sqlite3BtreeHoldsMutex(pRef) );
  if( pRef->inTrans==TRANS_NONE ){
    u8 inTransaction = pRef->pBt->inTransaction;
    btreeIntegrity(pRef);
    rc = sqlite3BtreeBeginTrans(pRef, 0);
    pRef->pBt->inTransaction = inTransaction;
    pRef->inTrans = TRANS_NONE;
    if( rc==SQLITE_OK ){
      pRef->pBt->nTransaction--;
    }
    btreeIntegrity(pRef);
  }
  return rc;
}
       

/*
** If there are no outstanding cursors and we are not in the middle
** of a transaction but there is a read lock on the database, then
** this routine unrefs the first page of the database file which 
** has the effect of releasing the read lock.
**
** If there are any outstanding cursors, this routine is a no-op.
**
** If there is a transaction in progress, this routine is a no-op.
*/
static void unlockBtreeIfUnused(BtShared *pBt){
  assert( sqlite3_mutex_held(pBt->mutex) );
  assert( pBt->pCursor==0 || pBt->inTransaction>TRANS_NONE );
  if( pBt->inTransaction==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){
  if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){
    assert( pBt->pPage1->aData );
    assert( sqlite3PagerRefcount(pBt->pPager)==1 );
    assert( pBt->pPage1->aData );
    releasePage(pBt->pPage1);
    pBt->pPage1 = 0;
  }
}

/*
** If pBt points to an empty file then convert that empty file
** Create a new database by initializing the first page of the
** file.
** into a new empty database by initializing the first page of
** the database.
*/
static int newDatabase(BtShared *pBt){
  MemPage *pP1;
  unsigned char *data;
  int rc;
  int nPage;

  assert( sqlite3_mutex_held(pBt->mutex) );
  /* The database size has already been measured and cached, so failure
  ** is impossible here.  If the original size measurement failed, then
  ** processing aborts before entering this routine. */
  rc = sqlite3PagerPagecount(pBt->pPager, &nPage);
  if( rc!=SQLITE_OK || nPage>0 ){
  if( NEVER(rc!=SQLITE_OK) || nPage>0 ){
    return rc;
  }
  pP1 = pBt->pPage1;
  assert( pP1!=0 );
  data = pP1->aData;
  rc = sqlite3PagerWrite(pP1->pDbPage);
  if( rc ) return rc;
2240
2241
2242
2243
2244
2245
2246






2247
2248
2249
2250
2251
2252
2253
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473







+
+
+
+
+
+







  if( pBlock ){
    sqlite3ConnectionBlocked(p->db, pBlock);
    rc = SQLITE_LOCKED_SHAREDCACHE;
    goto trans_begun;
  }
#endif

  /* Any read-only or read-write transaction implies a read-lock on 
  ** page 1. So if some other shared-cache client already has a write-lock 
  ** on page 1, the transaction cannot be opened. */
  rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK);
  if( SQLITE_OK!=rc ) goto trans_begun;

  do {
    /* Call lockBtree() until either pBt->pPage1 is populated or
    ** lockBtree() returns something other than SQLITE_OK. lockBtree()
    ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
    ** reading page 1 it discovers that the page-size of the database 
    ** file is not pBt->pageSize. In this case lockBtree() will update
    ** pBt->pageSize to the page-size of the file on disk.
2270
2271
2272
2273
2274
2275
2276








2277
2278
2279
2280
2281
2282
2283
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511







+
+
+
+
+
+
+
+







    }
  }while( rc==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
          btreeInvokeBusyHandler(pBt) );

  if( rc==SQLITE_OK ){
    if( p->inTrans==TRANS_NONE ){
      pBt->nTransaction++;
#ifndef SQLITE_OMIT_SHARED_CACHE
      if( p->sharable ){
	assert( p->lock.pBtree==p && p->lock.iTable==1 );
        p->lock.eLock = READ_LOCK;
        p->lock.pNext = pBt->pLock;
        pBt->pLock = &p->lock;
      }
#endif
    }
    p->inTrans = (wrflag?TRANS_WRITE:TRANS_READ);
    if( p->inTrans>pBt->inTransaction ){
      pBt->inTransaction = p->inTrans;
    }
#ifndef SQLITE_OMIT_SHARED_CACHE
    if( wrflag ){
2315
2316
2317
2318
2319
2320
2321
2322

2323
2324
2325
2326
2327
2328
2329
2330
2331

2332
2333
2334
2335
2336
2337
2338

2339
2340
2341
2342
2343
2344
2345

2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357



2358
2359
2360
2361
2362
2363
2364
2543
2544
2545
2546
2547
2548
2549

2550
2551
2552
2553
2554
2555
2556
2557
2558

2559



2560
2561
2562

2563

2564
2565
2566
2567
2568

2569
2570
2571
2572
2573
2574
2575
2576
2577




2578
2579
2580
2581
2582
2583
2584
2585
2586
2587







-
+








-
+
-
-
-



-
+
-





-
+








-
-
-
-
+
+
+







  int nCell;                         /* Number of cells in page pPage */
  int rc;                            /* Return code */
  BtShared *pBt = pPage->pBt;
  u8 isInitOrig = pPage->isInit;
  Pgno pgno = pPage->pgno;

  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  rc = sqlite3BtreeInitPage(pPage);
  rc = btreeInitPage(pPage);
  if( rc!=SQLITE_OK ){
    goto set_child_ptrmaps_out;
  }
  nCell = pPage->nCell;

  for(i=0; i<nCell; i++){
    u8 *pCell = findCell(pPage, i);

    rc = ptrmapPutOvflPtr(pPage, pCell);
    ptrmapPutOvflPtr(pPage, pCell, &rc);
    if( rc!=SQLITE_OK ){
      goto set_child_ptrmaps_out;
    }

    if( !pPage->leaf ){
      Pgno childPgno = get4byte(pCell);
      rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno);
      ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc);
      if( rc!=SQLITE_OK ) goto set_child_ptrmaps_out;
    }
  }

  if( !pPage->leaf ){
    Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
    rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno);
    ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc);
  }

set_child_ptrmaps_out:
  pPage->isInit = isInitOrig;
  return rc;
}

/*
** Somewhere on pPage, which is guaranteed to be a btree page, not an overflow
** page, is a pointer to page iFrom. Modify this pointer so that it points to
** iTo. Parameter eType describes the type of pointer to be modified, as 
** follows:
** Somewhere on pPage is a pointer to page iFrom.  Modify this pointer so
** that it points to iTo. Parameter eType describes the type of pointer to
** be modified, as  follows:
**
** PTRMAP_BTREE:     pPage is a btree-page. The pointer points at a child 
**                   page of pPage.
**
** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow
**                   page pointed to by one of the cells on pPage.
**
2375
2376
2377
2378
2379
2380
2381
2382

2383
2384
2385
2386
2387
2388
2389

2390
2391
2392
2393
2394
2395
2396
2598
2599
2600
2601
2602
2603
2604

2605
2606
2607
2608
2609
2610
2611

2612
2613
2614
2615
2616
2617
2618
2619







-
+






-
+







    }
    put4byte(pPage->aData, iTo);
  }else{
    u8 isInitOrig = pPage->isInit;
    int i;
    int nCell;

    sqlite3BtreeInitPage(pPage);
    btreeInitPage(pPage);
    nCell = pPage->nCell;

    for(i=0; i<nCell; i++){
      u8 *pCell = findCell(pPage, i);
      if( eType==PTRMAP_OVERFLOW1 ){
        CellInfo info;
        sqlite3BtreeParseCellPtr(pPage, pCell, &info);
        btreeParseCellPtr(pPage, pCell, &info);
        if( info.iOverflow ){
          if( iFrom==get4byte(&pCell[info.iOverflow]) ){
            put4byte(&pCell[info.iOverflow], iTo);
            break;
          }
        }
      }else{
2414
2415
2416
2417
2418
2419
2420





2421
2422
2423
2424
2425
2426
2427
2428

2429
2430
2431
2432
2433
2434
2435
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655

2656
2657
2658
2659
2660
2661
2662
2663







+
+
+
+
+







-
+







  return SQLITE_OK;
}


/*
** Move the open database page pDbPage to location iFreePage in the 
** database. The pDbPage reference remains valid.
**
** The isCommit flag indicates that there is no need to remember that
** the journal needs to be sync()ed before database page pDbPage->pgno 
** can be written to. The caller has already promised not to write to that
** page.
*/
static int relocatePage(
  BtShared *pBt,           /* Btree */
  MemPage *pDbPage,        /* Open page to move */
  u8 eType,                /* Pointer map 'type' entry for pDbPage */
  Pgno iPtrPage,           /* Pointer map 'page-no' entry for pDbPage */
  Pgno iFreePage,          /* The location to move pDbPage to */
  int isCommit
  int isCommit             /* isCommit flag passed to sqlite3PagerMovepage */
){
  MemPage *pPtrPage;   /* The page that contains a pointer to pDbPage */
  Pgno iDbPage = pDbPage->pgno;
  Pager *pPager = pBt->pPager;
  int rc;

  assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 || 
2458
2459
2460
2461
2462
2463
2464
2465

2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477

2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489

2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507

2508
2509
2510
2511




2512
2513
2514
2515
2516
2517
2518
2686
2687
2688
2689
2690
2691
2692

2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704

2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716

2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734

2735
2736
2737
2738

2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749







-
+











-
+











-
+

















-
+



-
+
+
+
+







    rc = setChildPtrmaps(pDbPage);
    if( rc!=SQLITE_OK ){
      return rc;
    }
  }else{
    Pgno nextOvfl = get4byte(pDbPage->aData);
    if( nextOvfl!=0 ){
      rc = ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage);
      ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage, &rc);
      if( rc!=SQLITE_OK ){
        return rc;
      }
    }
  }

  /* Fix the database pointer on page iPtrPage that pointed at iDbPage so
  ** that it points at iFreePage. Also fix the pointer map entry for
  ** iPtrPage.
  */
  if( eType!=PTRMAP_ROOTPAGE ){
    rc = sqlite3BtreeGetPage(pBt, iPtrPage, &pPtrPage, 0);
    rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0);
    if( rc!=SQLITE_OK ){
      return rc;
    }
    rc = sqlite3PagerWrite(pPtrPage->pDbPage);
    if( rc!=SQLITE_OK ){
      releasePage(pPtrPage);
      return rc;
    }
    rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType);
    releasePage(pPtrPage);
    if( rc==SQLITE_OK ){
      rc = ptrmapPut(pBt, iFreePage, eType, iPtrPage);
      ptrmapPut(pBt, iFreePage, eType, iPtrPage, &rc);
    }
  }
  return rc;
}

/* Forward declaration required by incrVacuumStep(). */
static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);

/*
** Perform a single step of an incremental-vacuum. If successful,
** return SQLITE_OK. If there is no work to do (and therefore no
** point in calling this function again), return SQLITE_DONE.
**
** More specificly, this function attempts to re-organize the 
** database so that the last page of the file currently in use
** is no longer in use.
**
** If the nFin parameter is non-zero, the implementation assumes
** If the nFin parameter is non-zero, this function assumes
** that the caller will keep calling incrVacuumStep() until
** it returns SQLITE_DONE or an error, and that nFin is the
** number of pages the database file will contain after this 
** process is complete.
** process is complete.  If nFin is zero, it is assumed that
** incrVacuumStep() will be called a finite amount of times
** which may or may not empty the freelist.  A full autovacuum
** has nFin>0.  A "PRAGMA incremental_vacuum" has nFin==0.
*/
static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
  Pgno nFreeList;           /* Number of pages still on the free-list */

  assert( sqlite3_mutex_held(pBt->mutex) );
  assert( iLastPg>nFin );

2550
2551
2552
2553
2554
2555
2556
2557

2558
2559
2560
2561
2562
2563
2564
2781
2782
2783
2784
2785
2786
2787

2788
2789
2790
2791
2792
2793
2794
2795







-
+







        assert( iFreePg==iLastPg );
        releasePage(pFreePg);
      }
    } else {
      Pgno iFreePg;             /* Index of free page to move pLastPg to */
      MemPage *pLastPg;

      rc = sqlite3BtreeGetPage(pBt, iLastPg, &pLastPg, 0);
      rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0);
      if( rc!=SQLITE_OK ){
        return rc;
      }

      /* If nFin is zero, this loop runs exactly once and page pLastPg
      ** is swapped with the first free page pulled off the free list.
      **
2589
2590
2591
2592
2593
2594
2595
2596

2597
2598
2599
2600
2601
2602
2603
2820
2821
2822
2823
2824
2825
2826

2827
2828
2829
2830
2831
2832
2833
2834







-
+







  }

  if( nFin==0 ){
    iLastPg--;
    while( iLastPg==PENDING_BYTE_PAGE(pBt)||PTRMAP_ISPAGE(pBt, iLastPg) ){
      if( PTRMAP_ISPAGE(pBt, iLastPg) ){
        MemPage *pPg;
        int rc = sqlite3BtreeGetPage(pBt, iLastPg, &pPg, 0);
        int rc = btreeGetPage(pBt, iLastPg, &pPg, 0);
        if( rc!=SQLITE_OK ){
          return rc;
        }
        rc = sqlite3PagerWrite(pPg->pDbPage);
        releasePage(pPg);
        if( rc!=SQLITE_OK ){
          return rc;
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660






2661

2662
2663
2664
2665
2666
2667
2668
2669
2670

2671

2672
2673
2674
2675
2676
2677
2678
2879
2880
2881
2882
2883
2884
2885






2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903

2904
2905
2906
2907
2908
2909
2910
2911







-
-
-
-
-
-
+
+
+
+
+
+

+









+
-
+







  Pager *pPager = pBt->pPager;
  VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager) );

  assert( sqlite3_mutex_held(pBt->mutex) );
  invalidateAllOverflowCache(pBt);
  assert(pBt->autoVacuum);
  if( !pBt->incrVacuum ){
    Pgno nFin;
    Pgno nFree;
    Pgno nPtrmap;
    Pgno iFree;
    const int pgsz = pBt->pageSize;
    Pgno nOrig = pagerPagecount(pBt);
    Pgno nFin;         /* Number of pages in database after autovacuuming */
    Pgno nFree;        /* Number of pages on the freelist initially */
    Pgno nPtrmap;      /* Number of PtrMap pages to be freed */
    Pgno iFree;        /* The next page to be freed */
    int nEntry;        /* Number of entries on one ptrmap page */
    Pgno nOrig;        /* Database size before freeing */

    nOrig = pagerPagecount(pBt);
    if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){
      /* It is not possible to create a database for which the final page
      ** is either a pointer-map page or the pending-byte page. If one
      ** is encountered, this indicates corruption.
      */
      return SQLITE_CORRUPT_BKPT;
    }

    nFree = get4byte(&pBt->pPage1->aData[36]);
    nEntry = pBt->usableSize/5;
    nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+pgsz/5)/(pgsz/5);
    nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+nEntry)/nEntry;
    nFin = nOrig - nFree - nPtrmap;
    if( nOrig>PENDING_BYTE_PAGE(pBt) && nFin<PENDING_BYTE_PAGE(pBt) ){
      nFin--;
    }
    while( PTRMAP_ISPAGE(pBt, nFin) || nFin==PENDING_BYTE_PAGE(pBt) ){
      nFin--;
    }
2742
2743
2744
2745
2746
2747
2748





































2749
2750
2751
2752
2753
2754
2755
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    }
#endif
    rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, 0);
    sqlite3BtreeLeave(p);
  }
  return rc;
}

/*
** This function is called from both BtreeCommitPhaseTwo() and BtreeRollback()
** at the conclusion of a transaction.
*/
static void btreeEndTransaction(Btree *p){
  BtShared *pBt = p->pBt;
  assert( sqlite3BtreeHoldsMutex(p) );

  btreeClearHasContent(pBt);
  if( p->inTrans>TRANS_NONE && p->db->activeVdbeCnt>1 ){
    /* If there are other active statements that belong to this database
    ** handle, downgrade to a read-only transaction. The other statements
    ** may still be reading from the database.  */
    downgradeAllSharedCacheTableLocks(p);
    p->inTrans = TRANS_READ;
  }else{
    /* If the handle had any kind of transaction open, decrement the 
    ** transaction count of the shared btree. If the transaction count 
    ** reaches 0, set the shared state to TRANS_NONE. The unlockBtreeIfUnused()
    ** call below will unlock the pager.  */
    if( p->inTrans!=TRANS_NONE ){
      clearAllSharedCacheTableLocks(p);
      pBt->nTransaction--;
      if( 0==pBt->nTransaction ){
        pBt->inTransaction = TRANS_NONE;
      }
    }

    /* Set the current transaction state to TRANS_NONE and unlock the 
    ** pager if this call closed the only read or write transaction.  */
    p->inTrans = TRANS_NONE;
    unlockBtreeIfUnused(pBt);
  }

  btreeIntegrity(p);
}

/*
** Commit the transaction currently in progress.
**
** This routine implements the second phase of a 2-phase commit.  The
** sqlite3BtreeCommitPhaseOne() routine does the first phase and should
** be invoked prior to calling this routine.  The sqlite3BtreeCommitPhaseOne()
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793

2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
3049
3050
3051
3052
3053
3054
3055








3056













3057
3058
3059
3060
3061
3062
3063







-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-







    if( rc!=SQLITE_OK ){
      sqlite3BtreeLeave(p);
      return rc;
    }
    pBt->inTransaction = TRANS_READ;
  }

  /* If the handle has any kind of transaction open, decrement the transaction
  ** count of the shared btree. If the transaction count reaches 0, set
  ** the shared state to TRANS_NONE. The unlockBtreeIfUnused() call below
  ** will unlock the pager.
  */
  if( p->inTrans!=TRANS_NONE ){
    clearAllSharedCacheTableLocks(p);
    pBt->nTransaction--;
  btreeEndTransaction(p);
    if( 0==pBt->nTransaction ){
      pBt->inTransaction = TRANS_NONE;
    }
  }

  /* Set the current transaction state to TRANS_NONE and unlock
  ** the pager if this call closed the only read or write transaction.
  */
  btreeClearHasContent(pBt);
  p->inTrans = TRANS_NONE;
  unlockBtreeIfUnused(pBt);

  btreeIntegrity(p);
  sqlite3BtreeLeave(p);
  return SQLITE_OK;
}

/*
** Do both phases of a commit.
*/
2863
2864
2865
2866
2867
2868
2869
2870

2871
2872
2873
2874
2875
2876
2877
3113
3114
3115
3116
3117
3118
3119

3120
3121
3122
3123
3124
3125
3126
3127







-
+







void sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode){
  BtCursor *p;
  sqlite3BtreeEnter(pBtree);
  for(p=pBtree->pBt->pCursor; p; p=p->pNext){
    int i;
    sqlite3BtreeClearCursor(p);
    p->eState = CURSOR_FAULT;
    p->skip = errCode;
    p->skipNext = errCode;
    for(i=0; i<=p->iPage; i++){
      releasePage(p->apPage[i]);
      p->apPage[i] = 0;
    }
  }
  sqlite3BtreeLeave(pBtree);
}
2912
2913
2914
2915
2916
2917
2918
2919

2920
2921

2922
2923
2924
2925
2926
2927
2928
2929
2930
2931

2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
3162
3163
3164
3165
3166
3167
3168

3169
3170

3171
3172
3173
3174
3175
3176
3177




3178










3179
3180
3181
3182
3183
3184
3185







-
+

-
+






-
-
-
-
+
-
-
-
-
-
-
-
-
-
-







    assert( TRANS_WRITE==pBt->inTransaction );
    rc2 = sqlite3PagerRollback(pBt->pPager);
    if( rc2!=SQLITE_OK ){
      rc = rc2;
    }

    /* The rollback may have destroyed the pPage1->aData value.  So
    ** call sqlite3BtreeGetPage() on page 1 again to make
    ** call btreeGetPage() on page 1 again to make
    ** sure pPage1->aData is set correctly. */
    if( sqlite3BtreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
    if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
      releasePage(pPage1);
    }
    assert( countWriteCursors(pBt)==0 );
    pBt->inTransaction = TRANS_READ;
  }

  if( p->inTrans!=TRANS_NONE ){
    clearAllSharedCacheTableLocks(p);
    assert( pBt->nTransaction>0 );
    pBt->nTransaction--;
  btreeEndTransaction(p);
    if( 0==pBt->nTransaction ){
      pBt->inTransaction = TRANS_NONE;
    }
  }

  btreeClearHasContent(pBt);
  p->inTrans = TRANS_NONE;
  unlockBtreeIfUnused(pBt);

  btreeIntegrity(p);
  sqlite3BtreeLeave(p);
  return rc;
}

/*
** Start a statement subtransaction. The subtransaction can can be rolled
** back independently of the main transaction. You must start a transaction 
3010
3011
3012
3013
3014
3015
3016
3017
3018




3019
3020
3021
3022
3023
3024
3025
3247
3248
3249
3250
3251
3252
3253


3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264







-
-
+
+
+
+







    sqlite3BtreeLeave(p);
  }
  return rc;
}

/*
** Create a new cursor for the BTree whose root is on the page
** iTable.  The act of acquiring a cursor gets a read lock on 
** the database file.
** iTable. If a read-only cursor is requested, it is assumed that
** the caller already has at least a read-only transaction open
** on the database already. If a write-cursor is requested, then
** the caller is assumed to have an open write transaction.
**
** If wrFlag==0, then the cursor can only be used for reading.
** If wrFlag==1, then the cursor can be used for reading or for
** writing if other conditions for writing are also met.  These
** are the conditions that must be met in order for writing to
** be allowed:
**
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054

3055
3056
3057
3058
3059
3060
3061
3062
3063







3064
3065
3066
3067

3068
3069
3070




3071
3072
3073
3074

3075
3076
3077
3078
3079


3080
3081
3082


3083
3084
3085
3086
3087
3088

3089
3090
3091

3092
3093


3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3284
3285
3286
3287
3288
3289
3290



3291
3292
3293
3294






3295
3296
3297
3298
3299
3300
3301




3302



3303
3304
3305
3306




3307





3308
3309
3310


3311
3312

3313




3314

3315

3316


3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329

3330





3331
3332
3333
3334
3335
3336
3337







-
-
-
+



-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
+
-
-
-
+
+
+
+
-
-
-
-
+
-
-
-
-
-
+
+

-
-
+
+
-

-
-
-
-
+
-

-
+
-
-
+
+











-

-
-
-
-
-







static int btreeCursor(
  Btree *p,                              /* The btree */
  int iTable,                            /* Root page of table to open */
  int wrFlag,                            /* 1 to write. 0 read-only */
  struct KeyInfo *pKeyInfo,              /* First arg to comparison function */
  BtCursor *pCur                         /* Space for new cursor */
){
  int rc;
  Pgno nPage;
  BtShared *pBt = p->pBt;
  BtShared *pBt = p->pBt;                /* Shared b-tree handle */

  assert( sqlite3BtreeHoldsMutex(p) );
  assert( wrFlag==0 || wrFlag==1 );
  if( wrFlag ){
    assert( !pBt->readOnly );
    if( NEVER(pBt->readOnly) ){
      return SQLITE_READONLY;
    }
    rc = checkForReadConflicts(p, iTable, 0, 0);

  /* The following assert statements verify that if this is a sharable 
  ** b-tree database, the connection is holding the required table locks, 
  ** and that no other connection has any open cursor that conflicts with 
  ** this lock.  */
  assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, wrFlag+1) );
  assert( wrFlag==0 || !hasReadConflicts(p, iTable) );
    if( rc!=SQLITE_OK ){
      assert( rc==SQLITE_LOCKED_SHAREDCACHE );
      return rc;
    }

  }

  if( pBt->pPage1==0 ){
  /* Assert that the caller has opened the required transaction. */
  assert( p->inTrans>TRANS_NONE );
  assert( wrFlag==0 || p->inTrans==TRANS_WRITE );
  assert( pBt->pPage1 && pBt->pPage1->aData );
    rc = lockBtreeWithRetry(p);
    if( rc!=SQLITE_OK ){
      return rc;
    }

  }
  pCur->pgnoRoot = (Pgno)iTable;
  rc = sqlite3PagerPagecount(pBt->pPager, (int *)&nPage); 
  if( rc!=SQLITE_OK ){
    return rc;
  if( NEVER(wrFlag && pBt->readOnly) ){
    return SQLITE_READONLY;
  }
  if( iTable==1 && nPage==0 ){
    rc = SQLITE_EMPTY;
  if( iTable==1 && pagerPagecount(pBt)==0 ){
    return SQLITE_EMPTY;
    goto create_cursor_exception;
  }
  rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0]);
  if( rc!=SQLITE_OK ){
    goto create_cursor_exception;
  }


  /* Now that no other errors can occur, finish filling in the BtCursor
  ** variables, link the cursor into the BtShared list and set *ppCur (the
  ** variables and link the cursor into the BtShared list.  */
  ** output argument to this function).
  */
  pCur->pgnoRoot = (Pgno)iTable;
  pCur->iPage = -1;
  pCur->pKeyInfo = pKeyInfo;
  pCur->pBtree = p;
  pCur->pBt = pBt;
  pCur->wrFlag = (u8)wrFlag;
  pCur->pNext = pBt->pCursor;
  if( pCur->pNext ){
    pCur->pNext->pPrev = pCur;
  }
  pBt->pCursor = pCur;
  pCur->eState = CURSOR_INVALID;
  pCur->cachedRowid = 0;

  return SQLITE_OK;

create_cursor_exception:
  releasePage(pCur->apPage[0]);
  unlockBtreeIfUnused(pBt);
  return rc;
}
int sqlite3BtreeCursor(
  Btree *p,                                   /* The btree */
  int iTable,                                 /* Root page of table to open */
  int wrFlag,                                 /* 1 to write. 0 read-only */
  struct KeyInfo *pKeyInfo,                   /* First arg to xCompare() */
  BtCursor *pCur                              /* Write new cursor here */
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235

3236
3237
3238

3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252

3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263

3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274

3275
3276
3277
3278
3279











3280
3281
3282
3283
3284
3285
3286
3287




3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301







3302
3303

3304
3305
3306
3307
3308
3309







3310
3311


3312
3313
3314
3315
3316
3317
3318
3319

3320
3321
3322
3323
3324
3325


3326
3327
3328

3329
3330
3331
3332
3333
3334
3335
3411
3412
3413
3414
3415
3416
3417

3418
































3419
3420

3421
3422
3423

3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437

3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448

3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459

3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490


3491









3492
3493
3494
3495
3496
3497
3498


3499
3500
3501
3502
3503


3504
3505
3506
3507
3508
3509
3510


3511
3512
3513
3514


3515



3516






3517
3518



3519
3520
3521
3522
3523
3524
3525
3526







-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


-
+


-
+













-
+










-
+










-
+





+
+
+
+
+
+
+
+
+
+
+








+
+
+
+


-
-

-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+




-
-
+
+
+
+
+
+
+
-
-
+
+


-
-

-
-
-
+
-
-
-
-
-
-
+
+
-
-
-
+







    invalidateOverflowCache(pCur);
    /* sqlite3_free(pCur); */
    sqlite3BtreeLeave(pBtree);
  }
  return SQLITE_OK;
}

#ifdef SQLITE_TEST
/*
** Make a temporary cursor by filling in the fields of pTempCur.
** The temporary cursor is not on the cursor list for the Btree.
*/
void sqlite3BtreeGetTempCursor(BtCursor *pCur, BtCursor *pTempCur){
  int i;
  assert( cursorHoldsMutex(pCur) );
  memcpy(pTempCur, pCur, sizeof(BtCursor));
  pTempCur->pNext = 0;
  pTempCur->pPrev = 0;
  for(i=0; i<=pTempCur->iPage; i++){
    sqlite3PagerRef(pTempCur->apPage[i]->pDbPage);
  }
  assert( pTempCur->pKey==0 );
}
#endif /* SQLITE_TEST */

#ifdef SQLITE_TEST
/*
** Delete a temporary cursor such as was made by the CreateTemporaryCursor()
** function above.
*/
void sqlite3BtreeReleaseTempCursor(BtCursor *pCur){
  int i;
  assert( cursorHoldsMutex(pCur) );
  for(i=0; i<=pCur->iPage; i++){
    sqlite3PagerUnref(pCur->apPage[i]->pDbPage);
  }
  sqlite3_free(pCur->pKey);
}
#endif /* SQLITE_TEST */

/*
** Make sure the BtCursor* given in the argument has a valid
** BtCursor.info structure.  If it is not already valid, call
** sqlite3BtreeParseCell() to fill it in.
** btreeParseCell() to fill it in.
**
** BtCursor.info is a cache of the information in the current cell.
** Using this cache reduces the number of calls to sqlite3BtreeParseCell().
** Using this cache reduces the number of calls to btreeParseCell().
**
** 2007-06-25:  There is a bug in some versions of MSVC that cause the
** compiler to crash when getCellInfo() is implemented as a macro.
** But there is a measureable speed advantage to using the macro on gcc
** (when less compiler optimizations like -Os or -O0 are used and the
** compiler is not doing agressive inlining.)  So we use a real function
** for MSVC and a macro for everything else.  Ticket #2457.
*/
#ifndef NDEBUG
  static void assertCellInfo(BtCursor *pCur){
    CellInfo info;
    int iPage = pCur->iPage;
    memset(&info, 0, sizeof(info));
    sqlite3BtreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info);
    btreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info);
    assert( memcmp(&info, &pCur->info, sizeof(info))==0 );
  }
#else
  #define assertCellInfo(x)
#endif
#ifdef _MSC_VER
  /* Use a real function in MSVC to work around bugs in that compiler. */
  static void getCellInfo(BtCursor *pCur){
    if( pCur->info.nSize==0 ){
      int iPage = pCur->iPage;
      sqlite3BtreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info);
      btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info);
      pCur->validNKey = 1;
    }else{
      assertCellInfo(pCur);
    }
  }
#else /* if not _MSC_VER */
  /* Use a macro in all other compilers so that the function is inlined */
#define getCellInfo(pCur)                                                      \
  if( pCur->info.nSize==0 ){                                                   \
    int iPage = pCur->iPage;                                                   \
    sqlite3BtreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); \
    btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); \
    pCur->validNKey = 1;                                                       \
  }else{                                                                       \
    assertCellInfo(pCur);                                                      \
  }
#endif /* _MSC_VER */

#ifndef NDEBUG  /* The next routine used only within assert() statements */
/*
** Return true if the given BtCursor is valid.  A valid cursor is one
** that is currently pointing to a row in a (non-empty) table.
** This is a verification routine is used only within assert() statements.
*/
int sqlite3BtreeCursorIsValid(BtCursor *pCur){
  return pCur && pCur->eState==CURSOR_VALID;
}
#endif /* NDEBUG */

/*
** Set *pSize to the size of the buffer needed to hold the value of
** the key for the current entry.  If the cursor is not pointing
** to a valid entry, *pSize is set to 0. 
**
** For a table with the INTKEY flag set, this routine returns the key
** itself, not the number of bytes in the key.
**
** The caller must position the cursor prior to invoking this routine.
** 
** This routine cannot fail.  It always returns SQLITE_OK.  
*/
int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
  int rc;

  assert( cursorHoldsMutex(pCur) );
  rc = restoreCursorPosition(pCur);
  if( rc==SQLITE_OK ){
    assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
    if( pCur->eState==CURSOR_INVALID ){
      *pSize = 0;
    }else{
      getCellInfo(pCur);
      *pSize = pCur->info.nKey;
    }
  assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
  if( pCur->eState!=CURSOR_VALID ){
    *pSize = 0;
  }else{
    getCellInfo(pCur);
    *pSize = pCur->info.nKey;
  }
  }
  return rc;
  return SQLITE_OK;
}

/*
** Set *pSize to the number of bytes of data in the entry the
** cursor currently points to.  Always return SQLITE_OK.
** Failure is not possible.  If the cursor is not currently
** cursor currently points to.
**
** The caller must guarantee that the cursor is pointing to a non-NULL
** valid entry.  In other words, the calling procedure must guarantee
** that the cursor has Cursor.eState==CURSOR_VALID.
**
** Failure is not possible.  This function always returns SQLITE_OK.
** pointing to an entry (which can happen, for example, if
** the database is empty) then *pSize is set to 0.
** It might just as well be a procedure (returning void) but we continue
** to return an integer result code for historical reasons.
*/
int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
  int rc;

  assert( cursorHoldsMutex(pCur) );
  rc = restoreCursorPosition(pCur);
  if( rc==SQLITE_OK ){
    assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
  assert( pCur->eState==CURSOR_VALID );
    if( pCur->eState==CURSOR_INVALID ){
      /* Not pointing at a valid entry - set *pSize to 0. */
      *pSize = 0;
    }else{
      getCellInfo(pCur);
      *pSize = pCur->info.nData;
  getCellInfo(pCur);
  *pSize = pCur->info.nData;
    }
  }
  return rc;
  return SQLITE_OK;
}

/*
** Given the page number of an overflow page in the database (parameter
** ovfl), this function finds the page number of the next page in the 
** linked list of overflow pages. If possible, it uses the auto-vacuum
** pointer-map data instead of reading the content of page ovfl to do so. 
3344
3345
3346
3347
3348
3349
3350
3351
3352


3353
3354
3355
3356
3357
3358
3359
3535
3536
3537
3538
3539
3540
3541


3542
3543
3544
3545
3546
3547
3548
3549
3550







-
-
+
+







** to page number pOvfl was obtained, then *ppPage is set to point to that
** reference. It is the responsibility of the caller to call releasePage()
** on *ppPage to free the reference. In no reference was obtained (because
** the pointer-map was used to obtain the value for *pPgnoNext), then
** *ppPage is set to zero.
*/
static int getOverflowPage(
  BtShared *pBt, 
  Pgno ovfl,                   /* Overflow page */
  BtShared *pBt,               /* The database file */
  Pgno ovfl,                   /* Current overflow page number */
  MemPage **ppPage,            /* OUT: MemPage handle (may be NULL) */
  Pgno *pPgnoNext              /* OUT: Next overflow page number */
){
  Pgno next = 0;
  MemPage *pPage = 0;
  int rc = SQLITE_OK;

3382
3383
3384
3385
3386
3387
3388

3389
3390
3391
3392



3393
3394
3395
3396
3397
3398
3399
3573
3574
3575
3576
3577
3578
3579
3580
3581



3582
3583
3584
3585
3586
3587
3588
3589
3590
3591







+

-
-
-
+
+
+







        next = iGuess;
        rc = SQLITE_DONE;
      }
    }
  }
#endif

  assert( next==0 || rc==SQLITE_DONE );
  if( rc==SQLITE_OK ){
    rc = sqlite3BtreeGetPage(pBt, ovfl, &pPage, 0);
    assert(rc==SQLITE_OK || pPage==0);
    if( next==0 && rc==SQLITE_OK ){
    rc = btreeGetPage(pBt, ovfl, &pPage, 0);
    assert( rc==SQLITE_OK || pPage==0 );
    if( rc==SQLITE_OK ){
      next = get4byte(pPage->aData);
    }
  }

  *pPgnoNext = next;
  if( ppPage ){
    *ppPage = pPage;
3441
3442
3443
3444
3445
3446
3447
3448

3449
3450

3451
3452
3453
3454
3455
3456
3457
3458
3633
3634
3635
3636
3637
3638
3639

3640


3641

3642
3643
3644
3645
3646
3647
3648







-
+
-
-
+
-







** parameter is 0, this is a read operation (data copied into
** buffer pBuf). If it is non-zero, a write (data copied from
** buffer pBuf).
**
** A total of "amt" bytes are read or written beginning at "offset".
** Data is read to or from the buffer pBuf.
**
** This routine does not make a distinction between key and data.
** The content being read or written might appear on the main page
** It just reads or writes bytes from the payload area.  Data might 
** appear on the main page or be scattered out on multiple overflow 
** or be scattered out on multiple overflow pages.
** pages.
**
** If the BtCursor.isIncrblobHandle flag is set, and the current
** cursor entry uses one or more overflow pages, this function
** allocates space for and lazily popluates the overflow page-list 
** cache array (BtCursor.aOverflow). Subsequent calls use this
** cache to make seeking to the supplied offset more efficient.
**
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495

3496
3497
3498
3499
3500
3501
3502
3656
3657
3658
3659
3660
3661
3662

3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680




3681
3682
3683
3684
3685
3686
3687
3688







-


















-
-
-
-
+







**   * Creating a table (may require moving an overflow page).
*/
static int accessPayload(
  BtCursor *pCur,      /* Cursor pointing to entry to read from */
  u32 offset,          /* Begin reading this far into payload */
  u32 amt,             /* Read this many bytes */
  unsigned char *pBuf, /* Write the bytes into this buffer */ 
  int skipKey,         /* offset begins at data if this is true */
  int eOp              /* zero to read. non-zero to write. */
){
  unsigned char *aPayload;
  int rc = SQLITE_OK;
  u32 nKey;
  int iIdx = 0;
  MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */
  BtShared *pBt = pCur->pBt;                  /* Btree this cursor belongs to */

  assert( pPage );
  assert( pCur->eState==CURSOR_VALID );
  assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
  assert( cursorHoldsMutex(pCur) );

  getCellInfo(pCur);
  aPayload = pCur->info.pCell + pCur->info.nHeader;
  nKey = (pPage->intKey ? 0 : (int)pCur->info.nKey);

  if( skipKey ){
    offset += nKey;
  }
  if( offset+amt > nKey+pCur->info.nData 
  if( NEVER(offset+amt > nKey+pCur->info.nData) 
   || &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
  ){
    /* Trying to read or write past the end of the data is an error */
    return SQLITE_CORRUPT_BKPT;
  }

  /* Check if data must be read/written to/from the btree page itself. */
3526
3527
3528
3529
3530
3531
3532


3533

3534
3535
3536
3537
3538
3539
3540
3712
3713
3714
3715
3716
3717
3718
3719
3720

3721
3722
3723
3724
3725
3726
3727
3728







+
+
-
+







    ** page number of the first overflow page is stored in aOverflow[0],
    ** etc. A value of 0 in the aOverflow[] array means "not yet known"
    ** (the cache is lazily populated).
    */
    if( pCur->isIncrblobHandle && !pCur->aOverflow ){
      int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize;
      pCur->aOverflow = (Pgno *)sqlite3MallocZero(sizeof(Pgno)*nOvfl);
      /* nOvfl is always positive.  If it were zero, fetchPayload would have
      ** been used instead of this routine. */
      if( nOvfl && !pCur->aOverflow ){
      if( ALWAYS(nOvfl) && !pCur->aOverflow ){
        rc = SQLITE_NOMEM;
      }
    }

    /* If the overflow page-list cache has been allocated and the
    ** entry for the first required overflow page is valid, skip
    ** directly to it.
3599
3600
3601
3602
3603
3604
3605



3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618


3619
3620
3621
3622
3623


3624
3625
3626
3627
3628
3629
3630
3631
3632
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802


3803




3804
3805





3806
3807


3808
3809
3810
3811
3812
3813
3814







+
+
+






-
-

-
-
-
-
+
+
-
-
-
-
-
+
+
-
-







  return rc;
}

/*
** Read part of the key associated with cursor pCur.  Exactly
** "amt" bytes will be transfered into pBuf[].  The transfer
** begins at "offset".
**
** The caller must ensure that pCur is pointing to a valid row
** in the table.
**
** Return SQLITE_OK on success or an error code if anything goes
** wrong.  An error is returned if "offset+amt" is larger than
** the available payload.
*/
int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
  int rc;

  assert( cursorHoldsMutex(pCur) );
  rc = restoreCursorPosition(pCur);
  if( rc==SQLITE_OK ){
    assert( pCur->eState==CURSOR_VALID );
    assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] );
  assert( pCur->eState==CURSOR_VALID );
  assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] );
    if( pCur->apPage[0]->intKey ){
      return SQLITE_CORRUPT_BKPT;
    }
    assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
    rc = accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0, 0);
  assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
  return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
  }
  return rc;
}

/*
** Read part of the data associated with cursor pCur.  Exactly
** "amt" bytes will be transfered into pBuf[].  The transfer
** begins at "offset".
**
3645
3646
3647
3648
3649
3650
3651
3652

3653
3654
3655
3656
3657
3658
3659
3827
3828
3829
3830
3831
3832
3833

3834
3835
3836
3837
3838
3839
3840
3841







-
+








  assert( cursorHoldsMutex(pCur) );
  rc = restoreCursorPosition(pCur);
  if( rc==SQLITE_OK ){
    assert( pCur->eState==CURSOR_VALID );
    assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] );
    assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
    rc = accessPayload(pCur, offset, amt, pBuf, 1, 0);
    rc = accessPayload(pCur, offset, amt, pBuf, 0);
  }
  return rc;
}

/*
** Return a pointer to payload information from the entry that the 
** pCur cursor is pointing to.  The pointer is to the beginning of
3684
3685
3686
3687
3688
3689
3690


3691


3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704

3705
3706
3707
3708
3709
3710
3711
3712
3713
3866
3867
3868
3869
3870
3871
3872
3873
3874

3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888

3889


3890
3891
3892
3893
3894
3895
3896







+
+
-
+
+












-
+
-
-







  u32 nLocal;

  assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
  assert( pCur->eState==CURSOR_VALID );
  assert( cursorHoldsMutex(pCur) );
  pPage = pCur->apPage[pCur->iPage];
  assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
  if( NEVER(pCur->info.nSize==0) ){
    btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage],
  getCellInfo(pCur);
                   &pCur->info);
  }
  aPayload = pCur->info.pCell;
  aPayload += pCur->info.nHeader;
  if( pPage->intKey ){
    nKey = 0;
  }else{
    nKey = (int)pCur->info.nKey;
  }
  if( skipKey ){
    aPayload += nKey;
    nLocal = pCur->info.nLocal - nKey;
  }else{
    nLocal = pCur->info.nLocal;
    if( nLocal>nKey ){
    assert( nLocal<=nKey );
      nLocal = nKey;
    }
  }
  *pAmt = nLocal;
  return aPayload;
}


/*
3721
3722
3723
3724
3725
3726
3727

3728
3729
3730
3731


3732
3733

3734
3735

3736
3737
3738
3739


3740
3741

3742
3743
3744
3745
3746
3747





3748
3749
3750
3751
3752
3753
3754
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913


3914
3915
3916

3917
3918
3919
3920
3921
3922


3923
3924
3925

3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944







+


-
-
+
+

-
+


+


-
-
+
+

-
+






+
+
+
+
+







** Hence, a mutex on the BtShared should be held prior to calling
** this routine.
**
** These routines is used to get quick access to key and data
** in the common case where no overflow pages are used.
*/
const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){
  const void *p = 0;
  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  assert( cursorHoldsMutex(pCur) );
  if( pCur->eState==CURSOR_VALID ){
    return (const void*)fetchPayload(pCur, pAmt, 0);
  if( ALWAYS(pCur->eState==CURSOR_VALID) ){
    p = (const void*)fetchPayload(pCur, pAmt, 0);
  }
  return 0;
  return p;
}
const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){
  const void *p = 0;
  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  assert( cursorHoldsMutex(pCur) );
  if( pCur->eState==CURSOR_VALID ){
    return (const void*)fetchPayload(pCur, pAmt, 1);
  if( ALWAYS(pCur->eState==CURSOR_VALID) ){
    p = (const void*)fetchPayload(pCur, pAmt, 1);
  }
  return 0;
  return p;
}


/*
** Move the cursor down to a new child page.  The newPgno argument is the
** page number of the child page to move to.
**
** This function returns SQLITE_CORRUPT if the page-header flags field of
** the new child page does not match the flags field of the parent (i.e.
** if an intkey page appears to be the parent of a non-intkey page, or
** vice-versa).
*/
static int moveToChild(BtCursor *pCur, u32 newPgno){
  int rc;
  int i = pCur->iPage;
  MemPage *pNewPage;
  BtShared *pBt = pCur->pBt;

3762
3763
3764
3765
3766
3767
3768
3769

3770
3771
3772
3773
3774
3775
3776
3952
3953
3954
3955
3956
3957
3958

3959
3960
3961
3962
3963
3964
3965
3966







-
+







  if( rc ) return rc;
  pCur->apPage[i+1] = pNewPage;
  pCur->aiIdx[i+1] = 0;
  pCur->iPage++;

  pCur->info.nSize = 0;
  pCur->validNKey = 0;
  if( pNewPage->nCell<1 ){
  if( pNewPage->nCell<1 || pNewPage->intKey!=pCur->apPage[i]->intKey ){
    return SQLITE_CORRUPT_BKPT;
  }
  return SQLITE_OK;
}

#ifndef NDEBUG
/*
3796
3797
3798
3799
3800
3801
3802
3803

3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820



















3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833

3834

3835
3836
3837
3838
3839
3840
3841
3842
3843

3844
3845
3846
3847


3848
3849
3850

3851
3852

















3853
3854

3855

3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3986
3987
3988
3989
3990
3991
3992

3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009

4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042

4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054



4055
4056
4057
4058
4059
4060


4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080

4081
4082
4083
4084
4085
4086
4087
4088
4089

4090

4091
4092
4093
4094
4095
4096
4097







-
+
















-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+













+
-
+









+

-
-
-
+
+



+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
-
+








-

-







** Move the cursor up to the parent page.
**
** pCur->idx is set to the cell index that contains the pointer
** to the page we are coming from.  If we are coming from the
** right-most child page then pCur->idx is set to one more than
** the largest cell index.
*/
void sqlite3BtreeMoveToParent(BtCursor *pCur){
static void moveToParent(BtCursor *pCur){
  assert( cursorHoldsMutex(pCur) );
  assert( pCur->eState==CURSOR_VALID );
  assert( pCur->iPage>0 );
  assert( pCur->apPage[pCur->iPage] );
  assertParentIndex(
    pCur->apPage[pCur->iPage-1], 
    pCur->aiIdx[pCur->iPage-1], 
    pCur->apPage[pCur->iPage]->pgno
  );
  releasePage(pCur->apPage[pCur->iPage]);
  pCur->iPage--;
  pCur->info.nSize = 0;
  pCur->validNKey = 0;
}

/*
** Move the cursor to the root page
** Move the cursor to point to the root page of its b-tree structure.
**
** If the table has a virtual root page, then the cursor is moved to point
** to the virtual root page instead of the actual root page. A table has a
** virtual root page when the actual root page contains no cells and a 
** single child page. This can only happen with the table rooted at page 1.
**
** If the b-tree structure is empty, the cursor state is set to 
** CURSOR_INVALID. Otherwise, the cursor is set to point to the first
** cell located on the root (or virtual root) page and the cursor state
** is set to CURSOR_VALID.
**
** If this function returns successfully, it may be assumed that the
** page-header flags indicate that the [virtual] root-page is the expected 
** kind of b-tree page (i.e. if when opening the cursor the caller did not
** specify a KeyInfo structure the flags byte is set to 0x05 or 0x0D,
** indicating a table b-tree, or if the caller did specify a KeyInfo 
** structure the flags byte is set to 0x02 or 0x0A, indicating an index
** b-tree).
*/
static int moveToRoot(BtCursor *pCur){
  MemPage *pRoot;
  int rc = SQLITE_OK;
  Btree *p = pCur->pBtree;
  BtShared *pBt = p->pBt;

  assert( cursorHoldsMutex(pCur) );
  assert( CURSOR_INVALID < CURSOR_REQUIRESEEK );
  assert( CURSOR_VALID   < CURSOR_REQUIRESEEK );
  assert( CURSOR_FAULT   > CURSOR_REQUIRESEEK );
  if( pCur->eState>=CURSOR_REQUIRESEEK ){
    if( pCur->eState==CURSOR_FAULT ){
      assert( pCur->skipNext!=SQLITE_OK );
      return pCur->skip;
      return pCur->skipNext;
    }
    sqlite3BtreeClearCursor(pCur);
  }

  if( pCur->iPage>=0 ){
    int i;
    for(i=1; i<=pCur->iPage; i++){
      releasePage(pCur->apPage[i]);
    }
    pCur->iPage = 0;
  }else{
    if( 
      SQLITE_OK!=(rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0]))
    ){
    rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0]);
    if( rc!=SQLITE_OK ){
      pCur->eState = CURSOR_INVALID;
      return rc;
    }
    pCur->iPage = 0;
  }


    /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
    ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is
    ** NULL, the caller expects a table b-tree. If this is not the case,
    ** return an SQLITE_CORRUPT error.  */
    assert( pCur->apPage[0]->intKey==1 || pCur->apPage[0]->intKey==0 );
    if( (pCur->pKeyInfo==0)!=pCur->apPage[0]->intKey ){
      return SQLITE_CORRUPT_BKPT;
    }
  }

  /* Assert that the root page is of the correct type. This must be the
  ** case as the call to this function that loaded the root-page (either
  ** this call or a previous invocation) would have detected corruption 
  ** if the assumption were not true, and it is not possible for the flags 
  ** byte to have been modified while this cursor is holding a reference
  ** to the page.  */
  pRoot = pCur->apPage[0];
  assert( pRoot->pgno==pCur->pgnoRoot );
  assert( pRoot->isInit && (pCur->pKeyInfo==0)==pRoot->intKey );
  pCur->iPage = 0;

  pCur->aiIdx[0] = 0;
  pCur->info.nSize = 0;
  pCur->atLast = 0;
  pCur->validNKey = 0;

  if( pRoot->nCell==0 && !pRoot->leaf ){
    Pgno subpage;
    if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT;
    assert( pRoot->pgno==1 );
    subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]);
    assert( subpage>0 );
    pCur->eState = CURSOR_VALID;
    rc = moveToChild(pCur, subpage);
  }else{
    pCur->eState = ((pRoot->nCell>0)?CURSOR_VALID:CURSOR_INVALID);
  }
  return rc;
}
4023
4024
4025
4026
4027
4028
4029


4030
4031
4032
4033
4034
4035
4036
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262







+
+







  int biasRight,           /* If true, bias the search to the high end */
  int *pRes                /* Write search results here */
){
  int rc;

  assert( cursorHoldsMutex(pCur) );
  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  assert( pRes );
  assert( (pIdxKey==0)==(pCur->pKeyInfo==0) );

  /* If the cursor is already positioned at the point we are trying
  ** to move to, then just return without doing any work */
  if( pCur->eState==CURSOR_VALID && pCur->validNKey 
   && pCur->apPage[0]->intKey 
  ){
    if( pCur->info.nKey==intKey ){
4045
4046
4047
4048
4049
4050
4051

4052
4053
4054
4055
4056
4057
4058
4059
4060
4061

4062









4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289

4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300




4301
4302
4303
4304
4305
4306
4307







+










+
-
+
+
+
+
+
+
+
+
+


-
-
-
-








  rc = moveToRoot(pCur);
  if( rc ){
    return rc;
  }
  assert( pCur->apPage[pCur->iPage] );
  assert( pCur->apPage[pCur->iPage]->isInit );
  assert( pCur->apPage[pCur->iPage]->nCell>0 || pCur->eState==CURSOR_INVALID );
  if( pCur->eState==CURSOR_INVALID ){
    *pRes = -1;
    assert( pCur->apPage[pCur->iPage]->nCell==0 );
    return SQLITE_OK;
  }
  assert( pCur->apPage[0]->intKey || pIdxKey );
  for(;;){
    int lwr, upr;
    Pgno chldPg;
    MemPage *pPage = pCur->apPage[pCur->iPage];
    int c;
    int c = -1;  /* pRes return if table is empty must be -1 */

    /* pPage->nCell must be greater than zero. If this is the root-page
    ** the cursor would have been INVALID above and this for(;;) loop
    ** not run. If this is not the root-page, then the moveToChild() routine
    ** would have already detected db corruption. Similarly, pPage must
    ** be the right kind (index or table) of b-tree page. Otherwise
    ** a moveToChild() or moveToRoot() call would have detected corruption.  */
    assert( pPage->nCell>0 );
    assert( pPage->intKey==(pIdxKey==0) );
    lwr = 0;
    upr = pPage->nCell-1;
    if( (!pPage->intKey && pIdxKey==0) || upr<0 ){
      rc = SQLITE_CORRUPT_BKPT;
      goto moveto_finish;
    }
    if( biasRight ){
      pCur->aiIdx[pCur->iPage] = (u16)upr;
    }else{
      pCur->aiIdx[pCur->iPage] = (u16)((upr+lwr)/2);
    }
    for(;;){
      int idx = pCur->aiIdx[pCur->iPage]; /* Index of current cell in pPage */
4118
4119
4120
4121
4122
4123
4124
4125

4126
4127
4128
4129
4130
4131
4132





4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4350
4351
4352
4353
4354
4355
4356

4357
4358
4359
4360
4361
4362
4363

4364
4365
4366
4367
4368
4369
4370

4371
4372
4373
4374
4375
4376
4377







-
+






-
+
+
+
+
+


-







        }else{
          /* The record flows over onto one or more overflow pages. In
          ** this case the whole cell needs to be parsed, a buffer allocated
          ** and accessPayload() used to retrieve the record into the
          ** buffer before VdbeRecordCompare() can be called. */
          void *pCellKey;
          u8 * const pCellBody = pCell - pPage->childPtrSize;
          sqlite3BtreeParseCellPtr(pPage, pCellBody, &pCur->info);
          btreeParseCellPtr(pPage, pCellBody, &pCur->info);
          nCell = (int)pCur->info.nKey;
          pCellKey = sqlite3Malloc( nCell );
          if( pCellKey==0 ){
            rc = SQLITE_NOMEM;
            goto moveto_finish;
          }
          rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0, 0);
          rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
          if( rc ){
            sqlite3_free(pCellKey);
            goto moveto_finish;
          }
          c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey);
          sqlite3_free(pCellKey);
          if( rc ) goto moveto_finish;
        }
      }
      if( c==0 ){
        if( pPage->intKey && !pPage->leaf ){
          lwr = idx;
          upr = lwr - 1;
          break;
4163
4164
4165
4166
4167
4168
4169
4170

4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4398
4399
4400
4401
4402
4403
4404

4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
































4416
4417
4418
4419
4420
4421
4422







-
+










-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    }else if( lwr>=pPage->nCell ){
      chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
    }else{
      chldPg = get4byte(findCell(pPage, lwr));
    }
    if( chldPg==0 ){
      assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
      if( pRes ) *pRes = c;
      *pRes = c;
      rc = SQLITE_OK;
      goto moveto_finish;
    }
    pCur->aiIdx[pCur->iPage] = (u16)lwr;
    pCur->info.nSize = 0;
    pCur->validNKey = 0;
    rc = moveToChild(pCur, chldPg);
    if( rc ) goto moveto_finish;
  }
moveto_finish:
  return rc;
}

/*
** In this version of BtreeMoveto, pKey is a packed index record
** such as is generated by the OP_MakeRecord opcode.  Unpack the
** record and then call BtreeMovetoUnpacked() to do the work.
*/
int sqlite3BtreeMoveto(
  BtCursor *pCur,     /* Cursor open on the btree to be searched */
  const void *pKey,   /* Packed key if the btree is an index */
  i64 nKey,           /* Integer key for tables.  Size of pKey for indices */
  int bias,           /* Bias search to the high end */
  int *pRes           /* Write search results here */
){
  int rc;                    /* Status code */
  UnpackedRecord *pIdxKey;   /* Unpacked index key */
  char aSpace[150];          /* Temp space for pIdxKey - to avoid a malloc */


  if( pKey ){
    assert( nKey==(i64)(int)nKey );
    pIdxKey = sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey,
                                      aSpace, sizeof(aSpace));
    if( pIdxKey==0 ) return SQLITE_NOMEM;
  }else{
    pIdxKey = 0;
  }
  rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes);
  if( pKey ){
    sqlite3VdbeDeleteUnpackedRecord(pIdxKey);
  }
  return rc;
}


/*
** Return TRUE if the cursor is not pointing at an entry of the table.
**
4246
4247
4248
4249
4250
4251
4252
4253
4254


4255
4256
4257
4258

4259
4260
4261
4262
4263
4264
4265
4449
4450
4451
4452
4453
4454
4455


4456
4457
4458
4459
4460

4461
4462
4463
4464
4465
4466
4467
4468







-
-
+
+



-
+







    return rc;
  }
  assert( pRes!=0 );
  if( CURSOR_INVALID==pCur->eState ){
    *pRes = 1;
    return SQLITE_OK;
  }
  if( pCur->skip>0 ){
    pCur->skip = 0;
  if( pCur->skipNext>0 ){
    pCur->skipNext = 0;
    *pRes = 0;
    return SQLITE_OK;
  }
  pCur->skip = 0;
  pCur->skipNext = 0;

  pPage = pCur->apPage[pCur->iPage];
  idx = ++pCur->aiIdx[pCur->iPage];
  assert( pPage->isInit );
  assert( idx<=pPage->nCell );

  pCur->info.nSize = 0;
4274
4275
4276
4277
4278
4279
4280
4281

4282
4283
4284
4285
4286
4287
4288
4477
4478
4479
4480
4481
4482
4483

4484
4485
4486
4487
4488
4489
4490
4491







-
+







    }
    do{
      if( pCur->iPage==0 ){
        *pRes = 1;
        pCur->eState = CURSOR_INVALID;
        return SQLITE_OK;
      }
      sqlite3BtreeMoveToParent(pCur);
      moveToParent(pCur);
      pPage = pCur->apPage[pCur->iPage];
    }while( pCur->aiIdx[pCur->iPage]>=pPage->nCell );
    *pRes = 0;
    if( pPage->intKey ){
      rc = sqlite3BtreeNext(pCur, pRes);
    }else{
      rc = SQLITE_OK;
4314
4315
4316
4317
4318
4319
4320
4321
4322


4323
4324
4325
4326

4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344

4345
4346
4347
4348
4349
4350
4351
4517
4518
4519
4520
4521
4522
4523


4524
4525
4526
4527
4528

4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546

4547
4548
4549
4550
4551
4552
4553
4554







-
-
+
+



-
+

















-
+







    return rc;
  }
  pCur->atLast = 0;
  if( CURSOR_INVALID==pCur->eState ){
    *pRes = 1;
    return SQLITE_OK;
  }
  if( pCur->skip<0 ){
    pCur->skip = 0;
  if( pCur->skipNext<0 ){
    pCur->skipNext = 0;
    *pRes = 0;
    return SQLITE_OK;
  }
  pCur->skip = 0;
  pCur->skipNext = 0;

  pPage = pCur->apPage[pCur->iPage];
  assert( pPage->isInit );
  if( !pPage->leaf ){
    int idx = pCur->aiIdx[pCur->iPage];
    rc = moveToChild(pCur, get4byte(findCell(pPage, idx)));
    if( rc ){
      return rc;
    }
    rc = moveToRightmost(pCur);
  }else{
    while( pCur->aiIdx[pCur->iPage]==0 ){
      if( pCur->iPage==0 ){
        pCur->eState = CURSOR_INVALID;
        *pRes = 1;
        return SQLITE_OK;
      }
      sqlite3BtreeMoveToParent(pCur);
      moveToParent(pCur);
    }
    pCur->info.nSize = 0;
    pCur->validNKey = 0;

    pCur->aiIdx[pCur->iPage]--;
    pPage = pCur->apPage[pCur->iPage];
    if( pPage->intKey && !pPage->leaf ){
4394
4395
4396
4397
4398
4399
4400

4401

4402
4403
4404
4405
4406
4407
4408
4597
4598
4599
4600
4601
4602
4603
4604

4605
4606
4607
4608
4609
4610
4611
4612







+
-
+







  MemPage *pPrevTrunk = 0;
  Pgno mxPage;     /* Total size of the database file */

  assert( sqlite3_mutex_held(pBt->mutex) );
  pPage1 = pBt->pPage1;
  mxPage = pagerPagecount(pBt);
  n = get4byte(&pPage1->aData[36]);
  testcase( n==mxPage-1 );
  if( n>mxPage ){
  if( n>=mxPage ){
    return SQLITE_CORRUPT_BKPT;
  }
  if( n>0 ){
    /* There are pages on the freelist.  Reuse one of those pages. */
    Pgno iTrunk;
    u8 searchList = 0; /* If the free-list must be searched for 'nearby' */
    
4438
4439
4440
4441
4442
4443
4444

4445
4446
4447
4448

4449
4450
4451
4452
4453
4454
4455
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652

4653
4654
4655
4656
4657
4658
4659
4660







+



-
+







    do {
      pPrevTrunk = pTrunk;
      if( pPrevTrunk ){
        iTrunk = get4byte(&pPrevTrunk->aData[0]);
      }else{
        iTrunk = get4byte(&pPage1->aData[32]);
      }
      testcase( iTrunk==mxPage );
      if( iTrunk>mxPage ){
        rc = SQLITE_CORRUPT_BKPT;
      }else{
        rc = sqlite3BtreeGetPage(pBt, iTrunk, &pTrunk, 0);
        rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
      }
      if( rc ){
        pTrunk = 0;
        goto end_allocate_page;
      }

      k = get4byte(&pTrunk->aData[4]);
4496
4497
4498
4499
4500
4501
4502

4503

4504
4505
4506
4507
4508
4509
4510
4701
4702
4703
4704
4705
4706
4707
4708

4709
4710
4711
4712
4713
4714
4715
4716







+
-
+







          */
          MemPage *pNewTrunk;
          Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
          if( iNewTrunk>mxPage ){ 
            rc = SQLITE_CORRUPT_BKPT;
            goto end_allocate_page;
          }
          testcase( iNewTrunk==mxPage );
          rc = sqlite3BtreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
          rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
          if( rc!=SQLITE_OK ){
            goto end_allocate_page;
          }
          rc = sqlite3PagerWrite(pNewTrunk->pDbPage);
          if( rc!=SQLITE_OK ){
            releasePage(pNewTrunk);
            goto end_allocate_page;
4551
4552
4553
4554
4555
4556
4557

4558
4559
4560
4561

4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581

4582
4583
4584
4585
4586
4587
4588
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771

4772






4773
4774
4775
4776
4777
4778
4779
4780
4781

4782
4783
4784
4785
4786
4787
4788
4789







+




+


-

-
-
-
-
-
-









-
+







            }
          }
        }else{
          closest = 0;
        }

        iPage = get4byte(&aData[8+closest*4]);
        testcase( iPage==mxPage );
        if( iPage>mxPage ){
          rc = SQLITE_CORRUPT_BKPT;
          goto end_allocate_page;
        }
        testcase( iPage==mxPage );
        if( !searchList || iPage==nearby ){
          int noContent;
          Pgno nPage;
          *pPgno = iPage;
          nPage = pagerPagecount(pBt);
          if( iPage>nPage ){
            /* Free page off the end of the file */
            rc = SQLITE_CORRUPT_BKPT;
            goto end_allocate_page;
          }
          TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
                 ": %d more free pages\n",
                 *pPgno, closest+1, k, pTrunk->pgno, n-1));
          if( closest<k-1 ){
            memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
          }
          put4byte(&aData[4], k-1);
          assert( sqlite3PagerIswriteable(pTrunk->pDbPage) );
          noContent = !btreeGetHasContent(pBt, *pPgno);
          rc = sqlite3BtreeGetPage(pBt, *pPgno, ppPage, noContent);
          rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
          if( rc==SQLITE_OK ){
            rc = sqlite3PagerWrite((*ppPage)->pDbPage);
            if( rc!=SQLITE_OK ){
              releasePage(*ppPage);
            }
          }
          searchList = 0;
4606
4607
4608
4609
4610
4611
4612
4613

4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625

4626
4627
4628
4629
4630
4631
4632
4807
4808
4809
4810
4811
4812
4813

4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825

4826
4827
4828
4829
4830
4831
4832
4833







-
+











-
+







      /* If *pPgno refers to a pointer-map page, allocate two new pages
      ** at the end of the file instead of one. The first allocated page
      ** becomes a new pointer-map page, the second is used by the caller.
      */
      MemPage *pPg = 0;
      TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", *pPgno));
      assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
      rc = sqlite3BtreeGetPage(pBt, *pPgno, &pPg, 0);
      rc = btreeGetPage(pBt, *pPgno, &pPg, 0);
      if( rc==SQLITE_OK ){
        rc = sqlite3PagerWrite(pPg->pDbPage);
        releasePage(pPg);
      }
      if( rc ) return rc;
      (*pPgno)++;
      if( *pPgno==PENDING_BYTE_PAGE(pBt) ){ (*pPgno)++; }
    }
#endif

    assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
    rc = sqlite3BtreeGetPage(pBt, *pPgno, ppPage, 0);
    rc = btreeGetPage(pBt, *pPgno, ppPage, 0);
    if( rc ) return rc;
    rc = sqlite3PagerWrite((*ppPage)->pDbPage);
    if( rc!=SQLITE_OK ){
      releasePage(*ppPage);
    }
    TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
  }
4685
4686
4687
4688
4689
4690
4691
4692

4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704

4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716

4717
4718
4719

4720
4721
4722
4723
4724

4725

4726
4727
4728
4729

4730
4731
4732
4733
4734
4735
4736
4737
4738
4739

4740
4741
4742
4743
4744
4745
4746
4886
4887
4888
4889
4890
4891
4892

4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904

4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916

4917
4918
4919

4920
4921
4922
4923
4924
4925
4926

4927
4928
4929
4930

4931
4932
4933
4934
4935
4936
4937
4938
4939
4940

4941
4942
4943
4944
4945
4946
4947
4948







-
+











-
+











-
+


-
+





+
-
+



-
+









-
+







  nFree = get4byte(&pPage1->aData[36]);
  put4byte(&pPage1->aData[36], nFree+1);

#ifdef SQLITE_SECURE_DELETE
  /* If the SQLITE_SECURE_DELETE compile-time option is enabled, then
  ** always fully overwrite deleted information with zeros.
  */
  if( (!pPage && (rc = sqlite3BtreeGetPage(pBt, iPage, &pPage, 0)))
  if( (!pPage && (rc = btreeGetPage(pBt, iPage, &pPage, 0)))
   ||            (rc = sqlite3PagerWrite(pPage->pDbPage))
  ){
    goto freepage_out;
  }
  memset(pPage->aData, 0, pPage->pBt->pageSize);
#endif

  /* If the database supports auto-vacuum, write an entry in the pointer-map
  ** to indicate that the page is free.
  */
  if( ISAUTOVACUUM ){
    rc = ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0);
    ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0, &rc);
    if( rc ) goto freepage_out;
  }

  /* Now manipulate the actual database free-list structure. There are two
  ** possibilities. If the free-list is currently empty, or if the first
  ** trunk page in the free-list is full, then this page will become a
  ** new free-list trunk page. Otherwise, it will become a leaf of the
  ** first trunk page in the current free-list. This block tests if it
  ** is possible to add the page as a new free-list leaf.
  */
  if( nFree!=0 ){
    int nLeaf;                /* Initial number of leaf cells on trunk page */
    u32 nLeaf;                /* Initial number of leaf cells on trunk page */

    iTrunk = get4byte(&pPage1->aData[32]);
    rc = sqlite3BtreeGetPage(pBt, iTrunk, &pTrunk, 0);
    rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
    if( rc!=SQLITE_OK ){
      goto freepage_out;
    }

    nLeaf = get4byte(&pTrunk->aData[4]);
    assert( pBt->usableSize>32 );
    if( nLeaf<0 ){
    if( nLeaf > (u32)pBt->usableSize/4 - 2 ){
      rc = SQLITE_CORRUPT_BKPT;
      goto freepage_out;
    }
    if( nLeaf<pBt->usableSize/4 - 8 ){
    if( nLeaf < (u32)pBt->usableSize/4 - 8 ){
      /* In this case there is room on the trunk page to insert the page
      ** being freed as a new leaf.
      **
      ** Note that the trunk page is not really full until it contains
      ** usableSize/4 - 2 entries, not usableSize/4 - 8 entries as we have
      ** coded.  But due to a coding error in versions of SQLite prior to
      ** 3.6.0, databases with freelist trunk pages holding more than
      ** usableSize/4 - 8 entries will be reported as corrupt.  In order
      ** to maintain backwards compatibility with older versions of SQLite,
      ** we will contain to restrict the number of entries to usableSize/4 - 8
      ** we will continue to restrict the number of entries to usableSize/4 - 8
      ** for now.  At some point in the future (once everyone has upgraded
      ** to 3.6.0 or later) we should consider fixing the conditional above
      ** to read "usableSize/4-2" instead of "usableSize/4-8".
      */
      rc = sqlite3PagerWrite(pTrunk->pDbPage);
      if( rc==SQLITE_OK ){
        put4byte(&pTrunk->aData[4], nLeaf+1);
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768





4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785




4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800

4801
4802
4803
4804
4805
4806
4807
4961
4962
4963
4964
4965
4966
4967



4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987


4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005

5006
5007
5008
5009
5010
5011
5012
5013







-
-
-
+
+
+
+
+















-
-
+
+
+
+














-
+








  /* If control flows to this point, then it was not possible to add the
  ** the page being freed as a leaf page of the first trunk in the free-list.
  ** Possibly because the free-list is empty, or possibly because the 
  ** first trunk in the free-list is full. Either way, the page being freed
  ** will become the new first trunk page in the free-list.
  */
  if(   ((!pPage) && (0 != (rc = sqlite3BtreeGetPage(pBt, iPage, &pPage, 0))))
     || (0 != (rc = sqlite3PagerWrite(pPage->pDbPage)))
  ){
  if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){
    goto freepage_out;
  }
  rc = sqlite3PagerWrite(pPage->pDbPage);
  if( rc!=SQLITE_OK ){
    goto freepage_out;
  }
  put4byte(pPage->aData, iTrunk);
  put4byte(&pPage->aData[4], 0);
  put4byte(&pPage1->aData[32], iPage);
  TRACE(("FREE-PAGE: %d new trunk page replacing %d\n", pPage->pgno, iTrunk));

freepage_out:
  if( pPage ){
    pPage->isInit = 0;
  }
  releasePage(pPage);
  releasePage(pTrunk);
  return rc;
}
static int freePage(MemPage *pPage){
  return freePage2(pPage->pBt, pPage, pPage->pgno);
static void freePage(MemPage *pPage, int *pRC){
  if( (*pRC)==SQLITE_OK ){
    *pRC = freePage2(pPage->pBt, pPage, pPage->pgno);
  }
}

/*
** Free any overflow pages associated with the given Cell.
*/
static int clearCell(MemPage *pPage, unsigned char *pCell){
  BtShared *pBt = pPage->pBt;
  CellInfo info;
  Pgno ovflPgno;
  int rc;
  int nOvfl;
  u16 ovflPageSize;

  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  sqlite3BtreeParseCellPtr(pPage, pCell, &info);
  btreeParseCellPtr(pPage, pCell, &info);
  if( info.iOverflow==0 ){
    return SQLITE_OK;  /* No overflow pages. Return without doing anything */
  }
  ovflPgno = get4byte(&pCell[info.iOverflow]);
  assert( pBt->usableSize > 4 );
  ovflPageSize = pBt->usableSize - 4;
  nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
4876
4877
4878
4879
4880
4881
4882
4883

4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896


4897
4898
4899
4900
4901
4902
4903
5082
5083
5084
5085
5086
5087
5088

5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100


5101
5102
5103
5104
5105
5106
5107
5108
5109







-
+











-
-
+
+







  }
  if( pPage->hasData ){
    nHeader += putVarint(&pCell[nHeader], nData+nZero);
  }else{
    nData = nZero = 0;
  }
  nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey);
  sqlite3BtreeParseCellPtr(pPage, pCell, &info);
  btreeParseCellPtr(pPage, pCell, &info);
  assert( info.nHeader==nHeader );
  assert( info.nKey==nKey );
  assert( info.nData==(u32)(nData+nZero) );
  
  /* Fill in the payload */
  nPayload = nData + nZero;
  if( pPage->intKey ){
    pSrc = pData;
    nSrc = nData;
    nData = 0;
  }else{ 
    if( nKey>0x7fffffff || pKey==0 ){
      return SQLITE_CORRUPT;
    if( NEVER(nKey>0x7fffffff || pKey==0) ){
      return SQLITE_CORRUPT_BKPT;
    }
    nPayload += (int)nKey;
    pSrc = pKey;
    nSrc = (int)nKey;
  }
  *pnSize = info.nSize;
  spaceLeft = info.nLocal;
4926
4927
4928
4929
4930
4931
4932
4933

4934
4935
4936
4937
4938
4939
4940
5132
5133
5134
5135
5136
5137
5138

5139
5140
5141
5142
5143
5144
5145
5146







-
+







      ** to the pointer-map. If we write nothing to this pointer-map slot,
      ** then the optimistic overflow chain processing in clearCell()
      ** may misinterpret the uninitialised values and delete the
      ** wrong pages from the database.
      */
      if( pBt->autoVacuum && rc==SQLITE_OK ){
        u8 eType = (pgnoPtrmap?PTRMAP_OVERFLOW2:PTRMAP_OVERFLOW1);
        rc = ptrmapPut(pBt, pgnoOvfl, eType, pgnoPtrmap);
        ptrmapPut(pBt, pgnoOvfl, eType, pgnoPtrmap, &rc);
        if( rc ){
          releasePage(pOvfl);
        }
      }
#endif
      if( rc ){
        releasePage(pToRelease);
4995
4996
4997
4998
4999
5000
5001
5002

5003
5004
5005
5006
5007



5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018






5019
5020
5021
5022



5023
5024
5025
5026
5027
5028
5029

5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051

5052
5053
5054
5055
5056
5057


5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069


5070
5071
5072
5073
5074
5075
5076
5201
5202
5203
5204
5205
5206
5207

5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224



5225
5226
5227
5228
5229
5230
5231
5232


5233
5234
5235
5236
5237
5238
5239
5240
5241

5242
5243

5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262

5263
5264
5265
5266
5267
5268

5269
5270
5271
5272
5273

5274
5275

5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289







-
+





+
+
+








-
-
-
+
+
+
+
+
+


-
-
+
+
+






-
+

-



















-
+





-
+
+



-


-





+
+







** Remove the i-th cell from pPage.  This routine effects pPage only.
** The cell content is not freed or deallocated.  It is assumed that
** the cell content has been copied someplace else.  This routine just
** removes the reference to the cell from pPage.
**
** "sz" must be the number of bytes in the cell.
*/
static int dropCell(MemPage *pPage, int idx, int sz){
static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
  int i;          /* Loop counter */
  int pc;         /* Offset to cell content of cell being deleted */
  u8 *data;       /* pPage->aData */
  u8 *ptr;        /* Used to move bytes around within data[] */
  int rc;         /* The return code */
  int hdr;        /* Beginning of the header.  0 most pages.  100 page 1 */

  if( *pRC ) return;

  assert( idx>=0 && idx<pPage->nCell );
  assert( sz==cellSize(pPage, idx) );
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  data = pPage->aData;
  ptr = &data[pPage->cellOffset + 2*idx];
  pc = get2byte(ptr);
  if( (pc<pPage->hdrOffset+6+(pPage->leaf?0:4))
     || (pc+sz>pPage->pBt->usableSize) ){
    return SQLITE_CORRUPT_BKPT;
  hdr = pPage->hdrOffset;
  testcase( pc==get2byte(&data[hdr+5]) );
  testcase( pc+sz==pPage->pBt->usableSize );
  if( pc < get2byte(&data[hdr+5]) || pc+sz > pPage->pBt->usableSize ){
    *pRC = SQLITE_CORRUPT_BKPT;
    return;
  }
  rc = freeSpace(pPage, pc, sz);
  if( rc!=SQLITE_OK ){
    return rc;
  if( rc ){
    *pRC = rc;
    return;
  }
  for(i=idx+1; i<pPage->nCell; i++, ptr+=2){
    ptr[0] = ptr[2];
    ptr[1] = ptr[3];
  }
  pPage->nCell--;
  put2byte(&data[pPage->hdrOffset+3], pPage->nCell);
  put2byte(&data[hdr+3], pPage->nCell);
  pPage->nFree += 2;
  return SQLITE_OK;
}

/*
** Insert a new cell on pPage at cell index "i".  pCell points to the
** content of the cell.
**
** If the cell content will fit on the page, then put it there.  If it
** will not fit, then make a copy of the cell content into pTemp if
** pTemp is not null.  Regardless of pTemp, allocate a new entry
** in pPage->aOvfl[] and make it point to the cell content (either
** in pTemp or the original pCell) and also record its index. 
** Allocating a new entry in pPage->aCell[] implies that 
** pPage->nOverflow is incremented.
**
** If nSkip is non-zero, then do not copy the first nSkip bytes of the
** cell. The caller will overwrite them after this function returns. If
** nSkip is non-zero, then pCell may not point to an invalid memory location 
** (but pCell+nSkip is always valid).
*/
static int insertCell(
static void insertCell(
  MemPage *pPage,   /* Page into which we are copying */
  int i,            /* New cell becomes the i-th cell of the page */
  u8 *pCell,        /* Content of the new cell */
  int sz,           /* Bytes of content in pCell */
  u8 *pTemp,        /* Temp storage space for pCell, if needed */
  Pgno iChild       /* If non-zero, replace first 4 bytes with this value */
  Pgno iChild,      /* If non-zero, replace first 4 bytes with this value */
  int *pRC          /* Read and write return code from here */
){
  int idx;          /* Where to write new cell content in data[] */
  int j;            /* Loop counter */
  int top;          /* First byte of content for any cell in data[] */
  int end;          /* First byte past the last cell pointer in data[] */
  int ins;          /* Index in data[] where new cell pointer is inserted */
  int hdr;          /* Offset into data[] of the page header */
  int cellOffset;   /* Address of first cell pointer in data[] */
  u8 *data;         /* The content of the whole page */
  u8 *ptr;          /* Used for moving information around in data[] */

  int nSkip = (iChild ? 4 : 0);

  if( *pRC ) return;

  assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
  assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=5460 );
  assert( pPage->nOverflow<=ArraySize(pPage->aOvfl) );
  assert( sz==cellSizePtr(pPage, pCell) );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  if( pPage->nOverflow || sz+2>pPage->nFree ){
5084
5085
5086
5087
5088
5089
5090

5091

5092
5093
5094
5095
5096
5097
5098

5099
5100
5101

5102
5103

5104
5105
5106
5107
5108
5109



5110
5111

5112
5113
5114
5115

5116
5117
5118
5119
5120

5121
5122
5123
5124
5125

5126
5127
5128
5129
5130
5131

5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5297
5298
5299
5300
5301
5302
5303
5304

5305
5306
5307
5308


5309

5310
5311


5312


5313






5314
5315
5316


5317


5318

5319
5320
5321
5322
5323

5324
5325
5326
5327
5328

5329
5330
5331
5332
5333
5334

5335
5336
5337
5338


5339
5340
5341
5342
5343
5344
5345







+
-
+



-
-

-
+

-
-
+
-
-
+
-
-
-
-
-
-
+
+
+
-
-
+
-
-

-
+




-
+




-
+





-
+



-
-







    j = pPage->nOverflow++;
    assert( j<(int)(sizeof(pPage->aOvfl)/sizeof(pPage->aOvfl[0])) );
    pPage->aOvfl[j].pCell = pCell;
    pPage->aOvfl[j].idx = (u16)i;
  }else{
    int rc = sqlite3PagerWrite(pPage->pDbPage);
    if( rc!=SQLITE_OK ){
      *pRC = rc;
      return rc;
      return;
    }
    assert( sqlite3PagerIswriteable(pPage->pDbPage) );
    data = pPage->aData;
    hdr = pPage->hdrOffset;
    top = get2byte(&data[hdr+5]);
    cellOffset = pPage->cellOffset;
    end = cellOffset + 2*pPage->nCell + 2;
    end = cellOffset + 2*pPage->nCell;
    ins = cellOffset + 2*i;
    if( end > top - sz ){
      rc = defragmentPage(pPage);
    rc = allocateSpace(pPage, sz, &idx);
      if( rc!=SQLITE_OK ){
        return rc;
    if( rc ){ *pRC = rc; return; }
      }
      top = get2byte(&data[hdr+5]);
      assert( end + sz <= top );
    }
    idx = allocateSpace(pPage, sz);
    assert( idx>0 );
    /* The allocateSpace() routine guarantees the following two properties
    ** if it returns success */
    assert( idx >= end+2 );
    assert( end <= get2byte(&data[hdr+5]) );
    if (idx+sz > pPage->pBt->usableSize) {
    assert( idx+sz <= pPage->pBt->usableSize );
      return SQLITE_CORRUPT_BKPT;
    }
    pPage->nCell++;
    pPage->nFree = pPage->nFree - (u16)(2 + sz);
    pPage->nFree -= (u16)(2 + sz);
    memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip);
    if( iChild ){
      put4byte(&data[idx], iChild);
    }
    for(j=end-2, ptr=&data[j]; j>ins; j-=2, ptr-=2){
    for(j=end, ptr=&data[j]; j>ins; j-=2, ptr-=2){
      ptr[0] = ptr[-2];
      ptr[1] = ptr[-1];
    }
    put2byte(&data[ins], idx);
    put2byte(&data[hdr+3], pPage->nCell);
    put2byte(&data[pPage->hdrOffset+3], pPage->nCell);
#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pPage->pBt->autoVacuum ){
      /* The cell may contain a pointer to an overflow page. If so, write
      ** the entry for the overflow page into the pointer map.
      */
      return ptrmapPutOvflPtr(pPage, pCell);
      ptrmapPutOvflPtr(pPage, pCell, pRC);
    }
#endif
  }

  return SQLITE_OK;
}

/*
** Add a list of cells to a page.  The page should be initially empty.
** The cells are guaranteed to fit on the page.
*/
static void assemblePage(
5195
5196
5197
5198
5199
5200
5201
5202

5203
5204
5205
5206
5207
5208
5209
5397
5398
5399
5400
5401
5402
5403

5404
5405
5406
5407
5408
5409
5410
5411







-
+







#ifndef SQLITE_OMIT_QUICKBALANCE
/*
** This version of balance() handles the common special case where
** a new entry is being inserted on the extreme right-end of the
** tree, in other words, when the new entry will become the largest
** entry in the tree.
**
** Instead of trying balance the 3 right-most leaf pages, just add
** Instead of trying to balance the 3 right-most leaf pages, just add
** a new page to the right-hand side and put the one new entry in
** that page.  This leaves the right side of the tree somewhat
** unbalanced.  But odds are that we will be inserting new entries
** at the end soon afterwards so the nearly empty page will quickly
** fill up.  On average.
**
** pPage is the leaf page which is the right-most page in the tree.
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261



5262
5263
5264
5265
5266
5267
5268
5454
5455
5456
5457
5458
5459
5460



5461
5462
5463
5464
5465
5466
5467
5468
5469
5470







-
-
-
+
+
+







    ** operations fails, the return code is set, but the contents
    ** of the parent page are still manipulated by thh code below.
    ** That is Ok, at this point the parent page is guaranteed to
    ** be marked as dirty. Returning an error code will cause a
    ** rollback, undoing any changes made to the parent page.
    */
    if( ISAUTOVACUUM ){
      rc = ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno);
      if( szCell>pNew->minLocal && rc==SQLITE_OK ){
        rc = ptrmapPutOvflPtr(pNew, pCell);
      ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc);
      if( szCell>pNew->minLocal ){
        ptrmapPutOvflPtr(pNew, pCell, &rc);
      }
    }
  
    /* Create a divider cell to insert into pParent. The divider cell
    ** consists of a 4-byte page number (the page number of pPage) and
    ** a variable length key value (which must be the same value as the
    ** largest key on pPage).
5278
5279
5280
5281
5282
5283
5284
5285


5286
5287
5288
5289
5290
5291
5292
5480
5481
5482
5483
5484
5485
5486

5487
5488
5489
5490
5491
5492
5493
5494
5495







-
+
+







    pCell = findCell(pPage, pPage->nCell-1);
    pStop = &pCell[9];
    while( (*(pCell++)&0x80) && pCell<pStop );
    pStop = &pCell[9];
    while( ((*(pOut++) = *(pCell++))&0x80) && pCell<pStop );

    /* Insert the new divider cell into pParent. */
    insertCell(pParent,pParent->nCell,pSpace,(int)(pOut-pSpace),0,pPage->pgno);
    insertCell(pParent, pParent->nCell, pSpace, (int)(pOut-pSpace),
               0, pPage->pgno, &rc);

    /* Set the right-child pointer of pParent to point to the new page. */
    put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew);
  
    /* Release the reference to the new page. */
    releasePage(pNew);
  }
5311
5312
5313
5314
5315
5316
5317
5318

5319
5320
5321
5322
5323
5324
5325
5514
5515
5516
5517
5518
5519
5520

5521
5522
5523
5524
5525
5526
5527
5528







-
+







    assert( pPage->isInit );

    for(j=0; j<pPage->nCell; j++){
      CellInfo info;
      u8 *z;
     
      z = findCell(pPage, j);
      sqlite3BtreeParseCellPtr(pPage, z, &info);
      btreeParseCellPtr(pPage, z, &info);
      if( info.iOverflow ){
        Pgno ovfl = get4byte(&z[info.iOverflow]);
        ptrmapGet(pBt, ovfl, &e, &n);
        assert( n==pPage->pgno && e==PTRMAP_OVERFLOW1 );
      }
      if( !pPage->leaf ){
        Pgno child = get4byte(z);
5344
5345
5346
5347
5348
5349
5350
5351

5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386

































5387

5388
5389
5390
5391
5392
5393
5394
5547
5548
5549
5550
5551
5552
5553

5554
5555
5556
5557
5558
5559






























5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592

5593
5594
5595
5596
5597
5598
5599
5600







-
+





-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+







** parent page stored in the pointer map is page pTo. If pFrom contained
** any cells with overflow page pointers, then the corresponding pointer
** map entries are also updated so that the parent page is page pTo.
**
** If pFrom is currently carrying any overflow cells (entries in the
** MemPage.aOvfl[] array), they are not copied to pTo. 
**
** Before returning, page pTo is reinitialized using sqlite3BtreeInitPage().
** Before returning, page pTo is reinitialized using btreeInitPage().
**
** The performance of this function is not critical. It is only used by 
** the balance_shallower() and balance_deeper() procedures, neither of
** which are called often under normal circumstances.
*/
static int copyNodeContent(MemPage *pFrom, MemPage *pTo){
  BtShared * const pBt = pFrom->pBt;
  u8 * const aFrom = pFrom->aData;
  u8 * const aTo = pTo->aData;
  int const iFromHdr = pFrom->hdrOffset;
  int const iToHdr = ((pTo->pgno==1) ? 100 : 0);
  int rc = SQLITE_OK;
  int iData;

  assert( pFrom->isInit );
  assert( pFrom->nFree>=iToHdr );
  assert( get2byte(&aFrom[iFromHdr+5])<=pBt->usableSize );

  /* Copy the b-tree node content from page pFrom to page pTo. */
  iData = get2byte(&aFrom[iFromHdr+5]);
  memcpy(&aTo[iData], &aFrom[iData], pBt->usableSize-iData);
  memcpy(&aTo[iToHdr], &aFrom[iFromHdr], pFrom->cellOffset + 2*pFrom->nCell);

  /* Reinitialize page pTo so that the contents of the MemPage structure
  ** match the new data. The initialization of pTo "cannot" fail, as the
  ** data copied from pFrom is known to be valid.  */
  pTo->isInit = 0;
  TESTONLY(rc = ) sqlite3BtreeInitPage(pTo);
  assert( rc==SQLITE_OK );

  /* If this is an auto-vacuum database, update the pointer-map entries
  ** for any b-tree or overflow pages that pTo now contains the pointers to. */
  if( ISAUTOVACUUM ){
    rc = setChildPtrmaps(pTo);
  }
static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){
  if( (*pRC)==SQLITE_OK ){
    BtShared * const pBt = pFrom->pBt;
    u8 * const aFrom = pFrom->aData;
    u8 * const aTo = pTo->aData;
    int const iFromHdr = pFrom->hdrOffset;
    int const iToHdr = ((pTo->pgno==1) ? 100 : 0);
    TESTONLY(int rc;)
    int iData;
  
  
    assert( pFrom->isInit );
    assert( pFrom->nFree>=iToHdr );
    assert( get2byte(&aFrom[iFromHdr+5])<=pBt->usableSize );
  
    /* Copy the b-tree node content from page pFrom to page pTo. */
    iData = get2byte(&aFrom[iFromHdr+5]);
    memcpy(&aTo[iData], &aFrom[iData], pBt->usableSize-iData);
    memcpy(&aTo[iToHdr], &aFrom[iFromHdr], pFrom->cellOffset + 2*pFrom->nCell);
  
    /* Reinitialize page pTo so that the contents of the MemPage structure
    ** match the new data. The initialization of pTo "cannot" fail, as the
    ** data copied from pFrom is known to be valid.  */
    pTo->isInit = 0;
    TESTONLY(rc = ) btreeInitPage(pTo);
    assert( rc==SQLITE_OK );
  
    /* If this is an auto-vacuum database, update the pointer-map entries
    ** for any b-tree or overflow pages that pTo now contains the pointers to.
    */
    if( ISAUTOVACUUM ){
      *pRC = setChildPtrmaps(pTo);
    }
  return rc;
  }
}

/*
** This routine redistributes cells on the iParentIdx'th child of pParent
** (hereafter "the page") and up to 2 siblings so that all pages have about the
** same amount of free space. Usually a single sibling on either side of the
** page are used in the balancing, though both siblings might come from one
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421



5422
5423
5424
5425
5426
5427
5428
5618
5619
5620
5621
5622
5623
5624



5625
5626
5627
5628
5629
5630
5631
5632
5633
5634







-
-
-
+
+
+







** balancing routine to fix this problem (see the balance() routine). 
**
** If this routine fails for any reason, it might leave the database
** in a corrupted state. So if this routine fails, the database should
** be rolled back.
**
** The third argument to this function, aOvflSpace, is a pointer to a
** buffer page-size bytes in size. If, in inserting cells into the parent
** page (pParent), the parent page becomes overfull, this buffer is
** used to store the parents overflow cells. Because this function inserts
** buffer big enough to hold one page. If while inserting cells into the parent
** page (pParent) the parent page becomes overfull, this buffer is
** used to store the parent's overflow cells. Because this function inserts
** a maximum of four divider cells into the parent page, and the maximum
** size of a cell stored within an internal node is always less than 1/4
** of the page-size, the aOvflSpace[] buffer is guaranteed to be large
** enough for all overflow cells.
**
** If aOvflSpace is set to a null pointer, this function returns 
** SQLITE_NOMEM.
5468
5469
5470
5471
5472
5473
5474
5475


5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492



5493
5494
5495
5496
5497
5498
5499
5674
5675
5676
5677
5678
5679
5680

5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697


5698
5699
5700
5701
5702
5703
5704
5705
5706
5707







-
+
+















-
-
+
+
+







#if 0
  TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
#endif

  /* At this point pParent may have at most one overflow cell. And if
  ** this overflow cell is present, it must be the cell with 
  ** index iParentIdx. This scenario comes about when this function
  ** is called (indirectly) from sqlite3BtreeDelete(). */
  ** is called (indirectly) from sqlite3BtreeDelete().
  */
  assert( pParent->nOverflow==0 || pParent->nOverflow==1 );
  assert( pParent->nOverflow==0 || pParent->aOvfl[0].idx==iParentIdx );

  if( !aOvflSpace ){
    return SQLITE_NOMEM;
  }

  /* Find the sibling pages to balance. Also locate the cells in pParent 
  ** that divide the siblings. An attempt is made to find NN siblings on 
  ** either side of pPage. More siblings are taken from one side, however, 
  ** if there are fewer than NN siblings on the other side. If pParent
  ** has NB or fewer children then all children of pParent are taken.  
  **
  ** This loop also drops the divider cells from the parent page. This
  ** way, the remainder of the function does not have to deal with any
  ** overflow cells in the parent page, as if one existed it has already
  ** been removed.  */
  ** overflow cells in the parent page, since if any existed they will
  ** have already been removed.
  */
  i = pParent->nOverflow + pParent->nCell;
  if( i<2 ){
    nxDiv = 0;
    nOld = i+1;
  }else{
    nOld = 3;
    if( iParentIdx==0 ){                 
5510
5511
5512
5513
5514
5515
5516
5517

5518
5519
5520
5521
5522
5523

5524
5525
5526
5527
5528
5529
5530
5718
5719
5720
5721
5722
5723
5724

5725
5726
5727
5728
5729
5730

5731
5732
5733
5734
5735
5736
5737
5738







-
+





-
+







  }else{
    pRight = findCell(pParent, i+nxDiv-pParent->nOverflow);
  }
  pgno = get4byte(pRight);
  while( 1 ){
    rc = getAndInitPage(pBt, pgno, &apOld[i]);
    if( rc ){
      memset(apOld, 0, i*sizeof(MemPage*));
      memset(apOld, 0, (i+1)*sizeof(MemPage*));
      goto balance_cleanup;
    }
    nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow;
    if( (i--)==0 ) break;

    if( pParent->nOverflow && i+nxDiv==pParent->aOvfl[0].idx ){
    if( i+nxDiv==pParent->aOvfl[0].idx && pParent->nOverflow ){
      apDiv[i] = pParent->aOvfl[0].pCell;
      pgno = get4byte(apDiv[i]);
      szNew[i] = cellSizePtr(pParent, apDiv[i]);
      pParent->nOverflow = 0;
    }else{
      apDiv[i] = findCell(pParent, i+nxDiv-pParent->nOverflow);
      pgno = get4byte(apDiv[i]);
5542
5543
5544
5545
5546
5547
5548
5549

5550
5551
5552
5553
5554
5555
5556
5750
5751
5752
5753
5754
5755
5756

5757
5758
5759
5760
5761
5762
5763
5764







-
+







      ** In this case, temporarily copy the cell into the aOvflSpace[]
      ** buffer. It will be copied out again as soon as the aSpace[] buffer
      ** is allocated.  */
#ifdef SQLITE_SECURE_DELETE
      memcpy(&aOvflSpace[apDiv[i]-pParent->aData], apDiv[i], szNew[i]);
      apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData];
#endif
      dropCell(pParent, i+nxDiv-pParent->nOverflow, szNew[i]);
      dropCell(pParent, i+nxDiv-pParent->nOverflow, szNew[i], &rc);
    }
  }

  /* Make nMaxCells a multiple of 4 in order to preserve 8-byte
  ** alignment */
  nMaxCells = (nMaxCells + 3)&~3;

5736
5737
5738
5739
5740
5741
5742
5743

5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754

5755
5756
5757
5758
5759
5760
5761
5944
5945
5946
5947
5948
5949
5950

5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961

5962
5963
5964
5965
5966
5967
5968
5969







-
+










-
+







      rc = allocateBtreePage(pBt, &pNew, &pgno, pgno, 0);
      if( rc ) goto balance_cleanup;
      apNew[i] = pNew;
      nNew++;

      /* Set the pointer-map entry for the new sibling page. */
      if( ISAUTOVACUUM ){
        rc = ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno);
        ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno, &rc);
        if( rc!=SQLITE_OK ){
          goto balance_cleanup;
        }
      }
    }
  }

  /* Free any old pages that were not reused as new pages.
  */
  while( i<nOld ){
    rc = freePage(apOld[i]);
    freePage(apOld[i], &rc);
    if( rc ) goto balance_cleanup;
    releasePage(apOld[i]);
    apOld[i] = 0;
    i++;
  }

  /*
5835
5836
5837
5838
5839
5840
5841
5842

5843
5844
5845
5846
5847
5848
5849
5850
5851

5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867

5868
5869
5870
5871
5872
5873
5874
6043
6044
6045
6046
6047
6048
6049

6050
6051
6052
6053
6054
6055
6056
6057
6058

6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074

6075
6076
6077
6078
6079
6080
6081
6082







-
+








-
+















-
+







        /* If the tree is a leaf-data tree, and the siblings are leaves, 
        ** then there is no divider cell in apCell[]. Instead, the divider 
        ** cell consists of the integer key for the right-most cell of 
        ** the sibling-page assembled above only.
        */
        CellInfo info;
        j--;
        sqlite3BtreeParseCellPtr(pNew, apCell[j], &info);
        btreeParseCellPtr(pNew, apCell[j], &info);
        pCell = pTemp;
        sz = 4 + putVarint(&pCell[4], info.nKey);
        pTemp = 0;
      }else{
        pCell -= 4;
        /* Obscure case for non-leaf-data trees: If the cell at pCell was
        ** previously stored on a leaf node, and its reported size was 4
        ** bytes, then it may actually be smaller than this 
        ** (see sqlite3BtreeParseCellPtr(), 4 bytes is the minimum size of
        ** (see btreeParseCellPtr(), 4 bytes is the minimum size of
        ** any cell). But it is important to pass the correct size to 
        ** insertCell(), so reparse the cell now.
        **
        ** Note that this can never happen in an SQLite data file, as all
        ** cells are at least 4 bytes. It only happens in b-trees used
        ** to evaluate "IN (SELECT ...)" and similar clauses.
        */
        if( szCell[j]==4 ){
          assert(leafCorrection==4);
          sz = cellSizePtr(pParent, pCell);
        }
      }
      iOvflSpace += sz;
      assert( sz<=pBt->pageSize/4 );
      assert( iOvflSpace<=pBt->pageSize );
      rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, pNew->pgno);
      insertCell(pParent, nxDiv, pCell, sz, pTemp, pNew->pgno, &rc);
      if( rc!=SQLITE_OK ) goto balance_cleanup;
      assert( sqlite3PagerIswriteable(pParent->pDbPage) );

      j++;
      nxDiv++;
    }
  }
5895
5896
5897
5898
5899
5900
5901
5902
5903


5904
5905
5906
5907
5908
5909
5910
5911
6103
6104
6105
6106
6107
6108
6109


6110
6111

6112
6113
6114
6115
6116
6117
6118







-
-
+
+
-







    ** (it must be, as it was just reconstructed using assemblePage()). This
    ** is important if the parent page happens to be page 1 of the database
    ** image.  */
    assert( nNew==1 );
    assert( apNew[0]->nFree == 
        (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2) 
    );
    if( SQLITE_OK==(rc = copyNodeContent(apNew[0], pParent)) ){
      rc = freePage(apNew[0]);
    copyNodeContent(apNew[0], pParent, &rc);
    freePage(apNew[0], &rc);
    }
  }else if( ISAUTOVACUUM ){
    /* Fix the pointer-map entries for all the cells that were shifted around. 
    ** There are several different types of pointer-map entries that need to
    ** be dealt with by this routine. Some of these have been set already, but
    ** many have not. The following is a summary:
    **
    **   1) The entries associated with new sibling pages that were not
5937
5938
5939
5940
5941
5942
5943
5944

5945
5946
5947
5948
5949
5950
5951
6144
6145
6146
6147
6148
6149
6150

6151
6152
6153
6154
6155
6156
6157
6158







-
+







    MemPage *pNew = apNew[0];
    MemPage *pOld = apCopy[0];
    int nOverflow = pOld->nOverflow;
    int iNextOld = pOld->nCell + nOverflow;
    int iOverflow = (nOverflow ? pOld->aOvfl[0].idx : -1);
    j = 0;                             /* Current 'old' sibling page */
    k = 0;                             /* Current 'new' sibling page */
    for(i=0; i<nCell && rc==SQLITE_OK; i++){
    for(i=0; i<nCell; i++){
      int isDivider = 0;
      while( i==iNextOld ){
        /* Cell i is the cell immediately following the last cell on old
        ** sibling page j. If the siblings are not leaf pages of an
        ** intkey b-tree, then cell i was a divider cell. */
        pOld = apCopy[++j];
        iNextOld = i + !leafData + pOld->nCell + pOld->nOverflow;
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986

5987
5988
5989


5990
5991
5992
5993
5994
5995

5996
5997


5998
5999
6000
6001
6002
6003
6004
6176
6177
6178
6179
6180
6181
6182

6183
6184
6185
6186
6187
6188
6189
6190
6191

6192
6193


6194
6195
6196
6197
6198
6199
6200

6201


6202
6203
6204
6205
6206
6207
6208
6209
6210







-









-
+

-
-
+
+





-
+
-
-
+
+







      if( i==cntNew[k] ){
        /* Cell i is the cell immediately following the last cell on new
        ** sibling page k. If the siblings are not leaf pages of an
        ** intkey b-tree, then cell i is a divider cell.  */
        pNew = apNew[++k];
        if( !leafData ) continue;
      }
      assert( rc==SQLITE_OK );
      assert( j<nOld );
      assert( k<nNew );

      /* If the cell was originally divider cell (and is not now) or
      ** an overflow cell, or if the cell was located on a different sibling
      ** page before the balancing, then the pointer map entries associated
      ** with any child or overflow pages need to be updated.  */
      if( isDivider || pOld->pgno!=pNew->pgno ){
        if( !leafCorrection ){
          rc = ptrmapPut(pBt, get4byte(apCell[i]), PTRMAP_BTREE, pNew->pgno);
          ptrmapPut(pBt, get4byte(apCell[i]), PTRMAP_BTREE, pNew->pgno, &rc);
        }
        if( szCell[i]>pNew->minLocal && rc==SQLITE_OK ){
          rc = ptrmapPutOvflPtr(pNew, apCell[i]);
        if( szCell[i]>pNew->minLocal ){
          ptrmapPutOvflPtr(pNew, apCell[i], &rc);
        }
      }
    }

    if( !leafCorrection ){
      for(i=0; rc==SQLITE_OK && i<nNew; i++){
      for(i=0; i<nNew; i++){
        rc = ptrmapPut(
	    pBt, get4byte(&apNew[i]->aData[8]), PTRMAP_BTREE, apNew[i]->pgno);
        u32 key = get4byte(&apNew[i]->aData[8]);
        ptrmapPut(pBt, key, PTRMAP_BTREE, apNew[i]->pgno, &rc);
      }
    }

#if 0
    /* The ptrmapCheckPages() contains assert() statements that verify that
    ** all pointer map pages are set correctly. This is helpful while 
    ** debugging. This is usually disabled because a corrupt database may
6046
6047
6048
6049
6050
6051
6052
6053

6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068









6069
6070
6071
6072
6073
6074
6075
6252
6253
6254
6255
6256
6257
6258

6259
6260
6261
6262
6263
6264
6265
6266
6267
6268






6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284







-
+









-
-
-
-
-
-
+
+
+
+
+
+
+
+
+







** page and SQLITE_OK is returned. In this case the caller is required
** to call releasePage() on *ppChild exactly once. If an error occurs,
** an error code is returned and *ppChild is set to 0.
*/
static int balance_deeper(MemPage *pRoot, MemPage **ppChild){
  int rc;                        /* Return value from subprocedures */
  MemPage *pChild = 0;           /* Pointer to a new child page */
  Pgno pgnoChild;                /* Page number of the new child page */
  Pgno pgnoChild = 0;            /* Page number of the new child page */
  BtShared *pBt = pRoot->pBt;    /* The BTree */

  assert( pRoot->nOverflow>0 );
  assert( sqlite3_mutex_held(pBt->mutex) );

  /* Make pRoot, the root page of the b-tree, writable. Allocate a new 
  ** page that will become the new right-child of pPage. Copy the contents
  ** of the node stored on pRoot into the new child page.
  */
  if( SQLITE_OK!=(rc = sqlite3PagerWrite(pRoot->pDbPage))
   || SQLITE_OK!=(rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0))
   || SQLITE_OK!=(rc = copyNodeContent(pRoot, pChild))
   || (ISAUTOVACUUM && 
       SQLITE_OK!=(rc = ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno)))
  ){
  rc = sqlite3PagerWrite(pRoot->pDbPage);
  if( rc==SQLITE_OK ){
    rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0);
    copyNodeContent(pRoot, pChild, &rc);
    if( ISAUTOVACUUM ){
      ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno, &rc);
    }
  }
  if( rc ){
    *ppChild = 0;
    releasePage(pChild);
    return rc;
  }
  assert( sqlite3PagerIswriteable(pChild->pDbPage) );
  assert( sqlite3PagerIswriteable(pRoot->pDbPage) );
  assert( pChild->nCell==pRoot->nCell );
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293

6294
6295
6296
6297
6298


6299
6300


6301
6302
6303
6304
6305
6306
6307
6308
6309

6310
6311
6312
6313


6314
6315
6316
6317
6318
6319
6320





6321
6322
6323
6324
6325
6326



6327
6328






6329
6330
6331
6332






6333
6334
6335
6336
6337

6338
6339
6340
6341

6342
6343
6344
6345
6346
6347
6348




6349
6350

6351
6352
6353
6354
6355
6356

6357
6358
6359
6360
6361
6362
6363
6415
6416
6417
6418
6419
6420
6421





































































6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432

6433
6434
6435
6436
6437
6438
6439
6440


6441
6442
6443
6444
6445
6446
6447
6448
6449
6450

6451
6452
6453


6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468





6469
6470
6471


6472
6473
6474
6475
6476
6477




6478
6479
6480
6481
6482
6483
6484
6485
6486
6487

6488
6489
6490
6491

6492
6493
6494
6495
6496



6497
6498
6499
6500


6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-











-
+





+
+
-
-
+
+








-
+


-
-
+
+







+
+
+
+
+

-
-
-
-
-
+
+
+
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+




-
+



-
+




-
-
-
+
+
+
+
-
-
+






+








  if( pFree ){
    sqlite3PageFree(pFree);
  }
  return rc;
}

/*
** This routine checks all cursors that point to table pgnoRoot.
** If any of those cursors were opened with wrFlag==0 in a different
** database connection (a database connection that shares the pager
** cache with the current connection) and that other connection 
** is not in the ReadUncommmitted state, then this routine returns 
** SQLITE_LOCKED.
**
** As well as cursors with wrFlag==0, cursors with 
** isIncrblobHandle==1 are also considered 'read' cursors because
** incremental blob cursors are used for both reading and writing.
**
** When pgnoRoot is the root page of an intkey table, this function is also
** responsible for invalidating incremental blob cursors when the table row
** on which they are opened is deleted or modified. Cursors are invalidated
** according to the following rules:
**
**   1) When BtreeClearTable() is called to completely delete the contents
**      of a B-Tree table, pExclude is set to zero and parameter iRow is 
**      set to non-zero. In this case all incremental blob cursors open
**      on the table rooted at pgnoRoot are invalidated.
**
**   2) When BtreeInsert(), BtreeDelete() or BtreePutData() is called to 
**      modify a table row via an SQL statement, pExclude is set to the 
**      write cursor used to do the modification and parameter iRow is set
**      to the integer row id of the B-Tree entry being modified. Unless
**      pExclude is itself an incremental blob cursor, then all incremental
**      blob cursors open on row iRow of the B-Tree are invalidated.
**
**   3) If both pExclude and iRow are set to zero, no incremental blob 
**      cursors are invalidated.
*/
static int checkForReadConflicts(
  Btree *pBtree,          /* The database file to check */
  Pgno pgnoRoot,          /* Look for read cursors on this btree */
  BtCursor *pExclude,     /* Ignore this cursor */
  i64 iRow                /* The rowid that might be changing */
){
  BtCursor *p;
  BtShared *pBt = pBtree->pBt;
  sqlite3 *db = pBtree->db;
  assert( sqlite3BtreeHoldsMutex(pBtree) );
  for(p=pBt->pCursor; p; p=p->pNext){
    if( p==pExclude ) continue;
    if( p->pgnoRoot!=pgnoRoot ) continue;
#ifndef SQLITE_OMIT_INCRBLOB
    if( p->isIncrblobHandle && ( 
         (!pExclude && iRow)
      || (pExclude && !pExclude->isIncrblobHandle && p->info.nKey==iRow)
    )){
      p->eState = CURSOR_INVALID;
    }
#endif
    if( p->eState!=CURSOR_VALID ) continue;
    if( p->wrFlag==0 
#ifndef SQLITE_OMIT_INCRBLOB
     || p->isIncrblobHandle
#endif
    ){
      sqlite3 *dbOther = p->pBtree->db;
      assert(dbOther);
      if( dbOther!=db && (dbOther->flags & SQLITE_ReadUncommitted)==0 ){
        sqlite3ConnectionBlocked(db, dbOther);
        return SQLITE_LOCKED_SHAREDCACHE;
      }
    }
  }
  return SQLITE_OK;
}

/*
** Insert a new record into the BTree.  The key is given by (pKey,nKey)
** and the data is given by (pData,nData).  The cursor is used only to
** define what table the record should be inserted into.  The cursor
** is left pointing at a random location.
**
** For an INTKEY table, only the nKey value of the key is used.  pKey is
** ignored.  For a ZERODATA table, the pData and nData are both ignored.
**
** If the seekResult parameter is non-zero, then a successful call to
** sqlite3BtreeMoveto() to seek cursor pCur to (pKey, nKey) has already
** MovetoUnpacked() to seek cursor pCur to (pKey, nKey) has already
** been performed. seekResult is the search result returned (a negative
** number if pCur points at an entry that is smaller than (pKey, nKey), or
** a positive value if pCur points at an etry that is larger than 
** (pKey, nKey)). 
**
** If the seekResult parameter is non-zero, then the caller guarantees that
** cursor pCur is pointing at the existing copy of a row that is to be
** If the seekResult parameter is 0, then cursor pCur may point to any 
** entry or to no entry at all. In this case this function has to seek
** overwritten.  If the seekResult parameter is 0, then cursor pCur may
** point to any entry or to no entry at all and so this function has to seek
** the cursor before the new key can be inserted.
*/
int sqlite3BtreeInsert(
  BtCursor *pCur,                /* Insert data into the table of this cursor */
  const void *pKey, i64 nKey,    /* The key of the new record */
  const void *pData, int nData,  /* The data of the new record */
  int nZero,                     /* Number of extra 0 bytes to append to data */
  int appendBias,                /* True if this is likely an append */
  int seekResult                 /* Result of prior sqlite3BtreeMoveto() call */
  int seekResult                 /* Result of prior MovetoUnpacked() call */
){
  int rc;
  int loc = seekResult;
  int szNew;
  int loc = seekResult;          /* -1: before desired location  +1: after */
  int szNew = 0;
  int idx;
  MemPage *pPage;
  Btree *p = pCur->pBtree;
  BtShared *pBt = p->pBt;
  unsigned char *oldCell;
  unsigned char *newCell = 0;

  if( pCur->eState==CURSOR_FAULT ){
    assert( pCur->skipNext!=SQLITE_OK );
    return pCur->skipNext;
  }

  assert( cursorHoldsMutex(pCur) );
  assert( pBt->inTransaction==TRANS_WRITE );
  assert( !pBt->readOnly );
  assert( pCur->wrFlag );
  rc = checkForReadConflicts(pCur->pBtree, pCur->pgnoRoot, pCur, nKey);
  if( rc ){             
  assert( pCur->wrFlag && pBt->inTransaction==TRANS_WRITE && !pBt->readOnly );
  assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );

    /* The table pCur points to has a read lock */
    assert( rc==SQLITE_LOCKED_SHAREDCACHE );
  /* Assert that the caller has been consistent. If this cursor was opened
  ** expecting an index b-tree, then the caller should be inserting blob
  ** keys with no associated data. If the cursor was opened expecting an
  ** intkey table, the caller should be inserting integer keys with a
  ** blob of associated data.  */
  assert( (pKey==0)==(pCur->pKeyInfo==0) );
    return rc;
  }
  if( pCur->eState==CURSOR_FAULT ){
    return pCur->skip;

  /* If this is an insert into a table b-tree, invalidate any incrblob 
  ** cursors open on the row being replaced (assuming this is a replace
  ** operation - if it is not, the following is a no-op).  */
  if( pCur->pKeyInfo==0 ){
    invalidateIncrblobCursors(p, nKey, 0);
  }

  /* Save the positions of any other cursors open on this table.
  **
  ** In some cases, the call to sqlite3BtreeMoveto() below is a no-op. For
  ** In some cases, the call to btreeMoveto() below is a no-op. For
  ** example, when inserting data into a table with auto-generated integer
  ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the 
  ** integer key to use. It then calls this function to actually insert the 
  ** data into the intkey B-Tree. In this case sqlite3BtreeMoveto() recognizes
  ** data into the intkey B-Tree. In this case btreeMoveto() recognizes
  ** that the cursor is already where it needs to be and returns without
  ** doing any work. To avoid thwarting these optimizations, it is important
  ** not to clear the cursor here.
  */
  if(
    SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) || (!loc &&
    SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, appendBias, &loc))
  rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur);
  if( rc ) return rc;
  if( !loc ){
    rc = btreeMoveto(pCur, pKey, nKey, appendBias, &loc);
  )){
    return rc;
    if( rc ) return rc;
  }
  assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) );

  pPage = pCur->apPage[pCur->iPage];
  assert( pPage->intKey || nKey>=0 );
  assert( pPage->leaf || !pPage->intKey );

  TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
          pCur->pgnoRoot, nKey, nData, pPage->pgno,
          loc==0 ? "overwrite" : "new entry"));
  assert( pPage->isInit );
  allocateTempSpace(pBt);
  newCell = pBt->pTmpSpace;
  if( newCell==0 ) return SQLITE_NOMEM;
6375
6376
6377
6378
6379
6380
6381
6382
6383

6384
6385

6386
6387
6388
6389
6390
6391
6392
6393

6394
6395
6396
6397
6398
6399
6400
6527
6528
6529
6530
6531
6532
6533


6534


6535

6536
6537
6538
6539
6540
6541

6542
6543
6544
6545
6546
6547
6548
6549







-
-
+
-
-
+
-






-
+







    }
    oldCell = findCell(pPage, idx);
    if( !pPage->leaf ){
      memcpy(newCell, oldCell, 4);
    }
    szOld = cellSizePtr(pPage, oldCell);
    rc = clearCell(pPage, oldCell);
    if( rc ) goto end_insert;
    rc = dropCell(pPage, idx, szOld);
    dropCell(pPage, idx, szOld, &rc);
    if( rc!=SQLITE_OK ) {
      goto end_insert;
    if( rc ) goto end_insert;
    }
  }else if( loc<0 && pPage->nCell>0 ){
    assert( pPage->leaf );
    idx = ++pCur->aiIdx[pCur->iPage];
  }else{
    assert( pPage->leaf );
  }
  rc = insertCell(pPage, idx, newCell, szNew, 0, 0);
  insertCell(pPage, idx, newCell, szNew, 0, 0, &rc);
  assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 );

  /* If no error has occured and pPage has an overflow cell, call balance() 
  ** to redistribute the cells within the tree. Since balance() may move
  ** the cursor, zero the BtCursor.info.nSize and BtCursor.validNKey
  ** variables.
  **
6444
6445
6446
6447
6448
6449
6450



6451
6452
6453
6454
6455
6456
6457
6458



6459
6460

6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478


6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489








6490
6491

6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514



6515
6516

6517
6518
6519
6520
6521
6522
6523
6524
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608


6609
6610
6611


6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628


6629
6630

6631
6632
6633
6634
6635





6636
6637
6638
6639
6640
6641
6642
6643


6644

6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663



6664
6665
6666


6667

6668
6669
6670
6671
6672
6673
6674







+
+
+






-
-
+
+
+
-
-
+
















-
-
+
+
-





-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
-



















-
-
-
+
+
+
-
-
+
-







  int iCellIdx;                        /* Index of cell to delete */
  int iCellDepth;                      /* Depth of node containing pCell */ 

  assert( cursorHoldsMutex(pCur) );
  assert( pBt->inTransaction==TRANS_WRITE );
  assert( !pBt->readOnly );
  assert( pCur->wrFlag );
  assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
  assert( !hasReadConflicts(p, pCur->pgnoRoot) );

  if( NEVER(pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell) 
   || NEVER(pCur->eState!=CURSOR_VALID)
  ){
    return SQLITE_ERROR;  /* Something has gone awry. */
  }

  rc = checkForReadConflicts(p, pCur->pgnoRoot, pCur, pCur->info.nKey);
  if( rc!=SQLITE_OK ){
  /* If this is a delete operation to remove a row from a table b-tree,
  ** invalidate any incrblob cursors open on the row being deleted.  */
  if( pCur->pKeyInfo==0 ){
    assert( rc==SQLITE_LOCKED_SHAREDCACHE );
    return rc;            /* The table pCur points to has a read lock */
    invalidateIncrblobCursors(p, pCur->info.nKey, 0);
  }

  iCellDepth = pCur->iPage;
  iCellIdx = pCur->aiIdx[iCellDepth];
  pPage = pCur->apPage[iCellDepth];
  pCell = findCell(pPage, iCellIdx);

  /* If the page containing the entry to delete is not a leaf page, move
  ** the cursor to the largest entry in the tree that is smaller than
  ** the entry being deleted. This cell will replace the cell being deleted
  ** from the internal node. The 'previous' entry is used for this instead
  ** of the 'next' entry, as the previous entry is always a part of the
  ** sub-tree headed by the child page of the cell being deleted. This makes
  ** balancing the tree following the delete operation easier.  */
  if( !pPage->leaf ){
    int notUsed;
    if( SQLITE_OK!=(rc = sqlite3BtreePrevious(pCur, &notUsed)) ){
      return rc;
    rc = sqlite3BtreePrevious(pCur, &notUsed);
    if( rc ) return rc;
    }
  }

  /* Save the positions of any other cursors open on this table before
  ** making any modifications. Make the page containing the entry to be 
  ** deleted writable. Then free any overflow pages associated with the 
  ** entry and finally remove the cell itself from within the page.  */
  if( SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur))
   || SQLITE_OK!=(rc = sqlite3PagerWrite(pPage->pDbPage))
   || SQLITE_OK!=(rc = clearCell(pPage, pCell))
   || SQLITE_OK!=(rc = dropCell(pPage, iCellIdx, cellSizePtr(pPage, pCell)))
  ** entry and finally remove the cell itself from within the page.  
  */
  rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur);
  if( rc ) return rc;
  rc = sqlite3PagerWrite(pPage->pDbPage);
  if( rc ) return rc;
  rc = clearCell(pPage, pCell);
  dropCell(pPage, iCellIdx, cellSizePtr(pPage, pCell), &rc);
  ){
    return rc;
  if( rc ) return rc;
  }

  /* If the cell deleted was not located on a leaf page, then the cursor
  ** is currently pointing to the largest entry in the sub-tree headed
  ** by the child-page of the cell that was just deleted from an internal
  ** node. The cell from the leaf node needs to be moved to the internal
  ** node to replace the deleted cell.  */
  if( !pPage->leaf ){
    MemPage *pLeaf = pCur->apPage[pCur->iPage];
    int nCell;
    Pgno n = pCur->apPage[iCellDepth+1]->pgno;
    unsigned char *pTmp;

    pCell = findCell(pLeaf, pLeaf->nCell-1);
    nCell = cellSizePtr(pLeaf, pCell);
    assert( MX_CELL_SIZE(pBt)>=nCell );

    allocateTempSpace(pBt);
    pTmp = pBt->pTmpSpace;

    if( SQLITE_OK!=(rc = sqlite3PagerWrite(pLeaf->pDbPage)) 
     || SQLITE_OK!=(rc = insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n))
     || SQLITE_OK!=(rc = dropCell(pLeaf, pLeaf->nCell-1, nCell))
    rc = sqlite3PagerWrite(pLeaf->pDbPage);
    insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
    dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);
    ){
      return rc;
    if( rc ) return rc;
    }
  }

  /* Balance the tree. If the entry deleted was located on a leaf page,
  ** then the cursor still points to that page. In this case the first
  ** call to balance() repairs the tree, and the if(...) condition is
  ** never true.
  **
6584
6585
6586
6587
6588
6589
6590
6591

6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6734
6735
6736
6737
6738
6739
6740

6741



6742
6743
6744
6745
6746
6747
6748







-
+
-
-
-







    */
    invalidateAllOverflowCache(pBt);

    /* Read the value of meta[3] from the database to determine where the
    ** root page of the new table should go. meta[3] is the largest root-page
    ** created so far, so the new root-page is (meta[3]+1).
    */
    rc = sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot);
    sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot);
    if( rc!=SQLITE_OK ){
      return rc;
    }
    pgnoRoot++;

    /* The new root-page may not be allocated on a pointer-map page, or the
    ** PENDING_BYTE page.
    */
    while( pgnoRoot==PTRMAP_PAGENO(pBt, pgnoRoot) ||
        pgnoRoot==PENDING_BYTE_PAGE(pBt) ){
6615
6616
6617
6618
6619
6620
6621
6622
6623


6624
6625
6626
6627
6628

6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649

6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663

6664
6665
6666
6667
6668
6669
6670
6762
6763
6764
6765
6766
6767
6768


6769
6770
6771
6772
6773
6774

6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795

6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809

6810
6811
6812
6813
6814
6815
6816
6817







-
-
+
+




-
+




















-
+













-
+







    if( pgnoMove!=pgnoRoot ){
      /* pgnoRoot is the page that will be used for the root-page of
      ** the new table (assuming an error did not occur). But we were
      ** allocated pgnoMove. If required (i.e. if it was not allocated
      ** by extending the file), the current page at position pgnoMove
      ** is already journaled.
      */
      u8 eType;
      Pgno iPtrPage;
      u8 eType = 0;
      Pgno iPtrPage = 0;

      releasePage(pPageMove);

      /* Move the page currently at pgnoRoot to pgnoMove. */
      rc = sqlite3BtreeGetPage(pBt, pgnoRoot, &pRoot, 0);
      rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage);
      if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){
        rc = SQLITE_CORRUPT_BKPT;
      }
      if( rc!=SQLITE_OK ){
        releasePage(pRoot);
        return rc;
      }
      assert( eType!=PTRMAP_ROOTPAGE );
      assert( eType!=PTRMAP_FREEPAGE );
      rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove, 0);
      releasePage(pRoot);

      /* Obtain the page at pgnoRoot */
      if( rc!=SQLITE_OK ){
        return rc;
      }
      rc = sqlite3BtreeGetPage(pBt, pgnoRoot, &pRoot, 0);
      rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      rc = sqlite3PagerWrite(pRoot->pDbPage);
      if( rc!=SQLITE_OK ){
        releasePage(pRoot);
        return rc;
      }
    }else{
      pRoot = pPageMove;
    } 

    /* Update the pointer-map and meta-data with the new root-page number. */
    rc = ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0);
    ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0, &rc);
    if( rc ){
      releasePage(pRoot);
      return rc;
    }
    rc = sqlite3BtreeUpdateMeta(p, 4, pgnoRoot);
    if( rc ){
      releasePage(pRoot);
6696
6697
6698
6699
6700
6701
6702
6703

6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714

6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732

6733
6734
6735
6736
6737
6738
6739
6843
6844
6845
6846
6847
6848
6849

6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860

6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878

6879
6880
6881
6882
6883
6884
6885
6886







-
+










-
+

















-
+







*/
static int clearDatabasePage(
  BtShared *pBt,           /* The BTree that contains the table */
  Pgno pgno,            /* Page number to clear */
  int freePageFlag,     /* Deallocate page if true */
  int *pnChange
){
  MemPage *pPage = 0;
  MemPage *pPage;
  int rc;
  unsigned char *pCell;
  int i;

  assert( sqlite3_mutex_held(pBt->mutex) );
  if( pgno>pagerPagecount(pBt) ){
    return SQLITE_CORRUPT_BKPT;
  }

  rc = getAndInitPage(pBt, pgno, &pPage);
  if( rc ) goto cleardatabasepage_out;
  if( rc ) return rc;
  for(i=0; i<pPage->nCell; i++){
    pCell = findCell(pPage, i);
    if( !pPage->leaf ){
      rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
      if( rc ) goto cleardatabasepage_out;
    }
    rc = clearCell(pPage, pCell);
    if( rc ) goto cleardatabasepage_out;
  }
  if( !pPage->leaf ){
    rc = clearDatabasePage(pBt, get4byte(&pPage->aData[8]), 1, pnChange);
    if( rc ) goto cleardatabasepage_out;
  }else if( pnChange ){
    assert( pPage->intKey );
    *pnChange += pPage->nCell;
  }
  if( freePageFlag ){
    rc = freePage(pPage);
    freePage(pPage, &rc);
  }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){
    zeroPage(pPage, pPage->aData[0] | PTF_LEAF);
  }

cleardatabasepage_out:
  releasePage(pPage);
  return rc;
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762







6763
6764

6765
6766
6767
6768
6769
6770
6771
6900
6901
6902
6903
6904
6905
6906



6907
6908
6909
6910
6911
6912
6913


6914
6915
6916
6917
6918
6919
6920
6921







-
-
-
+
+
+
+
+
+
+
-
-
+







** entries in the table.
*/
int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){
  int rc;
  BtShared *pBt = p->pBt;
  sqlite3BtreeEnter(p);
  assert( p->inTrans==TRANS_WRITE );
  if( (rc = checkForReadConflicts(p, iTable, 0, 1))!=SQLITE_OK ){
    /* nothing to do */
  }else if( SQLITE_OK!=(rc = saveAllCursors(pBt, iTable, 0)) ){

  /* Invalidate all incrblob cursors open on table iTable (assuming iTable
  ** is the root of a table b-tree - if it is not, the following call is
  ** a no-op).  */
  invalidateIncrblobCursors(p, 0, 1);

  rc = saveAllCursors(pBt, (Pgno)iTable, 0);
    /* nothing to do */
  }else{
  if( SQLITE_OK==rc ){
    rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange);
  }
  sqlite3BtreeLeave(p);
  return rc;
}

/*
6797
6798
6799
6800
6801
6802
6803


6804
6805

6806
6807
6808
6809
6810

6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822

6823
6824
6825
6826
6827

6828
6829
6830
6831
6832
6833
6834
6835
6836
6837

6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849

6850
6851
6852
6853
6854
6855
6856
6857

6858

6859
6860
6861
6862

6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876

6877
6878
6879

6880
6881
6882
6883
6884
6885
6886

6887
6888
6889
6890
6891




6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906



6907
6908
6909
6910
6911
6912
6913
6914
6915
6916

6917
6918
6919
6920
6921
6922
6923

6924
6925
6926
6927
6928
6929
6930

6931
6932
6933
6934
6935

6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952

6953
6954
6955

6956
6957
6958
6959
6960
6961
6962
6963
6964
6965


6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956

6957
6958
6959
6960
6961

6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973

6974
6975
6976
6977
6978

6979




6980
6981
6982
6983
6984

6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996

6997
6998
6999
7000
7001
7002
7003
7004
7005
7006

7007




7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021

7022



7023
7024
7025
7026
7027
7028
7029

7030
7031
7032
7033
7034

7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065

7066



7067
7068
7069

7070







7071





7072
7073
















7074



7075
7076









7077
7078

7079
7080
7081
7082








7083

7084
7085
7086
7087
7088
7089
7090







+
+

-
+




-
+











-
+




-
+
-
-
-
-





-
+











-
+








+
-
+
-
-
-
-
+













-
+
-
-
-
+






-
+




-
+
+
+
+















+
+
+









-
+
-
-
-



-
+
-
-
-
-
-
-
-
+
-
-
-
-
-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+

-
-
-
-
-
-
-
-
-
+
+
-




-
-
-
-
-
-
-
-

-







  assert( p->inTrans==TRANS_WRITE );

  /* It is illegal to drop a table if any cursors are open on the
  ** database. This is because in auto-vacuum mode the backend may
  ** need to move another root-page to fill a gap left by the deleted
  ** root page. If an open cursor was using this page a problem would 
  ** occur.
  **
  ** This error is caught long before control reaches this point.
  */
  if( pBt->pCursor ){
  if( NEVER(pBt->pCursor) ){
    sqlite3ConnectionBlocked(p->db, pBt->pCursor->pBtree->db);
    return SQLITE_LOCKED_SHAREDCACHE;
  }

  rc = sqlite3BtreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
  rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
  if( rc ) return rc;
  rc = sqlite3BtreeClearTable(p, iTable, 0);
  if( rc ){
    releasePage(pPage);
    return rc;
  }

  *piMoved = 0;

  if( iTable>1 ){
#ifdef SQLITE_OMIT_AUTOVACUUM
    rc = freePage(pPage);
    freePage(pPage, &rc);
    releasePage(pPage);
#else
    if( pBt->autoVacuum ){
      Pgno maxRootPgno;
      rc = sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno);
      sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno);
      if( rc!=SQLITE_OK ){
        releasePage(pPage);
        return rc;
      }

      if( iTable==maxRootPgno ){
        /* If the table being dropped is the table with the largest root-page
        ** number in the database, put the root page on the free list. 
        */
        rc = freePage(pPage);
        freePage(pPage, &rc);
        releasePage(pPage);
        if( rc!=SQLITE_OK ){
          return rc;
        }
      }else{
        /* The table being dropped does not have the largest root-page
        ** number in the database. So move the page that does into the 
        ** gap left by the deleted root-page.
        */
        MemPage *pMove;
        releasePage(pPage);
        rc = sqlite3BtreeGetPage(pBt, maxRootPgno, &pMove, 0);
        rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
        if( rc!=SQLITE_OK ){
          return rc;
        }
        rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0);
        releasePage(pMove);
        if( rc!=SQLITE_OK ){
          return rc;
        }
        pMove = 0;
        rc = sqlite3BtreeGetPage(pBt, maxRootPgno, &pMove, 0);
        rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
        if( rc!=SQLITE_OK ){
          return rc;
        }
        rc = freePage(pMove);
        freePage(pMove, &rc);
        releasePage(pMove);
        if( rc!=SQLITE_OK ){
          return rc;
        }
        *piMoved = maxRootPgno;
      }

      /* Set the new 'max-root-page' value in the database header. This
      ** is the old value less one, less one more if that happens to
      ** be a root-page number, less one again if that is the
      ** PENDING_BYTE_PAGE.
      */
      maxRootPgno--;
      if( maxRootPgno==PENDING_BYTE_PAGE(pBt) ){
      while( maxRootPgno==PENDING_BYTE_PAGE(pBt)
        maxRootPgno--;
      }
      if( maxRootPgno==PTRMAP_PAGENO(pBt, maxRootPgno) ){
             || PTRMAP_ISPAGE(pBt, maxRootPgno) ){
        maxRootPgno--;
      }
      assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) );

      rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno);
    }else{
      rc = freePage(pPage);
      freePage(pPage, &rc);
      releasePage(pPage);
    }
#endif
  }else{
    /* If sqlite3BtreeDropTable was called on page 1. */
    /* If sqlite3BtreeDropTable was called on page 1.
    ** This really never should happen except in a corrupt
    ** database. 
    */
    zeroPage(pPage, PTF_INTKEY|PTF_LEAF );
    releasePage(pPage);
  }
  return rc;  
}
int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
  int rc;
  sqlite3BtreeEnter(p);
  rc = btreeDropTable(p, iTable, piMoved);
  sqlite3BtreeLeave(p);
  return rc;
}


/*
** This function may only be called if the b-tree connection already
** has a read or write transaction open on the database.
**
** Read the meta-information out of a database file.  Meta[0]
** is the number of free pages currently in the database.  Meta[1]
** through meta[15] are available for use by higher layers.  Meta[0]
** is read-only, the others are read/write.
** 
** The schema layer numbers meta values differently.  At the schema
** layer (and the SetCookie and ReadCookie opcodes) the number of
** free pages is not visible.  So Cookie[0] is the same as Meta[1].
*/
int sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
  DbPage *pDbPage = 0;
  int rc;
  unsigned char *pP1;
  BtShared *pBt = p->pBt;

  sqlite3BtreeEnter(p);

  assert( p->inTrans>TRANS_NONE );
  /* Reading a meta-data value requires a read-lock on page 1 (and hence
  ** the sqlite_master table. We grab this lock regardless of whether or
  ** not the SQLITE_ReadUncommitted flag is set (the table rooted at page
  ** 1 is treated as a special case by querySharedCacheTableLock()
  ** and setSharedCacheTableLock()).
  */
  rc = querySharedCacheTableLock(p, 1, READ_LOCK);
  assert( SQLITE_OK==querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK) );
  if( rc!=SQLITE_OK ){
    sqlite3BtreeLeave(p);
    return rc;
  }

  assert( pBt->pPage1 );
  assert( idx>=0 && idx<=15 );
  if( pBt->pPage1 ){
    /* The b-tree is already holding a reference to page 1 of the database
    ** file. In this case the required meta-data value can be read directly
    ** from the page data of this reference. This is slightly faster than
    ** requesting a new reference from the pager layer.
    */
    pP1 = (unsigned char *)pBt->pPage1->aData;
  }else{
    /* The b-tree does not have a reference to page 1 of the database file.
    ** Obtain one from the pager layer.
    */
    rc = sqlite3PagerGet(pBt->pPager, 1, &pDbPage);
    if( rc ){
      sqlite3BtreeLeave(p);
      return rc;
    }

    pP1 = (unsigned char *)sqlite3PagerGetData(pDbPage);
  }
  *pMeta = get4byte(&pP1[36 + idx*4]);
  *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]);

  /* If the b-tree is not holding a reference to page 1, then one was 
  ** requested from the pager layer in the above block. Release it now.
  */
  if( !pBt->pPage1 ){
    sqlite3PagerUnref(pDbPage);
  }

  /* If autovacuumed is disabled in this build but we are trying to 
  ** access an autovacuumed database, then make the database readonly. 
  /* If auto-vacuum is disabled in this build and this is an auto-vacuum
  ** database, mark the database as read-only.  */
  */
#ifdef SQLITE_OMIT_AUTOVACUUM
  if( idx==BTREE_LARGEST_ROOT_PAGE && *pMeta>0 ) pBt->readOnly = 1;
#endif

  /* If there is currently an open transaction, grab a read-lock 
  ** on page 1 of the database file. This is done to make sure that
  ** no other connection can modify the meta value just read from
  ** the database until the transaction is concluded.
  */
  if( p->inTrans>0 ){
    rc = setSharedCacheTableLock(p, 1, READ_LOCK);
  }
  sqlite3BtreeLeave(p);
  return rc;
}

/*
** Write meta-information back into the database.  Meta[0] is
** read-only and may not be written.
*/
int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7107
7108
7109
7110
7111
7112
7113

















7114
7115
7116
7117
7118
7119
7120







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    }
#endif
  }
  sqlite3BtreeLeave(p);
  return rc;
}

/*
** Return the flag byte at the beginning of the page that the cursor
** is currently pointing to.
*/
int sqlite3BtreeFlags(BtCursor *pCur){
  /* TODO: What about CURSOR_REQUIRESEEK state? Probably need to call
  ** restoreCursorPosition() here.
  */
  MemPage *pPage;
  restoreCursorPosition(pCur);
  pPage = pCur->apPage[pCur->iPage];
  assert( cursorHoldsMutex(pCur) );
  assert( pPage!=0 );
  assert( pPage->pBt==pCur->pBt );
  return pPage->aData[pPage->hdrOffset];
}

#ifndef SQLITE_OMIT_BTREECOUNT
/*
** The first argument, pCur, is a cursor opened on some b-tree. Count the
** number of entries in the b-tree and write the result to *pnEntry.
**
** SQLITE_OK is returned if the operation is successfully executed. 
** Otherwise, if an error is encountered (i.e. an IO error or database
7068
7069
7070
7071
7072
7073
7074
7075

7076
7077
7078
7079
7080
7081
7082
7154
7155
7156
7157
7158
7159
7160

7161
7162
7163
7164
7165
7166
7167
7168







-
+







    if( pPage->leaf ){
      do {
        if( pCur->iPage==0 ){
          /* All pages of the b-tree have been visited. Return successfully. */
          *pnEntry = nEntry;
          return SQLITE_OK;
        }
        sqlite3BtreeMoveToParent(pCur);
        moveToParent(pCur);
      }while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell );

      pCur->aiIdx[pCur->iPage]++;
      pPage = pCur->apPage[pCur->iPage];
    }

    /* Descend to the child node of the cell that the cursor currently 
7295
7296
7297
7298
7299
7300
7301
7302

7303
7304
7305
7306
7307




7308

7309
7310
7311

7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329

7330
7331
7332
7333
7334
7335
7336
7381
7382
7383
7384
7385
7386
7387

7388

7389
7390
7391
7392
7393
7394
7395
7396

7397
7398
7399

7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417

7418
7419
7420
7421
7422
7423
7424
7425







-
+
-




+
+
+
+
-
+


-
+

















-
+








  /* Check that the page exists
  */
  pBt = pCheck->pBt;
  usableSize = pBt->usableSize;
  if( iPage==0 ) return 0;
  if( checkRef(pCheck, iPage, zParentContext) ) return 0;
  if( (rc = sqlite3BtreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
  if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
    if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck->mallocFailed = 1;
    checkAppendMsg(pCheck, zContext,
       "unable to get the page. error code=%d", rc);
    return 0;
  }

  /* Clear MemPage.isInit to make sure the corruption detection code in
  ** btreeInitPage() is executed.  */
  pPage->isInit = 0;
  if( (rc = sqlite3BtreeInitPage(pPage))!=0 ){
  if( (rc = btreeInitPage(pPage))!=0 ){
    assert( rc==SQLITE_CORRUPT );  /* The only possible error from InitPage */
    checkAppendMsg(pCheck, zContext, 
                   "sqlite3BtreeInitPage() returns error code %d", rc);
                   "btreeInitPage() returns error code %d", rc);
    releasePage(pPage);
    return 0;
  }

  /* Check out all the cells.
  */
  depth = 0;
  for(i=0; i<pPage->nCell && pCheck->mxErr; i++){
    u8 *pCell;
    u32 sz;
    CellInfo info;

    /* Check payload overflow pages
    */
    sqlite3_snprintf(sizeof(zContext), zContext,
             "On tree page %d cell %d: ", iPage, i);
    pCell = findCell(pPage,i);
    sqlite3BtreeParseCellPtr(pPage, pCell, &info);
    btreeParseCellPtr(pPage, pCell, &info);
    sz = info.nData;
    if( !pPage->intKey ) sz += (int)info.nKey;
    assert( sz==info.nPayload );
    if( (sz>info.nLocal) 
     && (&pCell[info.iOverflow]<=&pPage->aData[pBt->usableSize])
    ){
      int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4);
7376
7377
7378
7379
7380
7381
7382
7383

7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396

7397
7398
7399

7400
7401
7402
7403
7404
7405
7406
7407
7408





7409
7410

7411
7412
7413
7414

7415
7416




7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429

7430
7431
7432
7433
7434

7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445



7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465

7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7465
7466
7467
7468
7469
7470
7471

7472




7473
7474
7475
7476
7477
7478
7479
7480

7481
7482
7483

7484
7485
7486
7487
7488
7489
7490



7491
7492
7493
7494
7495


7496




7497


7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513

7514
7515
7516
7517


7518

7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553





7554
7555
7556
7557
7558
7559
7560
7561

7562
7563
7564
7565
7566

7567
7568
7569
7570
7571
7572
7573







-
+
-
-
-
-








-
+


-
+






-
-
-
+
+
+
+
+
-
-
+
-
-
-
-
+
-
-
+
+
+
+












-
+



-
-
+
-










+
+
+




















+

-
-
-
-
-








-





-







  data = pPage->aData;
  hdr = pPage->hdrOffset;
  hit = sqlite3PageMalloc( pBt->pageSize );
  if( hit==0 ){
    pCheck->mallocFailed = 1;
  }else{
    u16 contentOffset = get2byte(&data[hdr+5]);
    if (contentOffset > usableSize) {
    assert( contentOffset<=usableSize );  /* Enforced by btreeInitPage() */
      checkAppendMsg(pCheck, 0, 
                     "Corruption detected in header on page %d",iPage,0);
      goto check_page_abort;
    }
    memset(hit+contentOffset, 0, usableSize-contentOffset);
    memset(hit, 1, contentOffset);
    nCell = get2byte(&data[hdr+3]);
    cellStart = hdr + 12 - 4*pPage->leaf;
    for(i=0; i<nCell; i++){
      int pc = get2byte(&data[cellStart+i*2]);
      u16 size = 1024;
      int j;
      if( pc<=usableSize ){
      if( pc<=usableSize-4 ){
        size = cellSizePtr(pPage, &data[pc]);
      }
      if( (pc+size-1)>=usableSize || pc<0 ){
      if( (pc+size-1)>=usableSize ){
        checkAppendMsg(pCheck, 0, 
            "Corruption detected in cell %d on page %d",i,iPage,0);
      }else{
        for(j=pc+size-1; j>=pc; j--) hit[j]++;
      }
    }
    for(cnt=0, i=get2byte(&data[hdr+1]); i>0 && i<usableSize && cnt<10000; 
           cnt++){
      int size = get2byte(&data[i+2]);
    i = get2byte(&data[hdr+1]);
    while( i>0 ){
      int size, j;
      assert( i<=usableSize-4 );     /* Enforced by btreeInitPage() */
      size = get2byte(&data[i+2]);
      int j;
      if( (i+size-1)>=usableSize || i<0 ){
      assert( i+size<=usableSize );  /* Enforced by btreeInitPage() */
        checkAppendMsg(pCheck, 0,  
            "Corruption detected in cell %d on page %d",i,iPage,0);
      }else{
        for(j=i+size-1; j>=i; j--) hit[j]++;
      for(j=i+size-1; j>=i; j--) hit[j]++;
      }
      i = get2byte(&data[i]);
      j = get2byte(&data[i]);
      assert( j==0 || j>i+size );  /* Enforced by btreeInitPage() */
      assert( j<=usableSize-4 );   /* Enforced by btreeInitPage() */
      i = j;
    }
    for(i=cnt=0; i<usableSize; i++){
      if( hit[i]==0 ){
        cnt++;
      }else if( hit[i]>1 ){
        checkAppendMsg(pCheck, 0,
          "Multiple uses for byte %d of page %d", i, iPage);
        break;
      }
    }
    if( cnt!=data[hdr+7] ){
      checkAppendMsg(pCheck, 0, 
          "Fragmented space is %d byte reported as %d on page %d",
          "Fragmentation of %d bytes reported as %d on page %d",
          cnt, data[hdr+7], iPage);
    }
  }
check_page_abort:
  if (hit) sqlite3PageFree(hit);
  sqlite3PageFree(hit);

  releasePage(pPage);
  return depth+1;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/*
** This routine does a complete check of the given BTree file.  aRoot[] is
** an array of pages numbers were each page number is the root page of
** a table.  nRoot is the number of entries in aRoot.
**
** A read-only or read-write transaction must be opened before calling
** this function.
**
** Write the number of error seen in *pnErr.  Except for some memory
** allocation errors,  an error message held in memory obtained from
** malloc is returned if *pnErr is non-zero.  If *pnErr==0 then NULL is
** returned.  If a memory allocation error occurs, NULL is returned.
*/
char *sqlite3BtreeIntegrityCheck(
  Btree *p,     /* The btree to be checked */
  int *aRoot,   /* An array of root pages numbers for individual trees */
  int nRoot,    /* Number of entries in aRoot[] */
  int mxErr,    /* Stop reporting errors after this many */
  int *pnErr    /* Write number of errors seen to this variable */
){
  Pgno i;
  int nRef;
  IntegrityCk sCheck;
  BtShared *pBt = p->pBt;
  char zErr[100];

  sqlite3BtreeEnter(p);
  assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE );
  nRef = sqlite3PagerRefcount(pBt->pPager);
  if( lockBtreeWithRetry(p)!=SQLITE_OK ){
    *pnErr = 1;
    sqlite3BtreeLeave(p);
    return sqlite3DbStrDup(0, "cannot acquire a read lock on the database");
  }
  sCheck.pBt = pBt;
  sCheck.pPager = pBt->pPager;
  sCheck.nPage = pagerPagecount(sCheck.pBt);
  sCheck.mxErr = mxErr;
  sCheck.nErr = 0;
  sCheck.mallocFailed = 0;
  *pnErr = 0;
  if( sCheck.nPage==0 ){
    unlockBtreeIfUnused(pBt);
    sqlite3BtreeLeave(p);
    return 0;
  }
  sCheck.anRef = sqlite3Malloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) );
  if( !sCheck.anRef ){
    unlockBtreeIfUnused(pBt);
    *pnErr = 1;
    sqlite3BtreeLeave(p);
    return 0;
  }
  for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; }
  i = PENDING_BYTE_PAGE(pBt);
  if( i<=sCheck.nPage ){
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7614
7615
7616
7617
7618
7619
7620

7621
7622
7623
7624
7625
7626
7627







-







#endif
  }

  /* Make sure this analysis did not leave any unref() pages.
  ** This is an internal consistency check; an integrity check
  ** of the integrity check.
  */
  unlockBtreeIfUnused(pBt);
  if( NEVER(nRef != sqlite3PagerRefcount(pBt->pPager)) ){
    checkAppendMsg(&sCheck, 0, 
      "Outstanding page count goes from %d to %d during this analysis",
      nRef, sqlite3PagerRefcount(pBt->pPager)
    );
  }

7659
7660
7661
7662
7663
7664
7665

7666
7667
7668
7669

7670
7671
7672
7673
7674
7675
7676
7677
7678
7679
7680
7681
7682
7683
7684
7685

7686
7687




7688
7689
7690
7691
7692
7693
7694

7695
7696




7697
7698
7699
7700
7701
7702

7703
7704
7705




7706
7707
7708
7709
7710
7711
7712



7713
7714
7715
7716
7717
7718

7719
7720

7721
7722

7723
7724
7725
7726
7727
7728
7729
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766
7767


7768
7769
7770
7771
7772
7773
7774

7775
7776

7777
7778

7779
7780
7781
7782
7783
7784
7785
7786
7787

7788
7789


7790
7791
7792
7793
7794
7795
7796
7797



7798
7799
7800






7801


7802


7803
7804
7805
7806
7807
7808
7809
7810







+




+
















+
-
-
+
+
+
+



-


-
+

-
+
+
+
+





-
+

-
-
+
+
+
+




-
-
-
+
+
+
-
-
-
-
-
-
+
-
-
+
-
-
+







/*
** Obtain a lock on the table whose root page is iTab.  The
** lock is a write lock if isWritelock is true or a read lock
** if it is false.
*/
int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){
  int rc = SQLITE_OK;
  assert( p->inTrans!=TRANS_NONE );
  if( p->sharable ){
    u8 lockType = READ_LOCK + isWriteLock;
    assert( READ_LOCK+1==WRITE_LOCK );
    assert( isWriteLock==0 || isWriteLock==1 );

    sqlite3BtreeEnter(p);
    rc = querySharedCacheTableLock(p, iTab, lockType);
    if( rc==SQLITE_OK ){
      rc = setSharedCacheTableLock(p, iTab, lockType);
    }
    sqlite3BtreeLeave(p);
  }
  return rc;
}
#endif

#ifndef SQLITE_OMIT_INCRBLOB
/*
** Argument pCsr must be a cursor opened for writing on an 
** INTKEY table currently pointing at a valid table entry. 
** This function modifies the data stored as part of that entry.
**
** Only the data content may only be modified, it is not possible
** to change the length of the data stored.
** Only the data content may only be modified, it is not possible to 
** change the length of the data stored. If this function is called with
** parameters that attempt to write past the end of the existing data,
** no modifications are made and SQLITE_CORRUPT is returned.
*/
int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
  int rc;

  assert( cursorHoldsMutex(pCsr) );
  assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) );
  assert(pCsr->isIncrblobHandle);
  assert( pCsr->isIncrblobHandle );

  restoreCursorPosition(pCsr);
  rc = restoreCursorPosition(pCsr);
  if( rc!=SQLITE_OK ){
    return rc;
  }
  assert( pCsr->eState!=CURSOR_REQUIRESEEK );
  if( pCsr->eState!=CURSOR_VALID ){
    return SQLITE_ABORT;
  }

  /* Check some preconditions: 
  /* Check some assumptions: 
  **   (a) the cursor is open for writing,
  **   (b) there is no read-lock on the table being modified and
  **   (c) the cursor points at a valid row of an intKey table.
  **   (b) there is a read/write transaction open,
  **   (c) the connection holds a write-lock on the table (if required),
  **   (d) there are no conflicting read-locks, and
  **   (e) the cursor points at a valid row of an intKey table.
  */
  if( !pCsr->wrFlag ){
    return SQLITE_READONLY;
  }
  assert( !pCsr->pBt->readOnly 
          && pCsr->pBt->inTransaction==TRANS_WRITE );
  rc = checkForReadConflicts(pCsr->pBtree, pCsr->pgnoRoot, pCsr, 0);
  assert( !pCsr->pBt->readOnly && pCsr->pBt->inTransaction==TRANS_WRITE );
  assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) );
  assert( !hasReadConflicts(pCsr->pBtree, pCsr->pgnoRoot) );
  if( rc!=SQLITE_OK ){
    /* The table pCur points to has a read lock */
    assert( rc==SQLITE_LOCKED_SHAREDCACHE );
    return rc;
  }
  if( pCsr->eState==CURSOR_INVALID || !pCsr->apPage[pCsr->iPage]->intKey ){
  assert( pCsr->apPage[pCsr->iPage]->intKey );
    return SQLITE_ERROR;
  }


  return accessPayload(pCsr, offset, amt, (unsigned char *)z, 0, 1);
  return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1);
}

/* 
** Set a flag on this cursor to cache the locations of pages from the 
** overflow list for the current row. This is used by cursors opened
** for incremental blob IO only.
**
Changes to src/btree.h.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
8
9
10
11
12
13
14


15
16
17
18
19
20
21







-
-







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite B-Tree file
** subsystem.  See comments in the source code for a detailed description
** of what each interface routine does.
**
** @(#) $Id: btree.h,v 1.116 2009/06/03 11:25:07 danielk1977 Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_

/* TODO: This definition is just included so other modules compile. It
** needs to be revisited.
*/
93
94
95
96
97
98
99
100
101


102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
91
92
93
94
95
96
97


98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126







-
-
+
+



















-
+







int sqlite3BtreeRollback(Btree*);
int sqlite3BtreeBeginStmt(Btree*,int);
int sqlite3BtreeCreateTable(Btree*, int*, int flags);
int sqlite3BtreeIsInTrans(Btree*);
int sqlite3BtreeIsInReadTrans(Btree*);
int sqlite3BtreeIsInBackup(Btree*);
void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
int sqlite3BtreeSchemaLocked(Btree *);
int sqlite3BtreeLockTable(Btree *, int, u8);
int sqlite3BtreeSchemaLocked(Btree *pBtree);
int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock);
int sqlite3BtreeSavepoint(Btree *, int, int);

const char *sqlite3BtreeGetFilename(Btree *);
const char *sqlite3BtreeGetJournalname(Btree *);
int sqlite3BtreeCopyFile(Btree *, Btree *);

int sqlite3BtreeIncrVacuum(Btree *);

/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR
** of the following flags:
*/
#define BTREE_INTKEY     1    /* Table has only 64-bit signed integer keys */
#define BTREE_ZERODATA   2    /* Table has keys only - no data */
#define BTREE_LEAFDATA   4    /* Data stored in leaves only.  Implies INTKEY */

int sqlite3BtreeDropTable(Btree*, int, int*);
int sqlite3BtreeClearTable(Btree*, int, int*);
void sqlite3BtreeTripAllCursors(Btree*, int);

int sqlite3BtreeGetMeta(Btree*, int idx, u32 *pValue);
void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);

/*
** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta
** should be one of the following values. The integer values are assigned 
** to constants so that the offset of the corresponding field in an
** SQLite database header may be found using the following formula:
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194




195
196
197
198
199
200
201
146
147
148
149
150
151
152







153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195







-
-
-
-
-
-
-
















-
















+
+
+
+







  int wrFlag,                          /* 1 for writing.  0 for read-only */
  struct KeyInfo*,                     /* First argument to compare function */
  BtCursor *pCursor                    /* Space to write cursor structure */
);
int sqlite3BtreeCursorSize(void);

int sqlite3BtreeCloseCursor(BtCursor*);
int sqlite3BtreeMoveto(
  BtCursor*,
  const void *pKey,
  i64 nKey,
  int bias,
  int *pRes
);
int sqlite3BtreeMovetoUnpacked(
  BtCursor*,
  UnpackedRecord *pUnKey,
  i64 intKey,
  int bias,
  int *pRes
);
int sqlite3BtreeCursorHasMoved(BtCursor*, int*);
int sqlite3BtreeDelete(BtCursor*);
int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
                                  const void *pData, int nData,
                                  int nZero, int bias, int seekResult);
int sqlite3BtreeFirst(BtCursor*, int *pRes);
int sqlite3BtreeLast(BtCursor*, int *pRes);
int sqlite3BtreeNext(BtCursor*, int *pRes);
int sqlite3BtreeEof(BtCursor*);
int sqlite3BtreeFlags(BtCursor*);
int sqlite3BtreePrevious(BtCursor*, int *pRes);
int sqlite3BtreeKeySize(BtCursor*, i64 *pSize);
int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt);
const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt);
int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
void sqlite3BtreeSetCachedRowid(BtCursor*, sqlite3_int64);
sqlite3_int64 sqlite3BtreeGetCachedRowid(BtCursor*);

char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
struct Pager *sqlite3BtreePager(Btree*);

int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
void sqlite3BtreeCacheOverflow(BtCursor *);
void sqlite3BtreeClearCursor(BtCursor *);

#ifndef NDEBUG
int sqlite3BtreeCursorIsValid(BtCursor*);
#endif

#ifndef SQLITE_OMIT_BTREECOUNT
int sqlite3BtreeCount(BtCursor *, i64 *);
#endif

#ifdef SQLITE_TEST
int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
Changes to src/btreeInt.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11


12
13
14
15
16
17
18











-
-







/*
** 2004 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btreeInt.h,v 1.49 2009/06/24 05:40:34 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
**
44
45
46
47
48
49
50
51
52
53



54
55
56
57
58
59
60
42
43
44
45
46
47
48



49
50
51
52
53
54
55
56
57
58







-
-
-
+
+
+







** page has a small header which contains the Ptr(N) pointer and other
** information such as the size of key and data.
**
** FORMAT DETAILS
**
** The file is divided into pages.  The first page is called page 1,
** the second is page 2, and so forth.  A page number of zero indicates
** "no such page".  The page size can be anything between 512 and 65536.
** Each page can be either a btree page, a freelist page or an overflow
** page.
** "no such page".  The page size can be any power of 2 between 512 and 32768.
** Each page can be either a btree page, a freelist page, an overflow
** page, or a pointer-map page.
**
** The first page is always a btree page.  The first 100 bytes of the first
** page contain a special header (the "file header") that describes the file.
** The format of the file header is as follows:
**
**   OFFSET   SIZE    DESCRIPTION
**      0      16     Header string: "SQLite format 3\000"
298
299
300
301
302
303
304


















305
306
307
308
309
310
311
312
313
314
315


316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335



336
337
338
339
340
341
342
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329


330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+









-
-
+
+




















+
+
+







/*
** The in-memory image of a disk page has the auxiliary information appended
** to the end.  EXTRA_SIZE is the number of bytes of space needed to hold
** that extra information.
*/
#define EXTRA_SIZE sizeof(MemPage)

/*
** A linked list of the following structures is stored at BtShared.pLock.
** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor 
** is opened on the table with root page BtShared.iTable. Locks are removed
** from this list when a transaction is committed or rolled back, or when
** a btree handle is closed.
*/
struct BtLock {
  Btree *pBtree;        /* Btree handle holding this lock */
  Pgno iTable;          /* Root page of table */
  u8 eLock;             /* READ_LOCK or WRITE_LOCK */
  BtLock *pNext;        /* Next in BtShared.pLock list */
};

/* Candidate values for BtLock.eLock */
#define READ_LOCK     1
#define WRITE_LOCK    2

/* A Btree handle
**
** A database connection contains a pointer to an instance of
** this object for every database file that it has open.  This structure
** is opaque to the database connection.  The database connection cannot
** see the internals of this structure and only deals with pointers to
** this structure.
**
** For some database files, the same underlying database cache might be 
** shared between multiple connections.  In that case, each contection
** has it own pointer to this object.  But each instance of this object
** shared between multiple connections.  In that case, each connection
** has it own instance of this object.  But each instance of this object
** points to the same BtShared object.  The database cache and the
** schema associated with the database file are all contained within
** the BtShared object.
**
** All fields in this structure are accessed under sqlite3.mutex.
** The pBt pointer itself may not be changed while there exists cursors 
** in the referenced BtShared that point back to this Btree since those
** cursors have to do go through this Btree to find their BtShared and
** they often do so without holding sqlite3.mutex.
*/
struct Btree {
  sqlite3 *db;       /* The database connection holding this btree */
  BtShared *pBt;     /* Sharable content of this btree */
  u8 inTrans;        /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
  u8 sharable;       /* True if we can share pBt with another db */
  u8 locked;         /* True if db currently has pBt locked */
  int wantToLock;    /* Number of nested calls to sqlite3BtreeEnter() */
  int nBackup;       /* Number of backup operations reading this btree */
  Btree *pNext;      /* List of other sharable Btrees from the same db */
  Btree *pPrev;      /* Back pointer of the same list */
#ifndef SQLITE_OMIT_SHARED_CACHE
  BtLock lock;       /* Object used to lock page 1 */
#endif
};

/*
** Btree.inTrans may take one of the following values.
**
** If the shared-data extension is enabled, there may be multiple users
** of the Btree structure. At most one of these may open a write transaction,
446
447
448
449
450
451
452
453

454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474

475
476
477
478
479
480
481
465
466
467
468
469
470
471

472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492

493
494
495
496
497
498
499
500







-
+




















-
+







/*
** A cursor is a pointer to a particular entry within a particular
** b-tree within a database file.
**
** The entry is identified by its MemPage and the index in
** MemPage.aCell[] of the entry.
**
** When a single database file can shared by two more database connections,
** A single database file can shared by two more database connections,
** but cursors cannot be shared.  Each cursor is associated with a
** particular database connection identified BtCursor.pBtree.db.
**
** Fields in this structure are accessed under the BtShared.mutex
** found at self->pBt->mutex. 
*/
struct BtCursor {
  Btree *pBtree;            /* The Btree to which this cursor belongs */
  BtShared *pBt;            /* The BtShared this cursor points to */
  BtCursor *pNext, *pPrev;  /* Forms a linked list of all cursors */
  struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
  Pgno pgnoRoot;            /* The root page of this tree */
  sqlite3_int64 cachedRowid; /* Next rowid cache.  0 means not valid */
  CellInfo info;            /* A parse of the cell we are pointing at */
  u8 wrFlag;                /* True if writable */
  u8 atLast;                /* Cursor pointing to the last entry */
  u8 validNKey;             /* True if info.nKey is valid */
  u8 eState;                /* One of the CURSOR_XXX constants (see below) */
  void *pKey;      /* Saved key that was cursor's last known position */
  i64 nKey;        /* Size of pKey, or last integer key */
  int skip;        /* (skip<0) -> Prev() is a no-op. (skip>0) -> Next() is */
  int skipNext;    /* Prev() is noop if negative. Next() is noop if positive */
#ifndef SQLITE_OMIT_INCRBLOB
  u8 isIncrblobHandle;      /* True if this cursor is an incr. io handle */
  Pgno *aOverflow;          /* Cache of overflow page locations */
#endif
  i16 iPage;                            /* Index of current page in apPage */
  MemPage *apPage[BTCURSOR_MAX_DEPTH];  /* Pages from root to current page */
  u16 aiIdx[BTCURSOR_MAX_DEPTH];        /* Current index in apPage[i] */
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
531
532
533
534
535
536
537


















538
539
540
541
542
543
544







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







#define CURSOR_FAULT             3

/* 
** The database page the PENDING_BYTE occupies. This page is never used.
*/
# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)

/*
** A linked list of the following structures is stored at BtShared.pLock.
** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor 
** is opened on the table with root page BtShared.iTable. Locks are removed
** from this list when a transaction is committed or rolled back, or when
** a btree handle is closed.
*/
struct BtLock {
  Btree *pBtree;        /* Btree handle holding this lock */
  Pgno iTable;          /* Root page of table */
  u8 eLock;             /* READ_LOCK or WRITE_LOCK */
  BtLock *pNext;        /* Next in BtShared.pLock list */
};

/* Candidate values for BtLock.eLock */
#define READ_LOCK     1
#define WRITE_LOCK    2

/*
** These macros define the location of the pointer-map entry for a 
** database page. The first argument to each is the number of usable
** bytes on each page of the database (often 1024). The second is the
** page number to look up in the pointer map.
**
** PTRMAP_PAGENO returns the database page number of the pointer-map
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
632
633
634
635
636
637
638






















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/*
** Read or write a two- and four-byte big-endian integer values.
*/
#define get2byte(x)   ((x)[0]<<8 | (x)[1])
#define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v))
#define get4byte sqlite3Get4byte
#define put4byte sqlite3Put4byte

/*
** Internal routines that should be accessed by the btree layer only.
*/
int sqlite3BtreeGetPage(BtShared*, Pgno, MemPage**, int);
int sqlite3BtreeInitPage(MemPage *pPage);
void sqlite3BtreeParseCellPtr(MemPage*, u8*, CellInfo*);
void sqlite3BtreeParseCell(MemPage*, int, CellInfo*);
int sqlite3BtreeRestoreCursorPosition(BtCursor *pCur);
void sqlite3BtreeMoveToParent(BtCursor *pCur);

#ifdef SQLITE_TEST
void sqlite3BtreeGetTempCursor(BtCursor *pCur, BtCursor *pTempCur);
void sqlite3BtreeReleaseTempCursor(BtCursor *pCur);
#endif
Changes to src/build.c.
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
17
18
19
20
21
22
23


24
25
26
27
28
29
30







-
-







**     DROP TABLE
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.554 2009/06/25 11:50:21 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
*/
60
61
62
63
64
65
66

67
68
69
70
71

72
73


74
75
76
77
78
79
80
81
82
83
84





85
86
87
88
89
90
91


92
93
94
95
96
97
98
58
59
60
61
62
63
64
65
66
67
68

69
70


71
72
73
74
75
76
77
78





79
80
81
82
83
84
85
86
87
88


89
90
91
92
93
94
95
96
97







+



-

+
-
-
+
+






-
-
-
-
-
+
+
+
+
+





-
-
+
+







void sqlite3TableLock(
  Parse *pParse,     /* Parsing context */
  int iDb,           /* Index of the database containing the table to lock */
  int iTab,          /* Root page number of the table to be locked */
  u8 isWriteLock,    /* True for a write lock */
  const char *zName  /* Name of the table to be locked */
){
  Parse *pToplevel = sqlite3ParseToplevel(pParse);
  int i;
  int nBytes;
  TableLock *p;

  assert( iDb>=0 );

  for(i=0; i<pParse->nTableLock; i++){
    p = &pParse->aTableLock[i];
  for(i=0; i<pToplevel->nTableLock; i++){
    p = &pToplevel->aTableLock[i];
    if( p->iDb==iDb && p->iTab==iTab ){
      p->isWriteLock = (p->isWriteLock || isWriteLock);
      return;
    }
  }

  nBytes = sizeof(TableLock) * (pParse->nTableLock+1);
  pParse->aTableLock = 
      sqlite3DbReallocOrFree(pParse->db, pParse->aTableLock, nBytes);
  if( pParse->aTableLock ){
    p = &pParse->aTableLock[pParse->nTableLock++];
  nBytes = sizeof(TableLock) * (pToplevel->nTableLock+1);
  pToplevel->aTableLock =
      sqlite3DbReallocOrFree(pToplevel->db, pToplevel->aTableLock, nBytes);
  if( pToplevel->aTableLock ){
    p = &pToplevel->aTableLock[pToplevel->nTableLock++];
    p->iDb = iDb;
    p->iTab = iTab;
    p->isWriteLock = isWriteLock;
    p->zName = zName;
  }else{
    pParse->nTableLock = 0;
    pParse->db->mallocFailed = 1;
    pToplevel->nTableLock = 0;
    pToplevel->db->mallocFailed = 1;
  }
}

/*
** Code an OP_TableLock instruction for each table locked by the
** statement (configured by calls to sqlite3TableLock()).
*/
133
134
135
136
137
138
139


140
141
142
143
144
145
146
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147







+
+







  if( pParse->nested ) return;
  if( pParse->nErr ) return;

  /* Begin by generating some termination code at the end of the
  ** vdbe program
  */
  v = sqlite3GetVdbe(pParse);
  assert( !pParse->isMultiWrite 
       || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
  if( v ){
    sqlite3VdbeAddOp0(v, OP_Halt);

    /* The cookie mask contains one bit for each database file open.
    ** (Bit 0 is for main, bit 1 is for temp, and so forth.)  Bits are
    ** set for each database that is used.  Generate code to start a
    ** transaction on each used database and to verify the schema cookie
158
159
160
161
162
163
164
165

166
167
168
169
170
171
172
159
160
161
162
163
164
165

166
167
168
169
170
171
172
173







-
+







          sqlite3VdbeAddOp2(v,OP_VerifyCookie, iDb, pParse->cookieValue[iDb]);
        }
      }
#ifndef SQLITE_OMIT_VIRTUALTABLE
      {
        int i;
        for(i=0; i<pParse->nVtabLock; i++){
          char *vtab = (char *)pParse->apVtabLock[i]->pVtab;
          char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]);
          sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB);
        }
        pParse->nVtabLock = 0;
      }
#endif

      /* Once all the cookies have been verified and transactions opened, 
189
190
191
192
193
194
195



196
197


198
199
200
201
202
203
204
190
191
192
193
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208
209







+
+
+

-
+
+







  */
  if( v && ALWAYS(pParse->nErr==0) && !db->mallocFailed ){
#ifdef SQLITE_DEBUG
    FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
    sqlite3VdbeTrace(v, trace);
#endif
    assert( pParse->iCacheLevel==0 );  /* Disables and re-enables match */
    /* A minimum of one cursor is required if autoincrement is used
    *  See ticket [a696379c1f08866] */
    if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1;
    sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem,
                         pParse->nTab, pParse->explain);
                         pParse->nTab, pParse->nMaxArg, pParse->explain,
                         pParse->isMultiWrite && pParse->mayAbort);
    pParse->rc = SQLITE_DONE;
    pParse->colNamesSet = 0;
  }else if( pParse->rc==SQLITE_OK ){
    pParse->rc = SQLITE_ERROR;
  }
  pParse->nTab = 0;
  pParse->nMem = 0;
338
339
340
341
342
343
344
345



346
347
348
349
350
351
352
343
344
345
346
347
348
349

350
351
352
353
354
355
356
357
358
359







-
+
+
+







}

/*
** Reclaim the memory used by an index
*/
static void freeIndex(Index *p){
  sqlite3 *db = p->pTable->dbMem;
  /* testcase( db==0 ); */
#ifndef SQLITE_OMIT_ANALYZE
  sqlite3DeleteIndexSamples(p);
#endif
  sqlite3DbFree(db, p->zColAff);
  sqlite3DbFree(db, p);
}

/*
** Remove the given index from the index hash table, and free
** its memory structures.
420
421
422
423
424
425
426

427
428
429
430
431
432
433
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441







+







      assert(i==1 || (pDb->pBt && sqlite3BtreeHoldsMutex(pDb->pBt)));
      sqlite3SchemaFree(pDb->pSchema);
    }
    if( iDb>0 ) return;
  }
  assert( iDb==0 );
  db->flags &= ~SQLITE_InternChanges;
  sqlite3VtabUnlockList(db);
  sqlite3BtreeLeaveAll(db);

  /* If one or more of the auxiliary database files has been closed,
  ** then remove them from the auxiliary database list.  We take the
  ** opportunity to do this here since we have just deleted all of the
  ** schema hash tables and therefore do not have to make any changes
  ** to any of those tables.
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
498
499
500
501
502
503
504

505
506
507
508
509
510
511







-







** This routine just deletes the data structure.  It does not unlink
** the table data structure from the hash table.  But it does destroy
** memory structures of the indices and foreign keys associated with 
** the table.
*/
void sqlite3DeleteTable(Table *pTable){
  Index *pIndex, *pNext;
  FKey *pFKey, *pNextFKey;
  sqlite3 *db;

  if( pTable==0 ) return;
  db = pTable->dbMem;
  testcase( db==0 );

  /* Do not delete the table until the reference count reaches zero. */
512
513
514
515
516
517
518
519
520

521
522
523

524
525
526
527
528
529
530
531
532
519
520
521
522
523
524
525


526



527


528
529
530
531
532
533
534







-
-
+
-
-
-
+
-
-







  */
  for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
    pNext = pIndex->pNext;
    assert( pIndex->pSchema==pTable->pSchema );
    sqlite3DeleteIndex(pIndex);
  }

#ifndef SQLITE_OMIT_FOREIGN_KEY
  /* Delete all foreign keys associated with this table. */
  /* Delete any foreign keys attached to this table. */
  for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){
    pNextFKey = pFKey->pNextFrom;
    sqlite3DbFree(db, pFKey);
  sqlite3FkDelete(pTable);
  }
#endif

  /* Delete the Table structure itself.
  */
  sqliteResetColumnNames(pTable);
  sqlite3DbFree(db, pTable->zName);
  sqlite3DbFree(db, pTable->zColAff);
  sqlite3SelectDelete(db, pTable->pSelect);
1160
1161
1162
1163
1164
1165
1166

1167




1168
1169
1170
1171
1172
1173
1174
1162
1163
1164
1165
1166
1167
1168
1169

1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180







+
-
+
+
+
+







    pTab->tabFlags |= autoInc*TF_Autoincrement;
  }else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
    sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
       "INTEGER PRIMARY KEY");
#endif
  }else{
    Index *p;
    sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0);
    p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0);
    if( p ){
      p->autoIndex = 2;
    }
    pList = 0;
  }

primary_key_exit:
  sqlite3ExprListDelete(pParse->db, pList);
  return;
}
1251
1252
1253
1254
1255
1256
1257
1258

1259
1260
1261
1262
1263
1264
1265
1257
1258
1259
1260
1261
1262
1263

1264
1265
1266
1267
1268
1269
1270
1271







-
+







  sqlite3 *db = pParse->db;
  u8 enc = ENC(db);
  u8 initbusy = db->init.busy;
  CollSeq *pColl;

  pColl = sqlite3FindCollSeq(db, enc, zName, initbusy);
  if( !initbusy && (!pColl || !pColl->xCmp) ){
    pColl = sqlite3GetCollSeq(db, pColl, zName);
    pColl = sqlite3GetCollSeq(db, enc, pColl, zName);
    if( !pColl ){
      sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
    }
  }

  return pColl;
}
1871
1872
1873
1874
1875
1876
1877

1878
1879
1880
1881
1882
1883
1884
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891







+







** if a root-page of another table is moved by the btree-layer whilst
** erasing iTable (this can happen with an auto-vacuum database).
*/ 
static void destroyRootPage(Parse *pParse, int iTable, int iDb){
  Vdbe *v = sqlite3GetVdbe(pParse);
  int r1 = sqlite3GetTempReg(pParse);
  sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb);
  sqlite3MayAbort(pParse);
#ifndef SQLITE_OMIT_AUTOVACUUM
  /* OP_Destroy stores an in integer r1. If this integer
  ** is non-zero, then it is the root page number of a table moved to
  ** location iTable. The following code modifies the sqlite_master table to
  ** reflect this.
  **
  ** The "#NNN" in the SQL is a special constant that means whatever value
1998
1999
2000
2001
2002
2003
2004
2005

2006
2007
2008
2009
2010
2011
2012
2005
2006
2007
2008
2009
2010
2011

2012
2013
2014
2015
2016
2017
2018
2019







-
+







        code = SQLITE_DROP_TEMP_VIEW;
      }else{
        code = SQLITE_DROP_VIEW;
      }
#ifndef SQLITE_OMIT_VIRTUALTABLE
    }else if( IsVirtual(pTab) ){
      code = SQLITE_DROP_VTABLE;
      zArg2 = pTab->pMod->zName;
      zArg2 = sqlite3GetVTable(db, pTab)->pMod->zName;
#endif
    }else{
      if( !OMIT_TEMPDB && iDb==1 ){
        code = SQLITE_DROP_TEMP_TABLE;
      }else{
        code = SQLITE_DROP_TABLE;
      }
2048
2049
2050
2051
2052
2053
2054

2055
2056
2057
2058
2059
2060
2061
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069







+







    sqlite3BeginWriteOperation(pParse, 1, iDb);

#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( IsVirtual(pTab) ){
      sqlite3VdbeAddOp0(v, OP_VBegin);
    }
#endif
    sqlite3FkDropTable(pParse, pName, pTab);

    /* Drop all triggers associated with the table being dropped. Code
    ** is generated to remove entries from sqlite_master and/or
    ** sqlite_temp_master if required.
    */
    pTrigger = sqlite3TriggerList(pParse, pTab);
    while( pTrigger ){
2138
2139
2140
2141
2142
2143
2144

2145
2146
2147
2148
2149
2150
2151
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160







+







  Token *pTo,          /* Name of the other table */
  ExprList *pToCol,    /* Columns in the other table */
  int flags            /* Conflict resolution algorithms. */
){
  sqlite3 *db = pParse->db;
#ifndef SQLITE_OMIT_FOREIGN_KEY
  FKey *pFKey = 0;
  FKey *pNextTo;
  Table *p = pParse->pNewTable;
  int nByte;
  int i;
  int nCol;
  char *z;

  assert( pTo!=0 );
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221















2222
2223
2224
2225
2226
2227
2228
2221
2222
2223
2224
2225
2226
2227



2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249







-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







      pFKey->aCol[i].zCol = z;
      memcpy(z, pToCol->a[i].zName, n);
      z[n] = 0;
      z += n+1;
    }
  }
  pFKey->isDeferred = 0;
  pFKey->deleteConf = (u8)(flags & 0xff);
  pFKey->updateConf = (u8)((flags >> 8 ) & 0xff);
  pFKey->insertConf = (u8)((flags >> 16 ) & 0xff);
  pFKey->aAction[0] = (u8)(flags & 0xff);            /* ON DELETE action */
  pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff);    /* ON UPDATE action */

  pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash, 
      pFKey->zTo, sqlite3Strlen30(pFKey->zTo), (void *)pFKey
  );
  if( pNextTo==pFKey ){
    db->mallocFailed = 1;
    goto fk_end;
  }
  if( pNextTo ){
    assert( pNextTo->pPrevTo==0 );
    pFKey->pNextTo = pNextTo;
    pNextTo->pPrevTo = pFKey;
  }

  /* Link the foreign key to the table as the last step.
  */
  p->pFKey = pFKey;
  pFKey = 0;

fk_end:
2240
2241
2242
2243
2244
2245
2246
2247

2248
2249
2250
2251
2252
2253
2254
2261
2262
2263
2264
2265
2266
2267

2268
2269
2270
2271
2272
2273
2274
2275







-
+







** accordingly.
*/
void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){
#ifndef SQLITE_OMIT_FOREIGN_KEY
  Table *pTab;
  FKey *pFKey;
  if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return;
  assert( isDeferred==0 || isDeferred==1 );
  assert( isDeferred==0 || isDeferred==1 ); /* EV: R-30323-21917 */
  pFKey->isDeferred = (u8)isDeferred;
#endif
}

/*
** Generate code that will erase and refill index *pIdx.  This is
** used to initialize a newly created index or to recompute the
2312
2313
2314
2315
2316
2317
2318
2319
2320


2321
2322
2323
2324
2325
2326
2327
2333
2334
2335
2336
2337
2338
2339


2340
2341
2342
2343
2344
2345
2346
2347
2348







-
-
+
+







    ** (made available to the compiler for reuse) using 
    ** sqlite3ReleaseTempRange(). So in some ways having the OP_IsUnique
    ** opcode use the values stored within seems dangerous. However, since
    ** we can be sure that no other temp registers have been allocated
    ** since sqlite3ReleaseTempRange() was called, it is safe to do so.
    */
    sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx, j2, regRowid, pRegKey, P4_INT32);
    sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, OE_Abort, 0,
                    "indexed columns are not unique", P4_STATIC);
    sqlite3HaltConstraint(
        pParse, OE_Abort, "indexed columns are not unique", P4_STATIC);
  }
  sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord);
  sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
  sqlite3ReleaseTempReg(pParse, regRecord);
  sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
  sqlite3VdbeJumpHere(v, addr1);
  sqlite3VdbeAddOp1(v, OP_Close, iTab);
2335
2336
2337
2338
2339
2340
2341




2342
2343

2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354

2355
2356
2357
2358
2359
2360
2361
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367

2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387







+
+
+
+

-
+











+







** UNIQUE constraint.  If pTable and pIndex are NULL, use pParse->pNewTable
** as the table to be indexed.  pParse->pNewTable is a table that is
** currently being constructed by a CREATE TABLE statement.
**
** pList is a list of columns to be indexed.  pList will be NULL if this
** is a primary key or unique-constraint on the most recent column added
** to the table currently under construction.  
**
** If the index is created successfully, return a pointer to the new Index
** structure. This is used by sqlite3AddPrimaryKey() to mark the index
** as the tables primary key (Index.autoIndex==2).
*/
void sqlite3CreateIndex(
Index *sqlite3CreateIndex(
  Parse *pParse,     /* All information about this parse */
  Token *pName1,     /* First part of index name. May be NULL */
  Token *pName2,     /* Second part of index name. May be NULL */
  SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */
  ExprList *pList,   /* A list of columns to be indexed */
  int onError,       /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  Token *pStart,     /* The CREATE token that begins this statement */
  Token *pEnd,       /* The ")" that closes the CREATE INDEX statement */
  int sortOrder,     /* Sort order of primary key when pList==NULL */
  int ifNotExist     /* Omit error if index already exists */
){
  Index *pRet = 0;     /* Pointer to return */
  Table *pTab = 0;     /* Table to be indexed */
  Index *pIndex = 0;   /* The index to be created */
  char *zName = 0;     /* Name of the index */
  int nName;           /* Number of characters in zName */
  int i, j;
  Token nullId;        /* Fake token for an empty ID list */
  DbFixer sFix;        /* For assigning database names to pTable */
2783
2784
2785
2786
2787
2788
2789

2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802

2803
2804
2805
2806
2807
2808
2809
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828

2829
2830
2831
2832
2833
2834
2835
2836







+












-
+







      Index *pOther = pTab->pIndex;
      while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){
        pOther = pOther->pNext;
      }
      pIndex->pNext = pOther->pNext;
      pOther->pNext = pIndex;
    }
    pRet = pIndex;
    pIndex = 0;
  }

  /* Clean up before exiting */
exit_create_index:
  if( pIndex ){
    sqlite3_free(pIndex->zColAff);
    sqlite3DbFree(db, pIndex);
  }
  sqlite3ExprListDelete(db, pList);
  sqlite3SrcListDelete(db, pTblName);
  sqlite3DbFree(db, zName);
  return;
  return pRet;
}

/*
** Fill the Index.aiRowEst[] array with default information - information
** to be used when we have not run the ANALYZE command.
**
** aiRowEst[0] is suppose to contain the number of elements in the index.
3204
3205
3206
3207
3208
3209
3210






3211
3212
3213
3214
3215
3216

3217
3218
3219
3220
3221
3222
3223
3224
3225
3226







3227
3228
3229
3230
3231
3232
3233
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245




3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270







+
+
+
+
+
+


-
-
-
-
+










+
+
+
+
+
+
+







  Token *pAlias,          /* The right-hand side of the AS subexpression */
  Select *pSubquery,      /* A subquery used in place of a table name */
  Expr *pOn,              /* The ON clause of a join */
  IdList *pUsing          /* The USING clause of a join */
){
  struct SrcList_item *pItem;
  sqlite3 *db = pParse->db;
  if( !p && (pOn || pUsing) ){
    sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s", 
      (pOn ? "ON" : "USING")
    );
    goto append_from_error;
  }
  p = sqlite3SrcListAppend(db, p, pTable, pDatabase);
  if( p==0 || NEVER(p->nSrc==0) ){
    sqlite3ExprDelete(db, pOn);
    sqlite3IdListDelete(db, pUsing);
    sqlite3SelectDelete(db, pSubquery);
    return p;
    goto append_from_error;
  }
  pItem = &p->a[p->nSrc-1];
  assert( pAlias!=0 );
  if( pAlias->n ){
    pItem->zAlias = sqlite3NameFromToken(db, pAlias);
  }
  pItem->pSelect = pSubquery;
  pItem->pOn = pOn;
  pItem->pUsing = pUsing;
  return p;

 append_from_error:
  assert( p==0 );
  sqlite3ExprDelete(db, pOn);
  sqlite3IdListDelete(db, pUsing);
  sqlite3SelectDelete(db, pSubquery);
  return 0;
}

/*
** Add an INDEXED BY or NOT INDEXED clause to the most recently added 
** element of the source-list passed as the second argument.
*/
void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){
3406
3407
3408
3409
3410
3411
3412
3413

3414
3415
3416

3417
3418


3419
3420
3421

3422
3423



3424
3425
3426
3427
3428
3429
3430



3431
3432

3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451

3452
3453
3454
3455
3456
3457
3458














































3459

3460
3461
3462
3463
3464
3465
3466
3443
3444
3445
3446
3447
3448
3449

3450


3451
3452


3453
3454



3455
3456
3457
3458
3459
3460
3461
3462
3463
3464



3465
3466
3467
3468

3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490






3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545







-
+
-
-

+
-
-
+
+
-
-
-
+


+
+
+




-
-
-
+
+
+

-
+



















+

-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+







** cookie verification subroutine code happens in sqlite3FinishCoding().
**
** If iDb<0 then code the OP_Goto only - don't set flag to verify the
** schema on any databases.  This can be used to position the OP_Goto
** early in the code, before we know if any database tables will be used.
*/
void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
  sqlite3 *db;
  Parse *pToplevel = sqlite3ParseToplevel(pParse);
  Vdbe *v;
  int mask;

  if( pToplevel->cookieGoto==0 ){
  v = sqlite3GetVdbe(pParse);
  if( v==0 ) return;  /* This only happens if there was a prior error */
    Vdbe *v = sqlite3GetVdbe(pToplevel);
    if( v==0 ) return;  /* This only happens if there was a prior error */
  db = pParse->db;
  if( pParse->cookieGoto==0 ){
    pParse->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1;
    pToplevel->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1;
  }
  if( iDb>=0 ){
    sqlite3 *db = pToplevel->db;
    int mask;

    assert( iDb<db->nDb );
    assert( db->aDb[iDb].pBt!=0 || iDb==1 );
    assert( iDb<SQLITE_MAX_ATTACHED+2 );
    mask = 1<<iDb;
    if( (pParse->cookieMask & mask)==0 ){
      pParse->cookieMask |= mask;
      pParse->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
    if( (pToplevel->cookieMask & mask)==0 ){
      pToplevel->cookieMask |= mask;
      pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
      if( !OMIT_TEMPDB && iDb==1 ){
        sqlite3OpenTempDatabase(pParse);
        sqlite3OpenTempDatabase(pToplevel);
      }
    }
  }
}

/*
** Generate VDBE code that prepares for doing an operation that
** might change the database.
**
** This routine starts a new transaction if we are not already within
** a transaction.  If we are already within a transaction, then a checkpoint
** is set if the setStatement parameter is true.  A checkpoint should
** be set for operations that might fail (due to a constraint) part of
** the way through and which will need to undo some writes without having to
** rollback the whole transaction.  For operations where all constraints
** can be checked before any changes are made to the database, it is never
** necessary to undo a write and the checkpoint should not be set.
*/
void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
  Parse *pToplevel = sqlite3ParseToplevel(pParse);
  sqlite3CodeVerifySchema(pParse, iDb);
  pParse->writeMask |= 1<<iDb;
  if( setStatement && pParse->nested==0 ){
    /* Every place where this routine is called with setStatement!=0 has
    ** already successfully created a VDBE. */
    assert( pParse->pVdbe );
    sqlite3VdbeAddOp1(pParse->pVdbe, OP_Statement, iDb);
  pToplevel->writeMask |= 1<<iDb;
  pToplevel->isMultiWrite |= setStatement;
}

/*
** Indicate that the statement currently under construction might write
** more than one entry (example: deleting one row then inserting another,
** inserting multiple rows in a table, or inserting a row and index entries.)
** If an abort occurs after some of these writes have completed, then it will
** be necessary to undo the completed writes.
*/
void sqlite3MultiWrite(Parse *pParse){
  Parse *pToplevel = sqlite3ParseToplevel(pParse);
  pToplevel->isMultiWrite = 1;
}

/* 
** The code generator calls this routine if is discovers that it is
** possible to abort a statement prior to completion.  In order to 
** perform this abort without corrupting the database, we need to make
** sure that the statement is protected by a statement transaction.
**
** Technically, we only need to set the mayAbort flag if the
** isMultiWrite flag was previously set.  There is a time dependency
** such that the abort must occur after the multiwrite.  This makes
** some statements involving the REPLACE conflict resolution algorithm
** go a little faster.  But taking advantage of this time dependency
** makes it more difficult to prove that the code is correct (in 
** particular, it prevents us from writing an effective
** implementation of sqlite3AssertMayAbort()) and so we have chosen
** to take the safe route and skip the optimization.
*/
void sqlite3MayAbort(Parse *pParse){
  Parse *pToplevel = sqlite3ParseToplevel(pParse);
  pToplevel->mayAbort = 1;
}

/*
** Code an OP_Halt that causes the vdbe to return an SQLITE_CONSTRAINT
** error. The onError parameter determines which (if any) of the statement
** and/or current transaction is rolled back.
*/
void sqlite3HaltConstraint(Parse *pParse, int onError, char *p4, int p4type){
  Vdbe *v = sqlite3GetVdbe(pParse);
  if( onError==OE_Abort ){
    sqlite3MayAbort(pParse);
  }
  sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, p4, p4type);
}

/*
** Check to see if pIndex uses the collating sequence pColl.  Return
** true if it does and false if it does not.
*/
#ifndef SQLITE_OMIT_REINDEX
Changes to src/callback.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

24
25
26

27
28
29
30
31

32
33
34
35
36
37
38
8
9
10
11
12
13
14


15
16
17
18
19
20

21

22

23
24
25
26
27

28
29
30
31
32
33
34
35







-
-






-
+
-

-
+




-
+







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains functions used to access the internal hash tables
** of user defined functions and collation sequences.
**
** $Id: callback.c,v 1.42 2009/06/17 00:35:31 drh Exp $
*/

#include "sqliteInt.h"

/*
** Invoke the 'collation needed' callback to request a collation sequence
** in the database text encoding of name zName, length nName.
** in the encoding enc of name zName, length nName.
** If the collation sequence
*/
static void callCollNeeded(sqlite3 *db, const char *zName){
static void callCollNeeded(sqlite3 *db, int enc, const char *zName){
  assert( !db->xCollNeeded || !db->xCollNeeded16 );
  if( db->xCollNeeded ){
    char *zExternal = sqlite3DbStrDup(db, zName);
    if( !zExternal ) return;
    db->xCollNeeded(db->pCollNeededArg, db, (int)ENC(db), zExternal);
    db->xCollNeeded(db->pCollNeededArg, db, enc, zExternal);
    sqlite3DbFree(db, zExternal);
  }
#ifndef SQLITE_OMIT_UTF16
  if( db->xCollNeeded16 ){
    char const *zExternal;
    sqlite3_value *pTmp = sqlite3ValueNew(db);
    sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95

96
97
98
99
100
101
102


103
104
105
106
107
108
109
64
65
66
67
68
69
70

71

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

92
93
94
95
96
97


98
99
100
101
102
103
104
105
106







-
+
-












+







-
+





-
-
+
+







  }
  return SQLITE_ERROR;
}

/*
** This function is responsible for invoking the collation factory callback
** or substituting a collation sequence of a different encoding when the
** requested collation sequence is not available in the database native
** requested collation sequence is not available in the desired encoding.
** encoding.
** 
** If it is not NULL, then pColl must point to the database native encoding 
** collation sequence with name zName, length nName.
**
** The return value is either the collation sequence to be used in database
** db for collation type name zName, length nName, or NULL, if no collation
** sequence can be found.
**
** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq()
*/
CollSeq *sqlite3GetCollSeq(
  sqlite3* db,          /* The database connection */
  u8 enc,               /* The desired encoding for the collating sequence */
  CollSeq *pColl,       /* Collating sequence with native encoding, or NULL */
  const char *zName     /* Collating sequence name */
){
  CollSeq *p;

  p = pColl;
  if( !p ){
    p = sqlite3FindCollSeq(db, ENC(db), zName, 0);
    p = sqlite3FindCollSeq(db, enc, zName, 0);
  }
  if( !p || !p->xCmp ){
    /* No collation sequence of this type for this encoding is registered.
    ** Call the collation factory to see if it can supply us with one.
    */
    callCollNeeded(db, zName);
    p = sqlite3FindCollSeq(db, ENC(db), zName, 0);
    callCollNeeded(db, enc, zName);
    p = sqlite3FindCollSeq(db, enc, zName, 0);
  }
  if( p && !p->xCmp && synthCollSeq(db, p) ){
    p = 0;
  }
  assert( !p || p->xCmp );
  return p;
}
118
119
120
121
122
123
124

125

126
127
128
129
130
131
132
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130







+
-
+







** request a definition of the collating sequence. If this doesn't work, 
** an equivalent collating sequence that uses a text encoding different
** from the main database is substituted, if one is available.
*/
int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
  if( pColl ){
    const char *zName = pColl->zName;
    sqlite3 *db = pParse->db;
    CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName);
    CollSeq *p = sqlite3GetCollSeq(db, ENC(db), pColl, zName);
    if( !p ){
      sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
      pParse->nErr++;
      return SQLITE_ERROR;
    }
    assert( p==pColl );
  }
419
420
421
422
423
424
425

426
427
428
429
430
431
432
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431







+







  sqlite3HashInit(&pSchema->tblHash);
  for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
    Table *pTab = sqliteHashData(pElem);
    assert( pTab->dbMem==0 );
    sqlite3DeleteTable(pTab);
  }
  sqlite3HashClear(&temp1);
  sqlite3HashClear(&pSchema->fkeyHash);
  pSchema->pSeqTab = 0;
  pSchema->flags &= ~DB_SchemaLoaded;
}

/*
** Find and return the schema associated with a BTree.  Create
** a new one if necessary.
440
441
442
443
444
445
446

447
448
449
450
439
440
441
442
443
444
445
446
447
448
449
450







+




  }
  if( !p ){
    db->mallocFailed = 1;
  }else if ( 0==p->file_format ){
    sqlite3HashInit(&p->tblHash);
    sqlite3HashInit(&p->idxHash);
    sqlite3HashInit(&p->trigHash);
    sqlite3HashInit(&p->fkeyHash);
    p->enc = SQLITE_UTF8;
  }
  return p;
}
Changes to src/complete.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
11
12
13
14
15
16
17


18
19
20
21
22
23
24







-
-







*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that implements the sqlite3_complete() API.
** This code used to be part of the tokenizer.c source file.  But by
** separating it out, the code will be automatically omitted from
** static links that do not use it.
**
** $Id: complete.c,v 1.8 2009/04/28 04:46:42 drh Exp $
*/
#include "sqliteInt.h"
#ifndef SQLITE_OMIT_COMPLETE

/*
** This is defined in tokenize.c.  We just have to import the definition.
*/
Changes to src/date.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
12
13
14
15
16
17
18


19
20
21
22
23
24
25







-
-







** This file contains the C functions that implement date and time
** functions for SQLite.  
**
** There is only one exported symbol in this file - the function
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: date.c,v 1.107 2009/05/03 20:23:53 drh Exp $
**
** SQLite processes all times and dates as Julian Day numbers.  The
** dates and times are stored as the number of days since noon
** in Greenwich on November 24, 4714 B.C. according to the Gregorian
** calendar system. 
**
** 1970-01-01 00:00:00 is JD 2440587.5
** 2000-01-01 00:00:00 is JD 2451544.5
444
445
446
447
448
449
450
451

452
453
454
455
456
457
458
459
460
461
462
463

464
465
466
467
468
469
470
442
443
444
445
446
447
448

449
450
451
452
453
454
455
456
457
458
459
460

461
462
463
464
465
466
467
468







-
+











-
+







  } else {
    int s = (int)(x.s + 0.5);
    x.s = s;
  }
  x.tz = 0;
  x.validJD = 0;
  computeJD(&x);
  t = x.iJD/1000 - 21086676*(i64)10000;
  t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
#ifdef HAVE_LOCALTIME_R
  {
    struct tm sLocal;
    localtime_r(&t, &sLocal);
    y.Y = sLocal.tm_year + 1900;
    y.M = sLocal.tm_mon + 1;
    y.D = sLocal.tm_mday;
    y.h = sLocal.tm_hour;
    y.m = sLocal.tm_min;
    y.s = sLocal.tm_sec;
  }
#elif defined(HAVE_LOCALTIME_S)
#elif defined(HAVE_LOCALTIME_S) && HAVE_LOCALTIME_S
  {
    struct tm sLocal;
    localtime_s(&sLocal, &t);
    y.Y = sLocal.tm_year + 1900;
    y.M = sLocal.tm_mon + 1;
    y.D = sLocal.tm_mday;
    y.h = sLocal.tm_hour;
Changes to src/delete.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** in order to generate code for DELETE FROM statements.
**
** $Id: delete.c,v 1.204 2009/06/23 20:28:54 drh Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
39
40
41
42
43
44
45












46
47
48



49
50
51
52
53
54
55

56
57
58
59
60
61
62
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55



56
57
58



59
60
61
62
63
64
65
66
67
68
69
70







+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-




+








/*
** Check to make sure the given table is writable.  If it is not
** writable, generate an error message and return 1.  If it is
** writable return 0;
*/
int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
  /* A table is not writable under the following circumstances:
  **
  **   1) It is a virtual table and no implementation of the xUpdate method
  **      has been provided, or
  **   2) It is a system table (i.e. sqlite_master), this call is not
  **      part of a nested parse and writable_schema pragma has not 
  **      been specified.
  **
  ** In either case leave an error message in pParse and return non-zero.
  */
  if( ( IsVirtual(pTab) 
     && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 )
  if( ((pTab->tabFlags & TF_Readonly)!=0
        && (pParse->db->flags & SQLITE_WriteSchema)==0
        && pParse->nested==0) 
   || ( (pTab->tabFlags & TF_Readonly)!=0
     && (pParse->db->flags & SQLITE_WriteSchema)==0
     && pParse->nested==0 )
#ifndef SQLITE_OMIT_VIRTUALTABLE
      || (pTab->pMod && pTab->pMod->pModule->xUpdate==0)
#endif
  ){
    sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
    return 1;
  }

#ifndef SQLITE_OMIT_VIEW
  if( !viewOk && pTab->pSelect ){
    sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
    return 1;
  }
#endif
  return 0;
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
222
223
224
225
226
227
228

229
230
231
232
233
234
235
236
237





238

239
240
241
242
243
244
245
246







-









-
-
-
-
-

-
+







  int end, addr = 0;     /* A couple addresses of generated code */
  int i;                 /* Loop counter */
  WhereInfo *pWInfo;     /* Information about the WHERE clause */
  Index *pIdx;           /* For looping over indices of the table */
  int iCur;              /* VDBE Cursor number for pTab */
  sqlite3 *db;           /* Main database structure */
  AuthContext sContext;  /* Authorization context */
  int oldIdx = -1;       /* Cursor for the OLD table of AFTER triggers */
  NameContext sNC;       /* Name context to resolve expressions in */
  int iDb;               /* Database number */
  int memCnt = -1;       /* Memory cell used for change counting */
  int rcauth;            /* Value returned by authorization callback */

#ifndef SQLITE_OMIT_TRIGGER
  int isView;                  /* True if attempting to delete from a view */
  Trigger *pTrigger;           /* List of table triggers, if required */
#endif
  int iBeginAfterTrigger = 0;  /* Address of after trigger program */
  int iEndAfterTrigger = 0;    /* Exit of after trigger program */
  int iBeginBeforeTrigger = 0; /* Address of before trigger program */
  int iEndBeforeTrigger = 0;   /* Exit of before trigger program */
  u32 old_col_mask = 0;        /* Mask of OLD.* columns in use */

  sContext.pParse = 0;
  memset(&sContext, 0, sizeof(sContext));
  db = pParse->db;
  if( pParse->nErr || db->mallocFailed ){
    goto delete_from_cleanup;
  }
  assert( pTabList->nSrc==1 );

  /* Locate the table which we want to delete.  This table has to be
259
260
261
262
263
264
265






266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287












288
289
290
291
292
293
294







+
+
+
+
+
+














-
-
-
-
-
-
-
-
-
-
-
-







# define pTrigger 0
# define isView 0
#endif
#ifdef SQLITE_OMIT_VIEW
# undef isView
# define isView 0
#endif

  /* If pTab is really a view, make sure it has been initialized.
  */
  if( sqlite3ViewGetColumnNames(pParse, pTab) ){
    goto delete_from_cleanup;
  }

  if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){
    goto delete_from_cleanup;
  }
  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  assert( iDb<db->nDb );
  zDb = db->aDb[iDb].zName;
  rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb);
  assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE );
  if( rcauth==SQLITE_DENY ){
    goto delete_from_cleanup;
  }
  assert(!isView || pTrigger);

  /* If pTab is really a view, make sure it has been initialized.
  */
  if( sqlite3ViewGetColumnNames(pParse, pTab) ){
    goto delete_from_cleanup;
  }

  /* Allocate a cursor used to store the old.* data for a trigger.
  */
  if( pTrigger ){ 
    oldIdx = pParse->nTab++;
  }

  /* Assign  cursor number to the table and all its indices.
  */
  assert( pTabList->nSrc==1 );
  iCur = pTabList->a[0].iCursor = pParse->nTab++;
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    pParse->nTab++;
  }
306
307
308
309
310
311
312
313

314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
302
303
304
305
306
307
308

309


















310
311
312
313
314
315
316







-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







  /* Begin generating code.
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ){
    goto delete_from_cleanup;
  }
  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
  sqlite3BeginWriteOperation(pParse, (pTrigger?1:0), iDb);
  sqlite3BeginWriteOperation(pParse, 1, iDb);

  if( pTrigger ){
    int orconf = ((pParse->trigStack)?pParse->trigStack->orconf:OE_Default);
    int iGoto = sqlite3VdbeAddOp0(v, OP_Goto);
    addr = sqlite3VdbeMakeLabel(v);

    iBeginBeforeTrigger = sqlite3VdbeCurrentAddr(v);
    (void)sqlite3CodeRowTrigger(pParse, pTrigger, TK_DELETE, 0, 
        TRIGGER_BEFORE, pTab, -1, oldIdx, orconf, addr, &old_col_mask, 0);
    iEndBeforeTrigger = sqlite3VdbeAddOp0(v, OP_Goto);

    iBeginAfterTrigger = sqlite3VdbeCurrentAddr(v);
    (void)sqlite3CodeRowTrigger(pParse, pTrigger, TK_DELETE, 0, 
        TRIGGER_AFTER, pTab, -1, oldIdx, orconf, addr, &old_col_mask, 0);
    iEndAfterTrigger = sqlite3VdbeAddOp0(v, OP_Goto);

    sqlite3VdbeJumpHere(v, iGoto);
  }

  /* If we are trying to delete from a view, realize that view into
  ** a ephemeral table.
  */
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
  if( isView ){
    sqlite3MaterializeView(pParse, pTab, pWhere, iCur);
354
355
356
357
358
359
360
361
362
363
364






365
366
367
368
369
370
371
372
373
374
375
376
377
378
379

380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402

403
404
405




406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

444
445
446
447
448
449






450
451
452



453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470


471
472
473
474
475
476
477
478
479
480
481
482

483
484
485
486
487

488
489
490
491

492
493
494
495
496
497
498
499
500
501
502









503
504
505
506
507
508
509
510
511
512

513
514
515
516
517
518
519
520
521
522


523
524
525
526
527
528
529



530



531
532
533
534
535
536
537
538
539
540
541












































































542
543
544
545
546
547
548
332
333
334
335
336
337
338




339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357

358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373






374
375

376

377
378
379
380
381
382
383



384
385
386






387
388























389
390





391
392
393
394
395
396
397


398
399
400










401
402
403
404
405
406


407
408
409
410
411
412
413
414
415
416
417
418
419

420
421
422
423


424
425
426
427

428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457

458
459
460
461
462
463
464
465



466
467
468
469
470
471
472
473

474
475
476
477
478
479
480











481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563







-
-
-
-
+
+
+
+
+
+













-

+














-
-
-
-
-
-


-
+
-


+
+
+
+

-
-
-



-
-
-
-
-
-


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+

-
-
-
-
-
+
+
+
+
+
+

-
-
+
+
+
-
-
-
-
-
-
-
-
-
-






-
-
+
+











-
+



-
-
+



-
+











+
+
+
+
+
+
+
+
+









-
+







-
-
-
+
+






-
+
+
+

+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







  if( db->flags & SQLITE_CountRows ){
    memCnt = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt);
  }

#ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
  /* Special case: A DELETE without a WHERE clause deletes everything.
  ** It is easier just to erase the whole table.  Note, however, that
  ** this means that the row change count will be incorrect.
  */
  if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab) ){
  ** It is easier just to erase the whole table. Prior to version 3.6.5,
  ** this optimization caused the row change count (the value returned by 
  ** API function sqlite3_count_changes) to be set incorrectly.  */
  if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab) 
   && 0==sqlite3FkRequired(pParse, pTab, 0, 0)
  ){
    assert( !isView );
    sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt,
                      pTab->zName, P4_STATIC);
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      assert( pIdx->pSchema==pTab->pSchema );
      sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
    }
  }else
#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
  /* The usual case: There is a WHERE clause so we have to scan through
  ** the table and pick which records to delete.
  */
  {
    int iRowid = ++pParse->nMem;    /* Used for storing rowid values. */
    int iRowSet = ++pParse->nMem;   /* Register for rowset of rows to delete */
    int iRowid = ++pParse->nMem;    /* Used for storing rowid values. */
    int regRowid;                   /* Actual register containing rowids */

    /* Collect rowids of every row to be deleted.
    */
    sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet);
    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,WHERE_DUPLICATES_OK);
    if( pWInfo==0 ) goto delete_from_cleanup;
    regRowid = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, iRowid, 0);
    sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, regRowid);
    if( db->flags & SQLITE_CountRows ){
      sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
    }
    sqlite3WhereEnd(pWInfo);

    /* Open the pseudo-table used to store OLD if there are triggers.
    */
    if( pTrigger ){
      sqlite3VdbeAddOp3(v, OP_OpenPseudo, oldIdx, 0, pTab->nCol);
    }

    /* Delete every item whose key was written to the list during the
    ** database scan.  We have to delete items after the scan is complete
    ** because deleting an item can change the scan order.
    ** because deleting an item can change the scan order.  */
    */
    end = sqlite3VdbeMakeLabel(v);

    /* Unless this is a view, open cursors for the table we are 
    ** deleting from and all its indices. If this is a view, then the
    ** only effect this statement has is to fire the INSTEAD OF 
    ** triggers.  */
    if( !isView ){
      /* Open cursors for the table we are deleting from and 
      ** all its indices.
      */
      sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);
    }

    /* This is the beginning of the delete loop. If a trigger encounters
    ** an IGNORE constraint, it jumps back to here.
    */
    if( pTrigger ){
      sqlite3VdbeResolveLabel(v, addr);
    }
    addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, iRowid);

    if( pTrigger ){
      int iData = ++pParse->nMem;   /* For storing row data of OLD table */

      /* If the record is no longer present in the table, jump to the
      ** next iteration of the loop through the contents of the fifo.
      */
      sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, iRowid);

      /* Populate the OLD.* pseudo-table */
      if( old_col_mask ){
        sqlite3VdbeAddOp2(v, OP_RowData, iCur, iData);
      }else{
        sqlite3VdbeAddOp2(v, OP_Null, 0, iData);
      }
      sqlite3VdbeAddOp3(v, OP_Insert, oldIdx, iData, iRowid);

      /* Jump back and run the BEFORE triggers */
      sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger);
      sqlite3VdbeJumpHere(v, iEndBeforeTrigger);
    }

    if( !isView ){
      /* Delete the row */
    /* Delete the row */
#ifndef SQLITE_OMIT_VIRTUALTABLE
      if( IsVirtual(pTab) ){
        const char *pVtab = (const char *)pTab->pVtab;
        sqlite3VtabMakeWritable(pParse, pTab);
        sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVtab, P4_VTAB);
      }else
    if( IsVirtual(pTab) ){
      const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
      sqlite3VtabMakeWritable(pParse, pTab);
      sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB);
      sqlite3MayAbort(pParse);
    }else
#endif
      {
        sqlite3GenerateRowDelete(pParse, pTab, iCur, iRowid, pParse->nested==0);
    {
      int count = (pParse->nested==0);    /* True to count changes */
      sqlite3GenerateRowDelete(pParse, pTab, iCur, iRowid, count, pTrigger, OE_Default);
      }
    }

    /* If there are row triggers, close all cursors then invoke
    ** the AFTER triggers
    */
    if( pTrigger ){
      /* Jump back and run the AFTER triggers */
      sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginAfterTrigger);
      sqlite3VdbeJumpHere(v, iEndAfterTrigger);
    }

    /* End of the delete loop */
    sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
    sqlite3VdbeResolveLabel(v, end);

    /* Close the cursors after the loop if there are no row triggers */
    if( !isView  && !IsVirtual(pTab) ){
    /* Close the cursors open on the table and its indexes. */
    if( !isView && !IsVirtual(pTab) ){
      for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
        sqlite3VdbeAddOp2(v, OP_Close, iCur + i, pIdx->tnum);
      }
      sqlite3VdbeAddOp1(v, OP_Close, iCur);
    }
  }

  /* Update the sqlite_sequence table by storing the content of the
  ** maximum rowid counter values recorded while inserting into
  ** autoincrement tables.
  */
  if( pParse->nested==0 && pParse->trigStack==0 ){
  if( pParse->nested==0 && pParse->pTriggerTab==0 ){
    sqlite3AutoincrementEnd(pParse);
  }

  /*
  ** Return the number of rows that were deleted. If this routine is 
  /* Return the number of rows that were deleted. If this routine is 
  ** generating code because of a call to sqlite3NestedParse(), do not
  ** invoke the callback function.
  */
  if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
  if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){
    sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1);
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC);
  }

delete_from_cleanup:
  sqlite3AuthContextPop(&sContext);
  sqlite3SrcListDelete(db, pTabList);
  sqlite3ExprDelete(db, pWhere);
  return;
}
/* Make sure "isView" and other macros defined above are undefined. Otherwise
** thely may interfere with compilation of other functions in this file
** (or in another file, if this file becomes part of the amalgamation).  */
#ifdef isView
 #undef isView
#endif
#ifdef pTrigger
 #undef pTrigger
#endif

/*
** This routine generates VDBE code that causes a single row of a
** single table to be deleted.
**
** The VDBE must be in a particular state when this routine is called.
** These are the requirements:
**
**   1.  A read/write cursor pointing to pTab, the table containing the row
**       to be deleted, must be opened as cursor number "base".
**       to be deleted, must be opened as cursor number $iCur.
**
**   2.  Read/write cursors for all indices of pTab must be open as
**       cursor number base+i for the i-th index.
**
**   3.  The record number of the row to be deleted must be stored in
**       memory cell iRowid.
**
** This routine pops the top of the stack to remove the record number
** and then generates code to remove both the table record and all index
** entries that point to that record.
** This routine generates code to remove both the table record and all 
** index entries that point to that record.
*/
void sqlite3GenerateRowDelete(
  Parse *pParse,     /* Parsing context */
  Table *pTab,       /* Table containing the row to be deleted */
  int iCur,          /* Cursor number for the table */
  int iRowid,        /* Memory cell that contains the rowid to delete */
  int count          /* Increment the row change counter */
  int count,         /* If non-zero, increment the row change counter */
  Trigger *pTrigger, /* List of triggers to (potentially) fire */
  int onconf         /* Default ON CONFLICT policy for triggers */
){
  Vdbe *v = pParse->pVdbe;        /* Vdbe */
  int iOld = 0;                   /* First register in OLD.* array */
  int iLabel;                     /* Label resolved to end of generated code */
  int addr;
  Vdbe *v;

  v = pParse->pVdbe;
  addr = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowid);
  sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, 0);
  sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
  if( count ){
    sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC);
  }
  sqlite3VdbeJumpHere(v, addr);

  /* Vdbe is guaranteed to have been allocated by this stage. */
  assert( v );

  /* Seek cursor iCur to the row to delete. If this row no longer exists 
  ** (this can happen if a trigger program has already deleted it), do
  ** not attempt to delete it or fire any DELETE triggers.  */
  iLabel = sqlite3VdbeMakeLabel(v);
  sqlite3VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iRowid);
 
  /* If there are any triggers to fire, allocate a range of registers to
  ** use for the old.* references in the triggers.  */
  if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){
    u32 mask;                     /* Mask of OLD.* columns in use */
    int iCol;                     /* Iterator used while populating OLD.* */

    /* TODO: Could use temporary registers here. Also could attempt to
    ** avoid copying the contents of the rowid register.  */
    mask = sqlite3TriggerOldmask(pParse, pTrigger, 0, pTab, onconf);
    mask |= sqlite3FkOldmask(pParse, pTab);
    iOld = pParse->nMem+1;
    pParse->nMem += (1 + pTab->nCol);

    /* Populate the OLD.* pseudo-table register array. These values will be 
    ** used by any BEFORE and AFTER triggers that exist.  */
    sqlite3VdbeAddOp2(v, OP_Copy, iRowid, iOld);
    for(iCol=0; iCol<pTab->nCol; iCol++){
      if( mask==0xffffffff || mask&(1<<iCol) ){
        int iTarget = iOld + iCol + 1;
        sqlite3VdbeAddOp3(v, OP_Column, iCur, iCol, iTarget);
        sqlite3ColumnDefault(v, pTab, iCol, iTarget);
      }
    }

    /* Invoke BEFORE DELETE trigger programs. */
    sqlite3CodeRowTrigger(pParse, pTrigger, 
        TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel
    );

    /* Seek the cursor to the row to be deleted again. It may be that
    ** the BEFORE triggers coded above have already removed the row
    ** being deleted. Do not attempt to delete the row a second time, and 
    ** do not fire AFTER triggers.  */
    sqlite3VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iRowid);

    /* Do FK processing. This call checks that any FK constraints that
    ** refer to this table (i.e. constraints attached to other tables) 
    ** are not violated by deleting this row.  */
    sqlite3FkCheck(pParse, pTab, iOld, 0);
  }

  /* Delete the index and table entries. Skip this step if pTab is really
  ** a view (in which case the only effect of the DELETE statement is to
  ** fire the INSTEAD OF triggers).  */ 
  if( pTab->pSelect==0 ){
    sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, 0);
    sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
    if( count ){
      sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC);
    }
  }

  /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
  ** handle rows (possibly in other tables) that refer via a foreign key
  ** to the row just deleted. */ 
  sqlite3FkActions(pParse, pTab, 0, iOld);

  /* Invoke AFTER DELETE trigger programs. */
  sqlite3CodeRowTrigger(pParse, pTrigger, 
      TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel
  );

  /* Jump here if the row had already been deleted before any BEFORE
  ** trigger programs were invoked. Or if a trigger program throws a 
  ** RAISE(IGNORE) exception.  */
  sqlite3VdbeResolveLabel(v, iLabel);
}

/*
** This routine generates VDBE code that causes the deletion of all
** index entries associated with a single row of a single table.
**
** The VDBE must be in a particular state when this routine is called.
603
604
605
606
607
608
609
610

611
612
613
614
615

616
617
618
619
620
621
622
623
624
625
618
619
620
621
622
623
624

625
626
627
628
629

630
631
632
633
634
635












-
+




-
+





-
-
-
-
-
  sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
  for(j=0; j<nCol; j++){
    int idx = pIdx->aiColumn[j];
    if( idx==pTab->iPKey ){
      sqlite3VdbeAddOp2(v, OP_SCopy, regBase+nCol, regBase+j);
    }else{
      sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j);
      sqlite3ColumnDefault(v, pTab, idx);
      sqlite3ColumnDefault(v, pTab, idx, -1);
    }
  }
  if( doMakeRec ){
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut);
    sqlite3IndexAffinityStr(v, pIdx);
    sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0);
    sqlite3ExprCacheAffinityChange(pParse, regBase, nCol+1);
  }
  sqlite3ReleaseTempRange(pParse, regBase, nCol+1);
  return regBase;
}

/* Make sure "isView" gets undefined in case this file becomes part of
** the amalgamation - so that subsequent files do not see isView as a
** macro. */
#undef isView
Changes to src/expr.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.446 2009/06/19 18:32:55 drh Exp $
*/
#include "sqliteInt.h"

/*
** Return the 'affinity' of the expression pExpr if any.
**
** If pExpr is a column, a reference to a column via an 'AS' alias,
88
89
90
91
92
93
94

95


96
97
98
99
100
101
102
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102







+
-
+
+







  CollSeq *pColl = 0;
  Expr *p = pExpr;
  while( ALWAYS(p) ){
    int op;
    pColl = p->pColl;
    if( pColl ) break;
    op = p->op;
    if( p->pTab!=0 && (
    if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER) && p->pTab!=0 ){
        op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER || op==TK_TRIGGER
    )){
      /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
      ** a TK_COLUMN but was previously evaluated and cached in a register */
      const char *zColl;
      int j = p->iColumn;
      if( j>=0 ){
        sqlite3 *db = pParse->db;
        zColl = p->pTab->aCol[j].zColl;
148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162







-
+







** pExpr is a comparison operator.  Return the type affinity that should
** be applied to both operands prior to doing the comparison.
*/
static char comparisonAffinity(Expr *pExpr){
  char aff;
  assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT ||
          pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE ||
          pExpr->op==TK_NE );
          pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT );
  assert( pExpr->pLeft );
  aff = sqlite3ExprAffinity(pExpr->pLeft);
  if( pExpr->pRight ){
    aff = sqlite3CompareAffinity(pExpr->pRight, aff);
  }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
    aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff);
  }else if( !aff ){
567
568
569
570
571
572
573
574

575
576
577
578
579


580
581
582
583
584
585
586
567
568
569
570
571
572
573

574
575
576
577


578
579
580
581
582
583
584
585
586







-
+



-
-
+
+







  assert( !ExprHasAnyProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
  z = pExpr->u.zToken;
  assert( z!=0 );
  assert( z[0]!=0 );
  if( z[1]==0 ){
    /* Wildcard of the form "?".  Assign the next variable number */
    assert( z[0]=='?' );
    pExpr->iTable = ++pParse->nVar;
    pExpr->iColumn = (ynVar)(++pParse->nVar);
  }else if( z[0]=='?' ){
    /* Wildcard of the form "?nnn".  Convert "nnn" to an integer and
    ** use it as the variable number */
    int i;
    pExpr->iTable = i = atoi((char*)&z[1]);
    int i = atoi((char*)&z[1]);
    pExpr->iColumn = (ynVar)i;
    testcase( i==0 );
    testcase( i==1 );
    testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
    testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
    if( i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
      sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
          db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
596
597
598
599
600
601
602
603

604
605
606
607
608

609
610
611
612
613
614
615
596
597
598
599
600
601
602

603
604
605
606
607

608
609
610
611
612
613
614
615







-
+




-
+







    int i;
    u32 n;
    n = sqlite3Strlen30(z);
    for(i=0; i<pParse->nVarExpr; i++){
      Expr *pE = pParse->apVarExpr[i];
      assert( pE!=0 );
      if( memcmp(pE->u.zToken, z, n)==0 && pE->u.zToken[n]==0 ){
        pExpr->iTable = pE->iTable;
        pExpr->iColumn = pE->iColumn;
        break;
      }
    }
    if( i>=pParse->nVarExpr ){
      pExpr->iTable = ++pParse->nVar;
      pExpr->iColumn = (ynVar)(++pParse->nVar);
      if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){
        pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10;
        pParse->apVarExpr =
            sqlite3DbReallocOrFree(
              db,
              pParse->apVarExpr,
              pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0])
882
883
884
885
886
887
888
889
890
891

892
893
894
895
896
897
898
882
883
884
885
886
887
888

889

890
891
892
893
894
895
896
897







-

-
+







  pNew->a = pItem = sqlite3DbMallocRaw(db,  p->nExpr*sizeof(p->a[0]) );
  if( pItem==0 ){
    sqlite3DbFree(db, pNew);
    return 0;
  } 
  pOldItem = p->a;
  for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
    Expr *pNewExpr;
    Expr *pOldExpr = pOldItem->pExpr;
    pItem->pExpr = pNewExpr = sqlite3ExprDup(db, pOldExpr, flags);
    pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags);
    pItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
    pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan);
    pItem->sortOrder = pOldItem->sortOrder;
    pItem->done = 0;
    pItem->iCol = pOldItem->iCol;
    pItem->iAlias = pOldItem->iAlias;
  }
1368
1369
1370
1371
1372
1373
1374


1375
1376
1377
1378
1379
1380
1381
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382







+
+







*/
#ifndef SQLITE_OMIT_SUBQUERY
int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
  Select *p;                            /* SELECT to the right of IN operator */
  int eType = 0;                        /* Type of RHS table. IN_INDEX_* */
  int iTab = pParse->nTab++;            /* Cursor of the RHS table */
  int mustBeUnique = (prNotFound==0);   /* True if RHS must be unique */

  assert( pX->op==TK_IN );

  /* Check to see if an existing table or index can be used to
  ** satisfy the query.  This is preferable to generating a new 
  ** ephemeral table.
  */
  p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
  if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1396
1397
1398
1399
1400
1401
1402

1403
1404
1405
1406
1407
1408
1409







-







    ** has already been allocated. So assume sqlite3GetVdbe() is always
    ** successful here.
    */
    assert(v);
    if( iCol<0 ){
      int iMem = ++pParse->nMem;
      int iAddr;
      sqlite3VdbeUsesBtree(v, iDb);

      iAddr = sqlite3VdbeAddOp1(v, OP_If, iMem);
      sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem);

      sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
      eType = IN_INDEX_ROWID;

1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457

1458
1459
1460
1461
1462
1463
1464
1429
1430
1431
1432
1433
1434
1435



1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453

1454
1455
1456
1457
1458
1459
1460
1461







-
-
-


















-
+







         && (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None))
        ){
          int iMem = ++pParse->nMem;
          int iAddr;
          char *pKey;
  
          pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx);
          iDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
          sqlite3VdbeUsesBtree(v, iDb);

          iAddr = sqlite3VdbeAddOp1(v, OP_If, iMem);
          sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem);
  
          sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb,
                               pKey,P4_KEYINFO_HANDOFF);
          VdbeComment((v, "%s", pIdx->zName));
          eType = IN_INDEX_INDEX;

          sqlite3VdbeJumpHere(v, iAddr);
          if( prNotFound && !pTab->aCol[iCol].notNull ){
            *prNotFound = ++pParse->nMem;
          }
        }
      }
    }
  }

  if( eType==0 ){
    /* Could not found an existing able or index to use as the RHS b-tree.
    /* Could not found an existing table or index to use as the RHS b-tree.
    ** We will have to generate an ephemeral table to do the job.
    */
    int rMayHaveNull = 0;
    eType = IN_INDEX_EPH;
    if( prNotFound ){
      *prNotFound = rMayHaveNull = ++pParse->nMem;
    }else if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){
1497
1498
1499
1500
1501
1502
1503



1504
1505
1506

1507
1508
1509
1510
1511
1512

1513
1514

1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527

1528
1529
1530
1531
1532
1533
1534
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505

1506
1507
1508
1509
1510
1511
1512
1513
1514

1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527

1528
1529
1530
1531
1532
1533
1534
1535







+
+
+


-
+






+

-
+












-
+







** all corresponding LHS elements.  All this routine does is initialize
** the register given by rMayHaveNull to NULL.  Calling routines will take
** care of changing this register value to non-NULL if the RHS is NULL-free.
**
** If rMayHaveNull is zero, that means that the subquery is being used
** for membership testing only.  There is no need to initialize any
** registers to indicate the presense or absence of NULLs on the RHS.
**
** For a SELECT or EXISTS operator, return the register that holds the
** result.  For IN operators or if an error occurs, the return value is 0.
*/
#ifndef SQLITE_OMIT_SUBQUERY
void sqlite3CodeSubselect(
int sqlite3CodeSubselect(
  Parse *pParse,          /* Parsing context */
  Expr *pExpr,            /* The IN, SELECT, or EXISTS operator */
  int rMayHaveNull,       /* Register that records whether NULLs exist in RHS */
  int isRowid             /* If true, LHS of IN operator is a rowid */
){
  int testAddr = 0;                       /* One-time test address */
  int rReg = 0;                           /* Register storing resulting */
  Vdbe *v = sqlite3GetVdbe(pParse);
  if( NEVER(v==0) ) return;
  if( NEVER(v==0) ) return 0;
  sqlite3ExprCachePush(pParse);

  /* This code must be run in its entirety every time it is encountered
  ** if any of the following is true:
  **
  **    *  The right-hand side is a correlated subquery
  **    *  The right-hand side is an expression list containing variables
  **    *  We are inside a trigger
  **
  ** If all of the above are false, then we can run this code just once
  ** save the results, and reuse the same result on subsequent invocations.
  */
  if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){
  if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->pTriggerTab ){
    int mem = ++pParse->nMem;
    sqlite3VdbeAddOp1(v, OP_If, mem);
    testAddr = sqlite3VdbeAddOp2(v, OP_Integer, 1, mem);
    assert( testAddr>0 || pParse->db->mallocFailed );
  }

  switch( pExpr->op ){
1572
1573
1574
1575
1576
1577
1578
1579

1580
1581
1582
1583
1584
1585
1586
1573
1574
1575
1576
1577
1578
1579

1580
1581
1582
1583
1584
1585
1586
1587







-
+







        ExprList *pEList;

        assert( !isRowid );
        sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
        dest.affinity = (u8)affinity;
        assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
        if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
          return;
          return 0;
        }
        pEList = pExpr->x.pSelect->pEList;
        if( ALWAYS(pEList!=0 && pEList->nExpr>0) ){ 
          keyInfo.aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
              pEList->a[0].pExpr);
        }
      }else if( pExpr->x.pList!=0 ){
1603
1604
1605
1606
1607
1608
1609

1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621



1622
1623
1624
1625
1626
1627
1628
1629










1630
1631
1632
1633
1634
1635
1636
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626








1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643







+












+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+








        /* Loop through each expression in <exprlist>. */
        r1 = sqlite3GetTempReg(pParse);
        r2 = sqlite3GetTempReg(pParse);
        sqlite3VdbeAddOp2(v, OP_Null, 0, r2);
        for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
          Expr *pE2 = pItem->pExpr;
          int iValToIns;

          /* If the expression is not constant then we will need to
          ** disable the test that was generated above that makes sure
          ** this code only executes once.  Because for a non-constant
          ** expression we need to rerun this code each time.
          */
          if( testAddr && !sqlite3ExprIsConstant(pE2) ){
            sqlite3VdbeChangeToNoop(v, testAddr-1, 2);
            testAddr = 0;
          }

          /* Evaluate the expression and insert it into the temp table */
          if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){
            sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns);
          }else{
          r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
          if( isRowid ){
            sqlite3VdbeAddOp2(v, OP_MustBeInt, r3, sqlite3VdbeCurrentAddr(v)+2);
            sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
          }else{
            sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
            sqlite3ExprCacheAffinityChange(pParse, r3, 1);
            sqlite3VdbeAddOp2(v, OP_IdxInsert, pExpr->iTable, r2);
            r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
            if( isRowid ){
              sqlite3VdbeAddOp2(v, OP_MustBeInt, r3,
                                sqlite3VdbeCurrentAddr(v)+2);
              sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
            }else{
              sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
              sqlite3ExprCacheAffinityChange(pParse, r3, 1);
              sqlite3VdbeAddOp2(v, OP_IdxInsert, pExpr->iTable, r2);
            }
          }
        }
        sqlite3ReleaseTempReg(pParse, r1);
        sqlite3ReleaseTempReg(pParse, r2);
      }
      if( !isRowid ){
        sqlite3VdbeChangeP4(v, addr, (void *)&keyInfo, P4_KEYINFO);
1666
1667
1668
1669
1670
1671
1672
1673

1674
1675

1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686

1687
1688
1689
1690
1691
1692
1693
1673
1674
1675
1676
1677
1678
1679

1680
1681

1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692

1693
1694
1695
1696
1697
1698
1699
1700







-
+

-
+










-
+







        dest.eDest = SRT_Exists;
        sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iParm);
        VdbeComment((v, "Init EXISTS result"));
      }
      sqlite3ExprDelete(pParse->db, pSel->pLimit);
      pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &one);
      if( sqlite3Select(pParse, pSel, &dest) ){
        return;
        return 0;
      }
      pExpr->iColumn = dest.iParm;
      rReg = dest.iParm;
      ExprSetIrreducible(pExpr);
      break;
    }
  }

  if( testAddr ){
    sqlite3VdbeJumpHere(v, testAddr-1);
  }
  sqlite3ExprCachePop(pParse, 1);

  return;
  return rReg;
}
#endif /* SQLITE_OMIT_SUBQUERY */

/*
** Duplicate an 8-byte value
*/
static char *dup8bytes(Vdbe *v, const char *in){
1707
1708
1709
1710
1711
1712
1713
1714

1715
1716
1717
1718
1719



1720
1721
1722
1723
1724
1725
1726
1727
1714
1715
1716
1717
1718
1719
1720

1721





1722
1723
1724

1725
1726
1727
1728
1729
1730
1731







-
+
-
-
-
-
-
+
+
+
-







** like the continuation of the number.
*/
static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){
  if( ALWAYS(z!=0) ){
    double value;
    char *zV;
    sqlite3AtoF(z, &value);
    if( sqlite3IsNaN(value) ){
    assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */
      sqlite3VdbeAddOp2(v, OP_Null, 0, iMem);
    }else{
      if( negateFlag ) value = -value;
      zV = dup8bytes(v, (char*)&value);
      sqlite3VdbeAddOp4(v, OP_Real, 0, iMem, 0, zV, P4_REAL);
    if( negateFlag ) value = -value;
    zV = dup8bytes(v, (char*)&value);
    sqlite3VdbeAddOp4(v, OP_Real, 0, iMem, 0, zV, P4_REAL);
    }
  }
}


/*
** Generate an instruction that will put the integer describe by
** text z[0..n-1] into register iMem.
1921
1922
1923
1924
1925
1926
1927
1928

1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1925
1926
1927
1928
1929
1930
1931

1932





1933
1934
1935
1936
1937
1938
1939







-
+
-
-
-
-
-







  }  
  assert( v!=0 );
  if( iColumn<0 ){
    sqlite3VdbeAddOp2(v, OP_Rowid, iTable, iReg);
  }else if( ALWAYS(pTab!=0) ){
    int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
    sqlite3VdbeAddOp3(v, op, iTable, iColumn, iReg);
    sqlite3ColumnDefault(v, pTab, iColumn);
    sqlite3ColumnDefault(v, pTab, iColumn, iReg);
#ifndef SQLITE_OMIT_FLOATING_POINT
    if( pTab->aCol[iColumn].affinity==SQLITE_AFF_REAL ){
      sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
    }
#endif
  }
  sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg);
  return iReg;
}

/*
** Clear all column cache entries.
2173
2174
2175
2176
2177
2178
2179
2180

2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191

2192
2193
2194
2195
2196
2197
2198
2172
2173
2174
2175
2176
2177
2178

2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189

2190
2191
2192
2193
2194
2195
2196
2197







-
+










-
+







    case TK_VARIABLE: {
      VdbeOp *pOp;
      assert( !ExprHasProperty(pExpr, EP_IntValue) );
      assert( pExpr->u.zToken!=0 );
      assert( pExpr->u.zToken[0]!=0 );
      if( pExpr->u.zToken[1]==0
         && (pOp = sqlite3VdbeGetOp(v, -1))->opcode==OP_Variable
         && pOp->p1+pOp->p3==pExpr->iTable
         && pOp->p1+pOp->p3==pExpr->iColumn
         && pOp->p2+pOp->p3==target
         && pOp->p4.z==0
      ){
        /* If the previous instruction was a copy of the previous unnamed
        ** parameter into the previous register, then simply increment the
        ** repeat count on the prior instruction rather than making a new
        ** instruction.
        */
        pOp->p3++;
      }else{
        sqlite3VdbeAddOp3(v, OP_Variable, pExpr->iTable, target, 1);
        sqlite3VdbeAddOp3(v, OP_Variable, pExpr->iColumn, target, 1);
        if( pExpr->u.zToken[1]!=0 ){
          sqlite3VdbeChangeP4(v, -1, pExpr->u.zToken, 0);
        }
      }
      break;
    }
    case TK_REGISTER: {
2252
2253
2254
2255
2256
2257
2258













2259
2260
2261
2262
2263
2264
2265
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277







+
+
+
+
+
+
+
+
+
+
+
+
+







      codeCompareOperands(pParse, pExpr->pLeft, &r1, &regFree1,
                                  pExpr->pRight, &r2, &regFree2);
      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
                  r1, r2, inReg, SQLITE_STOREP2);
      testcase( regFree1==0 );
      testcase( regFree2==0 );
      break;
    }
    case TK_IS:
    case TK_ISNOT: {
      testcase( op==TK_IS );
      testcase( op==TK_ISNOT );
      codeCompareOperands(pParse, pExpr->pLeft, &r1, &regFree1,
                                  pExpr->pRight, &r2, &regFree2);
      op = (op==TK_IS) ? TK_EQ : TK_NE;
      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
                  r1, r2, inReg, SQLITE_STOREP2 | SQLITE_NULLEQ);
      testcase( regFree1==0 );
      testcase( regFree2==0 );
      break;
    }
    case TK_AND:
    case TK_OR:
    case TK_PLUS:
    case TK_STAR:
    case TK_MINUS:
    case TK_REM:
2374
2375
2376
2377
2378
2379
2380











2381














2382
2383

2384

2385
2386
2387
2388
2389
2390
2391
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403

2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429







+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+

+







        pFarg = pExpr->x.pList;
      }
      nFarg = pFarg ? pFarg->nExpr : 0;
      assert( !ExprHasProperty(pExpr, EP_IntValue) );
      zId = pExpr->u.zToken;
      nId = sqlite3Strlen30(zId);
      pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0);
      if( pDef==0 ){
        sqlite3ErrorMsg(pParse, "unknown function: %.*s()", nId, zId);
        break;
      }

      /* Attempt a direct implementation of the built-in COALESCE() and
      ** IFNULL() functions.  This avoids unnecessary evalation of
      ** arguments past the first non-NULL argument.
      */
      if( pDef->flags & SQLITE_FUNC_COALESCE ){
        int endCoalesce = sqlite3VdbeMakeLabel(v);
      assert( pDef!=0 );
        assert( nFarg>=2 );
        sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
        for(i=1; i<nFarg; i++){
          sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
          sqlite3ExprCacheRemove(pParse, target);
          sqlite3ExprCachePush(pParse);
          sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
          sqlite3ExprCachePop(pParse, 1);
        }
        sqlite3VdbeResolveLabel(v, endCoalesce);
        break;
      }


      if( pFarg ){
        r1 = sqlite3GetTempRange(pParse, nFarg);
        sqlite3ExprCachePush(pParse);     /* Ticket 2ea2425d34be */
        sqlite3ExprCodeExprList(pParse, pFarg, r1, 1);
        sqlite3ExprCachePop(pParse, 1);   /* Ticket 2ea2425d34be */
      }else{
        r1 = 0;
      }
#ifndef SQLITE_OMIT_VIRTUALTABLE
      /* Possibly overload the function if the first argument is
      ** a virtual table column.
      **
2426
2427
2428
2429
2430
2431
2432
2433

2434
2435
2436
2437
2438
2439
2440
2441
2464
2465
2466
2467
2468
2469
2470

2471

2472
2473
2474
2475
2476
2477
2478







-
+
-







      break;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_EXISTS:
    case TK_SELECT: {
      testcase( op==TK_EXISTS );
      testcase( op==TK_SELECT );
      sqlite3CodeSubselect(pParse, pExpr, 0, 0);
      inReg = sqlite3CodeSubselect(pParse, pExpr, 0, 0);
      inReg = pExpr->iColumn;
      break;
    }
    case TK_IN: {
      int rNotFound = 0;
      int rMayHaveNull = 0;
      int j2, j3, j4, j5;
      char affinity;
2559
2560
2561
2562
2563
2564
2565




















































2566
2567
2568
2569
2570
2571
2572
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







      sqlite3ReleaseTempReg(pParse, r4);
      break;
    }
    case TK_UPLUS: {
      inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
      break;
    }

    case TK_TRIGGER: {
      /* If the opcode is TK_TRIGGER, then the expression is a reference
      ** to a column in the new.* or old.* pseudo-tables available to
      ** trigger programs. In this case Expr.iTable is set to 1 for the
      ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
      ** is set to the column of the pseudo-table to read, or to -1 to
      ** read the rowid field.
      **
      ** The expression is implemented using an OP_Param opcode. The p1
      ** parameter is set to 0 for an old.rowid reference, or to (i+1)
      ** to reference another column of the old.* pseudo-table, where 
      ** i is the index of the column. For a new.rowid reference, p1 is
      ** set to (n+1), where n is the number of columns in each pseudo-table.
      ** For a reference to any other column in the new.* pseudo-table, p1
      ** is set to (n+2+i), where n and i are as defined previously. For
      ** example, if the table on which triggers are being fired is
      ** declared as:
      **
      **   CREATE TABLE t1(a, b);
      **
      ** Then p1 is interpreted as follows:
      **
      **   p1==0   ->    old.rowid     p1==3   ->    new.rowid
      **   p1==1   ->    old.a         p1==4   ->    new.a
      **   p1==2   ->    old.b         p1==5   ->    new.b       
      */
      Table *pTab = pExpr->pTab;
      int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;

      assert( pExpr->iTable==0 || pExpr->iTable==1 );
      assert( pExpr->iColumn>=-1 && pExpr->iColumn<pTab->nCol );
      assert( pTab->iPKey<0 || pExpr->iColumn!=pTab->iPKey );
      assert( p1>=0 && p1<(pTab->nCol*2+2) );

      sqlite3VdbeAddOp2(v, OP_Param, p1, target);
      VdbeComment((v, "%s.%s -> $%d",
        (pExpr->iTable ? "new" : "old"),
        (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName),
        target
      ));

      /* If the column has REAL affinity, it may currently be stored as an
      ** integer. Use OP_RealAffinity to make sure it is really real.  */
      if( pExpr->iColumn>=0 
       && pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL
      ){
        sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
      }
      break;
    }


    /*
    ** Form A:
    **   CASE x WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END
    **
    ** Form B:
    **   CASE WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END
2644
2645
2646
2647
2648
2649
2650





2651

2652
2653
2654
2655
2656

2657
2658

2659
2660
2661
2662
2663
2664







2665
2666
2667
2668

2669
2670
2671
2672
2673
2674
2675
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744

2745
2746
2747
2748
2749

2750


2751






2752
2753
2754
2755
2756
2757
2758



2759
2760
2761
2762
2763
2764
2765
2766
2767







+
+
+
+
+
-
+




-
+
-
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-

+







      assert( db->mallocFailed || pParse->nErr>0 
           || pParse->iCacheLevel==iCacheLevel );
      sqlite3VdbeResolveLabel(v, endLabel);
      break;
    }
#ifndef SQLITE_OMIT_TRIGGER
    case TK_RAISE: {
      assert( pExpr->affinity==OE_Rollback 
           || pExpr->affinity==OE_Abort
           || pExpr->affinity==OE_Fail
           || pExpr->affinity==OE_Ignore
      );
      if( !pParse->trigStack ){
      if( !pParse->pTriggerTab ){
        sqlite3ErrorMsg(pParse,
                       "RAISE() may only be used within a trigger-program");
        return 0;
      }
      if( pExpr->affinity!=OE_Ignore ){
      if( pExpr->affinity==OE_Abort ){
         assert( pExpr->affinity==OE_Rollback ||
                 pExpr->affinity == OE_Abort ||
        sqlite3MayAbort(pParse);
                 pExpr->affinity == OE_Fail );
         assert( !ExprHasProperty(pExpr, EP_IntValue) );
         sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->affinity, 0,
                           pExpr->u.zToken, 0);
      } else {
         assert( pExpr->affinity == OE_Ignore );
      }
      assert( !ExprHasProperty(pExpr, EP_IntValue) );
      if( pExpr->affinity==OE_Ignore ){
        sqlite3VdbeAddOp4(
            v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
      }else{
        sqlite3HaltConstraint(pParse, pExpr->affinity, pExpr->u.zToken, 0);
         sqlite3VdbeAddOp2(v, OP_ContextPop, 0, 0);
         sqlite3VdbeAddOp2(v, OP_Goto, 0, pParse->trigStack->ignoreJump);
         VdbeComment((v, "raise(IGNORE)"));
      }

      break;
    }
#endif
  }
  sqlite3ReleaseTempReg(pParse, regFree1);
  sqlite3ReleaseTempReg(pParse, regFree2);
  return inReg;
2737
2738
2739
2740
2741
2742
2743

2744
2745
2746
2747
2748
2749
2750
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843







+







  ** keep the ALWAYS() in case the conditions above change with future
  ** modifications or enhancements. */
  if( ALWAYS(pExpr->op!=TK_REGISTER) ){  
    int iMem;
    iMem = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem);
    pExpr->iTable = iMem;
    pExpr->op2 = pExpr->op;
    pExpr->op = TK_REGISTER;
  }
  return inReg;
}

/*
** Return TRUE if pExpr is an constant expression that is appropriate
2810
2811
2812
2813
2814
2815
2816

2817
2818
2819
2820
2821
2822
2823
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917







+







** factoring out of a loop, then evaluate the expression
** into a register and convert the expression into a TK_REGISTER
** expression.
*/
static int evalConstExpr(Walker *pWalker, Expr *pExpr){
  Parse *pParse = pWalker->pParse;
  switch( pExpr->op ){
    case TK_IN:
    case TK_REGISTER: {
      return WRC_Prune;
    }
    case TK_FUNCTION:
    case TK_AGG_FUNCTION:
    case TK_CONST_FUNC: {
      /* The arguments to a function have a fixed destination.
2837
2838
2839
2840
2841
2842
2843

2844
2845
2846
2847
2848
2849
2850
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945







+







    }
  }
  if( isAppropriateForFactoring(pExpr) ){
    int r1 = ++pParse->nMem;
    int r2;
    r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
    if( NEVER(r1!=r2) ) sqlite3ReleaseTempReg(pParse, r1);
    pExpr->op2 = pExpr->op;
    pExpr->op = TK_REGISTER;
    pExpr->iTable = r2;
    return WRC_Prune;
  }
  return WRC_Continue;
}

2965
2966
2967
2968
2969
2970
2971













2972
2973
2974
2975
2976
2977
2978
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086







+
+
+
+
+
+
+
+
+
+
+
+
+







      codeCompareOperands(pParse, pExpr->pLeft, &r1, &regFree1,
                                  pExpr->pRight, &r2, &regFree2);
      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
                  r1, r2, dest, jumpIfNull);
      testcase( regFree1==0 );
      testcase( regFree2==0 );
      break;
    }
    case TK_IS:
    case TK_ISNOT: {
      testcase( op==TK_IS );
      testcase( op==TK_ISNOT );
      codeCompareOperands(pParse, pExpr->pLeft, &r1, &regFree1,
                                  pExpr->pRight, &r2, &regFree2);
      op = (op==TK_IS) ? TK_EQ : TK_NE;
      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
                  r1, r2, dest, SQLITE_NULLEQ);
      testcase( regFree1==0 );
      testcase( regFree2==0 );
      break;
    }
    case TK_ISNULL:
    case TK_NOTNULL: {
      assert( TK_ISNULL==OP_IsNull );
      assert( TK_NOTNULL==OP_NotNull );
      testcase( op==TK_ISNULL );
      testcase( op==TK_NOTNULL );
3114
3115
3116
3117
3118
3119
3120













3121
3122
3123
3124
3125
3126
3127
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248







+
+
+
+
+
+
+
+
+
+
+
+
+







      codeCompareOperands(pParse, pExpr->pLeft, &r1, &regFree1,
                                  pExpr->pRight, &r2, &regFree2);
      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
                  r1, r2, dest, jumpIfNull);
      testcase( regFree1==0 );
      testcase( regFree2==0 );
      break;
    }
    case TK_IS:
    case TK_ISNOT: {
      testcase( pExpr->op==TK_IS );
      testcase( pExpr->op==TK_ISNOT );
      codeCompareOperands(pParse, pExpr->pLeft, &r1, &regFree1,
                                  pExpr->pRight, &r2, &regFree2);
      op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ;
      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
                  r1, r2, dest, SQLITE_NULLEQ);
      testcase( regFree1==0 );
      testcase( regFree2==0 );
      break;
    }
    case TK_ISNULL:
    case TK_NOTNULL: {
      testcase( op==TK_ISNULL );
      testcase( op==TK_NOTNULL );
      r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
      sqlite3VdbeAddOp2(v, op, r1, dest);
Changes to src/fault.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1
2
3
4
5
6
7
8
9
10
11
12




13
14
15
16
17
18
19












-
-
-
-







/*
** 2008 Jan 22
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** $Id: fault.c,v 1.11 2008/09/02 00:52:52 drh Exp $
*/

/*
** This file contains code to support the concept of "benign" 
** malloc failures (when the xMalloc() or xRealloc() method of the
** sqlite3_mem_methods structure fails to allocate a block of memory
** and returns 0). 
**
** Most malloc failures are non-benign. After they occur, SQLite
** abandons the current operation and returns an error code (usually
Added src/fkey.c.







































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used by the compiler to add foreign key
** support to compiled SQL statements.
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_FOREIGN_KEY
#ifndef SQLITE_OMIT_TRIGGER

/*
** Deferred and Immediate FKs
** --------------------------
**
** Foreign keys in SQLite come in two flavours: deferred and immediate.
** If an immediate foreign key constraint is violated, SQLITE_CONSTRAINT
** is returned and the current statement transaction rolled back. If a 
** deferred foreign key constraint is violated, no action is taken 
** immediately. However if the application attempts to commit the 
** transaction before fixing the constraint violation, the attempt fails.
**
** Deferred constraints are implemented using a simple counter associated
** with the database handle. The counter is set to zero each time a 
** database transaction is opened. Each time a statement is executed 
** that causes a foreign key violation, the counter is incremented. Each
** time a statement is executed that removes an existing violation from
** the database, the counter is decremented. When the transaction is
** committed, the commit fails if the current value of the counter is
** greater than zero. This scheme has two big drawbacks:
**
**   * When a commit fails due to a deferred foreign key constraint, 
**     there is no way to tell which foreign constraint is not satisfied,
**     or which row it is not satisfied for.
**
**   * If the database contains foreign key violations when the 
**     transaction is opened, this may cause the mechanism to malfunction.
**
** Despite these problems, this approach is adopted as it seems simpler
** than the alternatives.
**
** INSERT operations:
**
**   I.1) For each FK for which the table is the child table, search
**        the parent table for a match. If none is found increment the
**        constraint counter.
**
**   I.2) For each FK for which the table is the parent table, 
**        search the child table for rows that correspond to the new
**        row in the parent table. Decrement the counter for each row
**        found (as the constraint is now satisfied).
**
** DELETE operations:
**
**   D.1) For each FK for which the table is the child table, 
**        search the parent table for a row that corresponds to the 
**        deleted row in the child table. If such a row is not found, 
**        decrement the counter.
**
**   D.2) For each FK for which the table is the parent table, search 
**        the child table for rows that correspond to the deleted row 
**        in the parent table. For each found increment the counter.
**
** UPDATE operations:
**
**   An UPDATE command requires that all 4 steps above are taken, but only
**   for FK constraints for which the affected columns are actually 
**   modified (values must be compared at runtime).
**
** Note that I.1 and D.1 are very similar operations, as are I.2 and D.2.
** This simplifies the implementation a bit.
**
** For the purposes of immediate FK constraints, the OR REPLACE conflict
** resolution is considered to delete rows before the new row is inserted.
** If a delete caused by OR REPLACE violates an FK constraint, an exception
** is thrown, even if the FK constraint would be satisfied after the new 
** row is inserted.
**
** Immediate constraints are usually handled similarly. The only difference 
** is that the counter used is stored as part of each individual statement
** object (struct Vdbe). If, after the statement has run, its immediate
** constraint counter is greater than zero, it returns SQLITE_CONSTRAINT
** and the statement transaction is rolled back. An exception is an INSERT
** statement that inserts a single row only (no triggers). In this case,
** instead of using a counter, an exception is thrown immediately if the
** INSERT violates a foreign key constraint. This is necessary as such
** an INSERT does not open a statement transaction.
**
** TODO: How should dropping a table be handled? How should renaming a 
** table be handled?
**
**
** Query API Notes
** ---------------
**
** Before coding an UPDATE or DELETE row operation, the code-generator
** for those two operations needs to know whether or not the operation
** requires any FK processing and, if so, which columns of the original
** row are required by the FK processing VDBE code (i.e. if FKs were
** implemented using triggers, which of the old.* columns would be 
** accessed). No information is required by the code-generator before
** coding an INSERT operation. The functions used by the UPDATE/DELETE
** generation code to query for this information are:
**
**   sqlite3FkRequired() - Test to see if FK processing is required.
**   sqlite3FkOldmask()  - Query for the set of required old.* columns.
**
**
** Externally accessible module functions
** --------------------------------------
**
**   sqlite3FkCheck()    - Check for foreign key violations.
**   sqlite3FkActions()  - Code triggers for ON UPDATE/ON DELETE actions.
**   sqlite3FkDelete()   - Delete an FKey structure.
*/

/*
** VDBE Calling Convention
** -----------------------
**
** Example:
**
**   For the following INSERT statement:
**
**     CREATE TABLE t1(a, b INTEGER PRIMARY KEY, c);
**     INSERT INTO t1 VALUES(1, 2, 3.1);
**
**   Register (x):        2    (type integer)
**   Register (x+1):      1    (type integer)
**   Register (x+2):      NULL (type NULL)
**   Register (x+3):      3.1  (type real)
*/

/*
** A foreign key constraint requires that the key columns in the parent
** table are collectively subject to a UNIQUE or PRIMARY KEY constraint.
** Given that pParent is the parent table for foreign key constraint pFKey, 
** search the schema a unique index on the parent key columns. 
**
** If successful, zero is returned. If the parent key is an INTEGER PRIMARY 
** KEY column, then output variable *ppIdx is set to NULL. Otherwise, *ppIdx 
** is set to point to the unique index. 
** 
** If the parent key consists of a single column (the foreign key constraint
** is not a composite foreign key), output variable *paiCol is set to NULL.
** Otherwise, it is set to point to an allocated array of size N, where
** N is the number of columns in the parent key. The first element of the
** array is the index of the child table column that is mapped by the FK
** constraint to the parent table column stored in the left-most column
** of index *ppIdx. The second element of the array is the index of the
** child table column that corresponds to the second left-most column of
** *ppIdx, and so on.
**
** If the required index cannot be found, either because:
**
**   1) The named parent key columns do not exist, or
**
**   2) The named parent key columns do exist, but are not subject to a
**      UNIQUE or PRIMARY KEY constraint, or
**
**   3) No parent key columns were provided explicitly as part of the
**      foreign key definition, and the parent table does not have a
**      PRIMARY KEY, or
**
**   4) No parent key columns were provided explicitly as part of the
**      foreign key definition, and the PRIMARY KEY of the parent table 
**      consists of a a different number of columns to the child key in 
**      the child table.
**
** then non-zero is returned, and a "foreign key mismatch" error loaded
** into pParse. If an OOM error occurs, non-zero is returned and the
** pParse->db->mallocFailed flag is set.
*/
static int locateFkeyIndex(
  Parse *pParse,                  /* Parse context to store any error in */
  Table *pParent,                 /* Parent table of FK constraint pFKey */
  FKey *pFKey,                    /* Foreign key to find index for */
  Index **ppIdx,                  /* OUT: Unique index on parent table */
  int **paiCol                    /* OUT: Map of index columns in pFKey */
){
  Index *pIdx = 0;                    /* Value to return via *ppIdx */
  int *aiCol = 0;                     /* Value to return via *paiCol */
  int nCol = pFKey->nCol;             /* Number of columns in parent key */
  char *zKey = pFKey->aCol[0].zCol;   /* Name of left-most parent key column */

  /* The caller is responsible for zeroing output parameters. */
  assert( ppIdx && *ppIdx==0 );
  assert( !paiCol || *paiCol==0 );
  assert( pParse );

  /* If this is a non-composite (single column) foreign key, check if it 
  ** maps to the INTEGER PRIMARY KEY of table pParent. If so, leave *ppIdx 
  ** and *paiCol set to zero and return early. 
  **
  ** Otherwise, for a composite foreign key (more than one column), allocate
  ** space for the aiCol array (returned via output parameter *paiCol).
  ** Non-composite foreign keys do not require the aiCol array.
  */
  if( nCol==1 ){
    /* The FK maps to the IPK if any of the following are true:
    **
    **   1) There is an INTEGER PRIMARY KEY column and the FK is implicitly 
    **      mapped to the primary key of table pParent, or
    **   2) The FK is explicitly mapped to a column declared as INTEGER
    **      PRIMARY KEY.
    */
    if( pParent->iPKey>=0 ){
      if( !zKey ) return 0;
      if( !sqlite3StrICmp(pParent->aCol[pParent->iPKey].zName, zKey) ) return 0;
    }
  }else if( paiCol ){
    assert( nCol>1 );
    aiCol = (int *)sqlite3DbMallocRaw(pParse->db, nCol*sizeof(int));
    if( !aiCol ) return 1;
    *paiCol = aiCol;
  }

  for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){
    if( pIdx->nColumn==nCol && pIdx->onError!=OE_None ){ 
      /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number
      ** of columns. If each indexed column corresponds to a foreign key
      ** column of pFKey, then this index is a winner.  */

      if( zKey==0 ){
        /* If zKey is NULL, then this foreign key is implicitly mapped to 
        ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be 
        ** identified by the test (Index.autoIndex==2).  */
        if( pIdx->autoIndex==2 ){
          if( aiCol ){
            int i;
            for(i=0; i<nCol; i++) aiCol[i] = pFKey->aCol[i].iFrom;
          }
          break;
        }
      }else{
        /* If zKey is non-NULL, then this foreign key was declared to
        ** map to an explicit list of columns in table pParent. Check if this
        ** index matches those columns. Also, check that the index uses
        ** the default collation sequences for each column. */
        int i, j;
        for(i=0; i<nCol; i++){
          int iCol = pIdx->aiColumn[i];     /* Index of column in parent tbl */
          char *zDfltColl;                  /* Def. collation for column */
          char *zIdxCol;                    /* Name of indexed column */

          /* If the index uses a collation sequence that is different from
          ** the default collation sequence for the column, this index is
          ** unusable. Bail out early in this case.  */
          zDfltColl = pParent->aCol[iCol].zColl;
          if( !zDfltColl ){
            zDfltColl = "BINARY";
          }
          if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break;

          zIdxCol = pParent->aCol[iCol].zName;
          for(j=0; j<nCol; j++){
            if( sqlite3StrICmp(pFKey->aCol[j].zCol, zIdxCol)==0 ){
              if( aiCol ) aiCol[i] = pFKey->aCol[j].iFrom;
              break;
            }
          }
          if( j==nCol ) break;
        }
        if( i==nCol ) break;      /* pIdx is usable */
      }
    }
  }

  if( !pIdx ){
    if( !pParse->disableTriggers ){
      sqlite3ErrorMsg(pParse, "foreign key mismatch");
    }
    sqlite3DbFree(pParse->db, aiCol);
    return 1;
  }

  *ppIdx = pIdx;
  return 0;
}

/*
** This function is called when a row is inserted into or deleted from the 
** child table of foreign key constraint pFKey. If an SQL UPDATE is executed 
** on the child table of pFKey, this function is invoked twice for each row
** affected - once to "delete" the old row, and then again to "insert" the
** new row.
**
** Each time it is called, this function generates VDBE code to locate the
** row in the parent table that corresponds to the row being inserted into 
** or deleted from the child table. If the parent row can be found, no 
** special action is taken. Otherwise, if the parent row can *not* be
** found in the parent table:
**
**   Operation | FK type   | Action taken
**   --------------------------------------------------------------------------
**   INSERT      immediate   Increment the "immediate constraint counter".
**
**   DELETE      immediate   Decrement the "immediate constraint counter".
**
**   INSERT      deferred    Increment the "deferred constraint counter".
**
**   DELETE      deferred    Decrement the "deferred constraint counter".
**
** These operations are identified in the comment at the top of this file 
** (fkey.c) as "I.1" and "D.1".
*/
static void fkLookupParent(
  Parse *pParse,        /* Parse context */
  int iDb,              /* Index of database housing pTab */
  Table *pTab,          /* Parent table of FK pFKey */
  Index *pIdx,          /* Unique index on parent key columns in pTab */
  FKey *pFKey,          /* Foreign key constraint */
  int *aiCol,           /* Map from parent key columns to child table columns */
  int regData,          /* Address of array containing child table row */
  int nIncr,            /* Increment constraint counter by this */
  int isIgnore          /* If true, pretend pTab contains all NULL values */
){
  int i;                                    /* Iterator variable */
  Vdbe *v = sqlite3GetVdbe(pParse);         /* Vdbe to add code to */
  int iCur = pParse->nTab - 1;              /* Cursor number to use */
  int iOk = sqlite3VdbeMakeLabel(v);        /* jump here if parent key found */

  /* If nIncr is less than zero, then check at runtime if there are any
  ** outstanding constraints to resolve. If there are not, there is no need
  ** to check if deleting this row resolves any outstanding violations.
  **
  ** Check if any of the key columns in the child table row are NULL. If 
  ** any are, then the constraint is considered satisfied. No need to 
  ** search for a matching row in the parent table.  */
  if( nIncr<0 ){
    sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk);
  }
  for(i=0; i<pFKey->nCol; i++){
    int iReg = aiCol[i] + regData + 1;
    sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk);
  }

  if( isIgnore==0 ){
    if( pIdx==0 ){
      /* If pIdx is NULL, then the parent key is the INTEGER PRIMARY KEY
      ** column of the parent table (table pTab).  */
      int iMustBeInt;               /* Address of MustBeInt instruction */
      int regTemp = sqlite3GetTempReg(pParse);
  
      /* Invoke MustBeInt to coerce the child key value to an integer (i.e. 
      ** apply the affinity of the parent key). If this fails, then there
      ** is no matching parent key. Before using MustBeInt, make a copy of
      ** the value. Otherwise, the value inserted into the child key column
      ** will have INTEGER affinity applied to it, which may not be correct.  */
      sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp);
      iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0);
  
      /* If the parent table is the same as the child table, and we are about
      ** to increment the constraint-counter (i.e. this is an INSERT operation),
      ** then check if the row being inserted matches itself. If so, do not
      ** increment the constraint-counter.  */
      if( pTab==pFKey->pFrom && nIncr==1 ){
        sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp);
      }
  
      sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
      sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp);
      sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
      sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
      sqlite3VdbeJumpHere(v, iMustBeInt);
      sqlite3ReleaseTempReg(pParse, regTemp);
    }else{
      int nCol = pFKey->nCol;
      int regTemp = sqlite3GetTempRange(pParse, nCol);
      int regRec = sqlite3GetTempReg(pParse);
      KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
  
      sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb);
      sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);
      for(i=0; i<nCol; i++){
        sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[i]+1+regData, regTemp+i);
      }
  
      /* If the parent table is the same as the child table, and we are about
      ** to increment the constraint-counter (i.e. this is an INSERT operation),
      ** then check if the row being inserted matches itself. If so, do not
      ** increment the constraint-counter.  */
      if( pTab==pFKey->pFrom && nIncr==1 ){
        int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1;
        for(i=0; i<nCol; i++){
          int iChild = aiCol[i]+1+regData;
          int iParent = pIdx->aiColumn[i]+1+regData;
          sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent);
        }
        sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
      }
  
      sqlite3VdbeAddOp3(v, OP_MakeRecord, regTemp, nCol, regRec);
      sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0);
      sqlite3VdbeAddOp3(v, OP_Found, iCur, iOk, regRec);
  
      sqlite3ReleaseTempReg(pParse, regRec);
      sqlite3ReleaseTempRange(pParse, regTemp, nCol);
    }
  }

  if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
    /* Special case: If this is an INSERT statement that will insert exactly
    ** one row into the table, raise a constraint immediately instead of
    ** incrementing a counter. This is necessary as the VM code is being
    ** generated for will not open a statement transaction.  */
    assert( nIncr==1 );
    sqlite3HaltConstraint(
        pParse, OE_Abort, "foreign key constraint failed", P4_STATIC
    );
  }else{
    if( nIncr>0 && pFKey->isDeferred==0 ){
      sqlite3ParseToplevel(pParse)->mayAbort = 1;
    }
    sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
  }

  sqlite3VdbeResolveLabel(v, iOk);
  sqlite3VdbeAddOp1(v, OP_Close, iCur);
}

/*
** This function is called to generate code executed when a row is deleted
** from the parent table of foreign key constraint pFKey and, if pFKey is 
** deferred, when a row is inserted into the same table. When generating
** code for an SQL UPDATE operation, this function may be called twice -
** once to "delete" the old row and once to "insert" the new row.
**
** The code generated by this function scans through the rows in the child
** table that correspond to the parent table row being deleted or inserted.
** For each child row found, one of the following actions is taken:
**
**   Operation | FK type   | Action taken
**   --------------------------------------------------------------------------
**   DELETE      immediate   Increment the "immediate constraint counter".
**                           Or, if the ON (UPDATE|DELETE) action is RESTRICT,
**                           throw a "foreign key constraint failed" exception.
**
**   INSERT      immediate   Decrement the "immediate constraint counter".
**
**   DELETE      deferred    Increment the "deferred constraint counter".
**                           Or, if the ON (UPDATE|DELETE) action is RESTRICT,
**                           throw a "foreign key constraint failed" exception.
**
**   INSERT      deferred    Decrement the "deferred constraint counter".
**
** These operations are identified in the comment at the top of this file 
** (fkey.c) as "I.2" and "D.2".
*/
static void fkScanChildren(
  Parse *pParse,                  /* Parse context */
  SrcList *pSrc,                  /* SrcList containing the table to scan */
  Table *pTab,
  Index *pIdx,                    /* Foreign key index */
  FKey *pFKey,                    /* Foreign key relationship */
  int *aiCol,                     /* Map from pIdx cols to child table cols */
  int regData,                    /* Referenced table data starts here */
  int nIncr                       /* Amount to increment deferred counter by */
){
  sqlite3 *db = pParse->db;       /* Database handle */
  int i;                          /* Iterator variable */
  Expr *pWhere = 0;               /* WHERE clause to scan with */
  NameContext sNameContext;       /* Context used to resolve WHERE clause */
  WhereInfo *pWInfo;              /* Context used by sqlite3WhereXXX() */
  int iFkIfZero = 0;              /* Address of OP_FkIfZero */
  Vdbe *v = sqlite3GetVdbe(pParse);

  assert( !pIdx || pIdx->pTable==pTab );

  if( nIncr<0 ){
    iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0);
  }

  /* Create an Expr object representing an SQL expression like:
  **
  **   <parent-key1> = <child-key1> AND <parent-key2> = <child-key2> ...
  **
  ** The collation sequence used for the comparison should be that of
  ** the parent key columns. The affinity of the parent key column should
  ** be applied to each child key value before the comparison takes place.
  */
  for(i=0; i<pFKey->nCol; i++){
    Expr *pLeft;                  /* Value from parent table row */
    Expr *pRight;                 /* Column ref to child table */
    Expr *pEq;                    /* Expression (pLeft = pRight) */
    int iCol;                     /* Index of column in child table */ 
    const char *zCol;             /* Name of column in child table */

    pLeft = sqlite3Expr(db, TK_REGISTER, 0);
    if( pLeft ){
      /* Set the collation sequence and affinity of the LHS of each TK_EQ
      ** expression to the parent key column defaults.  */
      if( pIdx ){
        Column *pCol;
        iCol = pIdx->aiColumn[i];
        pCol = &pIdx->pTable->aCol[iCol];
        pLeft->iTable = regData+iCol+1;
        pLeft->affinity = pCol->affinity;
        pLeft->pColl = sqlite3LocateCollSeq(pParse, pCol->zColl);
      }else{
        pLeft->iTable = regData;
        pLeft->affinity = SQLITE_AFF_INTEGER;
      }
    }
    iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
    assert( iCol>=0 );
    zCol = pFKey->pFrom->aCol[iCol].zName;
    pRight = sqlite3Expr(db, TK_ID, zCol);
    pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0);
    pWhere = sqlite3ExprAnd(db, pWhere, pEq);
  }

  /* If the child table is the same as the parent table, and this scan
  ** is taking place as part of a DELETE operation (operation D.2), omit the
  ** row being deleted from the scan by adding ($rowid != rowid) to the WHERE 
  ** clause, where $rowid is the rowid of the row being deleted.  */
  if( pTab==pFKey->pFrom && nIncr>0 ){
    Expr *pEq;                    /* Expression (pLeft = pRight) */
    Expr *pLeft;                  /* Value from parent table row */
    Expr *pRight;                 /* Column ref to child table */
    pLeft = sqlite3Expr(db, TK_REGISTER, 0);
    pRight = sqlite3Expr(db, TK_COLUMN, 0);
    if( pLeft && pRight ){
      pLeft->iTable = regData;
      pLeft->affinity = SQLITE_AFF_INTEGER;
      pRight->iTable = pSrc->a[0].iCursor;
      pRight->iColumn = -1;
    }
    pEq = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0);
    pWhere = sqlite3ExprAnd(db, pWhere, pEq);
  }

  /* Resolve the references in the WHERE clause. */
  memset(&sNameContext, 0, sizeof(NameContext));
  sNameContext.pSrcList = pSrc;
  sNameContext.pParse = pParse;
  sqlite3ResolveExprNames(&sNameContext, pWhere);

  /* Create VDBE to loop through the entries in pSrc that match the WHERE
  ** clause. If the constraint is not deferred, throw an exception for
  ** each row found. Otherwise, for deferred constraints, increment the
  ** deferred constraint counter by nIncr for each row selected.  */
  pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0);
  if( nIncr>0 && pFKey->isDeferred==0 ){
    sqlite3ParseToplevel(pParse)->mayAbort = 1;
  }
  sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
  if( pWInfo ){
    sqlite3WhereEnd(pWInfo);
  }

  /* Clean up the WHERE clause constructed above. */
  sqlite3ExprDelete(db, pWhere);
  if( iFkIfZero ){
    sqlite3VdbeJumpHere(v, iFkIfZero);
  }
}

/*
** This function returns a pointer to the head of a linked list of FK
** constraints for which table pTab is the parent table. For example,
** given the following schema:
**
**   CREATE TABLE t1(a PRIMARY KEY);
**   CREATE TABLE t2(b REFERENCES t1(a);
**
** Calling this function with table "t1" as an argument returns a pointer
** to the FKey structure representing the foreign key constraint on table
** "t2". Calling this function with "t2" as the argument would return a
** NULL pointer (as there are no FK constraints for which t2 is the parent
** table).
*/
FKey *sqlite3FkReferences(Table *pTab){
  int nName = sqlite3Strlen30(pTab->zName);
  return (FKey *)sqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName, nName);
}

/*
** The second argument is a Trigger structure allocated by the 
** fkActionTrigger() routine. This function deletes the Trigger structure
** and all of its sub-components.
**
** The Trigger structure or any of its sub-components may be allocated from
** the lookaside buffer belonging to database handle dbMem.
*/
static void fkTriggerDelete(sqlite3 *dbMem, Trigger *p){
  if( p ){
    TriggerStep *pStep = p->step_list;
    sqlite3ExprDelete(dbMem, pStep->pWhere);
    sqlite3ExprListDelete(dbMem, pStep->pExprList);
    sqlite3SelectDelete(dbMem, pStep->pSelect);
    sqlite3ExprDelete(dbMem, p->pWhen);
    sqlite3DbFree(dbMem, p);
  }
}

/*
** This function is called to generate code that runs when table pTab is
** being dropped from the database. The SrcList passed as the second argument
** to this function contains a single entry guaranteed to resolve to
** table pTab.
**
** Normally, no code is required. However, if either
**
**   (a) The table is the parent table of a FK constraint, or
**   (b) The table is the child table of a deferred FK constraint and it is
**       determined at runtime that there are outstanding deferred FK 
**       constraint violations in the database,
**
** then the equivalent of "DELETE FROM <tbl>" is executed before dropping
** the table from the database. Triggers are disabled while running this
** DELETE, but foreign key actions are not.
*/
void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){
  sqlite3 *db = pParse->db;
  if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) && !pTab->pSelect ){
    int iSkip = 0;
    Vdbe *v = sqlite3GetVdbe(pParse);

    assert( v );                  /* VDBE has already been allocated */
    if( sqlite3FkReferences(pTab)==0 ){
      /* Search for a deferred foreign key constraint for which this table
      ** is the child table. If one cannot be found, return without 
      ** generating any VDBE code. If one can be found, then jump over
      ** the entire DELETE if there are no outstanding deferred constraints
      ** when this statement is run.  */
      FKey *p;
      for(p=pTab->pFKey; p; p=p->pNextFrom){
        if( p->isDeferred ) break;
      }
      if( !p ) return;
      iSkip = sqlite3VdbeMakeLabel(v);
      sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip);
    }

    pParse->disableTriggers = 1;
    sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0);
    pParse->disableTriggers = 0;

    /* If the DELETE has generated immediate foreign key constraint 
    ** violations, halt the VDBE and return an error at this point, before
    ** any modifications to the schema are made. This is because statement
    ** transactions are not able to rollback schema changes.  */
    sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
    sqlite3HaltConstraint(
        pParse, OE_Abort, "foreign key constraint failed", P4_STATIC
    );

    if( iSkip ){
      sqlite3VdbeResolveLabel(v, iSkip);
    }
  }
}

/*
** This function is called when inserting, deleting or updating a row of
** table pTab to generate VDBE code to perform foreign key constraint 
** processing for the operation.
**
** For a DELETE operation, parameter regOld is passed the index of the
** first register in an array of (pTab->nCol+1) registers containing the
** rowid of the row being deleted, followed by each of the column values
** of the row being deleted, from left to right. Parameter regNew is passed
** zero in this case.
**
** For an INSERT operation, regOld is passed zero and regNew is passed the
** first register of an array of (pTab->nCol+1) registers containing the new
** row data.
**
** For an UPDATE operation, this function is called twice. Once before
** the original record is deleted from the table using the calling convention
** described for DELETE. Then again after the original record is deleted
** but before the new record is inserted using the INSERT convention. 
*/
void sqlite3FkCheck(
  Parse *pParse,                  /* Parse context */
  Table *pTab,                    /* Row is being deleted from this table */ 
  int regOld,                     /* Previous row data is stored here */
  int regNew                      /* New row data is stored here */
){
  sqlite3 *db = pParse->db;       /* Database handle */
  Vdbe *v;                        /* VM to write code to */
  FKey *pFKey;                    /* Used to iterate through FKs */
  int iDb;                        /* Index of database containing pTab */
  const char *zDb;                /* Name of database containing pTab */
  int isIgnoreErrors = pParse->disableTriggers;

  /* Exactly one of regOld and regNew should be non-zero. */
  assert( (regOld==0)!=(regNew==0) );

  /* If foreign-keys are disabled, this function is a no-op. */
  if( (db->flags&SQLITE_ForeignKeys)==0 ) return;

  v = sqlite3GetVdbe(pParse);
  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  zDb = db->aDb[iDb].zName;

  /* Loop through all the foreign key constraints for which pTab is the
  ** child table (the table that the foreign key definition is part of).  */
  for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
    Table *pTo;                   /* Parent table of foreign key pFKey */
    Index *pIdx = 0;              /* Index on key columns in pTo */
    int *aiFree = 0;
    int *aiCol;
    int iCol;
    int i;
    int isIgnore = 0;

    /* Find the parent table of this foreign key. Also find a unique index 
    ** on the parent key columns in the parent table. If either of these 
    ** schema items cannot be located, set an error in pParse and return 
    ** early.  */
    if( pParse->disableTriggers ){
      pTo = sqlite3FindTable(db, pFKey->zTo, zDb);
    }else{
      pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb);
    }
    if( !pTo || locateFkeyIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){
      if( !isIgnoreErrors || db->mallocFailed ) return;
      continue;
    }
    assert( pFKey->nCol==1 || (aiFree && pIdx) );

    if( aiFree ){
      aiCol = aiFree;
    }else{
      iCol = pFKey->aCol[0].iFrom;
      aiCol = &iCol;
    }
    for(i=0; i<pFKey->nCol; i++){
      if( aiCol[i]==pTab->iPKey ){
        aiCol[i] = -1;
      }
#ifndef SQLITE_OMIT_AUTHORIZATION
      /* Request permission to read the parent key columns. If the 
      ** authorization callback returns SQLITE_IGNORE, behave as if any
      ** values read from the parent table are NULL. */
      if( db->xAuth ){
        int rcauth;
        char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName;
        rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb);
        isIgnore = (rcauth==SQLITE_IGNORE);
      }
#endif
    }

    /* Take a shared-cache advisory read-lock on the parent table. Allocate 
    ** a cursor to use to search the unique index on the parent key columns 
    ** in the parent table.  */
    sqlite3TableLock(pParse, iDb, pTo->tnum, 0, pTo->zName);
    pParse->nTab++;

    if( regOld!=0 ){
      /* A row is being removed from the child table. Search for the parent.
      ** If the parent does not exist, removing the child row resolves an 
      ** outstanding foreign key constraint violation. */
      fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1,isIgnore);
    }
    if( regNew!=0 ){
      /* A row is being added to the child table. If a parent row cannot
      ** be found, adding the child row has violated the FK constraint. */ 
      fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1,isIgnore);
    }

    sqlite3DbFree(db, aiFree);
  }

  /* Loop through all the foreign key constraints that refer to this table */
  for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){
    Index *pIdx = 0;              /* Foreign key index for pFKey */
    SrcList *pSrc;
    int *aiCol = 0;

    if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
      assert( regOld==0 && regNew!=0 );
      /* Inserting a single row into a parent table cannot cause an immediate
      ** foreign key violation. So do nothing in this case.  */
      continue;
    }

    if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){
      if( !isIgnoreErrors || db->mallocFailed ) return;
      continue;
    }
    assert( aiCol || pFKey->nCol==1 );

    /* Create a SrcList structure containing a single table (the table 
    ** the foreign key that refers to this table is attached to). This
    ** is required for the sqlite3WhereXXX() interface.  */
    pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
    if( pSrc ){
      struct SrcList_item *pItem = pSrc->a;
      pItem->pTab = pFKey->pFrom;
      pItem->zName = pFKey->pFrom->zName;
      pItem->pTab->nRef++;
      pItem->iCursor = pParse->nTab++;
  
      if( regNew!=0 ){
        fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1);
      }
      if( regOld!=0 ){
        /* If there is a RESTRICT action configured for the current operation
        ** on the parent table of this FK, then throw an exception 
        ** immediately if the FK constraint is violated, even if this is a
        ** deferred trigger. That's what RESTRICT means. To defer checking
        ** the constraint, the FK should specify NO ACTION (represented
        ** using OE_None). NO ACTION is the default.  */
        fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1);
      }
      pItem->zName = 0;
      sqlite3SrcListDelete(db, pSrc);
    }
    sqlite3DbFree(db, aiCol);
  }
}

#define COLUMN_MASK(x) (((x)>31) ? 0xffffffff : ((u32)1<<(x)))

/*
** This function is called before generating code to update or delete a 
** row contained in table pTab.
*/
u32 sqlite3FkOldmask(
  Parse *pParse,                  /* Parse context */
  Table *pTab                     /* Table being modified */
){
  u32 mask = 0;
  if( pParse->db->flags&SQLITE_ForeignKeys ){
    FKey *p;
    int i;
    for(p=pTab->pFKey; p; p=p->pNextFrom){
      for(i=0; i<p->nCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom);
    }
    for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
      Index *pIdx = 0;
      locateFkeyIndex(pParse, pTab, p, &pIdx, 0);
      if( pIdx ){
        for(i=0; i<pIdx->nColumn; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]);
      }
    }
  }
  return mask;
}

/*
** This function is called before generating code to update or delete a 
** row contained in table pTab. If the operation is a DELETE, then
** parameter aChange is passed a NULL value. For an UPDATE, aChange points
** to an array of size N, where N is the number of columns in table pTab.
** If the i'th column is not modified by the UPDATE, then the corresponding 
** entry in the aChange[] array is set to -1. If the column is modified,
** the value is 0 or greater. Parameter chngRowid is set to true if the
** UPDATE statement modifies the rowid fields of the table.
**
** If any foreign key processing will be required, this function returns
** true. If there is no foreign key related processing, this function 
** returns false.
*/
int sqlite3FkRequired(
  Parse *pParse,                  /* Parse context */
  Table *pTab,                    /* Table being modified */
  int *aChange,                   /* Non-NULL for UPDATE operations */
  int chngRowid                   /* True for UPDATE that affects rowid */
){
  if( pParse->db->flags&SQLITE_ForeignKeys ){
    if( !aChange ){
      /* A DELETE operation. Foreign key processing is required if the 
      ** table in question is either the child or parent table for any 
      ** foreign key constraint.  */
      return (sqlite3FkReferences(pTab) || pTab->pFKey);
    }else{
      /* This is an UPDATE. Foreign key processing is only required if the
      ** operation modifies one or more child or parent key columns. */
      int i;
      FKey *p;

      /* Check if any child key columns are being modified. */
      for(p=pTab->pFKey; p; p=p->pNextFrom){
        for(i=0; i<p->nCol; i++){
          int iChildKey = p->aCol[i].iFrom;
          if( aChange[iChildKey]>=0 ) return 1;
          if( iChildKey==pTab->iPKey && chngRowid ) return 1;
        }
      }

      /* Check if any parent key columns are being modified. */
      for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
        for(i=0; i<p->nCol; i++){
          char *zKey = p->aCol[i].zCol;
          int iKey;
          for(iKey=0; iKey<pTab->nCol; iKey++){
            Column *pCol = &pTab->aCol[iKey];
            if( (zKey ? !sqlite3StrICmp(pCol->zName, zKey) : pCol->isPrimKey) ){
              if( aChange[iKey]>=0 ) return 1;
              if( iKey==pTab->iPKey && chngRowid ) return 1;
            }
          }
        }
      }
    }
  }
  return 0;
}

/*
** This function is called when an UPDATE or DELETE operation is being 
** compiled on table pTab, which is the parent table of foreign-key pFKey.
** If the current operation is an UPDATE, then the pChanges parameter is
** passed a pointer to the list of columns being modified. If it is a
** DELETE, pChanges is passed a NULL pointer.
**
** It returns a pointer to a Trigger structure containing a trigger
** equivalent to the ON UPDATE or ON DELETE action specified by pFKey.
** If the action is "NO ACTION" or "RESTRICT", then a NULL pointer is
** returned (these actions require no special handling by the triggers
** sub-system, code for them is created by fkScanChildren()).
**
** For example, if pFKey is the foreign key and pTab is table "p" in 
** the following schema:
**
**   CREATE TABLE p(pk PRIMARY KEY);
**   CREATE TABLE c(ck REFERENCES p ON DELETE CASCADE);
**
** then the returned trigger structure is equivalent to:
**
**   CREATE TRIGGER ... DELETE ON p BEGIN
**     DELETE FROM c WHERE ck = old.pk;
**   END;
**
** The returned pointer is cached as part of the foreign key object. It
** is eventually freed along with the rest of the foreign key object by 
** sqlite3FkDelete().
*/
static Trigger *fkActionTrigger(
  Parse *pParse,                  /* Parse context */
  Table *pTab,                    /* Table being updated or deleted from */
  FKey *pFKey,                    /* Foreign key to get action for */
  ExprList *pChanges              /* Change-list for UPDATE, NULL for DELETE */
){
  sqlite3 *db = pParse->db;       /* Database handle */
  int action;                     /* One of OE_None, OE_Cascade etc. */
  Trigger *pTrigger;              /* Trigger definition to return */
  int iAction = (pChanges!=0);    /* 1 for UPDATE, 0 for DELETE */

  action = pFKey->aAction[iAction];
  pTrigger = pFKey->apTrigger[iAction];

  if( action!=OE_None && !pTrigger ){
    u8 enableLookaside;           /* Copy of db->lookaside.bEnabled */
    char const *zFrom;            /* Name of child table */
    int nFrom;                    /* Length in bytes of zFrom */
    Index *pIdx = 0;              /* Parent key index for this FK */
    int *aiCol = 0;               /* child table cols -> parent key cols */
    TriggerStep *pStep = 0;        /* First (only) step of trigger program */
    Expr *pWhere = 0;             /* WHERE clause of trigger step */
    ExprList *pList = 0;          /* Changes list if ON UPDATE CASCADE */
    Select *pSelect = 0;          /* If RESTRICT, "SELECT RAISE(...)" */
    int i;                        /* Iterator variable */
    Expr *pWhen = 0;              /* WHEN clause for the trigger */

    if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0;
    assert( aiCol || pFKey->nCol==1 );

    for(i=0; i<pFKey->nCol; i++){
      Token tOld = { "old", 3 };  /* Literal "old" token */
      Token tNew = { "new", 3 };  /* Literal "new" token */
      Token tFromCol;             /* Name of column in child table */
      Token tToCol;               /* Name of column in parent table */
      int iFromCol;               /* Idx of column in child table */
      Expr *pEq;                  /* tFromCol = OLD.tToCol */

      iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
      assert( iFromCol>=0 );
      tToCol.z = pIdx ? pTab->aCol[pIdx->aiColumn[i]].zName : "oid";
      tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName;

      tToCol.n = sqlite3Strlen30(tToCol.z);
      tFromCol.n = sqlite3Strlen30(tFromCol.z);

      /* Create the expression "OLD.zToCol = zFromCol". It is important
      ** that the "OLD.zToCol" term is on the LHS of the = operator, so
      ** that the affinity and collation sequence associated with the
      ** parent table are used for the comparison. */
      pEq = sqlite3PExpr(pParse, TK_EQ,
          sqlite3PExpr(pParse, TK_DOT, 
            sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
            sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
          , 0),
          sqlite3PExpr(pParse, TK_ID, 0, 0, &tFromCol)
      , 0);
      pWhere = sqlite3ExprAnd(db, pWhere, pEq);

      /* For ON UPDATE, construct the next term of the WHEN clause.
      ** The final WHEN clause will be like this:
      **
      **    WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN)
      */
      if( pChanges ){
        pEq = sqlite3PExpr(pParse, TK_IS,
            sqlite3PExpr(pParse, TK_DOT, 
              sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
              sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
              0),
            sqlite3PExpr(pParse, TK_DOT, 
              sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
              sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
              0),
            0);
        pWhen = sqlite3ExprAnd(db, pWhen, pEq);
      }
  
      if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){
        Expr *pNew;
        if( action==OE_Cascade ){
          pNew = sqlite3PExpr(pParse, TK_DOT, 
            sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
            sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
          , 0);
        }else if( action==OE_SetDflt ){
          Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
          if( pDflt ){
            pNew = sqlite3ExprDup(db, pDflt, 0);
          }else{
            pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
          }
        }else{
          pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
        }
        pList = sqlite3ExprListAppend(pParse, pList, pNew);
        sqlite3ExprListSetName(pParse, pList, &tFromCol, 0);
      }
    }
    sqlite3DbFree(db, aiCol);

    zFrom = pFKey->pFrom->zName;
    nFrom = sqlite3Strlen30(zFrom);

    if( action==OE_Restrict ){
      Token tFrom;
      Expr *pRaise; 

      tFrom.z = zFrom;
      tFrom.n = nFrom;
      pRaise = sqlite3Expr(db, TK_RAISE, "foreign key constraint failed");
      if( pRaise ){
        pRaise->affinity = OE_Abort;
      }
      pSelect = sqlite3SelectNew(pParse, 
          sqlite3ExprListAppend(pParse, 0, pRaise),
          sqlite3SrcListAppend(db, 0, &tFrom, 0),
          pWhere,
          0, 0, 0, 0, 0, 0
      );
      pWhere = 0;
    }

    /* In the current implementation, pTab->dbMem==0 for all tables except
    ** for temporary tables used to describe subqueries.  And temporary
    ** tables do not have foreign key constraints.  Hence, pTab->dbMem
    ** should always be 0 there.
    */
    enableLookaside = db->lookaside.bEnabled;
    db->lookaside.bEnabled = 0;

    pTrigger = (Trigger *)sqlite3DbMallocZero(db, 
        sizeof(Trigger) +         /* struct Trigger */
        sizeof(TriggerStep) +     /* Single step in trigger program */
        nFrom + 1                 /* Space for pStep->target.z */
    );
    if( pTrigger ){
      pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1];
      pStep->target.z = (char *)&pStep[1];
      pStep->target.n = nFrom;
      memcpy((char *)pStep->target.z, zFrom, nFrom);
  
      pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
      pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
      pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
      if( pWhen ){
        pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0, 0);
        pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
      }
    }

    /* Re-enable the lookaside buffer, if it was disabled earlier. */
    db->lookaside.bEnabled = enableLookaside;

    sqlite3ExprDelete(db, pWhere);
    sqlite3ExprDelete(db, pWhen);
    sqlite3ExprListDelete(db, pList);
    sqlite3SelectDelete(db, pSelect);
    if( db->mallocFailed==1 ){
      fkTriggerDelete(db, pTrigger);
      return 0;
    }

    switch( action ){
      case OE_Restrict:
        pStep->op = TK_SELECT; 
        break;
      case OE_Cascade: 
        if( !pChanges ){ 
          pStep->op = TK_DELETE; 
          break; 
        }
      default:
        pStep->op = TK_UPDATE;
    }
    pStep->pTrig = pTrigger;
    pTrigger->pSchema = pTab->pSchema;
    pTrigger->pTabSchema = pTab->pSchema;
    pFKey->apTrigger[iAction] = pTrigger;
    pTrigger->op = (pChanges ? TK_UPDATE : TK_DELETE);
  }

  return pTrigger;
}

/*
** This function is called when deleting or updating a row to implement
** any required CASCADE, SET NULL or SET DEFAULT actions.
*/
void sqlite3FkActions(
  Parse *pParse,                  /* Parse context */
  Table *pTab,                    /* Table being updated or deleted from */
  ExprList *pChanges,             /* Change-list for UPDATE, NULL for DELETE */
  int regOld                      /* Address of array containing old row */
){
  /* If foreign-key support is enabled, iterate through all FKs that 
  ** refer to table pTab. If there is an action associated with the FK 
  ** for this operation (either update or delete), invoke the associated 
  ** trigger sub-program.  */
  if( pParse->db->flags&SQLITE_ForeignKeys ){
    FKey *pFKey;                  /* Iterator variable */
    for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){
      Trigger *pAction = fkActionTrigger(pParse, pTab, pFKey, pChanges);
      if( pAction ){
        sqlite3CodeRowTriggerDirect(pParse, pAction, pTab, regOld, OE_Abort, 0);
      }
    }
  }
}

#endif /* ifndef SQLITE_OMIT_TRIGGER */

/*
** Free all memory associated with foreign key definitions attached to
** table pTab. Remove the deleted foreign keys from the Schema.fkeyHash
** hash table.
*/
void sqlite3FkDelete(Table *pTab){
  FKey *pFKey;                    /* Iterator variable */
  FKey *pNext;                    /* Copy of pFKey->pNextFrom */

  for(pFKey=pTab->pFKey; pFKey; pFKey=pNext){

    /* Remove the FK from the fkeyHash hash table. */
    if( pFKey->pPrevTo ){
      pFKey->pPrevTo->pNextTo = pFKey->pNextTo;
    }else{
      void *data = (void *)pFKey->pNextTo;
      const char *z = (data ? pFKey->pNextTo->zTo : pFKey->zTo);
      sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, sqlite3Strlen30(z), data);
    }
    if( pFKey->pNextTo ){
      pFKey->pNextTo->pPrevTo = pFKey->pPrevTo;
    }

    /* Delete any triggers created to implement actions for this FK. */
#ifndef SQLITE_OMIT_TRIGGER
    fkTriggerDelete(pTab->dbMem, pFKey->apTrigger[0]);
    fkTriggerDelete(pTab->dbMem, pFKey->apTrigger[1]);
#endif

    /* EV: R-30323-21917 Each foreign key constraint in SQLite is
    ** classified as either immediate or deferred.
    */
    assert( pFKey->isDeferred==0 || pFKey->isDeferred==1 );

    pNext = pFKey->pNextFrom;
    sqlite3DbFree(pTab->dbMem, pFKey);
  }
}
#endif /* ifndef SQLITE_OMIT_FOREIGN_KEY */
Changes to src/func.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
11
12
13
14
15
16
17


18
19
20
21
22
23
24







-
-







*************************************************************************
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.239 2009/06/19 16:44:41 drh Exp $
*/
#include "sqliteInt.h"
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"

/*
333
334
335
336
337
338
339








340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357


358
359
360
361
362
363
364
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372







+
+
+
+
+
+
+
+


















+
+







        z1[i] = sqlite3Tolower(z1[i]);
      }
      sqlite3_result_text(context, (char *)z1, -1, sqlite3_free);
    }
  }
}


#if 0  /* This function is never used. */
/*
** The COALESCE() and IFNULL() functions used to be implemented as shown
** here.  But now they are implemented as VDBE code so that unused arguments
** do not have to be computed.  This legacy implementation is retained as
** comment.
*/
/*
** Implementation of the IFNULL(), NVL(), and COALESCE() functions.  
** All three do the same thing.  They return the first non-NULL
** argument.
*/
static void ifnullFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int i;
  for(i=0; i<argc; i++){
    if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){
      sqlite3_result_value(context, argv[i]);
      break;
    }
  }
}
#endif /* NOT USED */
#define ifnullFunc versionFunc   /* Substitute function - never called */

/*
** Implementation of random().  Return a random integer.  
*/
static void randomFunc(
  sqlite3_context *context,
  int NotUsed,
698
699
700
701
702
703
704
705

706
707
708
709
710
711
712
713
714
715














716
717
718
719
720
721
722
706
707
708
709
710
711
712

713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744







-
+










+
+
+
+
+
+
+
+
+
+
+
+
+
+







  UNUSED_PARAMETER(NotUsed);
  if( sqlite3MemCompare(argv[0], argv[1], pColl)!=0 ){
    sqlite3_result_value(context, argv[0]);
  }
}

/*
** Implementation of the VERSION(*) function.  The result is the version
** Implementation of the sqlite_version() function.  The result is the version
** of the SQLite library that is running.
*/
static void versionFunc(
  sqlite3_context *context,
  int NotUsed,
  sqlite3_value **NotUsed2
){
  UNUSED_PARAMETER2(NotUsed, NotUsed2);
  sqlite3_result_text(context, sqlite3_version, -1, SQLITE_STATIC);
}

/*
** Implementation of the sqlite_source_id() function. The result is a string
** that identifies the particular version of the source code used to build
** SQLite.
*/
static void sourceidFunc(
  sqlite3_context *context,
  int NotUsed,
  sqlite3_value **NotUsed2
){
  UNUSED_PARAMETER2(NotUsed, NotUsed2);
  sqlite3_result_text(context, SQLITE_SOURCE_ID, -1, SQLITE_STATIC);
}

/* Array for converting from half-bytes (nybbles) into ASCII hex
** digits. */
static const char hexdigits[] = {
  '0', '1', '2', '3', '4', '5', '6', '7',
  '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' 
};
1421
1422
1423
1424
1425
1426
1427

1428
1429


1430
1431


1432
1433
1434
1435

1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450


1451
1452
1453

1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467







+
-
-
+
+

-
+
+




+







#ifndef SQLITE_OMIT_FLOATING_POINT
    FUNCTION(round,              1, 0, 0, roundFunc        ),
    FUNCTION(round,              2, 0, 0, roundFunc        ),
#endif
    FUNCTION(upper,              1, 0, 0, upperFunc        ),
    FUNCTION(lower,              1, 0, 0, lowerFunc        ),
    FUNCTION(coalesce,           1, 0, 0, 0                ),
    FUNCTION(coalesce,           0, 0, 0, 0                ),
    FUNCTION(coalesce,          -1, 0, 0, ifnullFunc       ),
    FUNCTION(coalesce,           0, 0, 0, 0                ),
/*  FUNCTION(coalesce,          -1, 0, 0, ifnullFunc       ), */
    {-1,SQLITE_UTF8,SQLITE_FUNC_COALESCE,0,0,ifnullFunc,0,0,"coalesce",0},
    FUNCTION(hex,                1, 0, 0, hexFunc          ),
    FUNCTION(ifnull,             2, 0, 1, ifnullFunc       ),
/*  FUNCTION(ifnull,             2, 0, 0, ifnullFunc       ), */
    {2,SQLITE_UTF8,SQLITE_FUNC_COALESCE,0,0,ifnullFunc,0,0,"ifnull",0},
    FUNCTION(random,             0, 0, 0, randomFunc       ),
    FUNCTION(randomblob,         1, 0, 0, randomBlob       ),
    FUNCTION(nullif,             2, 0, 1, nullifFunc       ),
    FUNCTION(sqlite_version,     0, 0, 0, versionFunc      ),
    FUNCTION(sqlite_source_id,   0, 0, 0, sourceidFunc     ),
    FUNCTION(quote,              1, 0, 0, quoteFunc        ),
    FUNCTION(last_insert_rowid,  0, 0, 0, last_insert_rowid),
    FUNCTION(changes,            0, 0, 0, changes          ),
    FUNCTION(total_changes,      0, 0, 0, total_changes    ),
    FUNCTION(replace,            3, 0, 0, replaceFunc      ),
    FUNCTION(zeroblob,           1, 0, 0, zeroblobFunc     ),
  #ifdef SQLITE_SOUNDEX
Changes to src/global.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2008 June 13
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains definitions of global variables and contants.
**
** $Id: global.c,v 1.12 2009/02/05 16:31:46 drh Exp $
*/
#include "sqliteInt.h"


/* An array to map all upper-case characters into their corresponding
** lower-case character. 
**
149
150
151
152
153
154
155
156

157
158

159

160
161
162
163
164
165
166
147
148
149
150
151
152
153

154
155
156
157
158
159
160
161
162
163
164
165
166







-
+


+

+







   0,                         /* szScratch */
   0,                         /* nScratch */
   (void*)0,                  /* pPage */
   0,                         /* szPage */
   0,                         /* nPage */
   0,                         /* mxParserStack */
   0,                         /* sharedCacheEnabled */
   /* All the rest need to always be zero */
   /* All the rest should always be initialized to zero */
   0,                         /* isInit */
   0,                         /* inProgress */
   0,                         /* isMutexInit */
   0,                         /* isMallocInit */
   0,                         /* isPCacheInit */
   0,                         /* pInitMutex */
   0,                         /* nRefInitMutex */
};


/*
** Hash table for global functions - functions common to all
Changes to src/hash.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2001 September 22
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This is the implementation of generic hash-tables
** used in SQLite.
**
** $Id: hash.c,v 1.38 2009/05/09 23:29:12 drh Exp $
*/
#include "sqliteInt.h"
#include <assert.h>

/* Turn bulk memory into a hash table object by initializing the
** fields of the Hash structure.
**
Changes to src/hash.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2001 September 22
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This is the header file for the generic hash-table implemenation
** used in SQLite.
**
** $Id: hash.h,v 1.15 2009/05/02 13:29:38 drh Exp $
*/
#ifndef _SQLITE_HASH_H_
#define _SQLITE_HASH_H_

/* Forward declarations of structures. */
typedef struct Hash Hash;
typedef struct HashElem HashElem;
Changes to src/hwtime.h.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
8
9
10
11
12
13
14


15
16
17
18
19
20
21







-
-







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains inline asm code for retrieving "high-performance"
** counters for x86 class CPUs.
**
** $Id: hwtime.h,v 1.3 2008/08/01 14:33:15 shane Exp $
*/
#ifndef _HWTIME_H_
#define _HWTIME_H_

/*
** The following routine only works on pentium-class (or newer) processors.
** It uses the RDTSC opcode to read the cycle count value out of the
Changes to src/insert.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.269 2009/06/23 20:28:54 drh Exp $
*/
#include "sqliteInt.h"

/*
** Generate code that will open a table for reading.
*/
void sqlite3OpenTable(
33
34
35
36
37
38
39
40
41
42



43
44
45
46
47
48
49
50
51
52
53




54
55

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

72
73
74
75
76
77
78
79
80

81
82
83
84
85
86
87
31
32
33
34
35
36
37



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89







-
-
-
+
+
+











+
+
+
+

-
+















-
+








-
+







  sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName);
  sqlite3VdbeAddOp3(v, opcode, iCur, pTab->tnum, iDb);
  sqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(pTab->nCol), P4_INT32);
  VdbeComment((v, "%s", pTab->zName));
}

/*
** Set P4 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
** Return a pointer to the column affinity string associated with index
** pIdx. A column affinity string has one character for each column in 
** the table, according to the affinity of the column:
**
**  Character      Column affinity
**  ------------------------------
**  'a'            TEXT
**  'b'            NONE
**  'c'            NUMERIC
**  'd'            INTEGER
**  'e'            REAL
**
** An extra 'b' is appended to the end of the string to cover the
** rowid that appears as the last column in every index.
**
** Memory for the buffer containing the column index affinity string
** is managed along with the rest of the Index structure. It will be
** released when sqlite3DeleteIndex() is called.
*/
void sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
  if( !pIdx->zColAff ){
    /* The first time a column affinity string for a particular index is
    ** required, it is allocated and populated here. It is then stored as
    ** a member of the Index structure for subsequent use.
    **
    ** The column affinity string will eventually be deleted by
    ** sqliteDeleteIndex() when the Index structure itself is cleaned
    ** up.
    */
    int n;
    Table *pTab = pIdx->pTable;
    sqlite3 *db = sqlite3VdbeDb(v);
    pIdx->zColAff = (char *)sqlite3Malloc(pIdx->nColumn+2);
    if( !pIdx->zColAff ){
      db->mallocFailed = 1;
      return;
      return 0;
    }
    for(n=0; n<pIdx->nColumn; n++){
      pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity;
    }
    pIdx->zColAff[n++] = SQLITE_AFF_NONE;
    pIdx->zColAff[n] = 0;
  }
 
  sqlite3VdbeChangeP4(v, -1, pIdx->zColAff, 0);
  return pIdx->zColAff;
}

/*
** Set P4 of the most recently inserted opcode to a column affinity
** string for table pTab. A column affinity string has one character
** for each column indexed by the index, according to the affinity of the
** column:
127
128
129
130
131
132
133
134


135
136




137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159

160
161
162
163
164
165
166
167







-
+
+


+
+
+
+
















-
+







/*
** Return non-zero if the table pTab in database iDb or any of its indices
** have been opened at any point in the VDBE program beginning at location
** iStartAddr throught the end of the program.  This is used to see if 
** a statement of the form  "INSERT INTO <iDb, pTab> SELECT ..." can 
** run without using temporary table for the results of the SELECT. 
*/
static int readsTable(Vdbe *v, int iStartAddr, int iDb, Table *pTab){
static int readsTable(Parse *p, int iStartAddr, int iDb, Table *pTab){
  Vdbe *v = sqlite3GetVdbe(p);
  int i;
  int iEnd = sqlite3VdbeCurrentAddr(v);
#ifndef SQLITE_OMIT_VIRTUALTABLE
  VTable *pVTab = IsVirtual(pTab) ? sqlite3GetVTable(p->db, pTab) : 0;
#endif

  for(i=iStartAddr; i<iEnd; i++){
    VdbeOp *pOp = sqlite3VdbeGetOp(v, i);
    assert( pOp!=0 );
    if( pOp->opcode==OP_OpenRead && pOp->p3==iDb ){
      Index *pIndex;
      int tnum = pOp->p2;
      if( tnum==pTab->tnum ){
        return 1;
      }
      for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
        if( tnum==pIndex->tnum ){
          return 1;
        }
      }
    }
#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( pOp->opcode==OP_VOpen && pOp->p4.pVtab==pTab->pVtab ){
    if( pOp->opcode==OP_VOpen && pOp->p4.pVtab==pVTab ){
      assert( pOp->p4.pVtab!=0 );
      assert( pOp->p4type==P4_VTAB );
      return 1;
    }
#endif
  }
  return 0;
184
185
186
187
188
189
190

191
192
193

194
195
196
197
198
199


200
201
202
203
204



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221





222
223
224
225
226
227
228
191
192
193
194
195
196
197
198
199
200

201
202
203
204
205


206
207
208
209



210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241







+


-
+




-
-
+
+


-
-
-
+
+
+

















+
+
+
+
+







static int autoIncBegin(
  Parse *pParse,      /* Parsing context */
  int iDb,            /* Index of the database holding pTab */
  Table *pTab         /* The table we are writing to */
){
  int memId = 0;      /* Register holding maximum rowid */
  if( pTab->tabFlags & TF_Autoincrement ){
    Parse *pToplevel = sqlite3ParseToplevel(pParse);
    AutoincInfo *pInfo;

    pInfo = pParse->pAinc;
    pInfo = pToplevel->pAinc;
    while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; }
    if( pInfo==0 ){
      pInfo = sqlite3DbMallocRaw(pParse->db, sizeof(*pInfo));
      if( pInfo==0 ) return 0;
      pInfo->pNext = pParse->pAinc;
      pParse->pAinc = pInfo;
      pInfo->pNext = pToplevel->pAinc;
      pToplevel->pAinc = pInfo;
      pInfo->pTab = pTab;
      pInfo->iDb = iDb;
      pParse->nMem++;                  /* Register to hold name of table */
      pInfo->regCtr = ++pParse->nMem;  /* Max rowid register */
      pParse->nMem++;                  /* Rowid in sqlite_sequence */
      pToplevel->nMem++;                  /* Register to hold name of table */
      pInfo->regCtr = ++pToplevel->nMem;  /* Max rowid register */
      pToplevel->nMem++;                  /* Rowid in sqlite_sequence */
    }
    memId = pInfo->regCtr;
  }
  return memId;
}

/*
** This routine generates code that will initialize all of the
** register used by the autoincrement tracker.  
*/
void sqlite3AutoincrementBegin(Parse *pParse){
  AutoincInfo *p;            /* Information about an AUTOINCREMENT */
  sqlite3 *db = pParse->db;  /* The database connection */
  Db *pDb;                   /* Database only autoinc table */
  int memId;                 /* Register holding max rowid */
  int addr;                  /* A VDBE address */
  Vdbe *v = pParse->pVdbe;   /* VDBE under construction */

  /* This routine is never called during trigger-generation.  It is
  ** only called from the top-level */
  assert( pParse->pTriggerTab==0 );
  assert( pParse==sqlite3ParseToplevel(pParse) );

  assert( v );   /* We failed long ago if this is not so */
  for(p = pParse->pAinc; p; p = p->pNext){
    pDb = &db->aDb[p->iDb];
    memId = p->regCtr;
    sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
    addr = sqlite3VdbeCurrentAddr(v);
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
450
451
452
453
454
455
456

457
458
459
460
461
462
463
464
465
466
467
468
469
470

471
472
473
474
475
476
477







-














-







  int endOfLoop;        /* Label for the end of the insertion loop */
  int useTempTable = 0; /* Store SELECT results in intermediate table */
  int srcTab = 0;       /* Data comes from this temporary cursor if >=0 */
  int addrInsTop = 0;   /* Jump to label "D" */
  int addrCont = 0;     /* Top of insert loop. Label "C" in templates 3 and 4 */
  int addrSelect = 0;   /* Address of coroutine that implements the SELECT */
  SelectDest dest;      /* Destination for SELECT on rhs of INSERT */
  int newIdx = -1;      /* Cursor for the NEW pseudo-table */
  int iDb;              /* Index of database holding TABLE */
  Db *pDb;              /* The database containing table being inserted into */
  int appendFlag = 0;   /* True if the insert is likely to be an append */

  /* Register allocations */
  int regFromSelect = 0;/* Base register for data coming from SELECT */
  int regAutoinc = 0;   /* Register holding the AUTOINCREMENT counter */
  int regRowCount = 0;  /* Memory cell used for the row counter */
  int regIns;           /* Block of regs holding rowid+data being inserted */
  int regRowid;         /* registers holding insert rowid */
  int regData;          /* register holding first column to insert */
  int regRecord;        /* Holds the assemblied row record */
  int regEof = 0;       /* Register recording end of SELECT data */
  int *aRegIdx = 0;     /* One register allocated to each index */


#ifndef SQLITE_OMIT_TRIGGER
  int isView;                 /* True if attempting to insert into a view */
  Trigger *pTrigger;          /* List of triggers on pTab, if required */
  int tmask;                  /* Mask of trigger times */
#endif

499
500
501
502
503
504
505








506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532









533
534
535
536
537
538
539
540





541
542
543
544
545
546
547







+
+
+
+
+
+
+
+








-
-
-
-
-
-
-
-
-








-
-
-
-
-







# define isView 0
#endif
#ifdef SQLITE_OMIT_VIEW
# undef isView
# define isView 0
#endif
  assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) );

  /* If pTab is really a view, make sure it has been initialized.
  ** ViewGetColumnNames() is a no-op if pTab is not a view (or virtual 
  ** module table).
  */
  if( sqlite3ViewGetColumnNames(pParse, pTab) ){
    goto insert_cleanup;
  }

  /* Ensure that:
  *  (a) the table is not read-only, 
  *  (b) that if it is a view then ON INSERT triggers exist
  */
  if( sqlite3IsReadOnly(pParse, pTab, tmask) ){
    goto insert_cleanup;
  }
  assert( pTab!=0 );

  /* If pTab is really a view, make sure it has been initialized.
  ** ViewGetColumnNames() is a no-op if pTab is not a view (or virtual 
  ** module table).
  */
  if( sqlite3ViewGetColumnNames(pParse, pTab) ){
    goto insert_cleanup;
  }

  /* Allocate a VDBE
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ) goto insert_cleanup;
  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
  sqlite3BeginWriteOperation(pParse, pSelect || pTrigger, iDb);

  /* if there are row triggers, allocate a temp table for new.* references. */
  if( pTrigger ){
    newIdx = pParse->nTab++;
  }

#ifndef SQLITE_OMIT_XFER_OPT
  /* If the statement is of the form
  **
  **       INSERT INTO <table1> SELECT * FROM <table2>;
  **
  ** Then special optimizations can be applied that make the transfer
  ** very fast and which reduce fragmentation of indices.
616
617
618
619
620
621
622
623

624
625
626
627
628
629
630
621
622
623
624
625
626
627

628
629
630
631
632
633
634
635







-
+







    ** FALSE if each* row of the SELECT can be written directly into
    ** the destination table (template 3).
    **
    ** A temp table must be used if the table being updated is also one
    ** of the tables being read by the SELECT statement.  Also use a 
    ** temp table in the case of row triggers.
    */
    if( pTrigger || readsTable(v, addrSelect, iDb, pTab) ){
    if( pTrigger || readsTable(pParse, addrSelect, iDb, pTab) ){
      useTempTable = 1;
    }

    if( useTempTable ){
      /* Invoke the coroutine to extract information from the SELECT
      ** and add it to a transient table srcTab.  The code generated
      ** here is from the 4th template:
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
737
738
739
740
741
742
743






744
745
746
747
748
749
750







-
-
-
-
-
-







  /* If there is no IDLIST term but the table has an integer primary
  ** key, the set the keyColumn variable to the primary key column index
  ** in the original table definition.
  */
  if( pColumn==0 && nColumn>0 ){
    keyColumn = pTab->iPKey;
  }

  /* Open the temp table for FOR EACH ROW triggers
  */
  if( pTrigger ){
    sqlite3VdbeAddOp3(v, OP_OpenPseudo, newIdx, 0, pTab->nCol);
  }
    
  /* Initialize the count of rows to be inserted
  */
  if( db->flags & SQLITE_CountRows ){
    regRowCount = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
  }
804
805
806
807
808
809
810
811
812

813
814
815
816
817
818
819
820
821
822
823

824
825
826
827

828
829
830

831
832
833


834
835

836
837
838
839
840
841

842
843
844
845
846
847
848
849
850
851
852
853
854
855

856
857

858
859
860

861
862
863
864
865
866
867
868
869
870
871

872
873
874
875
876
877
878
879
880
881


882
883


884
885
886
887
888
889
890
803
804
805
806
807
808
809


810

811
812
813
814
815
816
817

818

819
820
821
822

823
824
825

826
827


828
829
830

831
832
833
834
835
836

837
838
839
840

841
842
843
844
845
846
847
848
849

850
851

852
853
854

855
856
857


858
859
860
861
862
863
864
865
866
867




868
869


870
871


872
873
874
875
876
877
878
879
880







-
-
+
-







-

-
+



-
+


-
+

-
-
+
+

-
+





-
+



-









-
+

-
+


-
+


-
-







+


-
-
-
-


-
-
+
+
-
-
+
+







  }
  regData = regRowid+1;

  /* Run the BEFORE and INSTEAD OF triggers, if there are any
  */
  endOfLoop = sqlite3VdbeMakeLabel(v);
  if( tmask & TRIGGER_BEFORE ){
    int regTrigRowid;
    int regCols;
    int regCols = sqlite3GetTempRange(pParse, pTab->nCol+1);
    int regRec;

    /* build the NEW.* reference row.  Note that if there is an INTEGER
    ** PRIMARY KEY into which a NULL is being inserted, that NULL will be
    ** translated into a unique ID for the row.  But on a BEFORE trigger,
    ** we do not know what the unique ID will be (because the insert has
    ** not happened yet) so we substitute a rowid of -1
    */
    regTrigRowid = sqlite3GetTempReg(pParse);
    if( keyColumn<0 ){
      sqlite3VdbeAddOp2(v, OP_Integer, -1, regTrigRowid);
      sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
    }else{
      int j1;
      if( useTempTable ){
        sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regTrigRowid);
        sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regCols);
      }else{
        assert( pSelect==0 );  /* Otherwise useTempTable is true */
        sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regTrigRowid);
        sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regCols);
      }
      j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regTrigRowid);
      sqlite3VdbeAddOp2(v, OP_Integer, -1, regTrigRowid);
      j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols);
      sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
      sqlite3VdbeJumpHere(v, j1);
      sqlite3VdbeAddOp1(v, OP_MustBeInt, regTrigRowid);
      sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols);
    }

    /* Cannot have triggers on a virtual table. If it were possible,
    ** this block would have to account for hidden column.
    */
    assert(!IsVirtual(pTab));
    assert( !IsVirtual(pTab) );

    /* Create the new column data
    */
    regCols = sqlite3GetTempRange(pParse, pTab->nCol);
    for(i=0; i<pTab->nCol; i++){
      if( pColumn==0 ){
        j = i;
      }else{
        for(j=0; j<pColumn->nId; j++){
          if( pColumn->a[j].idx==i ) break;
        }
      }
      if( pColumn && j>=pColumn->nId ){
        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i);
        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i+1);
      }else if( useTempTable ){
        sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i); 
        sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i+1); 
      }else{
        assert( pSelect==0 ); /* Otherwise useTempTable is true */
        sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr, regCols+i);
        sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr, regCols+i+1);
      }
    }
    regRec = sqlite3GetTempReg(pParse);
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regCols, pTab->nCol, regRec);

    /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger,
    ** do not attempt any conversions before assembling the record.
    ** If this is a real table, attempt conversions as required by the
    ** table column affinities.
    */
    if( !isView ){
      sqlite3VdbeAddOp2(v, OP_Affinity, regCols+1, pTab->nCol);
      sqlite3TableAffinityStr(v, pTab);
    }
    sqlite3VdbeAddOp3(v, OP_Insert, newIdx, regRec, regTrigRowid);
    sqlite3ReleaseTempReg(pParse, regRec);
    sqlite3ReleaseTempReg(pParse, regTrigRowid);
    sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol);

    /* Fire BEFORE or INSTEAD OF triggers */
    if( sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, 
        pTab, newIdx, -1, onError, endOfLoop, 0, 0) ){
    sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, 
        pTab, regCols-pTab->nCol-1, onError, endOfLoop);
      goto insert_cleanup;
    }

    sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1);
  }

  /* Push the record number for the new entry onto the stack.  The
  ** record number is a randomly generate integer created by NewRowid
  ** except when the table has an INTEGER PRIMARY KEY column, in which
  ** case the record number is the same as that column. 
  */
972
973
974
975
976
977
978

979
980

981

982
983
984
985
986
987
988

989
990

991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005


1006
1007
1008
1009
1010
1011
1012
1013
1014
962
963
964
965
966
967
968
969
970

971

972
973
974
975
976
977
978
979
980
981

982

983
984
985
986
987
988
989
990
991
992
993
994


995
996


997
998
999
1000
1001
1002
1003







+

-
+
-
+







+

-
+
-












-
-
+
+
-
-







    }

    /* Generate code to check constraints and generate index keys and
    ** do the insertion.
    */
#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( IsVirtual(pTab) ){
      const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
      sqlite3VtabMakeWritable(pParse, pTab);
      sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns,
      sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns, pVTab, P4_VTAB);
                     (const char*)pTab->pVtab, P4_VTAB);
      sqlite3MayAbort(pParse);
    }else
#endif
    {
      int isReplace;    /* Set to true if constraints may cause a replace */
      sqlite3GenerateConstraintChecks(pParse, pTab, baseCur, regIns, aRegIdx,
          keyColumn>=0, 0, onError, endOfLoop, &isReplace
      );
      sqlite3FkCheck(pParse, pTab, 0, regIns);
      sqlite3CompleteInsertion(
          pParse, pTab, baseCur, regIns, aRegIdx, 0,
          pParse, pTab, baseCur, regIns, aRegIdx, 0, appendFlag, isReplace==0
          (tmask&TRIGGER_AFTER) ? newIdx : -1, appendFlag, isReplace==0
      );
    }
  }

  /* Update the count of rows that are inserted
  */
  if( (db->flags & SQLITE_CountRows)!=0 ){
    sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
  }

  if( pTrigger ){
    /* Code AFTER triggers */
    if( sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, 
          pTab, newIdx, -1, onError, endOfLoop, 0, 0) ){
    sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, 
        pTab, regData-2-pTab->nCol, onError, endOfLoop);
      goto insert_cleanup;
    }
  }

  /* The bottom of the main insertion loop, if the data source
  ** is a SELECT statement.
  */
  sqlite3VdbeResolveLabel(v, endOfLoop);
  if( useTempTable ){
1029
1030
1031
1032
1033
1034
1035
1036

1037
1038
1039
1040
1041
1042
1043
1044
1045

1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057














1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068

1069
1070

1071
1072
1073
1074
1075
1076

1077
1078
1079
1080
1081
1082
1083








1084
1085
1086
1087
1088
1089
1090
1018
1019
1020
1021
1022
1023
1024

1025
1026
1027
1028
1029
1030
1031
1032
1033

1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066





1067
1068

1069
1070
1071
1072
1073
1074

1075
1076






1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091







-
+








-
+












+
+
+
+
+
+
+
+
+
+
+
+
+
+






-
-
-
-
-
+

-
+





-
+

-
-
-
-
-
-
+
+
+
+
+
+
+
+







  }

insert_end:
  /* Update the sqlite_sequence table by storing the content of the
  ** maximum rowid counter values recorded while inserting into
  ** autoincrement tables.
  */
  if( pParse->nested==0 && pParse->trigStack==0 ){
  if( pParse->nested==0 && pParse->pTriggerTab==0 ){
    sqlite3AutoincrementEnd(pParse);
  }

  /*
  ** Return the number of rows inserted. If this routine is 
  ** generating code because of a call to sqlite3NestedParse(), do not
  ** invoke the callback function.
  */
  if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
  if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){
    sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC);
  }

insert_cleanup:
  sqlite3SrcListDelete(db, pTabList);
  sqlite3ExprListDelete(db, pList);
  sqlite3SelectDelete(db, pSelect);
  sqlite3IdListDelete(db, pColumn);
  sqlite3DbFree(db, aRegIdx);
}

/* Make sure "isView" and other macros defined above are undefined. Otherwise
** thely may interfere with compilation of other functions in this file
** (or in another file, if this file becomes part of the amalgamation).  */
#ifdef isView
 #undef isView
#endif
#ifdef pTrigger
 #undef pTrigger
#endif
#ifdef tmask
 #undef tmask
#endif


/*
** Generate code to do constraint checks prior to an INSERT or an UPDATE.
**
** The input is a range of consecutive registers as follows:
**
**    1.  The rowid of the row to be updated before the update.  This
**        value is omitted unless we are doing an UPDATE that involves a
**        change to the record number or writing to a virtual table.
**
**    2.  The rowid of the row after the update.
**    1.  The rowid of the row after the update.
**
**    3.  The data in the first column of the entry after the update.
**    2.  The data in the first column of the entry after the update.
**
**    i.  Data from middle columns...
**
**    N.  The data in the last column of the entry after the update.
**
** The regRowid parameter is the index of the register containing (2).
** The regRowid parameter is the index of the register containing (1).
**
** The old rowid shown as entry (1) above is omitted unless both isUpdate
** and rowidChng are 1.  isUpdate is true for UPDATEs and false for
** INSERTs.  RowidChng means that the new rowid is explicitly specified by
** the update or insert statement.  If rowidChng is false, it means that
** the rowid is computed automatically in an insert or that the rowid value
** is not modified by the update.
** If isUpdate is true and rowidChng is non-zero, then rowidChng contains
** the address of a register containing the rowid before the update takes
** place. isUpdate is true for UPDATEs and false for INSERTs. If isUpdate
** is false, indicating an INSERT statement, then a non-zero rowidChng 
** indicates that the rowid was explicitly specified as part of the
** INSERT statement. If rowidChng is false, it means that  the rowid is
** computed automatically in an insert or that the rowid value is not 
** modified by an update.
**
** The code generated by this routine store new index entries into
** registers identified by aRegIdx[].  No index entry is created for
** indices where aRegIdx[i]==0.  The order of indices in aRegIdx[] is
** the same as the order of indices on the linked list of indices
** attached to the table.
**
1151
1152
1153
1154
1155
1156
1157
1158

1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187



1188
1189
1190
1191
1192
1193
1194
1152
1153
1154
1155
1156
1157
1158

1159
1160
1161
1162
1163
1164
1165

1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185


1186
1187
1188
1189
1190
1191
1192
1193
1194
1195







-
+






-




















-
-
+
+
+







  int onError;        /* Conflict resolution strategy */
  int j1;             /* Addresss of jump instruction */
  int j2 = 0, j3;     /* Addresses of jump instructions */
  int regData;        /* Register containing first data column */
  int iCur;           /* Table cursor number */
  Index *pIdx;         /* Pointer to one of the indices */
  int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
  int hasTwoRowids = (isUpdate && rowidChng);
  int regOldRowid = (rowidChng && isUpdate) ? rowidChng : regRowid;

  v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  nCol = pTab->nCol;
  regData = regRowid + 1;


  /* Test all NOT NULL constraints.
  */
  for(i=0; i<nCol; i++){
    if( i==pTab->iPKey ){
      continue;
    }
    onError = pTab->aCol[i].notNull;
    if( onError==OE_None ) continue;
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }
    if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
      onError = OE_Abort;
    }
    assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
        || onError==OE_Ignore || onError==OE_Replace );
    switch( onError ){
      case OE_Rollback:
      case OE_Abort:
      case OE_Abort:
        sqlite3MayAbort(pParse);
      case OE_Rollback:
      case OE_Fail: {
        char *zMsg;
        j1 = sqlite3VdbeAddOp3(v, OP_HaltIfNull,
                                  SQLITE_CONSTRAINT, onError, regData+i);
        zMsg = sqlite3MPrintf(pParse->db, "%s.%s may not be NULL",
                              pTab->zName, pTab->aCol[i].zName);
        sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC);
1215
1216
1217
1218
1219
1220
1221
1222

1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257




































1258

1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270












1271
1272
1273
1274
1275
1276
1277
1278
1216
1217
1218
1219
1220
1221
1222

1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240


















1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278












1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290

1291
1292
1293
1294
1295
1296
1297







-
+

















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-







    int allOk = sqlite3VdbeMakeLabel(v);
    pParse->ckBase = regData;
    sqlite3ExprIfTrue(pParse, pTab->pCheck, allOk, SQLITE_JUMPIFNULL);
    onError = overrideError!=OE_Default ? overrideError : OE_Abort;
    if( onError==OE_Ignore ){
      sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
    }else{
      sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_CONSTRAINT, onError);
      sqlite3HaltConstraint(pParse, onError, 0, 0);
    }
    sqlite3VdbeResolveLabel(v, allOk);
  }
#endif /* !defined(SQLITE_OMIT_CHECK) */

  /* If we have an INTEGER PRIMARY KEY, make sure the primary key
  ** of the new record does not previously exist.  Except, if this
  ** is an UPDATE and the primary key is not changing, that is OK.
  */
  if( rowidChng ){
    onError = pTab->keyConf;
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }
    
    if( onError!=OE_Replace || pTab->pIndex ){
      if( isUpdate ){
        j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, regRowid-1);
      }
      j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid);
      switch( onError ){
        default: {
          onError = OE_Abort;
          /* Fall thru into the next case */
        }
        case OE_Rollback:
        case OE_Abort:
        case OE_Fail: {
          sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0,
                           "PRIMARY KEY must be unique", P4_STATIC);
          break;
        }
        case OE_Replace: {
    if( isUpdate ){
      j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, rowidChng);
    }
    j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid);
    switch( onError ){
      default: {
        onError = OE_Abort;
        /* Fall thru into the next case */
      }
      case OE_Rollback:
      case OE_Abort:
      case OE_Fail: {
        sqlite3HaltConstraint(
          pParse, onError, "PRIMARY KEY must be unique", P4_STATIC);
        break;
      }
      case OE_Replace: {
        /* If there are DELETE triggers on this table and the
        ** recursive-triggers flag is set, call GenerateRowDelete() to
        ** remove the conflicting row from the the table. This will fire
        ** the triggers and remove both the table and index b-tree entries.
        **
        ** Otherwise, if there are no triggers or the recursive-triggers
        ** flag is not set, call GenerateRowIndexDelete(). This removes
        ** the index b-tree entries only. The table b-tree entry will be 
        ** replaced by the new entry when it is inserted.  */
        Trigger *pTrigger = 0;
        if( pParse->db->flags&SQLITE_RecTriggers ){
          pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
        }
        sqlite3MultiWrite(pParse);
        if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
          sqlite3GenerateRowDelete(
              pParse, pTab, baseCur, regRowid, 0, pTrigger, OE_Replace
          );
        }else{
          sqlite3GenerateRowIndexDelete(pParse, pTab, baseCur, 0);
        }
          seenReplace = 1;
          break;
        }
        case OE_Ignore: {
          assert( seenReplace==0 );
          sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
          break;
        }
      }
      sqlite3VdbeJumpHere(v, j3);
      if( isUpdate ){
        sqlite3VdbeJumpHere(v, j2);
        seenReplace = 1;
        break;
      }
      case OE_Ignore: {
        assert( seenReplace==0 );
        sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
        break;
      }
    }
    sqlite3VdbeJumpHere(v, j3);
    if( isUpdate ){
      sqlite3VdbeJumpHere(v, j2);
      }
    }
  }

  /* Test all UNIQUE constraints by creating entries for each UNIQUE
  ** index and making sure that duplicate entries do not already exist.
  ** Add the new records to the indices as we go.
  */
1290
1291
1292
1293
1294
1295
1296
1297

1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319

1320
1321
1322
1323
1324
1325
1326
1309
1310
1311
1312
1313
1314
1315

1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334

1335
1336

1337
1338
1339
1340
1341
1342
1343
1344







-
+


















-


-
+







        sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
      }else{
        sqlite3VdbeAddOp2(v, OP_SCopy, regData+idx, regIdx+i);
      }
    }
    sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);
    sqlite3IndexAffinityStr(v, pIdx);
    sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0);
    sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);

    /* Find out what action to take in case there is an indexing conflict */
    onError = pIdx->onError;
    if( onError==OE_None ){ 
      sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
      continue;  /* pIdx is not a UNIQUE index */
    }
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }
    if( seenReplace ){
      if( onError==OE_Ignore ) onError = OE_Replace;
      else if( onError==OE_Fail ) onError = OE_Abort;
    }
    

    /* Check to see if the new index entry will be unique */
    regR = sqlite3GetTempReg(pParse);
    sqlite3VdbeAddOp2(v, OP_SCopy, regRowid-hasTwoRowids, regR);
    sqlite3VdbeAddOp2(v, OP_SCopy, regOldRowid, regR);
    j3 = sqlite3VdbeAddOp4(v, OP_IsUnique, baseCur+iCur+1, 0,
                           regR, SQLITE_INT_TO_PTR(regIdx),
                           P4_INT32);
    sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);

    /* Generate code that executes if the new index entry is not unique */
    assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
1342
1343
1344
1345
1346
1347
1348
1349

1350
1351
1352
1353
1354
1355
1356
1357
1358

1359




1360



1361
1362
1363
1364
1365
1366
1367
1368

1369
1370
1371
1372
1373
1374
1375
1360
1361
1362
1363
1364
1365
1366

1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382

1383
1384
1385
1386
1387
1388
1389
1390
1391
1392

1393
1394
1395
1396
1397
1398
1399
1400







-
+









+

+
+
+
+
-
+
+
+







-
+







          sqlite3StrAccumAppend(&errMsg, zSep, -1);
          zSep = ", ";
          sqlite3StrAccumAppend(&errMsg, zCol, -1);
        }
        sqlite3StrAccumAppend(&errMsg,
            pIdx->nColumn>1 ? " are not unique" : " is not unique", -1);
        zErr = sqlite3StrAccumFinish(&errMsg);
        sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, zErr, 0);
        sqlite3HaltConstraint(pParse, onError, zErr, 0);
        sqlite3DbFree(errMsg.db, zErr);
        break;
      }
      case OE_Ignore: {
        assert( seenReplace==0 );
        sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
        break;
      }
      default: {
        Trigger *pTrigger = 0;
        assert( onError==OE_Replace );
        sqlite3MultiWrite(pParse);
        if( pParse->db->flags&SQLITE_RecTriggers ){
          pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
        }
        sqlite3GenerateRowDelete(pParse, pTab, baseCur, regR, 0);
        sqlite3GenerateRowDelete(
            pParse, pTab, baseCur, regR, 0, pTrigger, OE_Replace
        );
        seenReplace = 1;
        break;
      }
    }
    sqlite3VdbeJumpHere(v, j3);
    sqlite3ReleaseTempReg(pParse, regR);
  }

  
  if( pbMayReplace ){
    *pbMayReplace = seenReplace;
  }
}

/*
** This routine generates code to finish the INSERT or UPDATE operation
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1408
1409
1410
1411
1412
1413
1414

1415
1416
1417
1418
1419
1420
1421







-







void sqlite3CompleteInsertion(
  Parse *pParse,      /* The parser context */
  Table *pTab,        /* the table into which we are inserting */
  int baseCur,        /* Index of a read/write cursor pointing at pTab */
  int regRowid,       /* Range of content */
  int *aRegIdx,       /* Register used by each index.  0 for unused indices */
  int isUpdate,       /* True for UPDATE, False for INSERT */
  int newIdx,         /* Index of NEW table for triggers.  -1 if none */
  int appendBias,     /* True if this is likely to be an append */
  int useSeekResult   /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
){
  int i;
  Vdbe *v;
  int nIdx;
  Index *pIdx;
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1435
1436
1437
1438
1439
1440
1441





1442
1443
1444
1445
1446
1447
1448







-
-
-
-
-







    }
  }
  regData = regRowid + 1;
  regRec = sqlite3GetTempReg(pParse);
  sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
  sqlite3TableAffinityStr(v, pTab);
  sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol);
#ifndef SQLITE_OMIT_TRIGGER
  if( newIdx>=0 ){
    sqlite3VdbeAddOp3(v, OP_Insert, newIdx, regRec, regRowid);
  }
#endif
  if( pParse->nested ){
    pik_flags = 0;
  }else{
    pik_flags = OPFLAG_NCHANGE;
    pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID);
  }
  if( appendBias ){
1739
1740
1741
1742
1743
1744
1745
1746
1747


1748
1749
1750
1751
1752
1753
1754
1758
1759
1760
1761
1762
1763
1764


1765
1766
1767
1768
1769
1770
1771
1772
1773







-
-
+
+







  sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
  emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
  regData = sqlite3GetTempReg(pParse);
  regRowid = sqlite3GetTempReg(pParse);
  if( pDest->iPKey>=0 ){
    addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
    addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
    sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0,
                      "PRIMARY KEY must be unique", P4_STATIC);
    sqlite3HaltConstraint(
        pParse, onError, "PRIMARY KEY must be unique", P4_STATIC);
    sqlite3VdbeJumpHere(v, addr2);
    autoIncStep(pParse, regAutoinc, regRowid);
  }else if( pDest->pIndex==0 ){
    addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
  }else{
    addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
    assert( (pDest->tabFlags & TF_Autoincrement)==0 );
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1809
1810
1811
1812
1813
1814
1815












-
-
-
-
-
    sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
    return 0;
  }else{
    return 1;
  }
}
#endif /* SQLITE_OMIT_XFER_OPT */

/* Make sure "isView" gets undefined in case this file becomes part of
** the amalgamation - so that subsequent files do not see isView as a
** macro. */
#undef isView
Changes to src/journal.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
1
2
3
4
5
6
7
8
9
10
11
12






13
14
15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34












-
-
-
-
-
-














-
+







/*
** 2007 August 22
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** @(#) $Id: journal.c,v 1.9 2009/01/20 17:06:27 danielk1977 Exp $
*/

#ifdef SQLITE_ENABLE_ATOMIC_WRITE

/*
** This file implements a special kind of sqlite3_file object used
** by SQLite to create journal files if the atomic-write optimization
** is enabled.
**
** The distinctive characteristic of this sqlite3_file is that the
** actual on disk file is created lazily. When the file is created,
** the caller specifies a buffer size for an in-memory buffer to
** be used to service read() and write() requests. The actual file
** on disk is not created or populated until either:
**
**   1) The in-memory representation grows too large for the allocated 
**      buffer, or
**   2) The sqlite3JournalCreate() function is called.
*/

#ifdef SQLITE_ENABLE_ATOMIC_WRITE
#include "sqliteInt.h"


/*
** A JournalFile object is a subclass of sqlite3_file used by
** as an open file handle for journal files.
*/
Changes to src/legacy.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
9
10
11
12
13
14
15


16
17
18
19
20
21
22







-
-







**    May you share freely, never taking more than you give.
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: legacy.c,v 1.33 2009/05/05 20:02:48 drh Exp $
*/

#include "sqliteInt.h"

/*
** Execute SQL code.  Return one of the SQLITE_ success/failure
** codes.  Also write an error message into memory obtained from
128
129
130
131
132
133
134



135
136
137
138
139
140
141
142
143
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144







+
+
+










  rc = sqlite3ApiExit(db, rc);
  if( rc!=SQLITE_OK && ALWAYS(rc==sqlite3_errcode(db)) && pzErrMsg ){
    int nErrMsg = 1 + sqlite3Strlen30(sqlite3_errmsg(db));
    *pzErrMsg = sqlite3Malloc(nErrMsg);
    if( *pzErrMsg ){
      memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg);
    }else{
      rc = SQLITE_NOMEM;
      sqlite3Error(db, SQLITE_NOMEM, 0);
    }
  }else if( pzErrMsg ){
    *pzErrMsg = 0;
  }

  assert( (rc&db->errMask)==rc );
  sqlite3_mutex_leave(db->mutex);
  return rc;
}
Added src/lempar.c.




























































































































































































































































































































































































































































































































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/* Driver template for the LEMON parser generator.
** The author disclaims copyright to this source code.
**
** This version of "lempar.c" is modified, slightly, for use by SQLite.
** The only modifications are the addition of a couple of NEVER()
** macros to disable tests that are needed in the case of a general
** LALR(1) grammar but which are always false in the
** specific grammar used by SQLite.
*/
/* First off, code is included that follows the "include" declaration
** in the input grammar file. */
#include <stdio.h>
%%
/* Next is all token values, in a form suitable for use by makeheaders.
** This section will be null unless lemon is run with the -m switch.
*/
/* 
** These constants (all generated automatically by the parser generator)
** specify the various kinds of tokens (terminals) that the parser
** understands. 
**
** Each symbol here is a terminal symbol in the grammar.
*/
%%
/* Make sure the INTERFACE macro is defined.
*/
#ifndef INTERFACE
# define INTERFACE 1
#endif
/* The next thing included is series of defines which control
** various aspects of the generated parser.
**    YYCODETYPE         is the data type used for storing terminal
**                       and nonterminal numbers.  "unsigned char" is
**                       used if there are fewer than 250 terminals
**                       and nonterminals.  "int" is used otherwise.
**    YYNOCODE           is a number of type YYCODETYPE which corresponds
**                       to no legal terminal or nonterminal number.  This
**                       number is used to fill in empty slots of the hash 
**                       table.
**    YYFALLBACK         If defined, this indicates that one or more tokens
**                       have fall-back values which should be used if the
**                       original value of the token will not parse.
**    YYACTIONTYPE       is the data type used for storing terminal
**                       and nonterminal numbers.  "unsigned char" is
**                       used if there are fewer than 250 rules and
**                       states combined.  "int" is used otherwise.
**    ParseTOKENTYPE     is the data type used for minor tokens given 
**                       directly to the parser from the tokenizer.
**    YYMINORTYPE        is the data type used for all minor tokens.
**                       This is typically a union of many types, one of
**                       which is ParseTOKENTYPE.  The entry in the union
**                       for base tokens is called "yy0".
**    YYSTACKDEPTH       is the maximum depth of the parser's stack.  If
**                       zero the stack is dynamically sized using realloc()
**    ParseARG_SDECL     A static variable declaration for the %extra_argument
**    ParseARG_PDECL     A parameter declaration for the %extra_argument
**    ParseARG_STORE     Code to store %extra_argument into yypParser
**    ParseARG_FETCH     Code to extract %extra_argument from yypParser
**    YYNSTATE           the combined number of states.
**    YYNRULE            the number of rules in the grammar
**    YYERRORSYMBOL      is the code number of the error symbol.  If not
**                       defined, then do no error processing.
*/
%%
#define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
#define YY_ACCEPT_ACTION  (YYNSTATE+YYNRULE+1)
#define YY_ERROR_ACTION   (YYNSTATE+YYNRULE)

/* The yyzerominor constant is used to initialize instances of
** YYMINORTYPE objects to zero. */
static const YYMINORTYPE yyzerominor = { 0 };

/* Define the yytestcase() macro to be a no-op if is not already defined
** otherwise.
**
** Applications can choose to define yytestcase() in the %include section
** to a macro that can assist in verifying code coverage.  For production
** code the yytestcase() macro should be turned off.  But it is useful
** for testing.
*/
#ifndef yytestcase
# define yytestcase(X)
#endif


/* Next are the tables used to determine what action to take based on the
** current state and lookahead token.  These tables are used to implement
** functions that take a state number and lookahead value and return an
** action integer.  
**
** Suppose the action integer is N.  Then the action is determined as
** follows
**
**   0 <= N < YYNSTATE                  Shift N.  That is, push the lookahead
**                                      token onto the stack and goto state N.
**
**   YYNSTATE <= N < YYNSTATE+YYNRULE   Reduce by rule N-YYNSTATE.
**
**   N == YYNSTATE+YYNRULE              A syntax error has occurred.
**
**   N == YYNSTATE+YYNRULE+1            The parser accepts its input.
**
**   N == YYNSTATE+YYNRULE+2            No such action.  Denotes unused
**                                      slots in the yy_action[] table.
**
** The action table is constructed as a single large table named yy_action[].
** Given state S and lookahead X, the action is computed as
**
**      yy_action[ yy_shift_ofst[S] + X ]
**
** If the index value yy_shift_ofst[S]+X is out of range or if the value
** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
** and that yy_default[S] should be used instead.  
**
** The formula above is for computing the action when the lookahead is
** a terminal symbol.  If the lookahead is a non-terminal (as occurs after
** a reduce action) then the yy_reduce_ofst[] array is used in place of
** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
** YY_SHIFT_USE_DFLT.
**
** The following are the tables generated in this section:
**
**  yy_action[]        A single table containing all actions.
**  yy_lookahead[]     A table containing the lookahead for each entry in
**                     yy_action.  Used to detect hash collisions.
**  yy_shift_ofst[]    For each state, the offset into yy_action for
**                     shifting terminals.
**  yy_reduce_ofst[]   For each state, the offset into yy_action for
**                     shifting non-terminals after a reduce.
**  yy_default[]       Default action for each state.
*/
%%

/* The next table maps tokens into fallback tokens.  If a construct
** like the following:
** 
**      %fallback ID X Y Z.
**
** appears in the grammar, then ID becomes a fallback token for X, Y,
** and Z.  Whenever one of the tokens X, Y, or Z is input to the parser
** but it does not parse, the type of the token is changed to ID and
** the parse is retried before an error is thrown.
*/
#ifdef YYFALLBACK
static const YYCODETYPE yyFallback[] = {
%%
};
#endif /* YYFALLBACK */

/* The following structure represents a single element of the
** parser's stack.  Information stored includes:
**
**   +  The state number for the parser at this level of the stack.
**
**   +  The value of the token stored at this level of the stack.
**      (In other words, the "major" token.)
**
**   +  The semantic value stored at this level of the stack.  This is
**      the information used by the action routines in the grammar.
**      It is sometimes called the "minor" token.
*/
struct yyStackEntry {
  YYACTIONTYPE stateno;  /* The state-number */
  YYCODETYPE major;      /* The major token value.  This is the code
                         ** number for the token at this stack level */
  YYMINORTYPE minor;     /* The user-supplied minor token value.  This
                         ** is the value of the token  */
};
typedef struct yyStackEntry yyStackEntry;

/* The state of the parser is completely contained in an instance of
** the following structure */
struct yyParser {
  int yyidx;                    /* Index of top element in stack */
#ifdef YYTRACKMAXSTACKDEPTH
  int yyidxMax;                 /* Maximum value of yyidx */
#endif
  int yyerrcnt;                 /* Shifts left before out of the error */
  ParseARG_SDECL                /* A place to hold %extra_argument */
#if YYSTACKDEPTH<=0
  int yystksz;                  /* Current side of the stack */
  yyStackEntry *yystack;        /* The parser's stack */
#else
  yyStackEntry yystack[YYSTACKDEPTH];  /* The parser's stack */
#endif
};
typedef struct yyParser yyParser;

#ifndef NDEBUG
#include <stdio.h>
static FILE *yyTraceFILE = 0;
static char *yyTracePrompt = 0;
#endif /* NDEBUG */

#ifndef NDEBUG
/* 
** Turn parser tracing on by giving a stream to which to write the trace
** and a prompt to preface each trace message.  Tracing is turned off
** by making either argument NULL 
**
** Inputs:
** <ul>
** <li> A FILE* to which trace output should be written.
**      If NULL, then tracing is turned off.
** <li> A prefix string written at the beginning of every
**      line of trace output.  If NULL, then tracing is
**      turned off.
** </ul>
**
** Outputs:
** None.
*/
void ParseTrace(FILE *TraceFILE, char *zTracePrompt){
  yyTraceFILE = TraceFILE;
  yyTracePrompt = zTracePrompt;
  if( yyTraceFILE==0 ) yyTracePrompt = 0;
  else if( yyTracePrompt==0 ) yyTraceFILE = 0;
}
#endif /* NDEBUG */

#ifndef NDEBUG
/* For tracing shifts, the names of all terminals and nonterminals
** are required.  The following table supplies these names */
static const char *const yyTokenName[] = { 
%%
};
#endif /* NDEBUG */

#ifndef NDEBUG
/* For tracing reduce actions, the names of all rules are required.
*/
static const char *const yyRuleName[] = {
%%
};
#endif /* NDEBUG */


#if YYSTACKDEPTH<=0
/*
** Try to increase the size of the parser stack.
*/
static void yyGrowStack(yyParser *p){
  int newSize;
  yyStackEntry *pNew;

  newSize = p->yystksz*2 + 100;
  pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
  if( pNew ){
    p->yystack = pNew;
    p->yystksz = newSize;
#ifndef NDEBUG
    if( yyTraceFILE ){
      fprintf(yyTraceFILE,"%sStack grows to %d entries!\n",
              yyTracePrompt, p->yystksz);
    }
#endif
  }
}
#endif

/* 
** This function allocates a new parser.
** The only argument is a pointer to a function which works like
** malloc.
**
** Inputs:
** A pointer to the function used to allocate memory.
**
** Outputs:
** A pointer to a parser.  This pointer is used in subsequent calls
** to Parse and ParseFree.
*/
void *ParseAlloc(void *(*mallocProc)(size_t)){
  yyParser *pParser;
  pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
  if( pParser ){
    pParser->yyidx = -1;
#ifdef YYTRACKMAXSTACKDEPTH
    pParser->yyidxMax = 0;
#endif
#if YYSTACKDEPTH<=0
    pParser->yystack = NULL;
    pParser->yystksz = 0;
    yyGrowStack(pParser);
#endif
  }
  return pParser;
}

/* The following function deletes the value associated with a
** symbol.  The symbol can be either a terminal or nonterminal.
** "yymajor" is the symbol code, and "yypminor" is a pointer to
** the value.
*/
static void yy_destructor(
  yyParser *yypParser,    /* The parser */
  YYCODETYPE yymajor,     /* Type code for object to destroy */
  YYMINORTYPE *yypminor   /* The object to be destroyed */
){
  ParseARG_FETCH;
  switch( yymajor ){
    /* Here is inserted the actions which take place when a
    ** terminal or non-terminal is destroyed.  This can happen
    ** when the symbol is popped from the stack during a
    ** reduce or during error processing or when a parser is 
    ** being destroyed before it is finished parsing.
    **
    ** Note: during a reduce, the only symbols destroyed are those
    ** which appear on the RHS of the rule, but which are not used
    ** inside the C code.
    */
%%
    default:  break;   /* If no destructor action specified: do nothing */
  }
}

/*
** Pop the parser's stack once.
**
** If there is a destructor routine associated with the token which
** is popped from the stack, then call it.
**
** Return the major token number for the symbol popped.
*/
static int yy_pop_parser_stack(yyParser *pParser){
  YYCODETYPE yymajor;
  yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];

  /* There is no mechanism by which the parser stack can be popped below
  ** empty in SQLite.  */
  if( NEVER(pParser->yyidx<0) ) return 0;
#ifndef NDEBUG
  if( yyTraceFILE && pParser->yyidx>=0 ){
    fprintf(yyTraceFILE,"%sPopping %s\n",
      yyTracePrompt,
      yyTokenName[yytos->major]);
  }
#endif
  yymajor = yytos->major;
  yy_destructor(pParser, yymajor, &yytos->minor);
  pParser->yyidx--;
  return yymajor;
}

/* 
** Deallocate and destroy a parser.  Destructors are all called for
** all stack elements before shutting the parser down.
**
** Inputs:
** <ul>
** <li>  A pointer to the parser.  This should be a pointer
**       obtained from ParseAlloc.
** <li>  A pointer to a function used to reclaim memory obtained
**       from malloc.
** </ul>
*/
void ParseFree(
  void *p,                    /* The parser to be deleted */
  void (*freeProc)(void*)     /* Function used to reclaim memory */
){
  yyParser *pParser = (yyParser*)p;
  /* In SQLite, we never try to destroy a parser that was not successfully
  ** created in the first place. */
  if( NEVER(pParser==0) ) return;
  while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
#if YYSTACKDEPTH<=0
  free(pParser->yystack);
#endif
  (*freeProc)((void*)pParser);
}

/*
** Return the peak depth of the stack for a parser.
*/
#ifdef YYTRACKMAXSTACKDEPTH
int ParseStackPeak(void *p){
  yyParser *pParser = (yyParser*)p;
  return pParser->yyidxMax;
}
#endif

/*
** Find the appropriate action for a parser given the terminal
** look-ahead token iLookAhead.
**
** If the look-ahead token is YYNOCODE, then check to see if the action is
** independent of the look-ahead.  If it is, return the action, otherwise
** return YY_NO_ACTION.
*/
static int yy_find_shift_action(
  yyParser *pParser,        /* The parser */
  YYCODETYPE iLookAhead     /* The look-ahead token */
){
  int i;
  int stateno = pParser->yystack[pParser->yyidx].stateno;
 
  if( stateno>YY_SHIFT_COUNT
   || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
    return yy_default[stateno];
  }
  assert( iLookAhead!=YYNOCODE );
  i += iLookAhead;
  if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
    if( iLookAhead>0 ){
#ifdef YYFALLBACK
      YYCODETYPE iFallback;            /* Fallback token */
      if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
             && (iFallback = yyFallback[iLookAhead])!=0 ){
#ifndef NDEBUG
        if( yyTraceFILE ){
          fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
             yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
        }
#endif
        return yy_find_shift_action(pParser, iFallback);
      }
#endif
#ifdef YYWILDCARD
      {
        int j = i - iLookAhead + YYWILDCARD;
        if( 
#if YY_SHIFT_MIN+YYWILDCARD<0
          j>=0 &&
#endif
#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
          j<YY_ACTTAB_COUNT &&
#endif
          yy_lookahead[j]==YYWILDCARD
        ){
#ifndef NDEBUG
          if( yyTraceFILE ){
            fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
               yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]);
          }
#endif /* NDEBUG */
          return yy_action[j];
        }
      }
#endif /* YYWILDCARD */
    }
    return yy_default[stateno];
  }else{
    return yy_action[i];
  }
}

/*
** Find the appropriate action for a parser given the non-terminal
** look-ahead token iLookAhead.
**
** If the look-ahead token is YYNOCODE, then check to see if the action is
** independent of the look-ahead.  If it is, return the action, otherwise
** return YY_NO_ACTION.
*/
static int yy_find_reduce_action(
  int stateno,              /* Current state number */
  YYCODETYPE iLookAhead     /* The look-ahead token */
){
  int i;
#ifdef YYERRORSYMBOL
  if( stateno>YY_REDUCE_COUNT ){
    return yy_default[stateno];
  }
#else
  assert( stateno<=YY_REDUCE_COUNT );
#endif
  i = yy_reduce_ofst[stateno];
  assert( i!=YY_REDUCE_USE_DFLT );
  assert( iLookAhead!=YYNOCODE );
  i += iLookAhead;
#ifdef YYERRORSYMBOL
  if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
    return yy_default[stateno];
  }
#else
  assert( i>=0 && i<YY_ACTTAB_COUNT );
  assert( yy_lookahead[i]==iLookAhead );
#endif
  return yy_action[i];
}

/*
** The following routine is called if the stack overflows.
*/
static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){
   ParseARG_FETCH;
   yypParser->yyidx--;
#ifndef NDEBUG
   if( yyTraceFILE ){
     fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
   }
#endif
   while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
   /* Here code is inserted which will execute if the parser
   ** stack every overflows */
%%
   ParseARG_STORE; /* Suppress warning about unused %extra_argument var */
}

/*
** Perform a shift action.
*/
static void yy_shift(
  yyParser *yypParser,          /* The parser to be shifted */
  int yyNewState,               /* The new state to shift in */
  int yyMajor,                  /* The major token to shift in */
  YYMINORTYPE *yypMinor         /* Pointer to the minor token to shift in */
){
  yyStackEntry *yytos;
  yypParser->yyidx++;
#ifdef YYTRACKMAXSTACKDEPTH
  if( yypParser->yyidx>yypParser->yyidxMax ){
    yypParser->yyidxMax = yypParser->yyidx;
  }
#endif
#if YYSTACKDEPTH>0 
  if( yypParser->yyidx>=YYSTACKDEPTH ){
    yyStackOverflow(yypParser, yypMinor);
    return;
  }
#else
  if( yypParser->yyidx>=yypParser->yystksz ){
    yyGrowStack(yypParser);
    if( yypParser->yyidx>=yypParser->yystksz ){
      yyStackOverflow(yypParser, yypMinor);
      return;
    }
  }
#endif
  yytos = &yypParser->yystack[yypParser->yyidx];
  yytos->stateno = (YYACTIONTYPE)yyNewState;
  yytos->major = (YYCODETYPE)yyMajor;
  yytos->minor = *yypMinor;
#ifndef NDEBUG
  if( yyTraceFILE && yypParser->yyidx>0 ){
    int i;
    fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
    fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
    for(i=1; i<=yypParser->yyidx; i++)
      fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
    fprintf(yyTraceFILE,"\n");
  }
#endif
}

/* The following table contains information about every rule that
** is used during the reduce.
*/
static const struct {
  YYCODETYPE lhs;         /* Symbol on the left-hand side of the rule */
  unsigned char nrhs;     /* Number of right-hand side symbols in the rule */
} yyRuleInfo[] = {
%%
};

static void yy_accept(yyParser*);  /* Forward Declaration */

/*
** Perform a reduce action and the shift that must immediately
** follow the reduce.
*/
static void yy_reduce(
  yyParser *yypParser,         /* The parser */
  int yyruleno                 /* Number of the rule by which to reduce */
){
  int yygoto;                     /* The next state */
  int yyact;                      /* The next action */
  YYMINORTYPE yygotominor;        /* The LHS of the rule reduced */
  yyStackEntry *yymsp;            /* The top of the parser's stack */
  int yysize;                     /* Amount to pop the stack */
  ParseARG_FETCH;
  yymsp = &yypParser->yystack[yypParser->yyidx];
#ifndef NDEBUG
  if( yyTraceFILE && yyruleno>=0 
        && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
    fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
      yyRuleName[yyruleno]);
  }
#endif /* NDEBUG */

  /* Silence complaints from purify about yygotominor being uninitialized
  ** in some cases when it is copied into the stack after the following
  ** switch.  yygotominor is uninitialized when a rule reduces that does
  ** not set the value of its left-hand side nonterminal.  Leaving the
  ** value of the nonterminal uninitialized is utterly harmless as long
  ** as the value is never used.  So really the only thing this code
  ** accomplishes is to quieten purify.  
  **
  ** 2007-01-16:  The wireshark project (www.wireshark.org) reports that
  ** without this code, their parser segfaults.  I'm not sure what there
  ** parser is doing to make this happen.  This is the second bug report
  ** from wireshark this week.  Clearly they are stressing Lemon in ways
  ** that it has not been previously stressed...  (SQLite ticket #2172)
  */
  /*memset(&yygotominor, 0, sizeof(yygotominor));*/
  yygotominor = yyzerominor;


  switch( yyruleno ){
  /* Beginning here are the reduction cases.  A typical example
  ** follows:
  **   case 0:
  **  #line <lineno> <grammarfile>
  **     { ... }           // User supplied code
  **  #line <lineno> <thisfile>
  **     break;
  */
%%
  };
  yygoto = yyRuleInfo[yyruleno].lhs;
  yysize = yyRuleInfo[yyruleno].nrhs;
  yypParser->yyidx -= yysize;
  yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
  if( yyact < YYNSTATE ){
#ifdef NDEBUG
    /* If we are not debugging and the reduce action popped at least
    ** one element off the stack, then we can push the new element back
    ** onto the stack here, and skip the stack overflow test in yy_shift().
    ** That gives a significant speed improvement. */
    if( yysize ){
      yypParser->yyidx++;
      yymsp -= yysize-1;
      yymsp->stateno = (YYACTIONTYPE)yyact;
      yymsp->major = (YYCODETYPE)yygoto;
      yymsp->minor = yygotominor;
    }else
#endif
    {
      yy_shift(yypParser,yyact,yygoto,&yygotominor);
    }
  }else{
    assert( yyact == YYNSTATE + YYNRULE + 1 );
    yy_accept(yypParser);
  }
}

/*
** The following code executes when the parse fails
*/
#ifndef YYNOERRORRECOVERY
static void yy_parse_failed(
  yyParser *yypParser           /* The parser */
){
  ParseARG_FETCH;
#ifndef NDEBUG
  if( yyTraceFILE ){
    fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
  }
#endif
  while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
  /* Here code is inserted which will be executed whenever the
  ** parser fails */
%%
  ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
}
#endif /* YYNOERRORRECOVERY */

/*
** The following code executes when a syntax error first occurs.
*/
static void yy_syntax_error(
  yyParser *yypParser,           /* The parser */
  int yymajor,                   /* The major type of the error token */
  YYMINORTYPE yyminor            /* The minor type of the error token */
){
  ParseARG_FETCH;
#define TOKEN (yyminor.yy0)
%%
  ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
}

/*
** The following is executed when the parser accepts
*/
static void yy_accept(
  yyParser *yypParser           /* The parser */
){
  ParseARG_FETCH;
#ifndef NDEBUG
  if( yyTraceFILE ){
    fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
  }
#endif
  while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
  /* Here code is inserted which will be executed whenever the
  ** parser accepts */
%%
  ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
}

/* The main parser program.
** The first argument is a pointer to a structure obtained from
** "ParseAlloc" which describes the current state of the parser.
** The second argument is the major token number.  The third is
** the minor token.  The fourth optional argument is whatever the
** user wants (and specified in the grammar) and is available for
** use by the action routines.
**
** Inputs:
** <ul>
** <li> A pointer to the parser (an opaque structure.)
** <li> The major token number.
** <li> The minor token number.
** <li> An option argument of a grammar-specified type.
** </ul>
**
** Outputs:
** None.
*/
void Parse(
  void *yyp,                   /* The parser */
  int yymajor,                 /* The major token code number */
  ParseTOKENTYPE yyminor       /* The value for the token */
  ParseARG_PDECL               /* Optional %extra_argument parameter */
){
  YYMINORTYPE yyminorunion;
  int yyact;            /* The parser action. */
  int yyendofinput;     /* True if we are at the end of input */
#ifdef YYERRORSYMBOL
  int yyerrorhit = 0;   /* True if yymajor has invoked an error */
#endif
  yyParser *yypParser;  /* The parser */

  /* (re)initialize the parser, if necessary */
  yypParser = (yyParser*)yyp;
  if( yypParser->yyidx<0 ){
#if YYSTACKDEPTH<=0
    if( yypParser->yystksz <=0 ){
      /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/
      yyminorunion = yyzerominor;
      yyStackOverflow(yypParser, &yyminorunion);
      return;
    }
#endif
    yypParser->yyidx = 0;
    yypParser->yyerrcnt = -1;
    yypParser->yystack[0].stateno = 0;
    yypParser->yystack[0].major = 0;
  }
  yyminorunion.yy0 = yyminor;
  yyendofinput = (yymajor==0);
  ParseARG_STORE;

#ifndef NDEBUG
  if( yyTraceFILE ){
    fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
  }
#endif

  do{
    yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
    if( yyact<YYNSTATE ){
      assert( !yyendofinput );  /* Impossible to shift the $ token */
      yy_shift(yypParser,yyact,yymajor,&yyminorunion);
      yypParser->yyerrcnt--;
      yymajor = YYNOCODE;
    }else if( yyact < YYNSTATE + YYNRULE ){
      yy_reduce(yypParser,yyact-YYNSTATE);
    }else{
      assert( yyact == YY_ERROR_ACTION );
#ifdef YYERRORSYMBOL
      int yymx;
#endif
#ifndef NDEBUG
      if( yyTraceFILE ){
        fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt);
      }
#endif
#ifdef YYERRORSYMBOL
      /* A syntax error has occurred.
      ** The response to an error depends upon whether or not the
      ** grammar defines an error token "ERROR".  
      **
      ** This is what we do if the grammar does define ERROR:
      **
      **  * Call the %syntax_error function.
      **
      **  * Begin popping the stack until we enter a state where
      **    it is legal to shift the error symbol, then shift
      **    the error symbol.
      **
      **  * Set the error count to three.
      **
      **  * Begin accepting and shifting new tokens.  No new error
      **    processing will occur until three tokens have been
      **    shifted successfully.
      **
      */
      if( yypParser->yyerrcnt<0 ){
        yy_syntax_error(yypParser,yymajor,yyminorunion);
      }
      yymx = yypParser->yystack[yypParser->yyidx].major;
      if( yymx==YYERRORSYMBOL || yyerrorhit ){
#ifndef NDEBUG
        if( yyTraceFILE ){
          fprintf(yyTraceFILE,"%sDiscard input token %s\n",
             yyTracePrompt,yyTokenName[yymajor]);
        }
#endif
        yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion);
        yymajor = YYNOCODE;
      }else{
         while(
          yypParser->yyidx >= 0 &&
          yymx != YYERRORSYMBOL &&
          (yyact = yy_find_reduce_action(
                        yypParser->yystack[yypParser->yyidx].stateno,
                        YYERRORSYMBOL)) >= YYNSTATE
        ){
          yy_pop_parser_stack(yypParser);
        }
        if( yypParser->yyidx < 0 || yymajor==0 ){
          yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
          yy_parse_failed(yypParser);
          yymajor = YYNOCODE;
        }else if( yymx!=YYERRORSYMBOL ){
          YYMINORTYPE u2;
          u2.YYERRSYMDT = 0;
          yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
        }
      }
      yypParser->yyerrcnt = 3;
      yyerrorhit = 1;
#elif defined(YYNOERRORRECOVERY)
      /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to
      ** do any kind of error recovery.  Instead, simply invoke the syntax
      ** error routine and continue going as if nothing had happened.
      **
      ** Applications can set this macro (for example inside %include) if
      ** they intend to abandon the parse upon the first syntax error seen.
      */
      yy_syntax_error(yypParser,yymajor,yyminorunion);
      yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
      yymajor = YYNOCODE;
      
#else  /* YYERRORSYMBOL is not defined */
      /* This is what we do if the grammar does not define ERROR:
      **
      **  * Report an error message, and throw away the input token.
      **
      **  * If the input token is $, then fail the parse.
      **
      ** As before, subsequent error messages are suppressed until
      ** three input tokens have been successfully shifted.
      */
      if( yypParser->yyerrcnt<=0 ){
        yy_syntax_error(yypParser,yymajor,yyminorunion);
      }
      yypParser->yyerrcnt = 3;
      yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
      if( yyendofinput ){
        yy_parse_failed(yypParser);
      }
      yymajor = YYNOCODE;
#endif
    }
  }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
  return;
}
Changes to src/loadext.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2006 June 7
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to dynamically load extensions into
** the SQLite library.
**
** $Id: loadext.c,v 1.60 2009/06/03 01:24:54 drh Exp $
*/

#ifndef SQLITE_CORE
  #define SQLITE_CORE 1  /* Disable the API redefinition in sqlite3ext.h */
#endif
#include "sqlite3ext.h"
#include "sqliteInt.h"
Changes to src/main.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
9
10
11
12
13
14
15


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43







-
-




















+







**    May you share freely, never taking more than you give.
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.560 2009/06/26 15:14:55 drh Exp $
*/
#include "sqliteInt.h"

#ifdef SQLITE_ENABLE_FTS3
# include "fts3.h"
#endif
#ifdef SQLITE_ENABLE_RTREE
# include "rtree.h"
#endif
#ifdef SQLITE_ENABLE_ICU
# include "sqliteicu.h"
#endif

/*
** The version of the library
*/
#ifndef SQLITE_AMALGAMATION
const char sqlite3_version[] = SQLITE_VERSION;
#endif
const char *sqlite3_libversion(void){ return sqlite3_version; }
const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }

#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
/*
** If the following function pointer is not NULL and if
** SQLITE_ENABLE_IOTRACE is enabled, then messages describing
121
122
123
124
125
126
127

128
129
130
131
132
133
134


135
136
137
138
139
140
141
142
143
144
145

146
147

148

149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

165


166

167

168
169
170
171
172
173
174
120
121
122
123
124
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
142
143
144
145

146


147

148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

166
167
168
169

170
171
172
173
174
175
176
177







+






-
+
+










-
+
-
-
+
-
+
















+
-
+
+

+
-
+







  ** This operation is protected by the STATIC_MASTER mutex.  Note that
  ** MutexAlloc() is called for a static mutex prior to initializing the
  ** malloc subsystem - this implies that the allocation of a static
  ** mutex must not require support from the malloc subsystem.
  */
  pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
  sqlite3_mutex_enter(pMaster);
  sqlite3GlobalConfig.isMutexInit = 1;
  if( !sqlite3GlobalConfig.isMallocInit ){
    rc = sqlite3MallocInit();
  }
  if( rc==SQLITE_OK ){
    sqlite3GlobalConfig.isMallocInit = 1;
    if( !sqlite3GlobalConfig.pInitMutex ){
      sqlite3GlobalConfig.pInitMutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
      sqlite3GlobalConfig.pInitMutex =
           sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
      if( sqlite3GlobalConfig.bCoreMutex && !sqlite3GlobalConfig.pInitMutex ){
        rc = SQLITE_NOMEM;
      }
    }
  }
  if( rc==SQLITE_OK ){
    sqlite3GlobalConfig.nRefInitMutex++;
  }
  sqlite3_mutex_leave(pMaster);

  /* If unable to initialize the malloc subsystem, then return early.
  /* If rc is not SQLITE_OK at this point, then either the malloc
  ** There is little hope of getting SQLite to run if the malloc
  ** subsystem cannot be initialized.
  ** subsystem could not be initialized or the system failed to allocate
  */
  ** the pInitMutex mutex. Return an error in either case.  */
  if( rc!=SQLITE_OK ){
    return rc;
  }

  /* Do the rest of the initialization under the recursive mutex so
  ** that we will be able to handle recursive calls into
  ** sqlite3_initialize().  The recursive calls normally come through
  ** sqlite3_os_init() when it invokes sqlite3_vfs_register(), but other
  ** recursive calls might also be possible.
  */
  sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex);
  if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){
    FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
    sqlite3GlobalConfig.inProgress = 1;
    memset(pHash, 0, sizeof(sqlite3GlobalFunctions));
    sqlite3RegisterGlobalFunctions();
    if( sqlite3GlobalConfig.isPCacheInit==0 ){
    rc = sqlite3PcacheInitialize();
      rc = sqlite3PcacheInitialize();
    }
    if( rc==SQLITE_OK ){
      sqlite3GlobalConfig.isPCacheInit = 1;
      rc = sqlite3_os_init();
      rc = sqlite3OsInit();
    }
    if( rc==SQLITE_OK ){
      sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, 
          sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage);
      sqlite3GlobalConfig.isInit = 1;
    }
    sqlite3GlobalConfig.inProgress = 0;
215
216
217
218
219
220
221


222



223
224
225



226



227
228

229

230
231
232
233
234
235
236
218
219
220
221
222
223
224
225
226

227
228
229
230


231
232
233
234
235
236
237
238

239
240
241
242
243
244
245
246
247
248







+
+
-
+
+
+

-
-
+
+
+

+
+
+

-
+

+







** while any part of SQLite is otherwise in use in any thread.  This
** routine is not threadsafe.  But it is safe to invoke this routine
** on when SQLite is already shut down.  If SQLite is already shut down
** when this routine is invoked, then this routine is a harmless no-op.
*/
int sqlite3_shutdown(void){
  if( sqlite3GlobalConfig.isInit ){
    sqlite3_os_end();
    sqlite3_reset_auto_extension();
    sqlite3GlobalConfig.isMallocInit = 0;
    sqlite3GlobalConfig.isInit = 0;
  }
  if( sqlite3GlobalConfig.isPCacheInit ){
    sqlite3PcacheShutdown();
    sqlite3_os_end();
    sqlite3_reset_auto_extension();
    sqlite3GlobalConfig.isPCacheInit = 0;
  }
  if( sqlite3GlobalConfig.isMallocInit ){
    sqlite3MallocEnd();
    sqlite3GlobalConfig.isMallocInit = 0;
  }
  if( sqlite3GlobalConfig.isMutexInit ){
    sqlite3MutexEnd();
    sqlite3GlobalConfig.isInit = 0;
    sqlite3GlobalConfig.isMutexInit = 0;
  }

  return SQLITE_OK;
}

/*
** This API allows applications to modify the global configuration of
** the SQLite library at run-time.
**
714
715
716
717
718
719
720



721
722
723
724
725
726
727
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742







+
+
+







  sqlite3VtabRollback(db);
  sqlite3EndBenignMalloc();

  if( db->flags&SQLITE_InternChanges ){
    sqlite3ExpirePreparedStatements(db);
    sqlite3ResetInternalSchema(db, 0);
  }

  /* Any deferred constraint violations have now been resolved. */
  db->nDeferredCons = 0;

  /* If one has been configured, invoke the rollback-hook callback */
  if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
    db->xRollbackCallback(db->pRollbackArg);
  }
}

1200
1201
1202
1203
1204
1205
1206
1207

1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221

1222
1223
1224
1225
1226
1227
1228
1229







-
+







** soon as the connection is closed.
**
** A virtual database can be either a disk file (that is automatically
** deleted when the file is closed) or it an be held entirely in memory.
** The sqlite3TempInMemory() function is used to determine which.
*/
int sqlite3BtreeFactory(
  const sqlite3 *db,        /* Main database when opening aux otherwise 0 */
  sqlite3 *db,              /* Main database when opening aux otherwise 0 */
  const char *zFilename,    /* Name of the file containing the BTree database */
  int omitJournal,          /* if TRUE then do not journal this file */
  int nCache,               /* How many pages in the page cache */
  int vfsFlags,             /* Flags passed through to vfsOpen */
  Btree **ppBtree           /* Pointer to new Btree object written here */
){
  int btFlags = 0;
1341
1342
1343
1344
1345
1346
1347
1348

1349
1350


1351
1352
1353
1354
1355
1356
1357
1356
1357
1358
1359
1360
1361
1362

1363
1364

1365
1366
1367
1368
1369
1370
1371
1372
1373







-
+

-
+
+







}

/*
** Create a new collating function for database "db".  The name is zName
** and the encoding is enc.
*/
static int createCollation(
  sqlite3* db, 
  sqlite3* db,
  const char *zName, 
  int enc, 
  u8 enc,
  u8 collType,
  void* pCtx,
  int(*xCompare)(void*,int,const void*,int,const void*),
  void(*xDel)(void*)
){
  CollSeq *pColl;
  int enc2;
  int nName = sqlite3Strlen30(zName);
1408
1409
1410
1411
1412
1413
1414

1415
1416
1417
1418
1419
1420
1421
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438







+








  pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1);
  if( pColl ){
    pColl->xCmp = xCompare;
    pColl->pUser = pCtx;
    pColl->xDel = xDel;
    pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED));
    pColl->type = collType;
  }
  sqlite3Error(db, SQLITE_OK, 0);
  return SQLITE_OK;
}


/*
1430
1431
1432
1433
1434
1435
1436

1437
1438
1439
1440
1441
1442
1443
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461







+







  SQLITE_MAX_EXPR_DEPTH,
  SQLITE_MAX_COMPOUND_SELECT,
  SQLITE_MAX_VDBE_OP,
  SQLITE_MAX_FUNCTION_ARG,
  SQLITE_MAX_ATTACHED,
  SQLITE_MAX_LIKE_PATTERN_LENGTH,
  SQLITE_MAX_VARIABLE_NUMBER,
  SQLITE_MAX_TRIGGER_DEPTH,
};

/*
** Make sure the hard limits are set to reasonable values
*/
#if SQLITE_MAX_LENGTH<100
# error SQLITE_MAX_LENGTH must be at least 100
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471



1472
1473
1474
1475
1476
1477
1478
1477
1478
1479
1480
1481
1482
1483



1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496







-
-
-



+
+
+







#endif
#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>30
# error SQLITE_MAX_ATTACHED must be between 0 and 30
#endif
#if SQLITE_MAX_LIKE_PATTERN_LENGTH<1
# error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1
#endif
#if SQLITE_MAX_VARIABLE_NUMBER<1
# error SQLITE_MAX_VARIABLE_NUMBER must be at least 1
#endif
#if SQLITE_MAX_COLUMN>32767
# error SQLITE_MAX_COLUMN must not exceed 32767
#endif
#if SQLITE_MAX_TRIGGER_DEPTH<1
# error SQLITE_MAX_TRIGGER_DEPTH must be at least 1
#endif


/*
** Change the value of a limit.  Report the old value.
** If an invalid limit index is supplied, report -1.
** Make no changes but still report the old value if the
** new limit is negative.
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528





1529
1530
1531
1532
1533
1534
1535
1523
1524
1525
1526
1527
1528
1529

1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557







-
















+
+
+
+
+







  const char *zFilename, /* Database filename UTF-8 encoded */
  sqlite3 **ppDb,        /* OUT: Returned database handle */
  unsigned flags,        /* Operational flags */
  const char *zVfs       /* Name of the VFS to use */
){
  sqlite3 *db;
  int rc;
  CollSeq *pColl;
  int isThreadsafe;

  *ppDb = 0;
#ifndef SQLITE_OMIT_AUTOINIT
  rc = sqlite3_initialize();
  if( rc ) return rc;
#endif

  if( sqlite3GlobalConfig.bCoreMutex==0 ){
    isThreadsafe = 0;
  }else if( flags & SQLITE_OPEN_NOMUTEX ){
    isThreadsafe = 0;
  }else if( flags & SQLITE_OPEN_FULLMUTEX ){
    isThreadsafe = 1;
  }else{
    isThreadsafe = sqlite3GlobalConfig.bFullMutex;
  }
  if( flags & SQLITE_OPEN_PRIVATECACHE ){
    flags &= ~SQLITE_OPEN_SHAREDCACHE;
  }else if( sqlite3GlobalConfig.sharedCacheEnabled ){
    flags |= SQLITE_OPEN_SHAREDCACHE;
  }

  /* Remove harmful bits from the flags parameter
  **
  ** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were
  ** dealt with in the previous code block.  Besides these, the only
  ** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY,
1574
1575
1576
1577
1578
1579
1580



1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601








1602
1603
1604
1605
1606
1607
1608
1609
1610


1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622




1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637


1638
1639






1640
1641
1642
1643
1644
1645
1646







+
+
+

















-
-
-
-
+
+
+
+
+
+
+
+







-
-
+
+
-
-
-
-
-
-







  db->flags |= SQLITE_ShortColNames
#if SQLITE_DEFAULT_FILE_FORMAT<4
                 | SQLITE_LegacyFileFmt
#endif
#ifdef SQLITE_ENABLE_LOAD_EXTENSION
                 | SQLITE_LoadExtension
#endif
#if SQLITE_DEFAULT_RECURSIVE_TRIGGERS
                 | SQLITE_RecTriggers
#endif
      ;
  sqlite3HashInit(&db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
  sqlite3HashInit(&db->aModule);
#endif

  db->pVfs = sqlite3_vfs_find(zVfs);
  if( !db->pVfs ){
    rc = SQLITE_ERROR;
    sqlite3Error(db, rc, "no such vfs: %s", zVfs);
    goto opendb_out;
  }

  /* Add the default collation sequence BINARY. BINARY works for both UTF-8
  ** and UTF-16, so add a version for each to avoid any unnecessary
  ** conversions. The only error that can occur here is a malloc() failure.
  */
  createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0);
  createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0);
  createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0);
  createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
  createCollation(db, "BINARY", SQLITE_UTF8, SQLITE_COLL_BINARY, 0,
                  binCollFunc, 0);
  createCollation(db, "BINARY", SQLITE_UTF16BE, SQLITE_COLL_BINARY, 0,
                  binCollFunc, 0);
  createCollation(db, "BINARY", SQLITE_UTF16LE, SQLITE_COLL_BINARY, 0,
                  binCollFunc, 0);
  createCollation(db, "RTRIM", SQLITE_UTF8, SQLITE_COLL_USER, (void*)1,
                  binCollFunc, 0);
  if( db->mallocFailed ){
    goto opendb_out;
  }
  db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
  assert( db->pDfltColl!=0 );

  /* Also add a UTF-8 case-insensitive collation sequence. */
  createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);

  createCollation(db, "NOCASE", SQLITE_UTF8, SQLITE_COLL_NOCASE, 0,
                  nocaseCollatingFunc, 0);
  /* Set flags on the built-in collating sequences */
  db->pDfltColl->type = SQLITE_COLL_BINARY;
  pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "NOCASE", 0);
  if( pColl ){
    pColl->type = SQLITE_COLL_NOCASE;
  }

  /* Open the backend database driver */
  db->openFlags = flags;
  rc = sqlite3BtreeFactory(db, zFilename, 0, SQLITE_DEFAULT_CACHE_SIZE, 
                           flags | SQLITE_OPEN_MAIN_DB,
                           &db->aDb[0].pBt);
  if( rc!=SQLITE_OK ){
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1655
1656
1657
1658
1659
1660
1661

1662
1663

1664
1665
1666
1667
1668
1669
1670







-


-









  /* The default safety_level for the main database is 'full'; for the temp
  ** database it is 'NONE'. This matches the pager layer defaults.  
  */
  db->aDb[0].zName = "main";
  db->aDb[0].safety_level = 3;
#ifndef SQLITE_OMIT_TEMPDB
  db->aDb[1].zName = "temp";
  db->aDb[1].safety_level = 1;
#endif

  db->magic = SQLITE_MAGIC_OPEN;
  if( db->mallocFailed ){
    goto opendb_out;
  }

  /* Register all built-in functions, but do not attempt to read the
1792
1793
1794
1795
1796
1797
1798
1799

1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819

1820
1821
1822
1823
1824
1825
1826
1813
1814
1815
1816
1817
1818
1819

1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839

1840
1841
1842
1843
1844
1845
1846
1847







-
+



















-
+







  int enc, 
  void* pCtx,
  int(*xCompare)(void*,int,const void*,int,const void*)
){
  int rc;
  sqlite3_mutex_enter(db->mutex);
  assert( !db->mallocFailed );
  rc = createCollation(db, zName, enc, pCtx, xCompare, 0);
  rc = createCollation(db, zName, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, 0);
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}

/*
** Register a new collation sequence with the database handle db.
*/
int sqlite3_create_collation_v2(
  sqlite3* db, 
  const char *zName, 
  int enc, 
  void* pCtx,
  int(*xCompare)(void*,int,const void*,int,const void*),
  void(*xDel)(void*)
){
  int rc;
  sqlite3_mutex_enter(db->mutex);
  assert( !db->mallocFailed );
  rc = createCollation(db, zName, enc, pCtx, xCompare, xDel);
  rc = createCollation(db, zName, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, xDel);
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}

#ifndef SQLITE_OMIT_UTF16
/*
1835
1836
1837
1838
1839
1840
1841
1842

1843
1844
1845
1846
1847
1848
1849
1856
1857
1858
1859
1860
1861
1862

1863
1864
1865
1866
1867
1868
1869
1870







-
+







){
  int rc = SQLITE_OK;
  char *zName8;
  sqlite3_mutex_enter(db->mutex);
  assert( !db->mallocFailed );
  zName8 = sqlite3Utf16to8(db, zName, -1);
  if( zName8 ){
    rc = createCollation(db, zName8, enc, pCtx, xCompare, 0);
    rc = createCollation(db, zName8, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, 0);
    sqlite3DbFree(db, zName8);
  }
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */
2241
2242
2243
2244
2245
2246
2247















2248
2249
2250
2251
2252
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+





    **    }
    */
    case SQLITE_TESTCTRL_ALWAYS: {
      int x = va_arg(ap,int);
      rc = ALWAYS(x);
      break;
    }

    /*   sqlite3_test_control(SQLITE_TESTCTRL_RESERVE, sqlite3 *db, int N)
    **
    ** Set the nReserve size to N for the main database on the database
    ** connection db.
    */
    case SQLITE_TESTCTRL_RESERVE: {
      sqlite3 *db = va_arg(ap, sqlite3*);
      int x = va_arg(ap,int);
      sqlite3_mutex_enter(db->mutex);
      sqlite3BtreeSetPageSize(db->aDb[0].pBt, 0, x, 0);
      sqlite3_mutex_leave(db->mutex);
      break;
    }

  }
  va_end(ap);
#endif /* SQLITE_OMIT_BUILTIN_TEST */
  return rc;
}
Changes to src/malloc.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** Memory allocation functions used throughout sqlite.
**
** $Id: malloc.c,v 1.64 2009/06/27 00:48:33 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>

/*
** This routine runs when the memory allocator sees that the
** total memory allocation is about to exceed the soft heap
39
40
41
42
43
44
45

46

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65



66
67
68
69
70
71
72







+

+



















-
-
-







  sqlite3_uint64 iLimit;
  int overage;
  if( n<0 ){
    iLimit = 0;
  }else{
    iLimit = n;
  }
#ifndef SQLITE_OMIT_AUTOINIT
  sqlite3_initialize();
#endif
  if( iLimit>0 ){
    sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, iLimit);
  }else{
    sqlite3MemoryAlarm(0, 0, 0);
  }
  overage = (int)(sqlite3_memory_used() - (i64)n);
  if( overage>0 ){
    sqlite3_release_memory(overage);
  }
}

/*
** Attempt to release up to n bytes of non-essential memory currently
** held by SQLite. An example of non-essential memory is memory used to
** cache database pages that are not currently in use.
*/
int sqlite3_release_memory(int n){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  int nRet = 0;
#if 0
  nRet += sqlite3VdbeReleaseMemory(n);
#endif
  nRet += sqlite3PcacheReleaseMemory(n-nRet);
  return nRet;
#else
  UNUSED_PARAMETER(n);
  return SQLITE_OK;
#endif
}
84
85
86
87
88
89
90
91

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

107
108
109
110
111
112
113
81
82
83
84
85
86
87

88

89
90
91
92

93
94
95
96
97
98
99
100

101
102
103
104
105
106
107
108







-
+
-




-








-
+








  sqlite3_mutex *mutex;         /* Mutex to serialize access */

  /*
  ** The alarm callback and its arguments.  The mem0.mutex lock will
  ** be held while the callback is running.  Recursive calls into
  ** the memory subsystem are allowed, but no new callbacks will be
  ** issued.  The alarmBusy variable is set to prevent recursive
  ** issued.
  ** callbacks.
  */
  sqlite3_int64 alarmThreshold;
  void (*alarmCallback)(void*, sqlite3_int64,int);
  void *alarmArg;
  int alarmBusy;

  /*
  ** Pointers to the end of sqlite3GlobalConfig.pScratch and
  ** sqlite3GlobalConfig.pPage to a block of memory that records
  ** which pages are available.
  */
  u32 *aScratchFree;
  u32 *aPageFree;
} mem0 = { 62560955, 0, 0, 0, 0, 0, 0, 0, 0 };
} mem0 = { 0, 0, 0, 0, 0, 0, 0, 0 };

#define mem0 GLOBAL(struct Mem0Global, mem0)

/*
** Initialize the memory allocation subsystem.
*/
int sqlite3MallocInit(void){
216
217
218
219
220
221
222
223

224
225
226
227

228
229
230

231

232
233
234
235
236
237
238
211
212
213
214
215
216
217

218

219
220
221
222
223
224
225
226

227
228
229
230
231
232
233
234







-
+
-



+



+
-
+







/*
** Trigger the alarm 
*/
static void sqlite3MallocAlarm(int nByte){
  void (*xCallback)(void*,sqlite3_int64,int);
  sqlite3_int64 nowUsed;
  void *pArg;
  if( mem0.alarmCallback==0 || mem0.alarmBusy  ) return;
  if( mem0.alarmCallback==0 ) return;
  mem0.alarmBusy = 1;
  xCallback = mem0.alarmCallback;
  nowUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
  pArg = mem0.alarmArg;
  mem0.alarmCallback = 0;
  sqlite3_mutex_leave(mem0.mutex);
  xCallback(pArg, nowUsed, nByte);
  sqlite3_mutex_enter(mem0.mutex);
  mem0.alarmCallback = xCallback;
  mem0.alarmBusy = 0;
  mem0.alarmArg = pArg;
}

/*
** Do a memory allocation with statistics and alarms.  Assume the
** lock is already held.
*/
static int mallocWithAlarm(int n, void **pp){
420
421
422
423
424
425
426
427
428
429

430
431
432
433
434
435
436
416
417
418
419
420
421
422



423
424
425
426
427
428
429
430







-
-
-
+







** sqlite3Malloc() or sqlite3_malloc().
*/
int sqlite3MallocSize(void *p){
  return sqlite3GlobalConfig.m.xSize(p);
}
int sqlite3DbMallocSize(sqlite3 *db, void *p){
  assert( db==0 || sqlite3_mutex_held(db->mutex) );
  if( p==0 ){
    return 0;
  }else if( isLookaside(db, p) ){
  if( isLookaside(db, p) ){
    return db->lookaside.sz;
  }else{
    return sqlite3GlobalConfig.m.xSize(p);
  }
}

/*
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504



















505
506
507
508

509
510
511
512
513
514
515
472
473
474
475
476
477
478




















479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497

498
499

500
501
502
503
504
505
506
507







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-


-
+







    return 0;
  }
  if( nBytes>=0x7fffff00 ){
    /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */
    return 0;
  }
  nOld = sqlite3MallocSize(pOld);
  if( sqlite3GlobalConfig.bMemstat ){
    sqlite3_mutex_enter(mem0.mutex);
    sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes);
    nNew = sqlite3GlobalConfig.m.xRoundup(nBytes);
    if( nOld==nNew ){
      pNew = pOld;
    }else{
      if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nNew-nOld >= 
            mem0.alarmThreshold ){
        sqlite3MallocAlarm(nNew-nOld);
      }
      pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
      if( pNew==0 && mem0.alarmCallback ){
        sqlite3MallocAlarm(nBytes);
        pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
      }
      if( pNew ){
        nNew = sqlite3MallocSize(pNew);
        sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
      }
  nNew = sqlite3GlobalConfig.m.xRoundup(nBytes);
  if( nOld==nNew ){
    pNew = pOld;
  }else if( sqlite3GlobalConfig.bMemstat ){
    sqlite3_mutex_enter(mem0.mutex);
    sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes);
    if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nNew-nOld >= 
          mem0.alarmThreshold ){
      sqlite3MallocAlarm(nNew-nOld);
    }
    pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
    if( pNew==0 && mem0.alarmCallback ){
      sqlite3MallocAlarm(nBytes);
      pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
    }
    if( pNew ){
      nNew = sqlite3MallocSize(pNew);
      sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
    }
    }
    sqlite3_mutex_leave(mem0.mutex);
  }else{
    pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nBytes);
    pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
  }
  return pNew;
}

/*
** The public interface to sqlite3Realloc.  Make sure that the memory
** subsystem is initialized prior to invoking sqliteRealloc.
Changes to src/mem0.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
11
12
13
14
15
16
17


18
19
20
21
22
23
24







-
-







*************************************************************************
**
** This file contains a no-op memory allocation drivers for use when
** SQLITE_ZERO_MALLOC is defined.  The allocation drivers implemented
** here always fail.  SQLite will not operate with these drivers.  These
** are merely placeholders.  Real drivers must be substituted using
** sqlite3_config() before SQLite will operate.
**
** $Id: mem0.c,v 1.1 2008/10/28 18:58:20 drh Exp $
*/
#include "sqliteInt.h"

/*
** This version of the memory allocator is the default.  It is
** used when no other memory allocator is specified using compile-time
** macros.
Changes to src/mem1.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
12
13
14
15
16
17
18


19
20
21
22
23
24
25







-
-







**
** This file contains low-level memory allocation drivers for when
** SQLite will use the standard C-library malloc/realloc/free interface
** to obtain the memory it needs.
**
** This file contains implementations of the low-level memory allocation
** routines specified in the sqlite3_mem_methods object.
**
** $Id: mem1.c,v 1.30 2009/03/23 04:33:33 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** This version of the memory allocator is the default.  It is
** used when no other memory allocator is specified using compile-time
** macros.
Changes to src/mem2.c.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
14
15
16
17
18
19
20


21
22
23
24
25
26
27







-
-







** SQLite will use the standard C-library malloc/realloc/free interface
** to obtain the memory it needs while adding lots of additional debugging
** information to each allocation in order to help detect and fix memory
** leaks and memory usage errors.
**
** This file contains implementations of the low-level memory allocation
** routines specified in the sqlite3_mem_methods object.
**
** $Id: mem2.c,v 1.45 2009/03/23 04:33:33 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** This version of the memory allocator is used only if the
** SQLITE_MEMDEBUG macro is defined
*/
Changes to src/mem3.c.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
18
19
20
21
22
23
24


25
26
27
28
29
30
31







-
-







** are made and returned by the xMalloc() and xRealloc() 
** implementations. Once sqlite3_initialize() has been called,
** the amount of memory available to SQLite is fixed and cannot
** be changed.
**
** This version of the memory allocation subsystem is included
** in the build only if SQLITE_ENABLE_MEMSYS3 is defined.
**
** $Id: mem3.c,v 1.25 2008/11/19 16:52:44 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** This version of the memory allocator is only built into the library
** SQLITE_ENABLE_MEMSYS3 is defined. Defining this symbol does not
** mean that the library will use a memory-pool by default, just that
574
575
576
577
578
579
580

581
582
583
584
585
586
587
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586







+







}

/*
** Deinitialize this module.
*/
static void memsys3Shutdown(void *NotUsed){
  UNUSED_PARAMETER(NotUsed);
  mem3.mutex = 0;
  return;
}



/*
** Open the file indicated and write a log of all unfreed memory 
Changes to src/mem5.c.
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
























27
28
29
30
31
32
33
34
35
36
37
38
39



40
41
42
43
44
45
46
47
48
49
50



51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92



93
94
95
96
97
98
99
100
101
102

103



104
105




106

107
108
109
110
111
112
113
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73



74
75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
90
91
92
93
94
95



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117

118
119
120
121
122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148







-
+









-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+













+
+
+








-
-
-
+
+
+






-
+












-
-
-
+
+
+



















-
+
+
+









-
+

+
+
+


+
+
+
+
-
+







**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement a memory
** allocation subsystem for use by SQLite. 
**
** This version of the memory allocation subsystem omits all
** use of malloc(). The SQLite user supplies a block of memory
** use of malloc(). The application gives SQLite a block of memory
** before calling sqlite3_initialize() from which allocations
** are made and returned by the xMalloc() and xRealloc() 
** implementations. Once sqlite3_initialize() has been called,
** the amount of memory available to SQLite is fixed and cannot
** be changed.
**
** This version of the memory allocation subsystem is included
** in the build only if SQLITE_ENABLE_MEMSYS5 is defined.
**
** $Id: mem5.c,v 1.19 2008/11/19 16:52:44 danielk1977 Exp $
** This memory allocator uses the following algorithm:
**
**   1.  All memory allocations sizes are rounded up to a power of 2.
**
**   2.  If two adjacent free blocks are the halves of a larger block,
**       then the two blocks are coalesed into the single larger block.
**
**   3.  New memory is allocated from the first available free block.
**
** This algorithm is described in: J. M. Robson. "Bounds for Some Functions
** Concerning Dynamic Storage Allocation". Journal of the Association for
** Computing Machinery, Volume 21, Number 8, July 1974, pages 491-499.
** 
** Let n be the size of the largest allocation divided by the minimum
** allocation size (after rounding all sizes up to a power of 2.)  Let M
** be the maximum amount of memory ever outstanding at one time.  Let
** N be the total amount of memory available for allocation.  Robson
** proved that this memory allocator will never breakdown due to 
** fragmentation as long as the following constraint holds:
**
**      N >=  M*(1 + log2(n)/2) - n + 1
**
** The sqlite3_status() logic tracks the maximum values of n and M so
** that an application can, at any time, verify this constraint.
*/
#include "sqliteInt.h"

/*
** This version of the memory allocator is used only when 
** SQLITE_ENABLE_MEMSYS5 is defined.
*/
#ifdef SQLITE_ENABLE_MEMSYS5

/*
** A minimum allocation is an instance of the following structure.
** Larger allocations are an array of these structures where the
** size of the array is a power of 2.
**
** The size of this object must be a power of two.  That fact is
** verified in memsys5Init().
*/
typedef struct Mem5Link Mem5Link;
struct Mem5Link {
  int next;       /* Index of next free chunk */
  int prev;       /* Index of previous free chunk */
};

/*
** Maximum size of any allocation is ((1<<LOGMAX)*mem5.nAtom). Since
** mem5.nAtom is always at least 8, this is not really a practical
** limitation.
** Maximum size of any allocation is ((1<<LOGMAX)*mem5.szAtom). Since
** mem5.szAtom is always at least 8 and 32-bit integers are used,
** it is not actually possible to reach this limit.
*/
#define LOGMAX 30

/*
** Masks used for mem5.aCtrl[] elements.
*/
#define CTRL_LOGSIZE  0x1f    /* Log2 Size of this block relative to POW2_MIN */
#define CTRL_LOGSIZE  0x1f    /* Log2 Size of this block */
#define CTRL_FREE     0x20    /* True if not checked out */

/*
** All of the static variables used by this module are collected
** into a single structure named "mem5".  This is to keep the
** static variables organized and to reduce namespace pollution
** when this module is combined with other in the amalgamation.
*/
static SQLITE_WSD struct Mem5Global {
  /*
  ** Memory available for allocation
  */
  int nAtom;       /* Smallest possible allocation in bytes */
  int nBlock;      /* Number of nAtom sized blocks in zPool */
  u8 *zPool;
  int szAtom;      /* Smallest possible allocation in bytes */
  int nBlock;      /* Number of szAtom sized blocks in zPool */
  u8 *zPool;       /* Memory available to be allocated */
  
  /*
  ** Mutex to control access to the memory allocation subsystem.
  */
  sqlite3_mutex *mutex;

  /*
  ** Performance statistics
  */
  u64 nAlloc;         /* Total number of calls to malloc */
  u64 totalAlloc;     /* Total of all malloc calls - includes internal frag */
  u64 totalExcess;    /* Total internal fragmentation */
  u32 currentOut;     /* Current checkout, including internal fragmentation */
  u32 currentCount;   /* Current number of distinct checkouts */
  u32 maxOut;         /* Maximum instantaneous currentOut */
  u32 maxCount;       /* Maximum instantaneous currentCount */
  u32 maxRequest;     /* Largest allocation (exclusive of internal frag) */
  
  /*
  ** Lists of free blocks of various sizes.
  ** Lists of free blocks.  aiFreelist[0] is a list of free blocks of
  ** size mem5.szAtom.  aiFreelist[1] holds blocks of size szAtom*2.
  ** and so forth.
  */
  int aiFreelist[LOGMAX+1];

  /*
  ** Space for tracking which blocks are checked out and the size
  ** of each block.  One byte per block.
  */
  u8 *aCtrl;

} mem5 = { 19804167 };
} mem5 = { 0 };

/*
** Access the static variable through a macro for SQLITE_OMIT_WSD
*/
#define mem5 GLOBAL(struct Mem5Global, mem5)

/*
** Assuming mem5.zPool is divided up into an array of Mem5Link
** structures, return a pointer to the idx-th such lik.
*/
#define MEM5LINK(idx) ((Mem5Link *)(&mem5.zPool[(idx)*mem5.nAtom]))
#define MEM5LINK(idx) ((Mem5Link *)(&mem5.zPool[(idx)*mem5.szAtom]))

/*
** Unlink the chunk at mem5.aPool[i] from list it is currently
** on.  It should be found on mem5.aiFreelist[iLogsize].
*/
static void memsys5Unlink(int i, int iLogsize){
  int next, prev;
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

174
175

176
177
178
179
180
181
182
184
185
186
187
188
189
190



191
192
193
194
195
196
197
198
199
200
201
202
203
204

205
206

207
208
209
210
211
212
213
214







-
-
-














-
+

-
+








/*
** If the STATIC_MEM mutex is not already held, obtain it now. The mutex
** will already be held (obtained by code in malloc.c) if
** sqlite3GlobalConfig.bMemStat is true.
*/
static void memsys5Enter(void){
  if( sqlite3GlobalConfig.bMemstat==0 && mem5.mutex==0 ){
    mem5.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
  }
  sqlite3_mutex_enter(mem5.mutex);
}
static void memsys5Leave(void){
  sqlite3_mutex_leave(mem5.mutex);
}

/*
** Return the size of an outstanding allocation, in bytes.  The
** size returned omits the 8-byte header overhead.  This only
** works for chunks that are currently checked out.
*/
static int memsys5Size(void *p){
  int iSize = 0;
  if( p ){
    int i = ((u8 *)p-mem5.zPool)/mem5.nAtom;
    int i = ((u8 *)p-mem5.zPool)/mem5.szAtom;
    assert( i>=0 && i<mem5.nBlock );
    iSize = mem5.nAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
    iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
  }
  return iSize;
}

/*
** Find the first entry on the freelist iLogsize.  Unlink that
** entry and return its index. 
194
195
196
197
198
199
200
201







202
203
204
205
206
207



208
209
210
211
212
213
214







215
216

217
218
219
220
221
222
223
226
227
228
229
230
231
232

233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271







-
+
+
+
+
+
+
+






+
+
+







+
+
+
+
+
+
+

-
+







  }
  memsys5Unlink(iFirst, iLogsize);
  return iFirst;
}

/*
** Return a block of memory of at least nBytes in size.
** Return NULL if unable.
** Return NULL if unable.  Return NULL if nBytes==0.
**
** The caller guarantees that nByte positive.
**
** The caller has obtained a mutex prior to invoking this
** routine so there is never any chance that two or more
** threads can be in this routine at the same time.
*/
static void *memsys5MallocUnsafe(int nByte){
  int i;           /* Index of a mem5.aPool[] slot */
  int iBin;        /* Index into mem5.aiFreelist[] */
  int iFullSz;     /* Size of allocation rounded up to power of 2 */
  int iLogsize;    /* Log2 of iFullSz/POW2_MIN */

  /* nByte must be a positive */
  assert( nByte>0 );

  /* Keep track of the maximum allocation request.  Even unfulfilled
  ** requests are counted */
  if( (u32)nByte>mem5.maxRequest ){
    mem5.maxRequest = nByte;
  }

  /* Abort if the requested allocation size is larger than the largest
  ** power of two that we can represent using 32-bit signed integers.
  */
  if( nByte > 0x40000000 ){
    return 0;
  }

  /* Round nByte up to the next valid power of two */
  for(iFullSz=mem5.nAtom, iLogsize=0; iFullSz<nByte; iFullSz *= 2, iLogsize++){}
  for(iFullSz=mem5.szAtom, iLogsize=0; iFullSz<nByte; iFullSz *= 2, iLogsize++){}

  /* Make sure mem5.aiFreelist[iLogsize] contains at least one free
  ** block.  If not, then split a block of the next larger power of
  ** two in order to create a new free block of size iLogsize.
  */
  for(iBin=iLogsize; mem5.aiFreelist[iBin]<0 && iBin<=LOGMAX; iBin++){}
  if( iBin>LOGMAX ) return 0;
238
239
240
241
242
243
244
245

246
247
248
249
250
251
252
253

254
255
256

257
258

259
260
261
262

263
264
265
266
267
268
269
270
271
272

273
274

275
276
277
278
279

280
281
282
283
284
285
286
286
287
288
289
290
291
292

293
294
295
296
297
298
299
300

301
302
303

304
305

306
307
308
309

310
311
312
313
314
315
316
317
318
319

320
321

322
323
324
325
326

327
328
329
330
331
332
333
334







-
+







-
+


-
+

-
+



-
+









-
+

-
+




-
+







  mem5.totalExcess += iFullSz - nByte;
  mem5.currentCount++;
  mem5.currentOut += iFullSz;
  if( mem5.maxCount<mem5.currentCount ) mem5.maxCount = mem5.currentCount;
  if( mem5.maxOut<mem5.currentOut ) mem5.maxOut = mem5.currentOut;

  /* Return a pointer to the allocated memory. */
  return (void*)&mem5.zPool[i*mem5.nAtom];
  return (void*)&mem5.zPool[i*mem5.szAtom];
}

/*
** Free an outstanding memory allocation.
*/
static void memsys5FreeUnsafe(void *pOld){
  u32 size, iLogsize;
  int iBlock;             
  int iBlock;

  /* Set iBlock to the index of the block pointed to by pOld in 
  ** the array of mem5.nAtom byte blocks pointed to by mem5.zPool.
  ** the array of mem5.szAtom byte blocks pointed to by mem5.zPool.
  */
  iBlock = ((u8 *)pOld-mem5.zPool)/mem5.nAtom;
  iBlock = ((u8 *)pOld-mem5.zPool)/mem5.szAtom;

  /* Check that the pointer pOld points to a valid, non-free block. */
  assert( iBlock>=0 && iBlock<mem5.nBlock );
  assert( ((u8 *)pOld-mem5.zPool)%mem5.nAtom==0 );
  assert( ((u8 *)pOld-mem5.zPool)%mem5.szAtom==0 );
  assert( (mem5.aCtrl[iBlock] & CTRL_FREE)==0 );

  iLogsize = mem5.aCtrl[iBlock] & CTRL_LOGSIZE;
  size = 1<<iLogsize;
  assert( iBlock+size-1<(u32)mem5.nBlock );

  mem5.aCtrl[iBlock] |= CTRL_FREE;
  mem5.aCtrl[iBlock+size-1] |= CTRL_FREE;
  assert( mem5.currentCount>0 );
  assert( mem5.currentOut>=(size*mem5.nAtom) );
  assert( mem5.currentOut>=(size*mem5.szAtom) );
  mem5.currentCount--;
  mem5.currentOut -= size*mem5.nAtom;
  mem5.currentOut -= size*mem5.szAtom;
  assert( mem5.currentOut>0 || mem5.currentCount==0 );
  assert( mem5.currentCount>0 || mem5.currentOut==0 );

  mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
  while( iLogsize<LOGMAX ){
  while( ALWAYS(iLogsize<LOGMAX) ){
    int iBuddy;
    if( (iBlock>>iLogsize) & 1 ){
      iBuddy = iBlock - size;
    }else{
      iBuddy = iBlock + size;
    }
    assert( iBuddy>=0 );
312
313
314
315
316
317
318



319
320
321
322

323
324
325
326
327
328
329
330
331










332
333
334
335
336
337



338
339

340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358







359
360
361

362

363
364
365










366
367
368
369
370
371
372
373




374
375
376
377
378
379
380





381
382
383

384
385
386










387
388
389
390
391



392
393
394

395
396

397
398
399
400
401
402
403
404
405
406
407
408
409
410
411





412
413
414
415
416
417
418
419
420

421
422
423

424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445

446
447
448

449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467

468
469
470
471
472
473
474
360
361
362
363
364
365
366
367
368
369
370
371


372


373
374
375
376
377
378

379
380
381
382
383
384
385
386
387
388
389
390
391
392


393
394
395


396

397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413

414
415
416
417
418
419
420
421
422
423
424

425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445

446
447
448
449
450
451





452
453
454
455
456
457
458
459
460



461
462
463
464
465
466
467
468
469
470
471
472



473
474
475
476
477

478
479

480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519

520
521
522
523
524
525
526
527
528
529
530
531
532
533
534

535
536
537

538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553



554
555
556
557
558
559
560
561
562







+
+
+


-
-
+
-
-






-
+
+
+
+
+
+
+
+
+
+




-
-
+
+
+
-
-
+
-

















-
+
+
+
+
+
+
+



+
-
+



+
+
+
+
+
+
+
+
+
+







-
+
+
+
+


-
-
-
-
-
+
+
+
+
+



+
-
-
-
+
+
+
+
+
+
+
+
+
+


-
-
-
+
+
+


-
+

-
+















+
+
+
+
+









+



+





-















-
+


-
+















-
-
-

+







    memsys5Leave();
  }
  return (void*)p; 
}

/*
** Free memory.
**
** The outer layer memory allocator prevents this routine from
** being called with pPrior==0.
*/
static void memsys5Free(void *pPrior){
  if( pPrior==0 ){
assert(0);
  assert( pPrior!=0 );
    return;
  }
  memsys5Enter();
  memsys5FreeUnsafe(pPrior);
  memsys5Leave();  
}

/*
** Change the size of an existing memory allocation
** Change the size of an existing memory allocation.
**
** The outer layer memory allocator prevents this routine from
** being called with pPrior==0.  
**
** nBytes is always a value obtained from a prior call to
** memsys5Round().  Hence nBytes is always a non-negative power
** of two.  If nBytes==0 that means that an oversize allocation
** (an allocation larger than 0x40000000) was requested and this
** routine should return 0 without freeing pPrior.
*/
static void *memsys5Realloc(void *pPrior, int nBytes){
  int nOld;
  void *p;
  if( pPrior==0 ){
    return memsys5Malloc(nBytes);
  assert( pPrior!=0 );
  assert( (nBytes&(nBytes-1))==0 );
  assert( nBytes>=0 );
  }
  if( nBytes<=0 ){
  if( nBytes==0 ){
    memsys5Free(pPrior);
    return 0;
  }
  nOld = memsys5Size(pPrior);
  if( nBytes<=nOld ){
    return pPrior;
  }
  memsys5Enter();
  p = memsys5MallocUnsafe(nBytes);
  if( p ){
    memcpy(p, pPrior, nOld);
    memsys5FreeUnsafe(pPrior);
  }
  memsys5Leave();
  return p;
}

/*
** Round up a request size to the next valid allocation size.
** Round up a request size to the next valid allocation size.  If
** the allocation is too large to be handled by this allocation system,
** return 0.
**
** All allocations must be a power of two and must be expressed by a
** 32-bit signed integer.  Hence the largest allocation is 0x40000000
** or 1073741824 bytes.
*/
static int memsys5Roundup(int n){
  int iFullSz;
  if( n > 0x40000000 ) return 0;
  for(iFullSz=mem5.nAtom; iFullSz<n; iFullSz *= 2);
  for(iFullSz=mem5.szAtom; iFullSz<n; iFullSz *= 2);
  return iFullSz;
}

/*
** Return the ceiling of the logarithm base 2 of iValue.
**
** Examples:   memsys5Log(1) -> 0
**             memsys5Log(2) -> 1
**             memsys5Log(4) -> 2
**             memsys5Log(5) -> 3
**             memsys5Log(8) -> 3
**             memsys5Log(9) -> 4
*/
static int memsys5Log(int iValue){
  int iLog;
  for(iLog=0; (1<<iLog)<iValue; iLog++);
  return iLog;
}

/*
** Initialize this module.
** Initialize the memory allocator.
**
** This routine is not threadsafe.  The caller must be holding a mutex
** to prevent multiple threads from entering at the same time.
*/
static int memsys5Init(void *NotUsed){
  int ii;
  int nByte = sqlite3GlobalConfig.nHeap;
  u8 *zByte = (u8 *)sqlite3GlobalConfig.pHeap;
  int nMinLog;                 /* Log of minimum allocation size in bytes*/
  int iOffset;
  int ii;            /* Loop counter */
  int nByte;         /* Number of bytes of memory available to this allocator */
  u8 *zByte;         /* Memory usable by this allocator */
  int nMinLog;       /* Log base 2 of minimum allocation size in bytes */
  int iOffset;       /* An offset into mem5.aCtrl[] */

  UNUSED_PARAMETER(NotUsed);

  /* For the purposes of this routine, disable the mutex */
  if( !zByte ){
    return SQLITE_ERROR;
  }
  mem5.mutex = 0;

  /* The size of a Mem5Link object must be a power of two.  Verify that
  ** this is case.
  */
  assert( (sizeof(Mem5Link)&(sizeof(Mem5Link)-1))==0 );

  nByte = sqlite3GlobalConfig.nHeap;
  zByte = (u8*)sqlite3GlobalConfig.pHeap;
  assert( zByte!=0 );  /* sqlite3_config() does not allow otherwise */

  nMinLog = memsys5Log(sqlite3GlobalConfig.mnReq);
  mem5.nAtom = (1<<nMinLog);
  while( (int)sizeof(Mem5Link)>mem5.nAtom ){
    mem5.nAtom = mem5.nAtom << 1;
  mem5.szAtom = (1<<nMinLog);
  while( (int)sizeof(Mem5Link)>mem5.szAtom ){
    mem5.szAtom = mem5.szAtom << 1;
  }

  mem5.nBlock = (nByte / (mem5.nAtom+sizeof(u8)));
  mem5.nBlock = (nByte / (mem5.szAtom+sizeof(u8)));
  mem5.zPool = zByte;
  mem5.aCtrl = (u8 *)&mem5.zPool[mem5.nBlock*mem5.nAtom];
  mem5.aCtrl = (u8 *)&mem5.zPool[mem5.nBlock*mem5.szAtom];

  for(ii=0; ii<=LOGMAX; ii++){
    mem5.aiFreelist[ii] = -1;
  }

  iOffset = 0;
  for(ii=LOGMAX; ii>=0; ii--){
    int nAlloc = (1<<ii);
    if( (iOffset+nAlloc)<=mem5.nBlock ){
      mem5.aCtrl[iOffset] = ii | CTRL_FREE;
      memsys5Link(iOffset, ii);
      iOffset += nAlloc;
    }
    assert((iOffset+nAlloc)>mem5.nBlock);
  }

  /* If a mutex is required for normal operation, allocate one */
  if( sqlite3GlobalConfig.bMemstat==0 ){
    mem5.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
  }

  return SQLITE_OK;
}

/*
** Deinitialize this module.
*/
static void memsys5Shutdown(void *NotUsed){
  UNUSED_PARAMETER(NotUsed);
  mem5.mutex = 0;
  return;
}

#ifdef SQLITE_TEST
/*
** Open the file indicated and write a log of all unfreed memory 
** allocations into that log.
*/
void sqlite3Memsys5Dump(const char *zFilename){
#ifdef SQLITE_DEBUG
  FILE *out;
  int i, j, n;
  int nMinLog;

  if( zFilename==0 || zFilename[0]==0 ){
    out = stdout;
  }else{
    out = fopen(zFilename, "w");
    if( out==0 ){
      fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
                      zFilename);
      return;
    }
  }
  memsys5Enter();
  nMinLog = memsys5Log(mem5.nAtom);
  nMinLog = memsys5Log(mem5.szAtom);
  for(i=0; i<=LOGMAX && i+nMinLog<32; i++){
    for(n=0, j=mem5.aiFreelist[i]; j>=0; j = MEM5LINK(j)->next, n++){}
    fprintf(out, "freelist items of size %d: %d\n", mem5.nAtom << i, n);
    fprintf(out, "freelist items of size %d: %d\n", mem5.szAtom << i, n);
  }
  fprintf(out, "mem5.nAlloc       = %llu\n", mem5.nAlloc);
  fprintf(out, "mem5.totalAlloc   = %llu\n", mem5.totalAlloc);
  fprintf(out, "mem5.totalExcess  = %llu\n", mem5.totalExcess);
  fprintf(out, "mem5.currentOut   = %u\n", mem5.currentOut);
  fprintf(out, "mem5.currentCount = %u\n", mem5.currentCount);
  fprintf(out, "mem5.maxOut       = %u\n", mem5.maxOut);
  fprintf(out, "mem5.maxCount     = %u\n", mem5.maxCount);
  fprintf(out, "mem5.maxRequest   = %u\n", mem5.maxRequest);
  memsys5Leave();
  if( out==stdout ){
    fflush(stdout);
  }else{
    fclose(out);
  }
#else
  UNUSED_PARAMETER(zFilename);
#endif
}
#endif

/*
** This routine is the only routine in this file with external 
** linkage. It returns a pointer to a static sqlite3_mem_methods
** struct populated with the memsys5 methods.
*/
const sqlite3_mem_methods *sqlite3MemGetMemsys5(void){
Changes to src/memjournal.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
9
10
11
12
13
14
15


16
17
18
19
20
21
22







-
-







**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code use to implement an in-memory rollback journal.
** The in-memory rollback journal is used to journal transactions for
** ":memory:" databases and when the journal_mode=MEMORY pragma is used.
**
** @(#) $Id: memjournal.c,v 1.12 2009/05/04 11:42:30 danielk1977 Exp $
*/
#include "sqliteInt.h"

/* Forward references to internal structures */
typedef struct MemJournal MemJournal;
typedef struct FilePoint FilePoint;
typedef struct FileChunk FileChunk;
Changes to src/mutex.c.
8
9
10
11
12
13
14


15
16
17





18


19

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42



43
44
45

46
47

48
49

50
51

52
53

54
55
56
57
58
59






60
61
62
63
64
65
66
67
68
69
70
71
72





73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

90
91
92
93
94
95
96
8
9
10
11
12
13
14
15
16
17


18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39






40



41
42
43



44


45


46


47


48






49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97







+
+

-
-
+
+
+
+
+

+
+
-
+













-
-
-
-
-
-

-
-
-
+
+
+
-
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
-
-
-
-
+
+
+
+
+
+













+
+
+
+
+

















+







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement mutexes.
**
** This file contains code that is common across all mutex implementations.
*/
#include "sqliteInt.h"

**
** $Id: mutex.c,v 1.30 2009/02/17 16:29:11 danielk1977 Exp $
#if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT)
/*
** For debugging purposes, record when the mutex subsystem is initialized
** and uninitialized so that we can assert() if there is an attempt to
** allocate a mutex while the system is uninitialized.
*/
static SQLITE_WSD int mutexIsInit = 0;
#endif /* SQLITE_DEBUG */
#include "sqliteInt.h"


#ifndef SQLITE_MUTEX_OMIT
/*
** Initialize the mutex system.
*/
int sqlite3MutexInit(void){ 
  int rc = SQLITE_OK;
  if( sqlite3GlobalConfig.bCoreMutex ){
    if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){
      /* If the xMutexAlloc method has not been set, then the user did not
      ** install a mutex implementation via sqlite3_config() prior to 
      ** sqlite3_initialize() being called. This block copies pointers to
      ** the default implementation into the sqlite3GlobalConfig structure.
      **
      ** The danger is that although sqlite3_config() is not a threadsafe
      ** API, sqlite3_initialize() is, and so multiple threads may be
      ** attempting to run this function simultaneously. To guard write
      ** access to the sqlite3GlobalConfig structure, the 'MASTER' static mutex
      ** is obtained before modifying it.
      */
      sqlite3_mutex_methods *p = sqlite3DefaultMutex();
      sqlite3_mutex *pMaster = 0;
  
      sqlite3_mutex_methods *pFrom = sqlite3DefaultMutex();
      sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex;

      rc = p->xMutexInit();
      if( rc==SQLITE_OK ){
        pMaster = p->xMutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
      memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc));
        assert(pMaster);
        p->xMutexEnter(pMaster);
      memcpy(&pTo->xMutexFree, &pFrom->xMutexFree,
        assert( sqlite3GlobalConfig.mutex.xMutexAlloc==0 
             || sqlite3GlobalConfig.mutex.xMutexAlloc==p->xMutexAlloc
             sizeof(*pTo) - offsetof(sqlite3_mutex_methods, xMutexFree));
        );
        if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){
      pTo->xMutexAlloc = pFrom->xMutexAlloc;
          sqlite3GlobalConfig.mutex = *p;
        }
    }
        p->xMutexLeave(pMaster);
      }
    }else{
      rc = sqlite3GlobalConfig.mutex.xMutexInit();
    }
  }
    rc = sqlite3GlobalConfig.mutex.xMutexInit();
  }

#ifdef SQLITE_DEBUG
  GLOBAL(int, mutexIsInit) = 1;
#endif

  return rc;
}

/*
** Shutdown the mutex system. This call frees resources allocated by
** sqlite3MutexInit().
*/
int sqlite3MutexEnd(void){
  int rc = SQLITE_OK;
  if( sqlite3GlobalConfig.mutex.xMutexEnd ){
    rc = sqlite3GlobalConfig.mutex.xMutexEnd();
  }

#ifdef SQLITE_DEBUG
  GLOBAL(int, mutexIsInit) = 0;
#endif

  return rc;
}

/*
** Retrieve a pointer to a static mutex or allocate a new dynamic one.
*/
sqlite3_mutex *sqlite3_mutex_alloc(int id){
#ifndef SQLITE_OMIT_AUTOINIT
  if( sqlite3_initialize() ) return 0;
#endif
  return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
}

sqlite3_mutex *sqlite3MutexAlloc(int id){
  if( !sqlite3GlobalConfig.bCoreMutex ){
    return 0;
  }
  assert( GLOBAL(int, mutexIsInit) );
  return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
}

/*
** Free a dynamic mutex.
*/
void sqlite3_mutex_free(sqlite3_mutex *p){
142
143
144
145
146
147
148
149

143
144
145
146
147
148
149

150







-
+
  return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
}
int sqlite3_mutex_notheld(sqlite3_mutex *p){
  return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
}
#endif

#endif /* SQLITE_OMIT_MUTEX */
#endif /* SQLITE_MUTEX_OMIT */
Changes to src/mutex.h.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
14
15
16
17
18
19
20


21
22
23
24
25
26
27







-
-







** The sqliteInt.h header #includes this file so that it is available
** to all source files.  We break it out in an effort to keep the code
** better organized.
**
** NOTE:  source files should *not* #include this header file directly.
** Source files should #include the sqliteInt.h file and let that file
** include this one indirectly.
**
** $Id: mutex.h,v 1.9 2008/10/07 15:25:48 drh Exp $
*/


/*
** Figure out what version of the code to use.  The choices are
**
**   SQLITE_MUTEX_OMIT         No mutex logic.  Not even stubs.  The
66
67
68
69
70
71
72
73

64
65
66
67
68
69
70

71







-
+
#define sqlite3_mutex_try(X)      SQLITE_OK
#define sqlite3_mutex_leave(X)
#define sqlite3_mutex_held(X)     1
#define sqlite3_mutex_notheld(X)  1
#define sqlite3MutexAlloc(X)      ((sqlite3_mutex*)8)
#define sqlite3MutexInit()        SQLITE_OK
#define sqlite3MutexEnd()
#endif /* defined(SQLITE_OMIT_MUTEX) */
#endif /* defined(SQLITE_MUTEX_OMIT) */
Changes to src/mutex_noop.c.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
20
21
22
23
24
25
26


27
28
29
30
31
32
33







-
-







**     sqlite3_config(SQLITE_CONFIG_MUTEX,...)
**
** interface.
**
** If compiled with SQLITE_DEBUG, then additional logic is inserted
** that does error checking on mutexes to make sure they are being
** called correctly.
**
** $Id: mutex_noop.c,v 1.3 2008/12/05 17:17:08 drh Exp $
*/
#include "sqliteInt.h"


#if defined(SQLITE_MUTEX_NOOP) && !defined(SQLITE_DEBUG)
/*
** Stub routines for all mutex methods.
Changes to src/mutex_os2.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19












-
-







/*
** 2007 August 28
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement mutexes for OS/2
**
** $Id: mutex_os2.c,v 1.11 2008/11/22 19:50:54 pweilbacher Exp $
*/
#include "sqliteInt.h"

/*
** The code in this file is only used if SQLITE_MUTEX_OS2 is defined.
** See the mutex.h file for details.
*/
Changes to src/mutex_unix.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19












-
-







/*
** 2007 August 28
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement mutexes for pthreads
**
** $Id: mutex_unix.c,v 1.16 2008/12/08 18:19:18 drh Exp $
*/
#include "sqliteInt.h"

/*
** The code in this file is only used if we are compiling threadsafe
** under unix with pthreads.
**
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113







+













-
+







** <li>  SQLITE_MUTEX_FAST
** <li>  SQLITE_MUTEX_RECURSIVE
** <li>  SQLITE_MUTEX_STATIC_MASTER
** <li>  SQLITE_MUTEX_STATIC_MEM
** <li>  SQLITE_MUTEX_STATIC_MEM2
** <li>  SQLITE_MUTEX_STATIC_PRNG
** <li>  SQLITE_MUTEX_STATIC_LRU
** <li>  SQLITE_MUTEX_STATIC_LRU2
** </ul>
**
** The first two constants cause sqlite3_mutex_alloc() to create
** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
** The mutex implementation does not need to make a distinction
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
** not want to.  But SQLite will only request a recursive mutex in
** cases where it really needs one.  If a faster non-recursive mutex
** implementation is available on the host platform, the mutex subsystem
** might return such a mutex in response to SQLITE_MUTEX_FAST.
**
** The other allowed parameters to sqlite3_mutex_alloc() each return
** a pointer to a static preexisting mutex.  Three static mutexes are
** a pointer to a static preexisting mutex.  Six static mutexes are
** used by the current version of SQLite.  Future versions of SQLite
** may add additional static mutexes.  Static mutexes are for internal
** use by SQLite only.  Applications that use SQLite mutexes should
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
** SQLITE_MUTEX_RECURSIVE.
**
** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
Changes to src/mutex_w32.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19












-
-







/*
** 2007 August 14
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement mutexes for win32
**
** $Id: mutex_w32.c,v 1.17 2009/06/01 17:10:22 shane Exp $
*/
#include "sqliteInt.h"

/*
** The code in this file is only used if we are compiling multithreaded
** on a win32 system.
*/
89
90
91
92
93
94
95
96

97
98

99
100
101
102

103
104
105
106
107
108
109
110
111
112
113

114
115
116

117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137








138
139
140
141
142
143
144
145
146
147
148
149
150
151

152
153
154
155
156
157
158
87
88
89
90
91
92
93

94
95

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

112
113
114

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131





132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

153
154
155
156
157
158
159
160







-
+

-
+




+










-
+


-
+
















-
-
-
-
-
+
+
+
+
+
+
+
+













-
+







** processing, the "interlocked" magic is probably not
** strictly necessary.
*/
static long winMutex_lock = 0;

static int winMutexInit(void){ 
  /* The first to increment to 1 does actual initialization */
  if( InterlockedIncrement(&winMutex_lock)==1 ){
  if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
    int i;
    for(i=0; i<sizeof(winMutex_staticMutexes)/sizeof(winMutex_staticMutexes[0]); i++){
    for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
      InitializeCriticalSection(&winMutex_staticMutexes[i].mutex);
    }
    winMutex_isInit = 1;
  }else{
    /* Someone else is in the process of initing the static mutexes */
    while( !winMutex_isInit ){
      Sleep(1);
    }
  }
  return SQLITE_OK; 
}

static int winMutexEnd(void){ 
  /* The first to decrement to 0 does actual shutdown 
  ** (which should be the last to shutdown.) */
  if( InterlockedDecrement(&winMutex_lock)==0 ){
  if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){
    if( winMutex_isInit==1 ){
      int i;
      for(i=0; i<sizeof(winMutex_staticMutexes)/sizeof(winMutex_staticMutexes[0]); i++){
      for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
        DeleteCriticalSection(&winMutex_staticMutexes[i].mutex);
      }
      winMutex_isInit = 0;
    }
  }
  return SQLITE_OK; 
}

/*
** The sqlite3_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it.  If it returns NULL
** that means that a mutex could not be allocated.  SQLite
** will unwind its stack and return an error.  The argument
** to sqlite3_mutex_alloc() is one of these integer constants:
**
** <ul>
** <li>  SQLITE_MUTEX_FAST               0
** <li>  SQLITE_MUTEX_RECURSIVE          1
** <li>  SQLITE_MUTEX_STATIC_MASTER      2
** <li>  SQLITE_MUTEX_STATIC_MEM         3
** <li>  SQLITE_MUTEX_STATIC_PRNG        4
** <li>  SQLITE_MUTEX_FAST
** <li>  SQLITE_MUTEX_RECURSIVE
** <li>  SQLITE_MUTEX_STATIC_MASTER
** <li>  SQLITE_MUTEX_STATIC_MEM
** <li>  SQLITE_MUTEX_STATIC_MEM2
** <li>  SQLITE_MUTEX_STATIC_PRNG
** <li>  SQLITE_MUTEX_STATIC_LRU
** <li>  SQLITE_MUTEX_STATIC_LRU2
** </ul>
**
** The first two constants cause sqlite3_mutex_alloc() to create
** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
** The mutex implementation does not need to make a distinction
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
** not want to.  But SQLite will only request a recursive mutex in
** cases where it really needs one.  If a faster non-recursive mutex
** implementation is available on the host platform, the mutex subsystem
** might return such a mutex in response to SQLITE_MUTEX_FAST.
**
** The other allowed parameters to sqlite3_mutex_alloc() each return
** a pointer to a static preexisting mutex.  Three static mutexes are
** a pointer to a static preexisting mutex.  Six static mutexes are
** used by the current version of SQLite.  Future versions of SQLite
** may add additional static mutexes.  Static mutexes are for internal
** use by SQLite only.  Applications that use SQLite mutexes should
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
** SQLITE_MUTEX_RECURSIVE.
**
** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189







-
+







        InitializeCriticalSection(&p->mutex);
      }
      break;
    }
    default: {
      assert( winMutex_isInit==1 );
      assert( iType-2 >= 0 );
      assert( iType-2 < sizeof(winMutex_staticMutexes)/sizeof(winMutex_staticMutexes[0]) );
      assert( iType-2 < ArraySize(winMutex_staticMutexes) );
      p = &winMutex_staticMutexes[iType-2];
      p->id = iType;
      break;
    }
  }
  return p;
}
Changes to src/notify.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
8
9
10
11
12
13
14


15
16
17
18
19
20
21







-
-







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains the implementation of the sqlite3_unlock_notify()
** API method and its associated functionality.
**
** $Id: notify.c,v 1.4 2009/04/07 22:06:57 drh Exp $
*/
#include "sqliteInt.h"
#include "btreeInt.h"

/* Omit this entire file if SQLITE_ENABLE_UNLOCK_NOTIFY is not defined. */
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY

Changes to src/os.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
8
9
10
11
12
13
14


15
16
17
18
19
20
21







-
-







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains OS interface code that is common to all
** architectures.
**
** $Id: os.c,v 1.126 2009/03/25 14:24:42 drh Exp $
*/
#define _SQLITE_OS_C_ 1
#include "sqliteInt.h"
#undef _SQLITE_OS_C_

/*
** The default SQLite sqlite3_vfs implementations do not allocate
33
34
35
36
37
38
39
40
41
42
43




44
45
46

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

65
66
67
68

69
70
71
72
73
74
75

76
77
78
79

80
81
82
83

84
85
86
87
88
89
90

91
92
93
94
95
96
97
31
32
33
34
35
36
37




38
39
40
41
42
43

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

62
63
64
65

66
67
68
69
70
71
72

73
74
75
76

77
78
79
80

81
82
83
84
85
86
87

88
89
90
91
92
93
94
95







-
-
-
-
+
+
+
+


-
+

















-
+



-
+






-
+



-
+



-
+






-
+







**     sqlite3OsRead()
**     sqlite3OsWrite()
**     sqlite3OsSync()
**     sqlite3OsLock()
**
*/
#if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0)
  #define DO_OS_MALLOC_TEST if (1) {            \
    void *pTstAlloc = sqlite3Malloc(10);       \
    if (!pTstAlloc) return SQLITE_IOERR_NOMEM;  \
    sqlite3_free(pTstAlloc);                    \
  #define DO_OS_MALLOC_TEST(x) if (!x || !sqlite3IsMemJournal(x)) {     \
    void *pTstAlloc = sqlite3Malloc(10);                             \
    if (!pTstAlloc) return SQLITE_IOERR_NOMEM;                       \
    sqlite3_free(pTstAlloc);                                         \
  }
#else
  #define DO_OS_MALLOC_TEST
  #define DO_OS_MALLOC_TEST(x)
#endif

/*
** The following routines are convenience wrappers around methods
** of the sqlite3_file object.  This is mostly just syntactic sugar. All
** of this would be completely automatic if SQLite were coded using
** C++ instead of plain old C.
*/
int sqlite3OsClose(sqlite3_file *pId){
  int rc = SQLITE_OK;
  if( pId->pMethods ){
    rc = pId->pMethods->xClose(pId);
    pId->pMethods = 0;
  }
  return rc;
}
int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
  DO_OS_MALLOC_TEST;
  DO_OS_MALLOC_TEST(id);
  return id->pMethods->xRead(id, pBuf, amt, offset);
}
int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
  DO_OS_MALLOC_TEST;
  DO_OS_MALLOC_TEST(id);
  return id->pMethods->xWrite(id, pBuf, amt, offset);
}
int sqlite3OsTruncate(sqlite3_file *id, i64 size){
  return id->pMethods->xTruncate(id, size);
}
int sqlite3OsSync(sqlite3_file *id, int flags){
  DO_OS_MALLOC_TEST;
  DO_OS_MALLOC_TEST(id);
  return id->pMethods->xSync(id, flags);
}
int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
  DO_OS_MALLOC_TEST;
  DO_OS_MALLOC_TEST(id);
  return id->pMethods->xFileSize(id, pSize);
}
int sqlite3OsLock(sqlite3_file *id, int lockType){
  DO_OS_MALLOC_TEST;
  DO_OS_MALLOC_TEST(id);
  return id->pMethods->xLock(id, lockType);
}
int sqlite3OsUnlock(sqlite3_file *id, int lockType){
  return id->pMethods->xUnlock(id, lockType);
}
int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
  DO_OS_MALLOC_TEST;
  DO_OS_MALLOC_TEST(id);
  return id->pMethods->xCheckReservedLock(id, pResOut);
}
int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
  return id->pMethods->xFileControl(id, op, pArg);
}
int sqlite3OsSectorSize(sqlite3_file *id){
  int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
109
110
111
112
113
114
115
116
117






118
119
120
121
122
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
107
108
109
110
111
112
113


114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139







-
-
+
+
+
+
+
+












-
+







  sqlite3_vfs *pVfs, 
  const char *zPath, 
  sqlite3_file *pFile, 
  int flags, 
  int *pFlagsOut
){
  int rc;
  DO_OS_MALLOC_TEST;
  rc = pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut);
  DO_OS_MALLOC_TEST(0);
  /* 0x7f1f is a mask of SQLITE_OPEN_ flags that are valid to be passed
  ** down into the VFS layer.  Some SQLITE_OPEN_ flags (for example,
  ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
  ** reaching the VFS. */
  rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x7f1f, pFlagsOut);
  assert( rc==SQLITE_OK || pFile->pMethods==0 );
  return rc;
}
int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
  return pVfs->xDelete(pVfs, zPath, dirSync);
}
int sqlite3OsAccess(
  sqlite3_vfs *pVfs, 
  const char *zPath, 
  int flags, 
  int *pResOut
){
  DO_OS_MALLOC_TEST;
  DO_OS_MALLOC_TEST(0);
  return pVfs->xAccess(pVfs, zPath, flags, pResOut);
}
int sqlite3OsFullPathname(
  sqlite3_vfs *pVfs, 
  const char *zPath, 
  int nPathOut, 
  char *zPathOut
185
186
187
188
189
190
191













192
193
194
195
196
197
198
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213







+
+
+
+
+
+
+
+
+
+
+
+
+







int sqlite3OsCloseFree(sqlite3_file *pFile){
  int rc = SQLITE_OK;
  assert( pFile );
  rc = sqlite3OsClose(pFile);
  sqlite3_free(pFile);
  return rc;
}

/*
** This function is a wrapper around the OS specific implementation of
** sqlite3_os_init(). The purpose of the wrapper is to provide the
** ability to simulate a malloc failure, so that the handling of an
** error in sqlite3_os_init() by the upper layers can be tested.
*/
int sqlite3OsInit(void){
  void *p = sqlite3_malloc(10);
  if( p==0 ) return SQLITE_NOMEM;
  sqlite3_free(p);
  return sqlite3_os_init();
}

/*
** The list of all registered VFS implementations.
*/
static sqlite3_vfs * SQLITE_WSD vfsList = 0;
#define vfsList GLOBAL(sqlite3_vfs *, vfsList)

Changes to src/os.h.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
12
13
14
15
16
17
18


19
20
21
22
23
24
25







-
-







**
** This header file (together with is companion C source-code file
** "os.c") attempt to abstract the underlying operating system so that
** the SQLite library will work on both POSIX and windows systems.
**
** This header file is #include-ed by sqliteInt.h and thus ends up
** being included by every source file.
**
** $Id: os.h,v 1.108 2009/02/05 16:31:46 drh Exp $
*/
#ifndef _SQLITE_OS_H_
#define _SQLITE_OS_H_

/*
** Figure out if we are dealing with Unix, Windows, or some other
** operating system.  After the following block of preprocess macros,
220
221
222
223
224
225
226





227
228
229
230
231
232
233
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236







+
+
+
+
+







**
*/
#define PENDING_BYTE      sqlite3PendingByte
#define RESERVED_BYTE     (PENDING_BYTE+1)
#define SHARED_FIRST      (PENDING_BYTE+2)
#define SHARED_SIZE       510

/*
** Wrapper around OS specific sqlite3_os_init() function.
*/
int sqlite3OsInit(void);

/* 
** Functions for accessing sqlite3_file methods 
*/
int sqlite3OsClose(sqlite3_file*);
int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset);
int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset);
int sqlite3OsTruncate(sqlite3_file*, i64 size);
Changes to src/os_common.h.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
12
13
14
15
16
17
18


19
20
21
22
23
24
25







-
-







**
** This file contains macros and a little bit of code that is common to
** all of the platform-specific files (os_*.c) and is #included into those
** files.
**
** This file should be #included by the os_*.c files only.  It is not a
** general purpose header file.
**
** $Id: os_common.h,v 1.38 2009/02/24 18:40:50 danielk1977 Exp $
*/
#ifndef _OS_COMMON_H_
#define _OS_COMMON_H_

/*
** At least two bugs have slipped in because we changed the MEMORY_DEBUG
** macro to SQLITE_DEBUG and some older makefiles have not yet made the
Changes to src/os_os2.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2006 Feb 14
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains code that is specific to OS/2.
**
** $Id: os_os2.c,v 1.63 2008/12/10 19:26:24 drh Exp $
*/

#include "sqliteInt.h"

#if SQLITE_OS_OS2

/*
Changes to src/os_unix.c.
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
38
39
40
41
42
43
44


45
46
47
48
49
50
51







-
-







**   *  sqlite3_file methods not associated with locking.
**   *  Definitions of sqlite3_io_methods objects for all locking
**      methods plus "finder" functions for each locking method.
**   *  sqlite3_vfs method implementations.
**   *  Locking primitives for the proxy uber-locking-method. (MacOSX only)
**   *  Definitions of sqlite3_vfs objects for all locking methods
**      plus implementations of sqlite3_os_init() and sqlite3_os_end().
**
** $Id: os_unix.c,v 1.253 2009/06/17 13:09:39 drh Exp $
*/
#include "sqliteInt.h"
#if SQLITE_OS_UNIX              /* This file is used on unix only */

/*
** There are various methods for file locking used for concurrency
** control:
165
166
167
168
169
170
171













172
173
174
175
176
177
178
179
180
181
182
183
184
185


186
187
188
189
190
191
192
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205







+
+
+
+
+
+
+
+
+
+
+
+
+














+
+







/*
** Only set the lastErrno if the error code is a real error and not 
** a normal expected return code of SQLITE_BUSY or SQLITE_OK
*/
#define IS_LOCK_ERROR(x)  ((x != SQLITE_OK) && (x != SQLITE_BUSY))


/*
** Sometimes, after a file handle is closed by SQLite, the file descriptor
** cannot be closed immediately. In these cases, instances of the following
** structure are used to store the file descriptor while waiting for an
** opportunity to either close or reuse it.
*/
typedef struct UnixUnusedFd UnixUnusedFd;
struct UnixUnusedFd {
  int fd;                   /* File descriptor to close */
  int flags;                /* Flags this file descriptor was opened with */
  UnixUnusedFd *pNext;      /* Next unused file descriptor on same file */
};

/*
** The unixFile structure is subclass of sqlite3_file specific to the unix
** VFS implementations.
*/
typedef struct unixFile unixFile;
struct unixFile {
  sqlite3_io_methods const *pMethod;  /* Always the first entry */
  struct unixOpenCnt *pOpen;       /* Info about all open fd's on this inode */
  struct unixLockInfo *pLock;      /* Info about locks on this inode */
  int h;                           /* The file descriptor */
  int dirfd;                       /* File descriptor for the directory */
  unsigned char locktype;          /* The type of lock held on this fd */
  int lastErrno;                   /* The unix errno from the last I/O error */
  void *lockingContext;            /* Locking style specific state */
  UnixUnusedFd *pUnused;           /* Pre-allocated UnixUnusedFd */
  int fileFlags;                   /* Miscellanous flags */
#if SQLITE_ENABLE_LOCKING_STYLE
  int openFlags;                   /* The flags specified at open() */
#endif
#if SQLITE_THREADSAFE && defined(__linux__)
  pthread_t tid;                   /* The thread that "owns" this unixFile */
#endif
#if OS_VXWORKS
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220





221
222
223
224
225
226
227
213
214
215
216
217
218
219





220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240







-
-
-
-
-









+
+
+
+
+







  ** occur if a file is updated without also updating the transaction
  ** counter.  This test is made to avoid new problems similar to the
  ** one described by ticket #3584. 
  */
  unsigned char transCntrChng;   /* True if the transaction counter changed */
  unsigned char dbUpdate;        /* True if any part of database file changed */
  unsigned char inNormalWrite;   /* True if in a normal write operation */

  /* If true, that means we are dealing with a database file that has
  ** a range of locking bytes from PENDING_BYTE through PENDING_BYTE+511
  ** which should never be read or written.  Asserts() will verify this */
  unsigned char isLockable;      /* True if file might be locked */
#endif
#ifdef SQLITE_TEST
  /* In test mode, increase the size of this structure a bit so that 
  ** it is larger than the struct CrashFile defined in test6.c.
  */
  char aPadding[32];
#endif
};

/*
** The following macros define bits in unixFile.fileFlags
*/
#define SQLITE_WHOLE_FILE_LOCKING  0x0001   /* Use whole-file locking */

/*
** Include code that is common to all os_*.c files
*/
#include "os_common.h"

/*
** Define various macros that are missing from some systems.
258
259
260
261
262
263
264
265












266
267
268
269
270
271
272





273
274
275
276
277
278
279
280
281
282
283
284
285
286
287





288
289
290
291
292
293
294
271
272
273
274
275
276
277

278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311





312
313
314
315
316
317
318
319
320
321
322
323







-
+
+
+
+
+
+
+
+
+
+
+
+







+
+
+
+
+










-
-
-
-
-
+
+
+
+
+







#define threadid pthread_self()
#else
#define threadid 0
#endif


/*
** Helper functions to obtain and relinquish the global mutex.
** Helper functions to obtain and relinquish the global mutex. The
** global mutex is used to protect the unixOpenCnt, unixLockInfo and
** vxworksFileId objects used by this file, all of which may be 
** shared by multiple threads.
**
** Function unixMutexHeld() is used to assert() that the global mutex 
** is held when required. This function is only used as part of assert() 
** statements. e.g.
**
**   unixEnterMutex()
**     assert( unixMutexHeld() );
**   unixEnterLeave()
*/
static void unixEnterMutex(void){
  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
}
static void unixLeaveMutex(void){
  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
}
#ifdef SQLITE_DEBUG
static int unixMutexHeld(void) {
  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
}
#endif


#ifdef SQLITE_DEBUG
/*
** Helper function for printing out trace information from debugging
** binaries. This returns the string represetation of the supplied
** integer lock-type.
*/
static const char *locktypeName(int locktype){
  switch( locktype ){
  case NO_LOCK: return "NONE";
  case SHARED_LOCK: return "SHARED";
  case RESERVED_LOCK: return "RESERVED";
  case PENDING_LOCK: return "PENDING";
  case EXCLUSIVE_LOCK: return "EXCLUSIVE";
    case NO_LOCK: return "NONE";
    case SHARED_LOCK: return "SHARED";
    case RESERVED_LOCK: return "RESERVED";
    case PENDING_LOCK: return "PENDING";
    case EXCLUSIVE_LOCK: return "EXCLUSIVE";
  }
  return "ERROR";
}
#endif

#ifdef SQLITE_LOCK_TRACE
/*
734
735
736
737
738
739
740
741

742
743
744
745

746
747
748
749
750
751
752
763
764
765
766
767
768
769

770

771
772

773
774
775
776
777
778
779
780







-
+
-


-
+







** The close() system call would only occur when the last database
** using the file closes.
*/
struct unixOpenCnt {
  struct unixFileId fileId;   /* The lookup key */
  int nRef;                   /* Number of pointers to this structure */
  int nLock;                  /* Number of outstanding locks */
  int nPending;               /* Number of pending close() operations */
  UnixUnusedFd *pUnused;      /* Unused file descriptors to close */
  int *aPending;            /* Malloced space holding fd's awaiting a close() */
#if OS_VXWORKS
  sem_t *pSem;                     /* Named POSIX semaphore */
  char aSemName[MAX_PATHNAME+1];   /* Name of that semaphore */
  char aSemName[MAX_PATHNAME+2];   /* Name of that semaphore */
#endif
  struct unixOpenCnt *pNext, *pPrev;   /* List of all unixOpenCnt objects */
};

/*
** Lists of all unixLockInfo and unixOpenCnt objects.  These used to be hash
** tables.  But the number of objects is rarely more than a dozen and
835
836
837
838
839
840
841
842
843



844
845
846
847
848

849
850
851



852
853

854
855
856
857
858
859
860
863
864
865
866
867
868
869


870
871
872
873
874
875
876

877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893







-
-
+
+
+




-
+



+
+
+


+







  l.l_whence = SEEK_SET;
  rc = fcntl(fd_orig, F_SETLK, &l);
  if( rc!=0 ) return;
  memset(&d, 0, sizeof(d));
  d.fd = fd;
  d.lock = l;
  d.lock.l_type = F_WRLCK;
  pthread_create(&t, 0, threadLockingTest, &d);
  pthread_join(t, 0);
  if( pthread_create(&t, 0, threadLockingTest, &d)==0 ){
    pthread_join(t, 0);
  }
  close(fd);
  if( d.result!=0 ) return;
  threadsOverrideEachOthersLocks = (d.lock.l_type==F_UNLCK);
}
#endif /* SQLITE_THERADSAFE && defined(__linux__) */
#endif /* SQLITE_THREADSAFE && defined(__linux__) */

/*
** Release a unixLockInfo structure previously allocated by findLockInfo().
**
** The mutex entered using the unixEnterMutex() function must be held
** when this function is called.
*/
static void releaseLockInfo(struct unixLockInfo *pLock){
  assert( unixMutexHeld() );
  if( pLock ){
    pLock->nRef--;
    if( pLock->nRef==0 ){
      if( pLock->pPrev ){
        assert( pLock->pPrev->pNext==pLock );
        pLock->pPrev->pNext = pLock->pNext;
      }else{
868
869
870
871
872
873
874



875
876

877
878
879
880
881
882
883
884
885
886
887
888
889
890



891








892
893
894
895
896
897
898
899
900



901
902
903
904
905
906
907
908
909
910
911
912
913
914
915


916
917
918
919
920
921
922
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930

931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974







+
+
+


+














+
+
+
-
+
+
+
+
+
+
+
+









+
+
+















+
+







      sqlite3_free(pLock);
    }
  }
}

/*
** Release a unixOpenCnt structure previously allocated by findLockInfo().
**
** The mutex entered using the unixEnterMutex() function must be held
** when this function is called.
*/
static void releaseOpenCnt(struct unixOpenCnt *pOpen){
  assert( unixMutexHeld() );
  if( pOpen ){
    pOpen->nRef--;
    if( pOpen->nRef==0 ){
      if( pOpen->pPrev ){
        assert( pOpen->pPrev->pNext==pOpen );
        pOpen->pPrev->pNext = pOpen->pNext;
      }else{
        assert( openList==pOpen );
        openList = pOpen->pNext;
      }
      if( pOpen->pNext ){
        assert( pOpen->pNext->pPrev==pOpen );
        pOpen->pNext->pPrev = pOpen->pPrev;
      }
#if SQLITE_THREADSAFE && defined(__linux__)
      assert( !pOpen->pUnused || threadsOverrideEachOthersLocks==0 );
#endif
      sqlite3_free(pOpen->aPending);

      /* If pOpen->pUnused is not null, then memory and file-descriptors
      ** are leaked.
      **
      ** This will only happen if, under Linuxthreads, the user has opened
      ** a transaction in one thread, then attempts to close the database
      ** handle from another thread (without first unlocking the db file).
      ** This is a misuse.  */
      sqlite3_free(pOpen);
    }
  }
}

/*
** Given a file descriptor, locate unixLockInfo and unixOpenCnt structures that
** describes that file descriptor.  Create new ones if necessary.  The
** return values might be uninitialized if an error occurs.
**
** The mutex entered using the unixEnterMutex() function must be held
** when this function is called.
**
** Return an appropriate error code.
*/
static int findLockInfo(
  unixFile *pFile,               /* Unix file with file desc used in the key */
  struct unixLockInfo **ppLock,  /* Return the unixLockInfo structure here */
  struct unixOpenCnt **ppOpen    /* Return the unixOpenCnt structure here */
){
  int rc;                        /* System call return code */
  int fd;                        /* The file descriptor for pFile */
  struct unixLockKey lockKey;    /* Lookup key for the unixLockInfo structure */
  struct unixFileId fileId;      /* Lookup key for the unixOpenCnt struct */
  struct stat statbuf;           /* Low-level file information */
  struct unixLockInfo *pLock = 0;/* Candidate unixLockInfo object */
  struct unixOpenCnt *pOpen;     /* Candidate unixOpenCnt object */

  assert( unixMutexHeld() );

  /* Get low-level information about the file that we can used to
  ** create a unique name for the file.
  */
  fd = pFile->h;
  rc = fstat(fd, &statbuf);
  if( rc!=0 ){
972
973
974
975
976
977
978
979

980
981
982
983
984
985
986
1024
1025
1026
1027
1028
1029
1030

1031
1032
1033
1034
1035
1036
1037
1038







-
+







    }
    if( pLock==0 ){
      pLock = sqlite3_malloc( sizeof(*pLock) );
      if( pLock==0 ){
        rc = SQLITE_NOMEM;
        goto exit_findlockinfo;
      }
      pLock->lockKey = lockKey;
      memcpy(&pLock->lockKey,&lockKey,sizeof(lockKey));
      pLock->nRef = 1;
      pLock->cnt = 0;
      pLock->locktype = 0;
      pLock->pNext = lockList;
      pLock->pPrev = 0;
      if( lockList ) lockList->pPrev = pLock;
      lockList = pLock;
997
998
999
1000
1001
1002
1003

1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058



1059

1060
1061




1062
1063
1064
1065
1066
1067
1068







+


-
-
-

-


-
-
-
-







    if( pOpen==0 ){
      pOpen = sqlite3_malloc( sizeof(*pOpen) );
      if( pOpen==0 ){
        releaseLockInfo(pLock);
        rc = SQLITE_NOMEM;
        goto exit_findlockinfo;
      }
      memset(pOpen, 0, sizeof(*pOpen));
      pOpen->fileId = fileId;
      pOpen->nRef = 1;
      pOpen->nLock = 0;
      pOpen->nPending = 0;
      pOpen->aPending = 0;
      pOpen->pNext = openList;
      pOpen->pPrev = 0;
      if( openList ) openList->pPrev = pOpen;
      openList = pOpen;
#if OS_VXWORKS
      pOpen->pSem = NULL;
      pOpen->aSemName[0] = '\0';
#endif
    }else{
      pOpen->nRef++;
    }
    *ppOpen = pOpen;
  }

exit_findlockinfo:
1115
1116
1117
1118
1119
1120
1121
























































1122
1123
1124
1125
1126
1127
1128
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







  
  unixLeaveMutex();
  OSTRACE4("TEST WR-LOCK %d %d %d\n", pFile->h, rc, reserved);

  *pResOut = reserved;
  return rc;
}

/*
** Perform a file locking operation on a range of bytes in a file.
** The "op" parameter should be one of F_RDLCK, F_WRLCK, or F_UNLCK.
** Return 0 on success or -1 for failure.  On failure, write the error
** code into *pErrcode.
**
** If the SQLITE_WHOLE_FILE_LOCKING bit is clear, then only lock
** the range of bytes on the locking page between SHARED_FIRST and
** SHARED_SIZE.  If SQLITE_WHOLE_FILE_LOCKING is set, then lock all
** bytes from 0 up to but not including PENDING_BYTE, and all bytes
** that follow SHARED_FIRST.
**
** In other words, of SQLITE_WHOLE_FILE_LOCKING if false (the historical
** default case) then only lock a small range of bytes from SHARED_FIRST
** through SHARED_FIRST+SHARED_SIZE-1.  But if SQLITE_WHOLE_FILE_LOCKING is
** true then lock every byte in the file except for PENDING_BYTE and
** RESERVED_BYTE.
**
** SQLITE_WHOLE_FILE_LOCKING=true overlaps SQLITE_WHOLE_FILE_LOCKING=false
** and so the locking schemes are compatible.  One type of lock will
** effectively exclude the other type.  The reason for using the
** SQLITE_WHOLE_FILE_LOCKING=true is that by indicating the full range
** of bytes to be read or written, we give hints to NFS to help it
** maintain cache coherency.  On the other hand, whole file locking
** is slower, so we don't want to use it except for NFS.
*/
static int rangeLock(unixFile *pFile, int op, int *pErrcode){
  struct flock lock;
  int rc;
  lock.l_type = op;
  lock.l_start = SHARED_FIRST;
  lock.l_whence = SEEK_SET;
  if( (pFile->fileFlags & SQLITE_WHOLE_FILE_LOCKING)==0 ){
    lock.l_len = SHARED_SIZE;
    rc = fcntl(pFile->h, F_SETLK, &lock);
    *pErrcode = errno;
  }else{
    lock.l_len = 0;
    rc = fcntl(pFile->h, F_SETLK, &lock);
    *pErrcode = errno;
    if( NEVER(op==F_UNLCK) || rc!=(-1) ){
      lock.l_start = 0;
      lock.l_len = PENDING_BYTE;
      rc = fcntl(pFile->h, F_SETLK, &lock);
      if( ALWAYS(op!=F_UNLCK) && rc==(-1) ){
        *pErrcode = errno;
        lock.l_type = F_UNLCK;
        lock.l_start = SHARED_FIRST;
        lock.l_len = 0;
        fcntl(pFile->h, F_SETLK, &lock);
      }
    }
  }
  return rc;
}

/*
** Lock the file with the lock specified by parameter locktype - one
** of the following:
**
**     (1) SHARED_LOCK
**     (2) RESERVED_LOCK
1183
1184
1185
1186
1187
1188
1189
1190


1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207




1208
1209
1210
1211
1212
1213
1214
1284
1285
1286
1287
1288
1289
1290

1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308

1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319







-
+
+
















-
+
+
+
+







  ** locking a random byte from a range, concurrent SHARED locks may exist
  ** even if the locking primitive used is always a write-lock.
  */
  int rc = SQLITE_OK;
  unixFile *pFile = (unixFile*)id;
  struct unixLockInfo *pLock = pFile->pLock;
  struct flock lock;
  int s;
  int s = 0;
  int tErrno;

  assert( pFile );
  OSTRACE7("LOCK    %d %s was %s(%s,%d) pid=%d\n", pFile->h,
      locktypeName(locktype), locktypeName(pFile->locktype),
      locktypeName(pLock->locktype), pLock->cnt , getpid());

  /* If there is already a lock of this type or more restrictive on the
  ** unixFile, do nothing. Don't use the end_lock: exit path, as
  ** unixEnterMutex() hasn't been called yet.
  */
  if( pFile->locktype>=locktype ){
    OSTRACE3("LOCK    %d %s ok (already held)\n", pFile->h,
            locktypeName(locktype));
    return SQLITE_OK;
  }

  /* Make sure the locking sequence is correct
  /* Make sure the locking sequence is correct.
  **  (1) We never move from unlocked to anything higher than shared lock.
  **  (2) SQLite never explicitly requests a pendig lock.
  **  (3) A shared lock is always held when a reserve lock is requested.
  */
  assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
  assert( locktype!=PENDING_LOCK );
  assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );

  /* This mutex is needed because pFile->pLock is shared across threads
  */
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258


1259
1260
1261
1262
1263
1264
1265
1266

1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289


1290
1291
1292
1293
1294
1295
1296
1349
1350
1351
1352
1353
1354
1355



1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369

1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383

1384
1385
1386
1387





1388
1389
1390
1391
1392
1393
1394
1395
1396







-
-
-





+
+







-
+













-




-
-
-
-
-
+
+







    assert( pLock->cnt>0 );
    pFile->locktype = SHARED_LOCK;
    pLock->cnt++;
    pFile->pOpen->nLock++;
    goto end_lock;
  }

  lock.l_len = 1L;

  lock.l_whence = SEEK_SET;

  /* A PENDING lock is needed before acquiring a SHARED lock and before
  ** acquiring an EXCLUSIVE lock.  For the SHARED lock, the PENDING will
  ** be released.
  */
  lock.l_len = 1L;
  lock.l_whence = SEEK_SET;
  if( locktype==SHARED_LOCK 
      || (locktype==EXCLUSIVE_LOCK && pFile->locktype<PENDING_LOCK)
  ){
    lock.l_type = (locktype==SHARED_LOCK?F_RDLCK:F_WRLCK);
    lock.l_start = PENDING_BYTE;
    s = fcntl(pFile->h, F_SETLK, &lock);
    if( s==(-1) ){
      int tErrno = errno;
      tErrno = errno;
      rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
      if( IS_LOCK_ERROR(rc) ){
        pFile->lastErrno = tErrno;
      }
      goto end_lock;
    }
  }


  /* If control gets to this point, then actually go ahead and make
  ** operating system calls for the specified lock.
  */
  if( locktype==SHARED_LOCK ){
    int tErrno = 0;
    assert( pLock->cnt==0 );
    assert( pLock->locktype==0 );

    /* Now get the read-lock */
    lock.l_start = SHARED_FIRST;
    lock.l_len = SHARED_SIZE;
    if( (s = fcntl(pFile->h, F_SETLK, &lock))==(-1) ){
      tErrno = errno;
    }
    s = rangeLock(pFile, F_RDLCK, &tErrno);

    /* Drop the temporary PENDING lock */
    lock.l_start = PENDING_BYTE;
    lock.l_len = 1L;
    lock.l_type = F_UNLCK;
    if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){
      if( s != -1 ){
        /* This could happen with a network mount */
1322
1323
1324
1325
1326
1327
1328


1329
1330
1331
1332

1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432


1433
1434
1435
1436
1437

1438

1439
1440
1441
1442
1443
1444
1445







+
+


-
-
+




-

-







    ** already.
    */
    assert( 0!=pFile->locktype );
    lock.l_type = F_WRLCK;
    switch( locktype ){
      case RESERVED_LOCK:
        lock.l_start = RESERVED_BYTE;
        s = fcntl(pFile->h, F_SETLK, &lock);
        tErrno = errno;
        break;
      case EXCLUSIVE_LOCK:
        lock.l_start = SHARED_FIRST;
        lock.l_len = SHARED_SIZE;
        s = rangeLock(pFile, F_WRLCK, &tErrno);
        break;
      default:
        assert(0);
    }
    s = fcntl(pFile->h, F_SETLK, &lock);
    if( s==(-1) ){
      int tErrno = errno;
      rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
      if( IS_LOCK_ERROR(rc) ){
        pFile->lastErrno = tErrno;
      }
    }
  }
  
1372
1373
1374
1375
1376
1377
1378











































1379
1380
1381
1382
1383
1384
1385
1386
1387

1388
1389
1390



1391
1392


1393
1394
1395
1396
1397
1398
1399
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530



1531
1532
1533


1534
1535
1536
1537
1538
1539
1540
1541
1542







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+









+
-
-
-
+
+
+
-
-
+
+








end_lock:
  unixLeaveMutex();
  OSTRACE4("LOCK    %d %s %s\n", pFile->h, locktypeName(locktype), 
      rc==SQLITE_OK ? "ok" : "failed");
  return rc;
}

/*
** Close all file descriptors accumuated in the unixOpenCnt->pUnused list.
** If all such file descriptors are closed without error, the list is
** cleared and SQLITE_OK returned.
**
** Otherwise, if an error occurs, then successfully closed file descriptor
** entries are removed from the list, and SQLITE_IOERR_CLOSE returned. 
** not deleted and SQLITE_IOERR_CLOSE returned.
*/ 
static int closePendingFds(unixFile *pFile){
  int rc = SQLITE_OK;
  struct unixOpenCnt *pOpen = pFile->pOpen;
  UnixUnusedFd *pError = 0;
  UnixUnusedFd *p;
  UnixUnusedFd *pNext;
  for(p=pOpen->pUnused; p; p=pNext){
    pNext = p->pNext;
    if( close(p->fd) ){
      pFile->lastErrno = errno;
      rc = SQLITE_IOERR_CLOSE;
      p->pNext = pError;
      pError = p;
    }else{
      sqlite3_free(p);
    }
  }
  pOpen->pUnused = pError;
  return rc;
}

/*
** Add the file descriptor used by file handle pFile to the corresponding
** pUnused list.
*/
static void setPendingFd(unixFile *pFile){
  struct unixOpenCnt *pOpen = pFile->pOpen;
  UnixUnusedFd *p = pFile->pUnused;
  p->pNext = pOpen->pUnused;
  pOpen->pUnused = p;
  pFile->h = -1;
  pFile->pUnused = 0;
}

/*
** Lower the locking level on file descriptor pFile to locktype.  locktype
** must be either NO_LOCK or SHARED_LOCK.
**
** If the locking level of the file descriptor is already at or below
** the requested locking level, this routine is a no-op.
*/
static int unixUnlock(sqlite3_file *id, int locktype){
  unixFile *pFile = (unixFile*)id; /* The open file */
  struct unixLockInfo *pLock;
  struct flock lock;
  int rc = SQLITE_OK;
  struct unixLockInfo *pLock;      /* Structure describing current lock state */
  struct flock lock;               /* Information passed into fcntl() */
  int rc = SQLITE_OK;              /* Return code from this interface */
  unixFile *pFile = (unixFile*)id;
  int h;
  int h;                           /* The underlying file descriptor */
  int tErrno;                      /* Error code from system call errors */

  assert( pFile );
  OSTRACE7("UNLOCK  %d %d was %d(%d,%d) pid=%d\n", pFile->h, locktype,
      pFile->locktype, pFile->pLock->locktype, pFile->pLock->cnt, getpid());

  assert( locktype<=SHARED_LOCK );
  if( pFile->locktype<=locktype ){
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436

1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452

1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479

1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496

1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512

1513
1514
1515
1516
1517



1518
1519
1520
1521
1522
1523
1524
1568
1569
1570
1571
1572
1573
1574





1575

1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589

1590
1591
1592
1593
1594
1595
1596
1597
1598
1599

1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615

1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632

1633
















1634





1635
1636
1637
1638
1639
1640
1641
1642
1643
1644







-
-
-
-
-
+
-














-
+









-
















-
+
















-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
+
+
+







         || pFile->dbUpdate==0
         || pFile->transCntrChng==1 );
    pFile->inNormalWrite = 0;
#endif


    if( locktype==SHARED_LOCK ){
      lock.l_type = F_RDLCK;
      lock.l_whence = SEEK_SET;
      lock.l_start = SHARED_FIRST;
      lock.l_len = SHARED_SIZE;
      if( fcntl(h, F_SETLK, &lock)==(-1) ){
      if( rangeLock(pFile, F_RDLCK, &tErrno)==(-1) ){
        int tErrno = errno;
        rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK);
        if( IS_LOCK_ERROR(rc) ){
          pFile->lastErrno = tErrno;
        }
        goto end_unlock;
      }
    }
    lock.l_type = F_UNLCK;
    lock.l_whence = SEEK_SET;
    lock.l_start = PENDING_BYTE;
    lock.l_len = 2L;  assert( PENDING_BYTE+1==RESERVED_BYTE );
    if( fcntl(h, F_SETLK, &lock)!=(-1) ){
      pLock->locktype = SHARED_LOCK;
    }else{
      int tErrno = errno;
      tErrno = errno;
      rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
      if( IS_LOCK_ERROR(rc) ){
        pFile->lastErrno = tErrno;
      }
      goto end_unlock;
    }
  }
  if( locktype==NO_LOCK ){
    struct unixOpenCnt *pOpen;
    int rc2 = SQLITE_OK;

    /* Decrement the shared lock counter.  Release the lock using an
    ** OS call only when all threads in this same process have released
    ** the lock.
    */
    pLock->cnt--;
    if( pLock->cnt==0 ){
      lock.l_type = F_UNLCK;
      lock.l_whence = SEEK_SET;
      lock.l_start = lock.l_len = 0L;
      SimulateIOErrorBenign(1);
      SimulateIOError( h=(-1) )
      SimulateIOErrorBenign(0);
      if( fcntl(h, F_SETLK, &lock)!=(-1) ){
        pLock->locktype = NO_LOCK;
      }else{
        int tErrno = errno;
        tErrno = errno;
        rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
        if( IS_LOCK_ERROR(rc) ){
          pFile->lastErrno = tErrno;
        }
        pLock->locktype = NO_LOCK;
        pFile->locktype = NO_LOCK;
      }
    }

    /* Decrement the count of locks against this same file.  When the
    ** count reaches zero, close any other file descriptors whose close
    ** was deferred because of outstanding locks.
    */
    pOpen = pFile->pOpen;
    pOpen->nLock--;
    assert( pOpen->nLock>=0 );
    if( pOpen->nLock==0 && pOpen->nPending>0 ){
    if( pOpen->nLock==0 ){
      int i;
      for(i=0; i<pOpen->nPending; i++){
        /* close pending fds, but if closing fails don't free the array
        ** assign -1 to the successfully closed descriptors and record the
        ** error.  The next attempt to unlock will try again. */
        if( pOpen->aPending[i] < 0 ) continue;
        if( close(pOpen->aPending[i]) ){
          pFile->lastErrno = errno;
          rc2 = SQLITE_IOERR_CLOSE;
        }else{
          pOpen->aPending[i] = -1;
        }
      }
      if( rc2==SQLITE_OK ){
        sqlite3_free(pOpen->aPending);
        pOpen->nPending = 0;
      int rc2 = closePendingFds(pFile);
        pOpen->aPending = 0;
      }
    }
    if( rc==SQLITE_OK ){
      rc = rc2;
      if( rc==SQLITE_OK ){
        rc = rc2;
      }
    }
  }
	
end_unlock:
  unixLeaveMutex();
  if( rc==SQLITE_OK ) pFile->locktype = locktype;
  return rc;
1560
1561
1562
1563
1564
1565
1566

1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585


1586
1587
1588
1589
1590
1591
1592
1593
1594
1595

1596
1597
1598
1599
1600
1601
1602
1603
1604
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704


1705
1706
1707









1708


1709
1710
1711
1712
1713
1714
1715







+

















-
-
+
+

-
-
-
-
-
-
-
-
-
+
-
-







      }
      vxworksReleaseFileId(pFile->pId);
      pFile->pId = 0;
    }
#endif
    OSTRACE2("CLOSE   %-3d\n", pFile->h);
    OpenCounter(-1);
    sqlite3_free(pFile->pUnused);
    memset(pFile, 0, sizeof(unixFile));
  }
  return SQLITE_OK;
}

/*
** Close a file.
*/
static int unixClose(sqlite3_file *id){
  int rc = SQLITE_OK;
  if( id ){
    unixFile *pFile = (unixFile *)id;
    unixUnlock(id, NO_LOCK);
    unixEnterMutex();
    if( pFile->pOpen && pFile->pOpen->nLock ){
      /* If there are outstanding locks, do not actually close the file just
      ** yet because that would clear those locks.  Instead, add the file
      ** descriptor to pOpen->aPending.  It will be automatically closed when
      ** the last lock is cleared.
      ** descriptor to pOpen->pUnused list.  It will be automatically closed 
      ** when the last lock is cleared.
      */
      int *aNew;
      struct unixOpenCnt *pOpen = pFile->pOpen;
      aNew = sqlite3_realloc(pOpen->aPending, (pOpen->nPending+1)*sizeof(int) );
      if( aNew==0 ){
        /* If a malloc fails, just leak the file descriptor */
      }else{
        pOpen->aPending = aNew;
        pOpen->aPending[pOpen->nPending] = pFile->h;
        pOpen->nPending++;
      setPendingFd(pFile);
        pFile->h = -1;
      }
    }
    releaseLockInfo(pFile->pLock);
    releaseOpenCnt(pFile->pOpen);
    rc = closeUnixFile(id);
    unixLeaveMutex();
  }
  return rc;
1647
1648
1649
1650
1651
1652
1653
1654

1655
1656
1657
1658
1659
1660
1661
1758
1759
1760
1761
1762
1763
1764

1765
1766
1767
1768
1769
1770
1771
1772







-
+








/******************* End of the no-op lock implementation *********************
******************************************************************************/

/******************************************************************************
************************* Begin dot-file Locking ******************************
**
** The dotfile locking implementation uses the existing of separate lock
** The dotfile locking implementation uses the existance of separate lock
** files in order to control access to the database.  This works on just
** about every filesystem imaginable.  But there are serious downsides:
**
**    (1)  There is zero concurrency.  A single reader blocks all other
**         connections from reading or writing the database.
**
**    (2)  An application crash or power loss can leave stale lock files
2427
2428
2429
2430
2431
2432
2433
2434


2435
2436
2437
2438
2439
2440
2441
2538
2539
2540
2541
2542
2543
2544

2545
2546
2547
2548
2549
2550
2551
2552
2553







-
+
+







    }
  }
  
  /* If control gets to this point, then actually go ahead and make
  ** operating system calls for the specified lock.
  */
  if( locktype==SHARED_LOCK ){
    int lk, lrc1, lrc2, lrc1Errno;
    int lk, lrc1, lrc2;
    int lrc1Errno = 0;
    
    /* Now get the read-lock SHARED_LOCK */
    /* note that the quality of the randomness doesn't matter that much */
    lk = random(); 
    context->sharedByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
    lrc1 = afpSetLock(context->dbPath, pFile, 
          SHARED_FIRST+context->sharedByte, 1, 1);
2559
2560
2561
2562
2563
2564
2565
2566

2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579

2580
2581
2582
2583
2584
2585
2586



2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612

2613
2614
2615
2616
2617
2618
2619
2620
2621
2671
2672
2673
2674
2675
2676
2677

2678













2679


2680
2681
2682
2683

2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703









2704


2705
2706
2707
2708
2709
2710
2711







-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-




-
+
+
+

















-
-
-
-
-
-
-
-
-
+
-
-







  }

  if( rc==SQLITE_OK ){
    if( locktype==NO_LOCK ){
      struct unixOpenCnt *pOpen = pFile->pOpen;
      pOpen->nLock--;
      assert( pOpen->nLock>=0 );
      if( pOpen->nLock==0 && pOpen->nPending>0 ){
      if( pOpen->nLock==0 ){
        int i;
        for(i=0; i<pOpen->nPending; i++){
          if( pOpen->aPending[i] < 0 ) continue;
          if( close(pOpen->aPending[i]) ){
            pFile->lastErrno = errno;
            rc = SQLITE_IOERR_CLOSE;
          }else{
            pOpen->aPending[i] = -1;
          }
        }
        if( rc==SQLITE_OK ){
          sqlite3_free(pOpen->aPending);
          pOpen->nPending = 0;
        rc = closePendingFds(pFile);
          pOpen->aPending = 0;
        }
      }
    }
  }
  unixLeaveMutex();
  if( rc==SQLITE_OK ) pFile->locktype = locktype;
  if( rc==SQLITE_OK ){
    pFile->locktype = locktype;
  }
  return rc;
}

/*
** Close a file & cleanup AFP specific locking context 
*/
static int afpClose(sqlite3_file *id) {
  if( id ){
    unixFile *pFile = (unixFile*)id;
    afpUnlock(id, NO_LOCK);
    unixEnterMutex();
    if( pFile->pOpen && pFile->pOpen->nLock ){
      /* If there are outstanding locks, do not actually close the file just
      ** yet because that would clear those locks.  Instead, add the file
      ** descriptor to pOpen->aPending.  It will be automatically closed when
      ** the last lock is cleared.
      */
      int *aNew;
      struct unixOpenCnt *pOpen = pFile->pOpen;
      aNew = sqlite3_realloc(pOpen->aPending, (pOpen->nPending+1)*sizeof(int) );
      if( aNew==0 ){
        /* If a malloc fails, just leak the file descriptor */
      }else{
        pOpen->aPending = aNew;
        pOpen->aPending[pOpen->nPending] = pFile->h;
        pOpen->nPending++;
      setPendingFd(pFile);
        pFile->h = -1;
      }
    }
    releaseOpenCnt(pFile->pOpen);
    sqlite3_free(pFile->lockingContext);
    closeUnixFile(id);
    unixLeaveMutex();
  }
  return SQLITE_OK;
2693
2694
2695
2696
2697
2698
2699

2700
2701
2702

2703
2704
2705
2706





2707
2708

2709
2710
2711
2712
2713
2714
2715

2716
2717
2718
2719
2720
2721
2722
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794




2795
2796
2797
2798
2799
2800

2801
2802
2803
2804
2805
2806
2807

2808
2809
2810
2811
2812
2813
2814
2815







+



+
-
-
-
-
+
+
+
+
+

-
+






-
+







*/
static int unixRead(
  sqlite3_file *id, 
  void *pBuf, 
  int amt,
  sqlite3_int64 offset
){
  unixFile *pFile = (unixFile *)id;
  int got;
  assert( id );

  /* If this is a database file (not a journal, master-journal or temp
  /* Never read or write any of the bytes in the locking range */
  assert( ((unixFile*)id)->isLockable==0
          || offset>=PENDING_BYTE+512
          || offset+amt<=PENDING_BYTE );
  ** file), the bytes in the locking range should never be read or written. */
  assert( pFile->pUnused==0
       || offset>=PENDING_BYTE+512
       || offset+amt<=PENDING_BYTE 
  );

  got = seekAndRead((unixFile*)id, offset, pBuf, amt);
  got = seekAndRead(pFile, offset, pBuf, amt);
  if( got==amt ){
    return SQLITE_OK;
  }else if( got<0 ){
    /* lastErrno set by seekAndRead */
    return SQLITE_IOERR_READ;
  }else{
    ((unixFile*)id)->lastErrno = 0; /* not a system error */
    pFile->lastErrno = 0; /* not a system error */
    /* Unread parts of the buffer must be zero-filled */
    memset(&((char*)pBuf)[got], 0, amt-got);
    return SQLITE_IOERR_SHORT_READ;
  }
}

/*
2762
2763
2764
2765
2766
2767
2768

2769
2770
2771
2772

2773
2774
2775
2776





2777
2778
2779
2780
2781
2782
2783
2784
2785

2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801

2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813

2814
2815
2816
2817
2818
2819
2820
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867




2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880

2881

2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895

2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907

2908
2909
2910
2911
2912
2913
2914
2915







+




+
-
-
-
-
+
+
+
+
+








-
+
-














-
+











-
+







*/
static int unixWrite(
  sqlite3_file *id, 
  const void *pBuf, 
  int amt,
  sqlite3_int64 offset 
){
  unixFile *pFile = (unixFile*)id;
  int wrote = 0;
  assert( id );
  assert( amt>0 );

  /* If this is a database file (not a journal, master-journal or temp
  /* Never read or write any of the bytes in the locking range */
  assert( ((unixFile*)id)->isLockable==0
          || offset>=PENDING_BYTE+512
          || offset+amt<=PENDING_BYTE );
  ** file), the bytes in the locking range should never be read or written. */
  assert( pFile->pUnused==0
       || offset>=PENDING_BYTE+512
       || offset+amt<=PENDING_BYTE 
  );

#ifndef NDEBUG
  /* If we are doing a normal write to a database file (as opposed to
  ** doing a hot-journal rollback or a write to some file other than a
  ** normal database file) then record the fact that the database
  ** has changed.  If the transaction counter is modified, record that
  ** fact too.
  */
  if( ((unixFile*)id)->inNormalWrite ){
  if( pFile->inNormalWrite ){
    unixFile *pFile = (unixFile*)id;
    pFile->dbUpdate = 1;  /* The database has been modified */
    if( offset<=24 && offset+amt>=27 ){
      int rc;
      char oldCntr[4];
      SimulateIOErrorBenign(1);
      rc = seekAndRead(pFile, 24, oldCntr, 4);
      SimulateIOErrorBenign(0);
      if( rc!=4 || memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ){
        pFile->transCntrChng = 1;  /* The transaction counter has changed */
      }
    }
  }
#endif

  while( amt>0 && (wrote = seekAndWrite((unixFile*)id, offset, pBuf, amt))>0 ){
  while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){
    amt -= wrote;
    offset += wrote;
    pBuf = &((char*)pBuf)[wrote];
  }
  SimulateIOError(( wrote=(-1), amt=1 ));
  SimulateDiskfullError(( wrote=0, amt=1 ));
  if( amt>0 ){
    if( wrote<0 ){
      /* lastErrno set by seekAndWrite */
      return SQLITE_IOERR_WRITE;
    }else{
      ((unixFile*)id)->lastErrno = 0; /* not a system error */
      pFile->lastErrno = 0; /* not a system error */
      return SQLITE_FULL;
    }
  }
  return SQLITE_OK;
}

#ifdef SQLITE_TEST
3014
3015
3016
3017
3018
3019
3020













3021
3022
3023
3024
3025
3026
3027
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135







+
+
+
+
+
+
+
+
+
+
+
+
+







  assert( id );
  SimulateIOError( return SQLITE_IOERR_TRUNCATE );
  rc = ftruncate(((unixFile*)id)->h, (off_t)nByte);
  if( rc ){
    ((unixFile*)id)->lastErrno = errno;
    return SQLITE_IOERR_TRUNCATE;
  }else{
#ifndef NDEBUG
    /* If we are doing a normal write to a database file (as opposed to
    ** doing a hot-journal rollback or a write to some file other than a
    ** normal database file) and we truncate the file to zero length,
    ** that effectively updates the change counter.  This might happen
    ** when restoring a database using the backup API from a zero-length
    ** source.
    */
    if( ((unixFile*)id)->inNormalWrite && nByte==0 ){
      ((unixFile*)id)->transCntrChng = 1;
    }
#endif

    return SQLITE_OK;
  }
}

/*
** Determine the current size of a file in bytes
*/
3134
3135
3136
3137
3138
3139
3140
3141

3142
3143
3144
3145
3146
3147
3148
3242
3243
3244
3245
3246
3247
3248

3249
3250
3251
3252
3253
3254
3255
3256







-
+







** looks at the filesystem type and tries to guess the best locking
** strategy from that.
**
** For finder-funtion F, two objects are created:
**
**    (1) The real finder-function named "FImpt()".
**
**    (2) A constant pointer to this functio named just "F".
**    (2) A constant pointer to this function named just "F".
**
**
** A pointer to the F pointer is used as the pAppData value for VFS
** objects.  We have to do this instead of letting pAppData point
** directly at the finder-function since C90 rules prevent a void*
** from be cast into a function pointer.
**
3167
3168
3169
3170
3171
3172
3173
3174
3175


3176
3177
3178

3179
3180
3181
3182
3183
3184
3185
3275
3276
3277
3278
3279
3280
3281


3282
3283
3284
3285

3286
3287
3288
3289
3290
3291
3292
3293







-
-
+
+


-
+







   LOCK,                       /* xLock */                                   \
   UNLOCK,                     /* xUnlock */                                 \
   CKLOCK,                     /* xCheckReservedLock */                      \
   unixFileControl,            /* xFileControl */                            \
   unixSectorSize,             /* xSectorSize */                             \
   unixDeviceCharacteristics   /* xDeviceCapabilities */                     \
};                                                                           \
static const sqlite3_io_methods *FINDER##Impl(const char *z, int h){         \
  UNUSED_PARAMETER(z); UNUSED_PARAMETER(h);                                  \
static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){   \
  UNUSED_PARAMETER(z); UNUSED_PARAMETER(p);                                  \
  return &METHOD;                                                            \
}                                                                            \
static const sqlite3_io_methods *(*const FINDER)(const char*,int)            \
static const sqlite3_io_methods *(*const FINDER)(const char*,unixFile *p)    \
    = FINDER##Impl;

/*
** Here are all of the sqlite3_io_methods objects for each of the
** locking strategies.  Functions that return pointers to these methods
** are also created.
*/
3237
3238
3239
3240
3241
3242
3243

















3244
3245
3246
3247
3248
3249
3250
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







  afpClose,                 /* xClose method */
  afpLock,                  /* xLock method */
  afpUnlock,                /* xUnlock method */
  afpCheckReservedLock      /* xCheckReservedLock method */
)
#endif

/*
** The "Whole File Locking" finder returns the same set of methods as
** the posix locking finder.  But it also sets the SQLITE_WHOLE_FILE_LOCKING
** flag to force the posix advisory locks to cover the whole file instead
** of just a small span of bytes near the 1GiB boundary.  Whole File Locking
** is useful on NFS-mounted files since it helps NFS to maintain cache
** coherency.  But it is a detriment to other filesystems since it runs
** slower.
*/
static const sqlite3_io_methods *posixWflIoFinderImpl(const char*z, unixFile*p){
  UNUSED_PARAMETER(z);
  p->fileFlags = SQLITE_WHOLE_FILE_LOCKING;
  return &posixIoMethods;
}
static const sqlite3_io_methods 
  *(*const posixWflIoFinder)(const char*,unixFile *p) = posixWflIoFinderImpl;

/*
** The proxy locking method is a "super-method" in the sense that it
** opens secondary file descriptors for the conch and lock files and
** it uses proxy, dot-file, AFP, and flock() locking methods on those
** secondary files.  For this reason, the division that implements
** proxy locking is located much further down in the file.  But we need
** to go ahead and define the sqlite3_io_methods and finder function
3272
3273
3274
3275
3276
3277
3278
3279

3280
3281
3282
3283
3284
3285
3286
3397
3398
3399
3400
3401
3402
3403

3404
3405
3406
3407
3408
3409
3410
3411







-
+







** for the database file "filePath".  It then returns the sqlite3_io_methods
** object that implements that strategy.
**
** This is for MacOSX only.
*/
static const sqlite3_io_methods *autolockIoFinderImpl(
  const char *filePath,    /* name of the database file */
  int fd                   /* file descriptor open on the database file */
  unixFile *pNew           /* open file object for the database file */
){
  static const struct Mapping {
    const char *zFilesystem;              /* Filesystem type name */
    const sqlite3_io_methods *pMethods;   /* Appropriate locking method */
  } aMap[] = {
    { "hfs",    &posixIoMethods },
    { "ufs",    &posixIoMethods },
3317
3318
3319
3320
3321
3322
3323
3324


3325
3326
3327
3328
3329
3330
3331


3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345

3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362

3363
3364
3365
3366
3367
3368
3369


3370
3371
3372
3373
3374
3375
3376

3377
3378
3379
3380
3381
3382
3383
3442
3443
3444
3445
3446
3447
3448

3449
3450
3451
3452
3453
3454
3455


3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470

3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487

3488
3489
3490
3491
3492
3493


3494
3495
3496
3497
3498
3499
3500
3501

3502
3503
3504
3505
3506
3507
3508
3509







-
+
+





-
-
+
+













-
+
















-
+





-
-
+
+






-
+







  ** Test byte-range lock using fcntl(). If the call succeeds, 
  ** assume that the file-system supports POSIX style locks. 
  */
  lockInfo.l_len = 1;
  lockInfo.l_start = 0;
  lockInfo.l_whence = SEEK_SET;
  lockInfo.l_type = F_RDLCK;
  if( fcntl(fd, F_GETLK, &lockInfo)!=-1 ) {
  if( fcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) {
    pNew->fileFlags = SQLITE_WHOLE_FILE_LOCKING;
    return &posixIoMethods;
  }else{
    return &dotlockIoMethods;
  }
}
static const sqlite3_io_methods *(*const autolockIoFinder)(const char*,int)
        = autolockIoFinderImpl;
static const sqlite3_io_methods 
  *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl;

#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */

#if OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE
/* 
** This "finder" function attempts to determine the best locking strategy 
** for the database file "filePath".  It then returns the sqlite3_io_methods
** object that implements that strategy.
**
** This is for VXWorks only.
*/
static const sqlite3_io_methods *autolockIoFinderImpl(
  const char *filePath,    /* name of the database file */
  int fd                   /* file descriptor open on the database file */
  unixFile *pNew           /* the open file object */
){
  struct flock lockInfo;

  if( !filePath ){
    /* If filePath==NULL that means we are dealing with a transient file
    ** that does not need to be locked. */
    return &nolockIoMethods;
  }

  /* Test if fcntl() is supported and use POSIX style locks.
  ** Otherwise fall back to the named semaphore method.
  */
  lockInfo.l_len = 1;
  lockInfo.l_start = 0;
  lockInfo.l_whence = SEEK_SET;
  lockInfo.l_type = F_RDLCK;
  if( fcntl(fd, F_GETLK, &lockInfo)!=-1 ) {
  if( fcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) {
    return &posixIoMethods;
  }else{
    return &semIoMethods;
  }
}
static const sqlite3_io_methods *(*const autolockIoFinder)(const char*,int)
        = autolockIoFinderImpl;
static const sqlite3_io_methods 
  *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl;

#endif /* OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE */

/*
** An abstract type for a pointer to a IO method finder function:
*/
typedef const sqlite3_io_methods *(*finder_type)(const char*,int);
typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*);


/****************************************************************************
**************************** sqlite3_vfs methods ****************************
**
** This division contains the implementation of methods on the
** sqlite3_vfs object.
3398
3399
3400
3401
3402
3403
3404
3405
3406


3407
3408
3409
3410
3411
3412
3413
3414
3415
3416

3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429

3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440






















3441
3442
3443
3444
3445
3446
3447
3524
3525
3526
3527
3528
3529
3530


3531
3532

3533

3534

3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552

3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593







-
-
+
+
-

-

-





+












-
+











+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







  const sqlite3_io_methods *pLockingStyle;
  unixFile *pNew = (unixFile *)pId;
  int rc = SQLITE_OK;

  assert( pNew->pLock==NULL );
  assert( pNew->pOpen==NULL );

  /* Parameter isDelete is only used on vxworks.
  ** Express this explicitly here to prevent compiler warnings
  /* Parameter isDelete is only used on vxworks. Express this explicitly 
  ** here to prevent compiler warnings about unused parameters.
  ** about unused parameters.
  */
#if !OS_VXWORKS
  UNUSED_PARAMETER(isDelete);
#endif

  OSTRACE3("OPEN    %-3d %s\n", h, zFilename);    
  pNew->h = h;
  pNew->dirfd = dirfd;
  SET_THREADID(pNew);
  pNew->fileFlags = 0;

#if OS_VXWORKS
  pNew->pId = vxworksFindFileId(zFilename);
  if( pNew->pId==0 ){
    noLock = 1;
    rc = SQLITE_NOMEM;
  }
#endif

  if( noLock ){
    pLockingStyle = &nolockIoMethods;
  }else{
    pLockingStyle = (**(finder_type*)pVfs->pAppData)(zFilename, h);
    pLockingStyle = (**(finder_type*)pVfs->pAppData)(zFilename, pNew);
#if SQLITE_ENABLE_LOCKING_STYLE
    /* Cache zFilename in the locking context (AFP and dotlock override) for
    ** proxyLock activation is possible (remote proxy is based on db name)
    ** zFilename remains valid until file is closed, to support */
    pNew->lockingContext = (void*)zFilename;
#endif
  }

  if( pLockingStyle == &posixIoMethods ){
    unixEnterMutex();
    rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
    if( rc!=SQLITE_OK ){
      /* If an error occured in findLockInfo(), close the file descriptor
      ** immediately, before releasing the mutex. findLockInfo() may fail
      ** in two scenarios:
      **
      **   (a) A call to fstat() failed.
      **   (b) A malloc failed.
      **
      ** Scenario (b) may only occur if the process is holding no other
      ** file descriptors open on the same file. If there were other file
      ** descriptors on this file, then no malloc would be required by
      ** findLockInfo(). If this is the case, it is quite safe to close
      ** handle h - as it is guaranteed that no posix locks will be released
      ** by doing so.
      **
      ** If scenario (a) caused the error then things are not so safe. The
      ** implicit assumption here is that if fstat() fails, things are in
      ** such bad shape that dropping a lock or two doesn't matter much.
      */
      close(h);
      h = -1;
    }
    unixLeaveMutex();
  }

#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
  else if( pLockingStyle == &afpIoMethods ){
    /* AFP locking uses the file path so it needs to be included in
    ** the afpLockingContext.
3485
3486
3487
3488
3489
3490
3491
3492

3493
3494

3495
3496
3497
3498
3499
3500
3501
3631
3632
3633
3634
3635
3636
3637

3638
3639

3640
3641
3642
3643
3644
3645
3646
3647







-
+

-
+







    ** included in the semLockingContext
    */
    unixEnterMutex();
    rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
    if( (rc==SQLITE_OK) && (pNew->pOpen->pSem==NULL) ){
      char *zSemName = pNew->pOpen->aSemName;
      int n;
      sqlite3_snprintf(MAX_PATHNAME, zSemName, "%s.sem",
      sqlite3_snprintf(MAX_PATHNAME, zSemName, "/%s.sem",
                       pNew->pId->zCanonicalName);
      for( n=0; zSemName[n]; n++ )
      for( n=1; zSemName[n]; n++ )
        if( zSemName[n]=='/' ) zSemName[n] = '_';
      pNew->pOpen->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
      if( pNew->pOpen->pSem == SEM_FAILED ){
        rc = SQLITE_NOMEM;
        pNew->pOpen->aSemName[0] = '\0';
      }
    }
3509
3510
3511
3512
3513
3514
3515
3516

3517
3518
3519
3520
3521
3522
3523
3655
3656
3657
3658
3659
3660
3661

3662
3663
3664
3665
3666
3667
3668
3669







-
+







    unlink(zFilename);
    isDelete = 0;
  }
  pNew->isDelete = isDelete;
#endif
  if( rc!=SQLITE_OK ){
    if( dirfd>=0 ) close(dirfd); /* silent leak if fail, already in error */
    close(h);
    if( h>=0 ) close(h);
  }else{
    pNew->pMethod = pLockingStyle;
    OpenCounter(+1);
  }
  return rc;
}

3618
3619
3620
3621
3622
3623
3624
























































3625
3626
3627
3628
3629
3630
3631
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







** Routine to transform a unixFile into a proxy-locking unixFile.
** Implementation in the proxy-lock division, but used by unixOpen()
** if SQLITE_PREFER_PROXY_LOCKING is defined.
*/
static int proxyTransformUnixFile(unixFile*, const char*);
#endif

/*
** Search for an unused file descriptor that was opened on the database 
** file (not a journal or master-journal file) identified by pathname
** zPath with SQLITE_OPEN_XXX flags matching those passed as the second
** argument to this function.
**
** Such a file descriptor may exist if a database connection was closed
** but the associated file descriptor could not be closed because some
** other file descriptor open on the same file is holding a file-lock.
** Refer to comments in the unixClose() function and the lengthy comment
** describing "Posix Advisory Locking" at the start of this file for 
** further details. Also, ticket #4018.
**
** If a suitable file descriptor is found, then it is returned. If no
** such file descriptor is located, -1 is returned.
*/
static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
  UnixUnusedFd *pUnused = 0;

  /* Do not search for an unused file descriptor on vxworks. Not because
  ** vxworks would not benefit from the change (it might, we're not sure),
  ** but because no way to test it is currently available. It is better 
  ** not to risk breaking vxworks support for the sake of such an obscure 
  ** feature.  */
#if !OS_VXWORKS
  struct stat sStat;                   /* Results of stat() call */

  /* A stat() call may fail for various reasons. If this happens, it is
  ** almost certain that an open() call on the same path will also fail.
  ** For this reason, if an error occurs in the stat() call here, it is
  ** ignored and -1 is returned. The caller will try to open a new file
  ** descriptor on the same path, fail, and return an error to SQLite.
  **
  ** Even if a subsequent open() call does succeed, the consequences of
  ** not searching for a resusable file descriptor are not dire.  */
  if( 0==stat(zPath, &sStat) ){
    struct unixOpenCnt *pO;
    struct unixFileId id;
    id.dev = sStat.st_dev;
    id.ino = sStat.st_ino;

    unixEnterMutex();
    for(pO=openList; pO && memcmp(&id, &pO->fileId, sizeof(id)); pO=pO->pNext);
    if( pO ){
      UnixUnusedFd **pp;
      for(pp=&pO->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext));
      pUnused = *pp;
      if( pUnused ){
        *pp = pUnused->pNext;
      }
    }
    unixLeaveMutex();
  }
#endif    /* if !OS_VXWORKS */
  return pUnused;
}

/*
** Open the file zPath.
** 
** Previously, the SQLite OS layer used three functions in place of this
** one:
**
3648
3649
3650
3651
3652
3653
3654

3655

3656
3657
3658
3659
3660

3661
3662
3663
3664
3665
3666
3667
3850
3851
3852
3853
3854
3855
3856
3857

3858
3859
3860
3861
3862

3863
3864
3865
3866
3867
3868
3869
3870







+
-
+




-
+







static int unixOpen(
  sqlite3_vfs *pVfs,           /* The VFS for which this is the xOpen method */
  const char *zPath,           /* Pathname of file to be opened */
  sqlite3_file *pFile,         /* The file descriptor to be filled in */
  int flags,                   /* Input flags to control the opening */
  int *pOutFlags               /* Output flags returned to SQLite core */
){
  unixFile *p = (unixFile *)pFile;
  int fd = -1;                    /* File descriptor returned by open() */
  int fd = -1;                   /* File descriptor returned by open() */
  int dirfd = -1;                /* Directory file descriptor */
  int openFlags = 0;             /* Flags to pass to open() */
  int eType = flags&0xFFFFFF00;  /* Type of file to open */
  int noLock;                    /* True to omit locking primitives */
  int rc = SQLITE_OK;
  int rc = SQLITE_OK;            /* Function Return Code */

  int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
  int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
  int isCreate     = (flags & SQLITE_OPEN_CREATE);
  int isReadonly   = (flags & SQLITE_OPEN_READONLY);
  int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);

3688
3689
3690
3691
3692
3693
3694
3695

3696
3697
3698
3699



3700
3701
3702
3703
3704
3705
3706
3707
3708

3709












3710


3711
3712
3713
3714
3715
3716
3717
3718




3719
3720
3721
3722
3723
3724


3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735

























3736
3737
3738
3739
3740
3741
3742
3743
3744
3745

3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761





3762

3763

3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774

3775
3776
3777
3778
3779


3780
3781
3782
3783
3784
3785
3786







3787
3788




3789
3790


3791
3792
3793
3794
3795
3796
3797
3798
3799

3800
3801
3802
3803
3804
3805








3806
3807
3808
3809
3810
3811
3812
3891
3892
3893
3894
3895
3896
3897

3898




3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909

3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923

3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945











3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979

3980









3981
3982
3983

3984
3985
3986
3987
3988
3989
3990
3991

3992

3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003

4004
4005
4006
4007


4008
4009

4010
4011
4012
4013

4014
4015
4016
4017
4018
4019
4020
4021


4022
4023
4024
4025
4026

4027
4028
4029
4030
4031
4032
4033
4034
4035
4036

4037
4038
4039
4040
4041


4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056







-
+
-
-
-
-
+
+
+








-
+

+
+
+
+
+
+
+
+
+
+
+
+
-
+
+








+
+
+
+






+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+









-
+
-
-
-
-
-
-
-
-
-



-



+
+
+
+
+
-
+
-
+










-
+



-
-
+
+
-




-

+
+
+
+
+
+
+
-
-
+
+
+
+

-
+
+








-
+




-
-
+
+
+
+
+
+
+
+







  */
  assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
  assert(isCreate==0 || isReadWrite);
  assert(isExclusive==0 || isCreate);
  assert(isDelete==0 || isCreate);

  /* The main DB, main journal, and master journal are never automatically
  ** deleted
  ** deleted. Nor are they ever temporary files.  */
  */
  assert( eType!=SQLITE_OPEN_MAIN_DB || !isDelete );
  assert( eType!=SQLITE_OPEN_MAIN_JOURNAL || !isDelete );
  assert( eType!=SQLITE_OPEN_MASTER_JOURNAL || !isDelete );
  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB );
  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL );
  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL );

  /* Assert that the upper layer has set one of the "file-type" flags. */
  assert( eType==SQLITE_OPEN_MAIN_DB      || eType==SQLITE_OPEN_TEMP_DB 
       || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL 
       || eType==SQLITE_OPEN_SUBJOURNAL   || eType==SQLITE_OPEN_MASTER_JOURNAL 
       || eType==SQLITE_OPEN_TRANSIENT_DB
  );

  memset(pFile, 0, sizeof(unixFile));
  memset(p, 0, sizeof(unixFile));

  if( eType==SQLITE_OPEN_MAIN_DB ){
    UnixUnusedFd *pUnused;
    pUnused = findReusableFd(zName, flags);
    if( pUnused ){
      fd = pUnused->fd;
    }else{
      pUnused = sqlite3_malloc(sizeof(*pUnused));
      if( !pUnused ){
        return SQLITE_NOMEM;
      }
    }
    p->pUnused = pUnused;
  if( !zName ){
  }else if( !zName ){
    /* If zName is NULL, the upper layer is requesting a temp file. */
    assert(isDelete && !isOpenDirectory);
    rc = getTempname(MAX_PATHNAME+1, zTmpname);
    if( rc!=SQLITE_OK ){
      return rc;
    }
    zName = zTmpname;
  }

  /* Determine the value of the flags parameter passed to POSIX function
  ** open(). These must be calculated even if open() is not called, as
  ** they may be stored as part of the file handle and used by the 
  ** 'conch file' locking functions later on.  */
  if( isReadonly )  openFlags |= O_RDONLY;
  if( isReadWrite ) openFlags |= O_RDWR;
  if( isCreate )    openFlags |= O_CREAT;
  if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW);
  openFlags |= (O_LARGEFILE|O_BINARY);

  if( fd<0 ){
    mode_t openMode = (isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS);
  fd = open(zName, openFlags, isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS);
  OSTRACE4("OPENX   %-3d %s 0%o\n", fd, zName, openFlags);
  if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
    /* Failed to open the file for read/write access. Try read-only. */
    flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
    flags |= SQLITE_OPEN_READONLY;
    return unixOpen(pVfs, zPath, pFile, flags, pOutFlags);
  }
  if( fd<0 ){
    return SQLITE_CANTOPEN;
  }
    fd = open(zName, openFlags, openMode);
    OSTRACE4("OPENX   %-3d %s 0%o\n", fd, zName, openFlags);
    if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
      /* Failed to open the file for read/write access. Try read-only. */
      flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
      openFlags &= ~(O_RDWR|O_CREAT);
      flags |= SQLITE_OPEN_READONLY;
      openFlags |= O_RDONLY;
      fd = open(zName, openFlags, openMode);
    }
    if( fd<0 ){
      rc = SQLITE_CANTOPEN;
      goto open_finished;
    }
  }
  assert( fd>=0 );
  if( pOutFlags ){
    *pOutFlags = flags;
  }

  if( p->pUnused ){
    p->pUnused->fd = fd;
    p->pUnused->flags = flags;
  }

  if( isDelete ){
#if OS_VXWORKS
    zPath = zName;
#else
    unlink(zName);
#endif
  }
#if SQLITE_ENABLE_LOCKING_STYLE
  else{
    ((unixFile*)pFile)->openFlags = openFlags;
    p->openFlags = openFlags;
  }
#endif
  if( pOutFlags ){
    *pOutFlags = flags;
  }

#ifndef NDEBUG
  if( (flags & SQLITE_OPEN_MAIN_DB)!=0 ){
    ((unixFile*)pFile)->isLockable = 1;
  }
#endif

  assert( fd>=0 );
  if( isOpenDirectory ){
    rc = openDirectory(zPath, &dirfd);
    if( rc!=SQLITE_OK ){
      /* It is safe to close fd at this point, because it is guaranteed not
      ** to be open on a database file. If it were open on a database file,
      ** it would not be safe to close as this would release any locks held
      ** on the file by this process.  */
      assert( eType!=SQLITE_OPEN_MAIN_DB );
      close(fd); /* silently leak if fail, already in error */
      close(fd);             /* silently leak if fail, already in error */
      return rc;
      goto open_finished;
    }
  }

#ifdef FD_CLOEXEC
  fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
#endif

  noLock = eType!=SQLITE_OPEN_MAIN_DB;

#if SQLITE_PREFER_PROXY_LOCKING
  if( zPath!=NULL && !noLock ){
  if( zPath!=NULL && !noLock && pVfs->xOpen ){
    char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING");
    int useProxy = 0;

    /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 
    ** 0 means never use proxy, NULL means use proxy for non-local files only
    /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means 
    ** never use proxy, NULL means use proxy for non-local files only.  */
    */
    if( envforce!=NULL ){
      useProxy = atoi(envforce)>0;
    }else{
      struct statfs fsInfo;

      if( statfs(zPath, &fsInfo) == -1 ){
        /* In theory, the close(fd) call is sub-optimal. If the file opened
        ** with fd is a database file, and there are other connections open
        ** on that file that are currently holding advisory locks on it,
        ** then the call to close() will cancel those locks. In practice,
        ** we're assuming that statfs() doesn't fail very often. At least
        ** not while other file descriptors opened by the same process on
        ** the same file are working.  */
				((unixFile*)pFile)->lastErrno = errno;
        if( dirfd>=0 ) close(dirfd); /* silently leak if fail, in error */
        p->lastErrno = errno;
        if( dirfd>=0 ){
          close(dirfd); /* silently leak if fail, in error */
        }
        close(fd); /* silently leak if fail, in error */
        return SQLITE_IOERR_ACCESS;
        rc = SQLITE_IOERR_ACCESS;
        goto open_finished;
      }
      useProxy = !(fsInfo.f_flags&MNT_LOCAL);
    }
    if( useProxy ){
      rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete);
      if( rc==SQLITE_OK ){
        rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:");
      }
      return rc;
      goto open_finished;
    }
  }
#endif
  
  return fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete);
}
  rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete);
open_finished:
  if( rc!=SQLITE_OK ){
    sqlite3_free(p->pUnused);
  }
  return rc;
}


/*
** Delete the file at zPath. If the dirSync argument is true, fsync()
** the directory after deleting the file.
*/
static int unixDelete(
  sqlite3_vfs *NotUsed,     /* VFS containing this as the xDelete method */
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477

4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488


4489
4490
4491
4492












4493
4494
4495
4496
4497





4498
4499

4500
4501






4502
4503
4504
4505
4506
4507
4508
4712
4713
4714
4715
4716
4717
4718


4719
4720
4721
4722
4723





4724


4725
4726

4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742




4743
4744
4745
4746
4747
4748

4749


4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762







-
-

+



-
-
-
-
-

-
-
+
+
-



+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
+
+
+
+
+

-
+
-
-
+
+
+
+
+
+







** Create a new VFS file descriptor (stored in memory obtained from
** sqlite3_malloc) and open the file named "path" in the file descriptor.
**
** The caller is responsible not only for closing the file descriptor
** but also for freeing the memory associated with the file descriptor.
*/
static int proxyCreateUnixFile(const char *path, unixFile **ppFile) {
  int fd;
  int dirfd = -1;
  unixFile *pNew;
  int flags = SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE;
  int rc = SQLITE_OK;
  sqlite3_vfs dummyVfs;

  fd = open(path, O_RDWR | O_CREAT, SQLITE_DEFAULT_FILE_PERMISSIONS);
  if( fd<0 ){
    return SQLITE_CANTOPEN;
  }
  
  pNew = (unixFile *)sqlite3_malloc(sizeof(unixFile));
  if( pNew==NULL ){
    rc = SQLITE_NOMEM;
  if( !pNew ){
    return SQLITE_NOMEM;
    goto end_create_proxy;
  }
  memset(pNew, 0, sizeof(unixFile));

  /* Call unixOpen() to open the proxy file. The flags passed to unixOpen()
  ** suggest that the file being opened is a "main database". This is
  ** necessary as other file types do not necessarily support locking. It
  ** is better to use unixOpen() instead of opening the file directly with
  ** open(), as unixOpen() sets up the various mechanisms required to
  ** make sure a call to close() does not cause the system to discard
  ** POSIX locks prematurely.
  **
  ** It is important that the xOpen member of the VFS object passed to 
  ** unixOpen() is NULL. This tells unixOpen() may try to open a proxy-file 
  ** for the proxy-file (creating a potential infinite loop).
  */
  dummyVfs.pAppData = (void*)&autolockIoFinder;
  rc = fillInUnixFile(&dummyVfs, fd, dirfd, (sqlite3_file*)pNew, path, 0, 0);
  if( rc==SQLITE_OK ){
    *ppFile = pNew;
    return SQLITE_OK;
  dummyVfs.xOpen = 0;
  rc = unixOpen(&dummyVfs, path, (sqlite3_file *)pNew, flags, &flags);
  if( rc==SQLITE_OK && (flags&SQLITE_OPEN_READONLY) ){
    pNew->pMethod->xClose((sqlite3_file *)pNew);
    rc = SQLITE_CANTOPEN;
  }
end_create_proxy:    

  close(fd); /* silently leak fd if error, we're already in error */
  sqlite3_free(pNew);
  if( rc!=SQLITE_OK ){
    sqlite3_free(pNew);
    pNew = 0;
  }

  *ppFile = pNew;
  return rc;
}

/* takes the conch by taking a shared lock and read the contents conch, if 
** lockPath is non-NULL, the host ID and lock file path must match.  A NULL 
** lockPath means that the lockPath in the conch file will be used if the 
** host IDs match, or a new lock path will be generated automatically 
5107
5108
5109
5110
5111
5112
5113

5114
5115
5116
5117
5118
5119
5120
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375







+







#if SQLITE_ENABLE_LOCKING_STYLE && (OS_VXWORKS || defined(__APPLE__))
    UNIXVFS("unix",          autolockIoFinder ),
#else
    UNIXVFS("unix",          posixIoFinder ),
#endif
    UNIXVFS("unix-none",     nolockIoFinder ),
    UNIXVFS("unix-dotfile",  dotlockIoFinder ),
    UNIXVFS("unix-wfl",      posixWflIoFinder ),
#if OS_VXWORKS
    UNIXVFS("unix-namedsem", semIoFinder ),
#endif
#if SQLITE_ENABLE_LOCKING_STYLE
    UNIXVFS("unix-posix",    posixIoFinder ),
#if !OS_VXWORKS
    UNIXVFS("unix-flock",    flockIoFinder ),
Changes to src/os_win.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2004 May 22
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains code that is specific to windows.
**
** $Id: os_win.c,v 1.156 2009/04/23 19:08:33 shane Exp $
*/
#include "sqliteInt.h"
#if SQLITE_OS_WIN               /* This file is used for windows only */


/*
** A Note About Memory Allocation:
71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83







-
+








/*
** Determine if we are dealing with WindowsCE - which has a much
** reduced API.
*/
#if SQLITE_OS_WINCE
# define AreFileApisANSI() 1
# define GetDiskFreeSpaceW() 0
# define FormatMessageW(a,b,c,d,e,f,g) 0
#endif

/*
** WinCE lacks native support for file locking so we have to fake it
** with some code of our own.
*/
#if SQLITE_OS_WINCE
305
306
307
308
309
310
311
312
313


314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333

334
335
336
337
338
339
340
303
304
305
306
307
308
309


310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330

331
332
333
334
335
336
337
338







-
-
+
+



















-
+







{
  static struct tm y;
  FILETIME uTm, lTm;
  SYSTEMTIME pTm;
  sqlite3_int64 t64;
  t64 = *t;
  t64 = (t64 + 11644473600)*10000000;
  uTm.dwLowDateTime = t64 & 0xFFFFFFFF;
  uTm.dwHighDateTime= t64 >> 32;
  uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF);
  uTm.dwHighDateTime= (DWORD)(t64 >> 32);
  FileTimeToLocalFileTime(&uTm,&lTm);
  FileTimeToSystemTime(&lTm,&pTm);
  y.tm_year = pTm.wYear - 1900;
  y.tm_mon = pTm.wMonth - 1;
  y.tm_wday = pTm.wDayOfWeek;
  y.tm_mday = pTm.wDay;
  y.tm_hour = pTm.wHour;
  y.tm_min = pTm.wMinute;
  y.tm_sec = pTm.wSecond;
  return &y;
}

/* This will never be called, but defined to make the code compile */
#define GetTempPathA(a,b)

#define LockFile(a,b,c,d,e)       winceLockFile(&a, b, c, d, e)
#define UnlockFile(a,b,c,d,e)     winceUnlockFile(&a, b, c, d, e)
#define LockFileEx(a,b,c,d,e,f)   winceLockFileEx(&a, b, c, d, e, f)

#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-offsetof(winFile,h)]
#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]

/*
** Acquire a lock on the handle h
*/
static void winceMutexAcquire(HANDLE h){
   DWORD dwErr;
   do {
465
466
467
468
469
470
471



472
473
474
475
476
477


478
479
480
481
482
483
484
485
486

487
488

489
490
491
492
493
494
495
496
497
498
499

500
501
502
503
504
505
506

507
508

509
510
511
512
513
514
515
463
464
465
466
467
468
469
470
471
472
473
474
475
476


477
478
479
480
481
482
483
484
485
486

487


488
489
490
491
492
493
494
495
496
497
498

499
500
501
502
503
504
505
506
507
508

509
510
511
512
513
514
515
516







+
+
+




-
-
+
+








-
+
-
-
+










-
+







+

-
+







  DWORD dwFileOffsetHigh,
  DWORD nNumberOfBytesToLockLow,
  DWORD nNumberOfBytesToLockHigh
){
  winFile *pFile = HANDLE_TO_WINFILE(phFile);
  BOOL bReturn = FALSE;

  UNUSED_PARAMETER(dwFileOffsetHigh);
  UNUSED_PARAMETER(nNumberOfBytesToLockHigh);

  if (!pFile->hMutex) return TRUE;
  winceMutexAcquire(pFile->hMutex);

  /* Wanting an exclusive lock? */
  if (dwFileOffsetLow == SHARED_FIRST
       && nNumberOfBytesToLockLow == SHARED_SIZE){
  if (dwFileOffsetLow == (DWORD)SHARED_FIRST
       && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
    if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
       pFile->shared->bExclusive = TRUE;
       pFile->local.bExclusive = TRUE;
       bReturn = TRUE;
    }
  }

  /* Want a read-only lock? */
  else if ((dwFileOffsetLow >= SHARED_FIRST &&
  else if (dwFileOffsetLow == (DWORD)SHARED_FIRST &&
            dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE) &&
            nNumberOfBytesToLockLow == 1){
           nNumberOfBytesToLockLow == 1){
    if (pFile->shared->bExclusive == 0){
      pFile->local.nReaders ++;
      if (pFile->local.nReaders == 1){
        pFile->shared->nReaders ++;
      }
      bReturn = TRUE;
    }
  }

  /* Want a pending lock? */
  else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToLockLow == 1){
  else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToLockLow == 1){
    /* If no pending lock has been acquired, then acquire it */
    if (pFile->shared->bPending == 0) {
      pFile->shared->bPending = TRUE;
      pFile->local.bPending = TRUE;
      bReturn = TRUE;
    }
  }

  /* Want a reserved lock? */
  else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
  else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
    if (pFile->shared->bReserved == 0) {
      pFile->shared->bReserved = TRUE;
      pFile->local.bReserved = TRUE;
      bReturn = TRUE;
    }
  }

526
527
528
529
530
531
532



533
534
535
536
537

538
539
540

541
542
543
544
545
546
547

548
549
550
551
552
553
554
555
556
557
558

559
560
561
562
563
564
565
566

567
568
569
570
571
572
573
527
528
529
530
531
532
533
534
535
536
537
538
539
540

541

542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562

563
564
565
566
567
568
569
570

571
572
573
574
575
576
577
578







+
+
+




-
+
-


+







+










-
+







-
+







  DWORD dwFileOffsetHigh,
  DWORD nNumberOfBytesToUnlockLow,
  DWORD nNumberOfBytesToUnlockHigh
){
  winFile *pFile = HANDLE_TO_WINFILE(phFile);
  BOOL bReturn = FALSE;

  UNUSED_PARAMETER(dwFileOffsetHigh);
  UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh);

  if (!pFile->hMutex) return TRUE;
  winceMutexAcquire(pFile->hMutex);

  /* Releasing a reader lock or an exclusive lock */
  if (dwFileOffsetLow >= SHARED_FIRST &&
  if (dwFileOffsetLow == (DWORD)SHARED_FIRST){
       dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE){
    /* Did we have an exclusive lock? */
    if (pFile->local.bExclusive){
      assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE);
      pFile->local.bExclusive = FALSE;
      pFile->shared->bExclusive = FALSE;
      bReturn = TRUE;
    }

    /* Did we just have a reader lock? */
    else if (pFile->local.nReaders){
      assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE || nNumberOfBytesToUnlockLow == 1);
      pFile->local.nReaders --;
      if (pFile->local.nReaders == 0)
      {
        pFile->shared->nReaders --;
      }
      bReturn = TRUE;
    }
  }

  /* Releasing a pending lock */
  else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
  else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
    if (pFile->local.bPending){
      pFile->local.bPending = FALSE;
      pFile->shared->bPending = FALSE;
      bReturn = TRUE;
    }
  }
  /* Releasing a reserved lock */
  else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
  else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
    if (pFile->local.bReserved) {
      pFile->local.bReserved = FALSE;
      pFile->shared->bReserved = FALSE;
      bReturn = TRUE;
    }
  }

582
583
584
585
586
587
588



589
590
591

592
593

594
595
596
597
598
599
600
587
588
589
590
591
592
593
594
595
596
597
598

599
600

601
602
603
604
605
606
607
608







+
+
+


-
+

-
+







  HANDLE *phFile,
  DWORD dwFlags,
  DWORD dwReserved,
  DWORD nNumberOfBytesToLockLow,
  DWORD nNumberOfBytesToLockHigh,
  LPOVERLAPPED lpOverlapped
){
  UNUSED_PARAMETER(dwReserved);
  UNUSED_PARAMETER(nNumberOfBytesToLockHigh);

  /* If the caller wants a shared read lock, forward this call
  ** to winceLockFile */
  if (lpOverlapped->Offset == SHARED_FIRST &&
  if (lpOverlapped->Offset == (DWORD)SHARED_FIRST &&
      dwFlags == 1 &&
      nNumberOfBytesToLockLow == SHARED_SIZE){
      nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
    return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);
  }
  return FALSE;
}
/*
** End of the special code for wince
*****************************************************************************/
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251


























1252
1253
1254
1255
1256





1257
1258


1259
1260
1261






1262
1263









1264
1265
1266
1267
1268
1269
1270
1244
1245
1246
1247
1248
1249
1250





1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280





1281
1282
1283
1284
1285


1286
1287



1288
1289
1290
1291
1292
1293
1294

1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310







-
-
-
-
-




+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
-
+
+
+
+
+
+

-
+
+
+
+
+
+
+
+
+








/*
** The return value of getLastErrorMsg
** is zero if the error message fits in the buffer, or non-zero
** otherwise (if the message was truncated).
*/
static int getLastErrorMsg(int nBuf, char *zBuf){
  DWORD error = GetLastError();

#if SQLITE_OS_WINCE
  sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
#else
  /* FormatMessage returns 0 on failure.  Otherwise it
  ** returns the number of TCHARs written to the output
  ** buffer, excluding the terminating null char.
  */
  DWORD error = GetLastError();
  DWORD dwLen = 0;
  char *zOut = 0;

  if( isNT() ){
    WCHAR *zTempWide = NULL;
    dwLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                           NULL,
                           error,
                           0,
                           (LPWSTR) &zTempWide,
                           0,
                           0);
    if( dwLen > 0 ){
      /* allocate a buffer and convert to UTF8 */
      zOut = unicodeToUtf8(zTempWide);
      /* free the system buffer allocated by FormatMessage */
      LocalFree(zTempWide);
    }
/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
** Since the ASCII version of these Windows API do not exist for WINCE,
** it's important to not reference them for WINCE builds.
*/
#if SQLITE_OS_WINCE==0
  }else{
    char *zTemp = NULL;
  if (!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
                      NULL,
                      error,
                      0,
                      zBuf,
    dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                           NULL,
                           error,
                           0,
                           (LPSTR) &zTemp,
                      nBuf-1,
                      0))
                           0,
                           0);
  {
    sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
  }
    if( dwLen > 0 ){
      /* allocate a buffer and convert to UTF8 */
      zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
      /* free the system buffer allocated by FormatMessage */
      LocalFree(zTemp);
    }
#endif

  }
  if( 0 == dwLen ){
    sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
  }else{
    /* copy a maximum of nBuf chars to output buffer */
    sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
    /* free the UTF8 buffer */
    free(zOut);
  }
  return 0;
}

/*
** Open a file.
*/
static int winOpen(
1588
1589
1590
1591
1592
1593
1594





1595
1596
1597


1598
1599
1600
1601
1602
1603
1604
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641

1642
1643
1644
1645
1646
1647
1648
1649
1650







+
+
+
+
+


-
+
+







** file.
*/
static int getSectorSize(
    sqlite3_vfs *pVfs,
    const char *zRelative     /* UTF-8 file name */
){
  DWORD bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE;
  /* GetDiskFreeSpace is not supported under WINCE */
#if SQLITE_OS_WINCE
  UNUSED_PARAMETER(pVfs);
  UNUSED_PARAMETER(zRelative);
#else
  char zFullpath[MAX_PATH+1];
  int rc;
  DWORD dwRet = 0, dwDummy;
  DWORD dwRet = 0;
  DWORD dwDummy;

  /*
  ** We need to get the full path name of the file
  ** to get the drive letter to look up the sector
  ** size.
  */
  rc = winFullPathname(pVfs, zRelative, MAX_PATH, zFullpath);
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626

1627
1628
1629
1630
1631
1632
1633

1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645

1646
1647
1648
1649
1650
1651
1652
1662
1663
1664
1665
1666
1667
1668

1669
1670

1671
1672
1673
1674
1675
1676
1677

1678
1679
1680
1681
1682

1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697







-


-
+






-
+




-







+







          }
        }
        dwRet = GetDiskFreeSpaceW((WCHAR*)zConverted,
                                  &dwDummy,
                                  &bytesPerSector,
                                  &dwDummy,
                                  &dwDummy);
#if SQLITE_OS_WINCE==0
      }else{
        /* trim path to just drive reference */
        CHAR *p = (CHAR *)zConverted;
        char *p = (char *)zConverted;
        for(;*p;p++){
          if( *p == '\\' ){
            *p = '\0';
            break;
          }
        }
        dwRet = GetDiskFreeSpaceA((CHAR*)zConverted,
        dwRet = GetDiskFreeSpaceA((char*)zConverted,
                                  &dwDummy,
                                  &bytesPerSector,
                                  &dwDummy,
                                  &dwDummy);
#endif
      }
      free(zConverted);
    }
    if( !dwRet ){
      bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE;
    }
  }
#endif
  return (int) bytesPerSector; 
}

#ifndef SQLITE_OMIT_LOAD_EXTENSION
/*
** Interfaces for opening a shared library, finding entry points
** within the shared library, and closing the shared library.
1865
1866
1867
1868
1869
1870
1871

1872
1873
1874
1875
1876
1877
1878
1879
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925







+








    winDlSym,          /* xDlSym */
    winDlClose,        /* xDlClose */
    winRandomness,     /* xRandomness */
    winSleep,          /* xSleep */
    winCurrentTime,    /* xCurrentTime */
    winGetLastError    /* xGetLastError */
  };

  sqlite3_vfs_register(&winVfs, 1);
  return SQLITE_OK; 
}
int sqlite3_os_end(void){ 
  return SQLITE_OK;
}

#endif /* SQLITE_OS_WIN */
Changes to src/pager.c.
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
13
14
15
16
17
18
19


20
21
22
23
24
25
26







-
-







** 
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.603 2009/06/26 12:15:23 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"

/*
** Macros for troubleshooting.  Normally turned off
*/
110
111
112
113
114
115
116
117

118
119
120
121
122

123
124
125
126
127
128
129
108
109
110
111
112
113
114

115
116
117
118
119

120
121
122
123
124
125
126
127







-
+




-
+







    if( (O=(char*)(P->xCodec(P->pCodec,D,N,X)))==0 ){ E; }
#else
# define CODEC1(P,D,N,X,E)   /* NO-OP */
# define CODEC2(P,D,N,X,E,O) O=(char*)D
#endif

/*
** The maximum allowed sector size. 16MB. If the xSectorsize() method 
** The maximum allowed sector size. 64KiB. If the xSectorsize() method 
** returns a value larger than this, then MAX_SECTOR_SIZE is used instead.
** This could conceivably cause corruption following a power failure on
** such a system. This is currently an undocumented limit.
*/
#define MAX_SECTOR_SIZE 0x0100000
#define MAX_SECTOR_SIZE 0x10000

/*
** An instance of the following structure is allocated for each active
** savepoint and statement transaction in the system. All such structures
** are stored in the Pager.aSavepoint[] array, which is allocated and
** resized using sqlite3Realloc().
**
781
782
783
784
785
786
787
788
789

790
791
792
793
794
795
796
779
780
781
782
783
784
785


786
787
788
789
790
791
792
793







-
-
+







  assert( isOpen(pPager->fd) || pPager->noSync );
  if( (pPager->noSync) || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY)
   || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) 
  ){
    memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
    put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff);
  }else{
    zHeader[0] = '\0';
    put32bits(&zHeader[sizeof(aJournalMagic)], 0);
    memset(zHeader, 0, sizeof(aJournalMagic)+4);
  }

  /* The random check-hash initialiser */ 
  sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
  put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit);
  /* The initial database size */
  put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbOrigSize);
1123
1124
1125
1126
1127
1128
1129
1130

1131
1132
1133
1134
1135
1136
1137
1120
1121
1122
1123
1124
1125
1126

1127
1128
1129
1130
1131
1132
1133
1134







-
+







    sqlite3BitvecDestroy(pPager->pInJournal);
    pPager->pInJournal = 0;
    releaseAllSavepoints(pPager);

    /* If the file is unlocked, somebody else might change it. The
    ** values stored in Pager.dbSize etc. might become invalid if
    ** this happens. TODO: Really, this doesn't need to be cleared
    ** until the change-counter check fails in pagerSharedLock().
    ** until the change-counter check fails in PagerSharedLock().
    */
    pPager->dbSizeValid = 0;

    rc = osUnlock(pPager->fd, NO_LOCK);
    if( rc ){
      pPager->errCode = rc;
    }
1170
1171
1172
1173
1174
1175
1176

1177
1178
1179
1180
1181
1182
1183

1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179


1180



1181









1182
1183
1184
1185
1186
1187
1188







+





-
-
+
-
-
-

-
-
-
-
-
-
-
-
-







** the contents of the pager-cache. If a transaction was active when
** the persistent error occurred, then the rollback journal may need
** to be replayed to restore the contents of the database file (as if
** it were a hot-journal).
*/
static int pager_error(Pager *pPager, int rc){
  int rc2 = rc & 0xff;
  assert( rc==SQLITE_OK || !MEMDB );
  assert(
       pPager->errCode==SQLITE_FULL ||
       pPager->errCode==SQLITE_OK ||
       (pPager->errCode & 0xff)==SQLITE_IOERR
  );
  if(
    rc2==SQLITE_FULL ||
  if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){
    rc2==SQLITE_IOERR ||
    rc2==SQLITE_CORRUPT
  ){
    pPager->errCode = rc;
    if( pPager->state==PAGER_UNLOCK 
     && sqlite3PcacheRefCount(pPager->pPCache)==0 
    ){
      /* If the pager is already unlocked, call pager_unlock() now to
      ** clear the error state and ensure that the pager-cache is 
      ** completely empty.
      */
      pager_unlock(pPager);
    }
  }
  return rc;
}

/*
** Execute a rollback if a transaction is active and unlock the 
** database file. 
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303

1304

1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325




1326



1327
1328

1329
1330
1331
1332
1333
1334
1335
1273
1274
1275
1276
1277
1278
1279








1280
1281

1282

1283



1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303

1304
1305
1306
1307

1308
1309
1310
1311
1312
1313
1314
1315







-
-
-
-
-
-
-
-

+
-
+
-

-
-
-
















+
+
+
+
-
+
+
+

-
+







    return SQLITE_OK;
  }
  releaseAllSavepoints(pPager);

  assert( isOpen(pPager->jfd) || pPager->pInJournal==0 );
  if( isOpen(pPager->jfd) ){

    /* TODO: There's a problem here if a journal-file was opened in MEMORY
    ** mode and then the journal-mode is changed to TRUNCATE or PERSIST
    ** during the transaction. This code should be changed to assume
    ** that the journal mode has not changed since the transaction was
    ** started. And the sqlite3PagerJournalMode() function should be
    ** changed to make sure that this is the case too.
    */

    /* Finalize the journal file. */
    if( sqlite3IsMemJournal(pPager->jfd) ){
    if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
      assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY );
      int isMemoryJournal = sqlite3IsMemJournal(pPager->jfd);
      sqlite3OsClose(pPager->jfd);
      if( !isMemoryJournal ){
        rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
      }
    }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
      if( pPager->journalOff==0 ){
        rc = SQLITE_OK;
      }else{
        rc = sqlite3OsTruncate(pPager->jfd, 0);
      }
      pPager->journalOff = 0;
      pPager->journalStarted = 0;
    }else if( pPager->exclusiveMode 
     || pPager->journalMode==PAGER_JOURNALMODE_PERSIST
    ){
      rc = zeroJournalHdr(pPager, hasMaster);
      pager_error(pPager, rc);
      pPager->journalOff = 0;
      pPager->journalStarted = 0;
    }else{
      /* This branch may be executed with Pager.journalMode==MEMORY if
      ** a hot-journal was just rolled back. In this case the journal
      ** file should be closed and deleted. If this connection writes to
      ** the database file, it will do so using an in-memory journal.  */
      assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE || rc );
      assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE 
           || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
      );
      sqlite3OsClose(pPager->jfd);
      if( rc==SQLITE_OK && !pPager->tempFile ){
      if( !pPager->tempFile ){
        rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
      }
    }

#ifdef SQLITE_CHECK_PAGES
    sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
#endif
1571
1572
1573
1574
1575
1576
1577
1578
1579

1580
1581
1582
1583
1584
1585
1586
1587
1551
1552
1553
1554
1555
1556
1557


1558

1559
1560
1561
1562
1563
1564
1565







-
-
+
-







    ** database active. However such a page may be rolled back as a result
    ** of an internal error resulting in an automatic call to
    ** sqlite3PagerRollback().
    */
    void *pData;
    pData = pPg->pData;
    memcpy(pData, aData, pPager->pageSize);
    if( pPager->xReiniter ){
      pPager->xReiniter(pPg);
    pPager->xReiniter(pPg);
    }
    if( isMainJrnl && (!isSavepnt || *pOffset<=pPager->journalHdr) ){
      /* If the contents of this page were just restored from the main 
      ** journal file, then its content must be as they were when the 
      ** transaction was first opened. In this case we can mark the page
      ** as clean, since there will be no need to write it out to the.
      **
      ** There is one exception to this rule. If the page is being rolled
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1589
1590
1591
1592
1593
1594
1595








































1596
1597
1598
1599
1600
1601
1602







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    /* Decode the page just read from disk */
    CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM);
    sqlite3PcacheRelease(pPg);
  }
  return rc;
}

#if !defined(NDEBUG) || defined(SQLITE_COVERAGE_TEST)
/*
** This routine looks ahead into the main journal file and determines
** whether or not the next record (the record that begins at file
** offset pPager->journalOff) is a well-formed page record consisting
** of a valid page number, pPage->pageSize bytes of content, followed
** by a valid checksum.
**
** The pager never needs to know this in order to do its job.   This
** routine is only used from with assert() and testcase() macros.
*/
static int pagerNextJournalPageIsValid(Pager *pPager){
  Pgno pgno;           /* The page number of the page */
  u32 cksum;           /* The page checksum */
  int rc;              /* Return code from read operations */
  sqlite3_file *fd;    /* The file descriptor from which we are reading */
  u8 *aData;           /* Content of the page */

  /* Read the page number header */
  fd = pPager->jfd;
  rc = read32bits(fd, pPager->journalOff, &pgno);
  if( rc!=SQLITE_OK ){ return 0; }                                  /*NO_TEST*/
  if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){ return 0; }         /*NO_TEST*/
  if( pgno>(Pgno)pPager->dbSize ){ return 0; }                      /*NO_TEST*/

  /* Read the checksum */
  rc = read32bits(fd, pPager->journalOff+pPager->pageSize+4, &cksum);
  if( rc!=SQLITE_OK ){ return 0; }                                  /*NO_TEST*/

  /* Read the data and verify the checksum */
  aData = (u8*)pPager->pTmpSpace;
  rc = sqlite3OsRead(fd, aData, pPager->pageSize, pPager->journalOff+4);
  if( rc!=SQLITE_OK ){ return 0; }                                  /*NO_TEST*/
  if( pager_cksum(pPager, aData)!=cksum ){ return 0; }              /*NO_TEST*/

  /* Reach this point only if the page is valid */
  return 1;
}
#endif /* !defined(NDEBUG) || defined(SQLITE_COVERAGE_TEST) */

/*
** Parameter zMaster is the name of a master journal file. A single journal
** file that referred to the master journal file has just been rolled back.
** This routine checks if it is possible to delete the master journal file,
** and does so if it is.
**
** Argument zMaster may point to Pager.pTmpSpace. So that buffer is not 
1726
1727
1728
1729
1730
1731
1732
1733

1734
1735
1736
1737
1738

1739
1740

1741
1742
1743
1744
1745
1746
1747
1664
1665
1666
1667
1668
1669
1670

1671
1672
1673
1674
1675

1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686







-
+




-
+


+







    char *zJournal;
    char *zMasterPtr = 0;
    int nMasterPtr = pVfs->mxPathname+1;

    /* Load the entire master journal file into space obtained from
    ** sqlite3_malloc() and pointed to by zMasterJournal. 
    */
    zMasterJournal = (char *)sqlite3Malloc((int)nMasterJournal + nMasterPtr);
    zMasterJournal = sqlite3Malloc((int)nMasterJournal + nMasterPtr + 1);
    if( !zMasterJournal ){
      rc = SQLITE_NOMEM;
      goto delmaster_out;
    }
    zMasterPtr = &zMasterJournal[nMasterJournal];
    zMasterPtr = &zMasterJournal[nMasterJournal+1];
    rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0);
    if( rc!=SQLITE_OK ) goto delmaster_out;
    zMasterJournal[nMasterJournal] = 0;

    zJournal = zMasterJournal;
    while( (zJournal-zMasterJournal)<nMasterJournal ){
      int exists;
      rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists);
      if( rc!=SQLITE_OK ){
        goto delmaster_out;
1875
1876
1877
1878
1879
1880
1881
1882
1883


1884
1885
1886
1887
1888
1889
1890

1891
1892
1893
1894
1895
1896


1897
1898
1899
1900
1901
1902
1903
1814
1815
1816
1817
1818
1819
1820


1821
1822







1823
1824
1825
1826
1827


1828
1829
1830
1831
1832
1833
1834
1835
1836







-
-
+
+
-
-
-
-
-
-
-
+




-
-
+
+







**       number of page records from the journal size.
**  (3)  4 byte big-endian integer which is the initial value for the 
**       sanity checksum.
**  (4)  4 byte integer which is the number of pages to truncate the
**       database to during a rollback.
**  (5)  4 byte big-endian integer which is the sector size.  The header
**       is this many bytes in size.
**  (6)  4 byte big-endian integer which is the page case.
**  (7)  4 byte integer which is the number of bytes in the master journal
**  (6)  4 byte big-endian integer which is the page size.
**  (7)  zero padding out to the next sector size.
**       name.  The value may be zero (indicate that there is no master
**       journal.)
**  (8)  N bytes of the master journal name.  The name will be nul-terminated
**       and might be shorter than the value read from (5).  If the first byte
**       of the name is \000 then there is no master journal.  The master
**       journal name is stored in UTF-8.
**  (9)  Zero or more pages instances, each as follows:
**  (8)  Zero or more pages instances, each as follows:
**        +  4 byte page number.
**        +  pPager->pageSize bytes of data.
**        +  4 byte checksum
**
** When we speak of the journal header, we mean the first 8 items above.
** Each entry in the journal is an instance of the 9th item.
** When we speak of the journal header, we mean the first 7 items above.
** Each entry in the journal is an instance of the 8th item.
**
** Call the value from the second bullet "nRec".  nRec is the number of
** valid page entries in the journal.  In most cases, you can compute the
** value of nRec from the size of the journal file.  But if a power
** failure occurred while the journal was being written, it could be the
** case that the size of the journal file had already been increased but
** the extra entries had not yet made it safely to disk.  In such a case,
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
1942
1943
1944
1945
1946
1947
1948





1949
1950
1951
1952
1953
1954
1955







-
-
-
-
-







    ** When rolling back a hot journal, nRec==0 always means that the next
    ** chunk of the journal contains zero pages to be rolled back.  But
    ** when doing a ROLLBACK and the nRec==0 chunk is the last chunk in
    ** the journal, it means that the journal might contain additional
    ** pages that need to be rolled back and that the number of pages 
    ** should be computed based on the journal file size.
    */
    testcase( nRec==0 && !isHot
         && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)!=pPager->journalOff
         && ((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager))>0
         && pagerNextJournalPageIsValid(pPager)
    );
    if( nRec==0 && !isHot &&
        pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){
      nRec = (int)((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager));
      isUnsync = 1;
    }

    /* If this is the first header read from the journal, truncate the
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2133
2134
2135
2136
2137
2138
2139





2140
2141
2142
2143
2144
2145
2146







-
-
-
-
-







    assert( rc!=SQLITE_DONE );

    /*
    ** The "pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff"
    ** test is related to ticket #2565.  See the discussion in the
    ** pager_playback() function for additional information.
    */
    assert( !(nJRec==0
         && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)!=pPager->journalOff
         && ((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager))>0
         && pagerNextJournalPageIsValid(pPager))
    );
    if( nJRec==0 
     && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff
    ){
      nJRec = (u32)((szJ - pPager->journalOff)/JOURNAL_PG_SZ(pPager));
    }
    for(ii=0; rc==SQLITE_OK && ii<nJRec && pPager->journalOff<szJ; ii++){
      rc = pager_playback_one_page(pPager, 1, 0, &pPager->journalOff, 1, pDone);
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2280
2281
2282
2283
2284
2285
2286











2287
2288
2289
2290
2291
2292
2293







-
-
-
-
-
-
-
-
-
-
-







  int (*xBusyHandler)(void *),         /* Pointer to busy-handler function */
  void *pBusyHandlerArg                /* Argument to pass to xBusyHandler */
){  
  pPager->xBusyHandler = xBusyHandler;
  pPager->pBusyHandlerArg = pBusyHandlerArg;
}

/*
** Set the reinitializer for this pager. If not NULL, the reinitializer
** is called when the content of a page in cache is modified (restored)
** as part of a transaction or savepoint rollback. The callback gives 
** higher-level code an opportunity to restore the EXTRA section to 
** agree with the restored page data.
*/
void sqlite3PagerSetReiniter(Pager *pPager, void (*xReinit)(DbPage*)){
  pPager->xReiniter = xReinit;
}

/*
** Report the current page size and number of reserved bytes back
** to the codec.
*/
#ifdef SQLITE_HAS_CODEC
static void pagerReportSize(Pager *pPager){
  if( pPager->xCodecSizeChng ){
2415
2416
2417
2418
2419
2420
2421

2422
2423
2424
2425
2426

2427

2428
2429
2430
2431
2432
2433
2434
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337


2338
2339
2340
2341
2342
2343
2344
2345
2346
2347







+



-
-
+

+







** If the page size is not changed, either because one of the enumerated
** conditions above is not true, the pager was in error state when this
** function was called, or because the memory allocation attempt failed, 
** then *pPageSize is set to the old, retained page size before returning.
*/
int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize, int nReserve){
  int rc = pPager->errCode;

  if( rc==SQLITE_OK ){
    u16 pageSize = *pPageSize;
    assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) );
    if( pageSize && pageSize!=pPager->pageSize 
     && (pPager->memDb==0 || pPager->dbSize==0)
    if( (pPager->memDb==0 || pPager->dbSize==0)
     && sqlite3PcacheRefCount(pPager->pPCache)==0 
     && pageSize && pageSize!=pPager->pageSize 
    ){
      char *pNew = (char *)sqlite3PageMalloc(pageSize);
      if( !pNew ){
        rc = SQLITE_NOMEM;
      }else{
        pager_reset(pPager);
        pPager->pageSize = pageSize;
2633
2634
2635
2636
2637
2638
2639


































2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650

2651
2652
2653
2654
2655
2656
2657
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+











+







      pPager->state = (u8)locktype;
      IOTRACE(("LOCK %p %d\n", pPager, locktype))
    }
  }
  return rc;
}

/*
** Function assertTruncateConstraint(pPager) checks that one of the 
** following is true for all dirty pages currently in the page-cache:
**
**   a) The page number is less than or equal to the size of the 
**      current database image, in pages, OR
**
**   b) if the page content were written at this time, it would not
**      be necessary to write the current content out to the sub-journal
**      (as determined by function subjRequiresPage()).
**
** If the condition asserted by this function were not true, and the
** dirty page were to be discarded from the cache via the pagerStress()
** routine, pagerStress() would not write the current page content to
** the database file. If a savepoint transaction were rolled back after
** this happened, the correct behaviour would be to restore the current
** content of the page. However, since this content is not present in either
** the database file or the portion of the rollback journal and 
** sub-journal rolled back the content could not be restored and the
** database image would become corrupt. It is therefore fortunate that 
** this circumstance cannot arise.
*/
#if defined(SQLITE_DEBUG)
static void assertTruncateConstraintCb(PgHdr *pPg){
  assert( pPg->flags&PGHDR_DIRTY );
  assert( !subjRequiresPage(pPg) || pPg->pgno<=pPg->pPager->dbSize );
}
static void assertTruncateConstraint(Pager *pPager){
  sqlite3PcacheIterateDirty(pPager->pPCache, assertTruncateConstraintCb);
}
#else
# define assertTruncateConstraint(pPager)
#endif

/*
** Truncate the in-memory database file image to nPage pages. This 
** function does not actually modify the database file on disk. It 
** just sets the internal state of the pager object so that the 
** truncation will be done when the current transaction is committed.
*/
void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
  assert( pPager->dbSizeValid );
  assert( pPager->dbSize>=nPage );
  assert( pPager->state>=PAGER_RESERVED );
  pPager->dbSize = nPage;
  assertTruncateConstraint(pPager);
}

/*
** Shutdown the page cache.  Free all memory and close all files.
**
** If a transaction was in progress when this routine is called, that
** transaction is rolled back.  All outstanding pages are invalidated
2879
2880
2881
2882
2883
2884
2885
2886

2887
2888
2889
2890
2891
2892
2893
2827
2828
2829
2830
2831
2832
2833

2834
2835
2836
2837
2838
2839
2840
2841







-
+







** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot
** be obtained, SQLITE_BUSY is returned.
*/
static int pager_write_pagelist(PgHdr *pList){
  Pager *pPager;                       /* Pager object */
  int rc;                              /* Return code */

  if( pList==0 ) return SQLITE_OK;
  if( NEVER(pList==0) ) return SQLITE_OK;
  pPager = pList->pPager;

  /* At this point there may be either a RESERVED or EXCLUSIVE lock on the
  ** database file. If there is already an EXCLUSIVE lock, the following
  ** call is a no-op.
  **
  ** Moving the lock from RESERVED to EXCLUSIVE actually involves going
2919
2920
2921
2922
2923
2924
2925
2926



2927
2928
2929
2930
2931
2932
2933
2867
2868
2869
2870
2871
2872
2873

2874
2875
2876
2877
2878
2879
2880
2881
2882
2883







-
+
+
+








    /* If there are dirty pages in the page cache with page numbers greater
    ** than Pager.dbSize, this means sqlite3PagerTruncateImage() was called to
    ** make the file smaller (presumably by auto-vacuum code). Do not write
    ** any such pages to the file.
    **
    ** Also, do not write out any page that has the PGHDR_DONT_WRITE flag
    ** set (set by sqlite3PagerDontWrite()).
    ** set (set by sqlite3PagerDontWrite()).  Note that if compiled with
    ** SQLITE_SECURE_DELETE the PGHDR_DONT_WRITE bit is never set and so
    ** the second test is always true.
    */
    if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){
      i64 offset = (pgno-1)*(i64)pPager->pageSize;   /* Offset to write */
      char *pData;                                   /* Data to write */    

      /* Encode the database */
      CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
2946
2947
2948
2949
2950
2951
2952

2953
2954
2955
2956
2957
2958
2959







-







      rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4);
    }
  }
  if( rc==SQLITE_OK ){
    pPager->nSubRec++;
    assert( pPager->nSavepoint>0 );
    rc = addToSavepointBitvecs(pPager, pPg->pgno);
    testcase( rc!=SQLITE_OK );
  }
  return rc;
}


/*
** This function is called by the pcache layer when it has reached some
3041
3042
3043
3044
3045
3046
3047

3048


3049
3050
3051
3052
3053
3054
3055
2990
2991
2992
2993
2994
2995
2996
2997

2998
2999
3000
3001
3002
3003
3004
3005
3006







+
-
+
+







  ** flag is set, return without doing anything. The pcache layer will
  ** just have to go ahead and allocate a new page buffer instead of
  ** reusing pPg.
  **
  ** Similarly, if the pager has already entered the error state, do not
  ** try to write the contents of pPg to disk.
  */
  if( NEVER(pPager->errCode)
  if( pPager->errCode || (pPager->doNotSync && pPg->flags&PGHDR_NEED_SYNC) ){
   || (pPager->doNotSync && pPg->flags&PGHDR_NEED_SYNC)
  ){
    return SQLITE_OK;
  }

  /* Sync the journal file if required. */
  if( pPg->flags&PGHDR_NEED_SYNC ){
    rc = syncJournal(pPager);
    if( rc==SQLITE_OK && pPager->fullSync && 
3084
3085
3086
3087
3088
3089
3090

3091


3092
3093
3094
3095
3096
3097
3098
3035
3036
3037
3038
3039
3040
3041
3042

3043
3044
3045
3046
3047
3048
3049
3050
3051







+
-
+
+







  ** was executed.
  **
  ** The solution is to write the current data for page X into the 
  ** sub-journal file now (if it is not already there), so that it will
  ** be restored to its current value when the "ROLLBACK TO sp" is 
  ** executed.
  */
  if( NEVER(
  if( rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg) ){
      rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg)
  ) ){
    rc = subjournalPage(pPg);
  }

  /* Write the contents of the page out to the database file. */
  if( rc==SQLITE_OK ){
    pPg->pDirty = 0;
    rc = pager_write_pagelist(pPg);
3140
3141
3142
3143
3144
3145
3146
3147


3148
3149
3150
3151
3152
3153
3154
3093
3094
3095
3096
3097
3098
3099

3100
3101
3102
3103
3104
3105
3106
3107
3108







-
+
+







*/
int sqlite3PagerOpen(
  sqlite3_vfs *pVfs,       /* The virtual file system to use */
  Pager **ppPager,         /* OUT: Return the Pager structure here */
  const char *zFilename,   /* Name of the database file to open */
  int nExtra,              /* Extra bytes append to each in-memory page */
  int flags,               /* flags controlling this file */
  int vfsFlags             /* flags passed through to sqlite3_vfs.xOpen() */
  int vfsFlags,            /* flags passed through to sqlite3_vfs.xOpen() */
  void (*xReinit)(DbPage*) /* Function to reinitialize pages */
){
  u8 *pPtr;
  Pager *pPager = 0;       /* Pager object to allocate and return */
  int rc = SQLITE_OK;      /* Return code */
  int tempFile = 0;        /* True for temp files (incl. in-memory files) */
  int memDb = 0;           /* True if this is an in-memory file */
  int readOnly = 0;        /* True if this is a read-only file */
3249
3250
3251
3252
3253
3254
3255

3256
3257
3258
3259
3260
3261
3262
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217







+








  /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */
  if( zPathname ){
    pPager->zJournal =   (char*)(pPtr += nPathname + 1);
    memcpy(pPager->zFilename, zPathname, nPathname);
    memcpy(pPager->zJournal, zPathname, nPathname);
    memcpy(&pPager->zJournal[nPathname], "-journal", 8);
    if( pPager->zFilename[0]==0 ) pPager->zJournal[0] = 0;
    sqlite3_free(zPathname);
  }
  pPager->pVfs = pVfs;
  pPager->vfsFlags = vfsFlags;

  /* Open the pager file.
  */
3358
3359
3360
3361
3362
3363
3364

3365

3366
3367
3368
3369
3370
3371
3372
3373
3374


3375

3376
3377
3378
3379

3380
3381
3382
3383
3384
3385
3386
3313
3314
3315
3316
3317
3318
3319
3320

3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332

3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345







+
-
+









+
+
-
+




+







          || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE );
  assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 );
  pPager->exclusiveMode = (u8)tempFile; 
  pPager->changeCountDone = pPager->tempFile;
  pPager->memDb = (u8)memDb;
  pPager->readOnly = (u8)readOnly;
  /* pPager->needSync = 0; */
  assert( useJournal || pPager->tempFile );
  pPager->noSync = (pPager->tempFile || !useJournal) ?1:0;
  pPager->noSync = pPager->tempFile;
  pPager->fullSync = pPager->noSync ?0:1;
  pPager->sync_flags = SQLITE_SYNC_NORMAL;
  /* pPager->pFirst = 0; */
  /* pPager->pFirstSynced = 0; */
  /* pPager->pLast = 0; */
  pPager->nExtra = (u16)nExtra;
  pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT;
  assert( isOpen(pPager->fd) || tempFile );
  setSectorSize(pPager);
  if( !useJournal ){
    pPager->journalMode = PAGER_JOURNALMODE_OFF;
  if( memDb ){
  }else if( memDb ){
    pPager->journalMode = PAGER_JOURNALMODE_MEMORY;
  }
  /* pPager->xBusyHandler = 0; */
  /* pPager->pBusyHandlerArg = 0; */
  pPager->xReiniter = xReinit;
  /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
  *ppPager = pPager;
  return SQLITE_OK;
}



3420
3421
3422
3423
3424
3425
3426

3427
3428
3429
3430
3431
3432
3433
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393







+







  int rc;                       /* Return code */
  int exists;                   /* True if a journal file is present */

  assert( pPager!=0 );
  assert( pPager->useJournal );
  assert( isOpen(pPager->fd) );
  assert( !isOpen(pPager->jfd) );
  assert( pPager->state <= PAGER_SHARED );

  *pExists = 0;
  rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists);
  if( rc==SQLITE_OK && exists ){
    int locked;                 /* True if some process holds a RESERVED lock */

    /* Race condition here:  Another process might have been holding the
3448
3449
3450
3451
3452
3453
3454
3455
3456

3457
3458
3459
3460

3461
3462
3463
3464
3465
3466
3467
3468
3408
3409
3410
3411
3412
3413
3414


3415
3416



3417

3418
3419
3420
3421
3422
3423
3424







-
-
+

-
-
-
+
-







      ** a RESERVED lock to avoid race conditions and to avoid violating
      ** [H33020].
      */
      rc = sqlite3PagerPagecount(pPager, &nPage);
      if( rc==SQLITE_OK ){
        if( nPage==0 ){
          sqlite3BeginBenignMalloc();
          if( pPager->state>=PAGER_RESERVED
                 ||  sqlite3OsLock(pPager->fd, RESERVED_LOCK)==SQLITE_OK ){
          if( sqlite3OsLock(pPager->fd, RESERVED_LOCK)==SQLITE_OK ){
            sqlite3OsDelete(pVfs, pPager->zJournal, 0);
            assert( pPager->state>=PAGER_SHARED );
            if( pPager->state==PAGER_SHARED ){
              sqlite3OsUnlock(pPager->fd, SHARED_LOCK);
            sqlite3OsUnlock(pPager->fd, SHARED_LOCK);
            }
          }
          sqlite3EndBenignMalloc();
        }else{
          /* The journal file exists and no other connection has a reserved
          ** or greater lock on the database file. Now check that there is
          ** at least one non-zero bytes at the start of the journal file.
          ** If there is, then we consider this journal to be hot. If not, 
3513
3514
3515
3516
3517
3518
3519

3520
3521

3522
3523
3524
3525
3526
3527
3528
3469
3470
3471
3472
3473
3474
3475
3476
3477

3478
3479
3480
3481
3482
3483
3484
3485







+

-
+







static int readDbPage(PgHdr *pPg){
  Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */
  Pgno pgno = pPg->pgno;       /* Page number to read */
  int rc;                      /* Return code */
  i64 iOffset;                 /* Byte offset of file to read from */

  assert( pPager->state>=PAGER_SHARED && !MEMDB );
  assert( isOpen(pPager->fd) );

  if( !isOpen(pPager->fd) ){
  if( NEVER(!isOpen(pPager->fd)) ){
    assert( pPager->tempFile );
    memset(pPg->pData, 0, pPager->pageSize);
    return SQLITE_OK;
  }
  iOffset = (pgno-1)*(i64)pPager->pageSize;
  rc = sqlite3OsRead(pPager->fd, pPg->pData, pPager->pageSize, iOffset);
  if( rc==SQLITE_IOERR_SHORT_READ ){
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550






3551
3552
3553
3554
3555
3556
3557
3497
3498
3499
3500
3501
3502
3503




3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516







-
-
-
-
+
+
+
+
+
+







  PAGERTRACE(("FETCH %d page %d hash(%08x)\n",
               PAGERID(pPager), pgno, pager_pagehash(pPg)));

  return rc;
}

/*
** This function is called whenever the upper layer requests a database
** page is requested, before the cache is checked for a suitable page
** or any data is read from the database. It performs the following
** two functions:
** This function is called to obtain a shared lock on the database file.
** It is illegal to call sqlite3PagerAcquire() until after this function
** has been successfully called. If a shared-lock is already held when
** this function is called, it is a no-op.
**
** The following operations are also performed by this function.
**
**   1) If the pager is currently in PAGER_UNLOCK state (no lock held
**      on the database file), then an attempt is made to obtain a
**      SHARED lock on the database file. Immediately after obtaining
**      the SHARED lock, the file-system is checked for a hot-journal,
**      which is played back if present. Following any hot-journal 
**      rollback, the contents of the cache are validated by checking
3569
3570
3571
3572
3573
3574
3575
3576

3577
3578
3579

3580
3581
3582
3583







3584
3585

3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606




3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620

3621
3622
3623
3624
3625
3626
3627
3528
3529
3530
3531
3532
3533
3534

3535
3536
3537
3538
3539




3540
3541
3542
3543
3544
3545
3546
3547

3548
3549
3550
3551
3552
3553
3554
3555








3556
3557
3558
3559
3560

3561
3562
3563
3564
3565
3566
3567
3568
3569


3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584







-
+



+
-
-
-
-
+
+
+
+
+
+
+

-
+







-
-
-
-
-
-
-
-





-
+
+
+
+





-
-







+







** the error state error code is returned. It is permitted to read the
** database when in SQLITE_FULL error state.
**
** Otherwise, if everything is successful, SQLITE_OK is returned. If an
** IO error occurs while locking the database, checking for a hot-journal
** file or rolling back a journal file, the IO error code is returned.
*/
static int pagerSharedLock(Pager *pPager){
int sqlite3PagerSharedLock(Pager *pPager){
  int rc = SQLITE_OK;                /* Return code */
  int isErrorReset = 0;              /* True if recovering from error state */

  /* This routine is only called from b-tree and only when there are no
  /* If this database has no outstanding page references and is in an 
  ** error-state, this is a chance to clear the error. Discard the 
  ** contents of the pager-cache and rollback any hot journal in the
  ** file-system.
  ** outstanding pages */
  assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
  if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; }

  /* If this database is in an error-state, now is a chance to clear
  ** the error. Discard the contents of the pager-cache and rollback
  ** any hot journal in the file-system.
  */
  if( !MEMDB && sqlite3PcacheRefCount(pPager->pPCache)==0 && pPager->errCode ){
  if( pPager->errCode ){
    if( isOpen(pPager->jfd) || pPager->zJournal ){
      isErrorReset = 1;
    }
    pPager->errCode = SQLITE_OK;
    pager_reset(pPager);
  }

  /* If the pager is still in an error state, do not proceed. The error 
  ** state will be cleared at some point in the future when all page 
  ** references are dropped and the cache can be discarded.
  */
  if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
    return pPager->errCode;
  }

  if( pPager->state==PAGER_UNLOCK || isErrorReset ){
    sqlite3_vfs * const pVfs = pPager->pVfs;
    int isHotJournal = 0;
    assert( !MEMDB );
    assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
    if( !pPager->noReadlock ){
    if( pPager->noReadlock ){
      assert( pPager->readOnly );
      pPager->state = PAGER_SHARED;
    }else{
      rc = pager_wait_on_lock(pPager, SHARED_LOCK);
      if( rc!=SQLITE_OK ){
        assert( pPager->state==PAGER_UNLOCK );
        return pager_error(pPager, rc);
      }
    }else if( pPager->state==PAGER_UNLOCK ){
      pPager->state = PAGER_SHARED;
    }
    assert( pPager->state>=SHARED_LOCK );

    /* If a journal file exists, and there is no RESERVED lock on the
    ** database file, then it either needs to be played back or deleted.
    */
    if( !isErrorReset ){
      assert( pPager->state <= PAGER_SHARED );
      rc = hasHotJournal(pPager, &isHotJournal);
      if( rc!=SQLITE_OK ){
        goto failed;
      }
    }
    if( isErrorReset || isHotJournal ){
      /* Get an EXCLUSIVE lock on the database file. At this point it is
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3722
3723
3724
3725
3726
3727
3728












3729
3730
3731
3732
3733





3734
3735
3736
3737
3738
3739
3740







-
-
-
-
-
-
-
-
-
-
-
-





-
-
-
-
-







  if( (sqlite3PcacheRefCount(pPager->pPCache)==0)
   && (!pPager->exclusiveMode || pPager->journalOff>0) 
  ){
    pagerUnlockAndRollback(pPager);
  }
}

/*
** Drop a page from the cache using sqlite3PcacheDrop().
**
** If this means there are now no pages with references to them, a rollback
** occurs and the lock on the database is removed.
*/
static void pagerDropPage(DbPage *pPg){
  Pager *pPager = pPg->pPager;
  sqlite3PcacheDrop(pPg);
  pagerUnlockIfUnused(pPager);
}

/*
** Acquire a reference to page number pgno in pager pPager (a page
** reference has type DbPage*). If the requested reference is 
** successfully obtained, it is copied to *ppPage and SQLITE_OK returned.
**
** This function calls pagerSharedLock() to obtain a SHARED lock on
** the database file if such a lock or greater is not already held.
** This may cause hot-journal rollback or a cache purge. See comments
** above function pagerSharedLock() for details.
**
** If the requested page is already in the cache, it is returned. 
** Otherwise, a new page object is allocated and populated with data
** read from the database file. In some cases, the pcache module may
** choose not to allocate a new page object and may reuse an existing
** object with no outstanding references.
**
** The extra data appended to a page is always initialized to zeros the 
3838
3839
3840
3841
3842
3843
3844
3845
3846

3847
3848
3849

3850
3851
3852
3853
3854
3855
3856
3857

3858
3859
3860
3861
3862
3863
3864
3865
3866








3867
3868
3869
3870
3871
3872





3873
3874


3875
3876
3877
3878
3879
3880
3881








3882
3883
3884
3885

3886
3887

3888

3889







3890
3891
3892
3893

3894
3895
3896
3897
3898
3899
3900


3901
3902
3903
3904
3905
3906
3907
3778
3779
3780
3781
3782
3783
3784

3785
3786
3787
3788

3789



3790




3791
3792
3793
3794






3795
3796
3797
3798
3799
3800
3801
3802




3803

3804
3805
3806
3807
3808
3809

3810
3811
3812






3813
3814
3815
3816
3817
3818
3819
3820


3821

3822

3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837

3838

3839
3840
3841
3842


3843
3844
3845
3846
3847
3848
3849
3850
3851







-

+


-
+
-
-
-

-
-
-
-
+



-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-

-
+
+
+
+
+

-
+
+

-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-

-
+
-

+

+

+
+
+
+
+
+
+



-
+
-




-
-
+
+







*/
int sqlite3PagerAcquire(
  Pager *pPager,      /* The pager open on the database file */
  Pgno pgno,          /* Page number to fetch */
  DbPage **ppPage,    /* Write a pointer to the page here */
  int noContent       /* Do not bother reading content from disk if true */
){
  PgHdr *pPg = 0;
  int rc;
  PgHdr *pPg;

  assert( assert_pager_state(pPager) );
  assert( pPager->state==PAGER_UNLOCK 
  assert( pPager->state>PAGER_UNLOCK );
       || sqlite3PcacheRefCount(pPager->pPCache)>0 
       || pgno==1
  );

  /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
  ** number greater than this, or zero, is requested.
  */
  if( pgno>PAGER_MAX_PGNO || pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){
  if( pgno==0 ){
    return SQLITE_CORRUPT_BKPT;
  }

  /* Make sure we have not hit any critical errors.
  */ 
  assert( pPager!=0 );
  *ppPage = 0;

  /* If this is the first page accessed, then get a SHARED lock
  /* If the pager is in the error state, return an error immediately. 
  ** Otherwise, request the page from the PCache layer. */
  if( pPager->errCode!=SQLITE_OK && pPager->errCode!=SQLITE_FULL ){
    rc = pPager->errCode;
  }else{
    rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, ppPage);
  }

  ** on the database file. pagerSharedLock() is a no-op if 
  ** a database lock is already held.
  */
  rc = pagerSharedLock(pPager);
  if( rc!=SQLITE_OK ){
    return rc;
    /* Either the call to sqlite3PcacheFetch() returned an error or the
    ** pager was already in the error-state when this function was called.
    ** Set pPg to 0 and jump to the exception handler.  */
    pPg = 0;
    goto pager_acquire_err;
  }
  assert( pPager->state!=PAGER_UNLOCK );
  assert( (*ppPage)->pgno==pgno );
  assert( (*ppPage)->pPager==pPager || (*ppPage)->pPager==0 );

  rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, &pPg);
  if( rc!=SQLITE_OK ){
    pagerUnlockIfUnused(pPager);
    return rc;
  }
  assert( pPg->pgno==pgno );
  if( (*ppPage)->pPager ){
    /* In this case the pcache already contains an initialized copy of
    ** the page. Return without further ado.  */
    assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) );
    PAGER_INCR(pPager->nHit);
    return SQLITE_OK;

  }else{
  assert( pPg->pPager==pPager || pPg->pPager==0 );
  if( pPg->pPager==0 ){
    /* The pager cache has created a new page. Its content needs to 
    ** be initialized.
    ** be initialized.  */
    */
    int nMax;

    PAGER_INCR(pPager->nMiss);
    pPg = *ppPage;
    pPg->pPager = pPager;

    /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
    ** number greater than this, or the unused locking-page, is requested. */
    if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){
      rc = SQLITE_CORRUPT_BKPT;
      goto pager_acquire_err;
    }

    rc = sqlite3PagerPagecount(pPager, &nMax);
    if( rc!=SQLITE_OK ){
      sqlite3PagerUnref(pPg);
      goto pager_acquire_err;
      return rc;
    }

    if( nMax<(int)pgno || MEMDB || noContent ){
      if( pgno>pPager->mxPgno ){
        sqlite3PagerUnref(pPg);
        return SQLITE_FULL;
	rc = SQLITE_FULL;
	goto pager_acquire_err;
      }
      if( noContent ){
        /* Failure to set the bits in the InJournal bit-vectors is benign.
        ** It merely means that we might do some extra work to journal a 
        ** page that does not need to be journaled.  Nevertheless, be sure 
        ** to test the case where a malloc error occurs while trying to set 
        ** a bit in a bit vector.
3918
3919
3920
3921
3922
3923
3924
3925

3926
3927
3928
3929
3930
3931

3932
3933
3934







3935

3936
3937
3938


3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959


3960
3961
3962

3963
3964
3965
3966
3967
3968
3969
3970
3971
3862
3863
3864
3865
3866
3867
3868

3869

3870
3871
3872
3873
3874
3875



3876
3877
3878
3879
3880
3881
3882
3883
3884
3885


3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906


3907
3908



3909


3910
3911
3912
3913
3914
3915
3916







-
+
-





+
-
-
-
+
+
+
+
+
+
+

+

-
-
+
+



















-
-
+
+
-
-
-
+
-
-







        memset(pPg->pData, 0, pPager->pageSize);
      }
      IOTRACE(("ZERO %p %d\n", pPager, pgno));
    }else{
      assert( pPg->pPager==pPager );
      rc = readDbPage(pPg);
      if( rc!=SQLITE_OK ){
        pagerDropPage(pPg);
        goto pager_acquire_err;
        return rc;
      }
    }
#ifdef SQLITE_CHECK_PAGES
    pPg->pageHash = pager_pagehash(pPg);
#endif
  }
  }else{
    /* The requested page is in the page cache. */
    PAGER_INCR(pPager->nHit);

  return SQLITE_OK;

pager_acquire_err:
  assert( rc!=SQLITE_OK );
  if( pPg ){
    sqlite3PcacheDrop(pPg);
  }
  pagerUnlockIfUnused(pPager);

  *ppPage = pPg;
  return SQLITE_OK;
  *ppPage = 0;
  return rc;
}

/*
** Acquire a page if it is already in the in-memory cache.  Do
** not read the page from disk.  Return a pointer to the page,
** or 0 if the page is not in cache. Also, return 0 if the 
** pager is in PAGER_UNLOCK state when this function is called,
** or if the pager is in an error state other than SQLITE_FULL.
**
** See also sqlite3PagerGet().  The difference between this routine
** and sqlite3PagerGet() is that _get() will go to the disk and read
** in the page if the page is not already in cache.  This routine
** returns NULL if the page is not in cache or if a disk I/O error 
** has ever happened.
*/
DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
  PgHdr *pPg = 0;
  assert( pPager!=0 );
  assert( pgno!=0 );

  if( (pPager->state!=PAGER_UNLOCK)
  assert( pPager->pPCache!=0 );
  assert( pPager->state > PAGER_UNLOCK );
   && (pPager->errCode==SQLITE_OK || pPager->errCode==SQLITE_FULL)
  ){
    sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg);
  sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg);
  }

  return pPg;
}

/*
** Release a page reference.
**
** If the number of references to the page drop to zero, then the
4026
4027
4028
4029
4030
4031
4032

4033
4034
4035
4036
4037




4038
4039
4040
4041
4042
4043
4044
4045
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980



3981
3982
3983
3984

3985
3986
3987
3988
3989
3990
3991







+


-
-
-
+
+
+
+
-







*/
static int pager_open_journal(Pager *pPager){
  int rc = SQLITE_OK;                        /* Return code */
  sqlite3_vfs * const pVfs = pPager->pVfs;   /* Local cache of vfs pointer */

  assert( pPager->state>=PAGER_RESERVED );
  assert( pPager->useJournal );
  assert( pPager->journalMode!=PAGER_JOURNALMODE_OFF );
  assert( pPager->pInJournal==0 );
  
  /* If already in the error state, this function is a no-op. */
  if( pPager->errCode ){
    return pPager->errCode;
  /* If already in the error state, this function is a no-op.  But on
  ** the other hand, this routine is never called if we are already in
  ** an error state. */
  if( NEVER(pPager->errCode) ) return pPager->errCode;
  }

  /* TODO: Is it really possible to get here with dbSizeValid==0? If not,
  ** the call to PagerPagecount() can be removed.
  */
  testcase( pPager->dbSizeValid==0 );
  sqlite3PagerPagecount(pPager, 0);

4141
4142
4143
4144
4145
4146
4147
4148

4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167









4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182

4183

4184
4185

4186
4187
4188
4189
4190









4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209



4210
4211
4212
4213

4214
4215
4216
4217
4218


4219
4220
4221
4222
4223
4224
4225
4087
4088
4089
4090
4091
4092
4093

4094


4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136

4137
4138

4139





4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165


4166
4167
4168
4169

4170

4171
4172
4173



4174
4175
4176
4177
4178
4179
4180
4181
4182







-
+
-
-

















+
+
+
+
+
+
+
+
+















+
-
+

-
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+

















-
-
+
+
+

-

-
+


-
-
-
+
+







        rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
      }
    }

    /* If the required locks were successfully obtained, open the journal
    ** file and write the first journal-header to it.
    */
    if( rc==SQLITE_OK && pPager->useJournal
    if( rc==SQLITE_OK && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
     && pPager->journalMode!=PAGER_JOURNALMODE_OFF 
    ){
      rc = pager_open_journal(pPager);
    }
  }else if( isOpen(pPager->jfd) && pPager->journalOff==0 ){
    /* This happens when the pager was in exclusive-access mode the last
    ** time a (read or write) transaction was successfully concluded
    ** by this connection. Instead of deleting the journal file it was 
    ** kept open and either was truncated to 0 bytes or its header was
    ** overwritten with zeros.
    */
    assert( pPager->nRec==0 );
    assert( pPager->dbOrigSize==0 );
    assert( pPager->pInJournal==0 );
    rc = pager_open_journal(pPager);
  }

  PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager)));
  assert( !isOpen(pPager->jfd) || pPager->journalOff>0 || rc!=SQLITE_OK );
  if( rc!=SQLITE_OK ){
    assert( !pPager->dbModified );
    /* Ignore any IO error that occurs within pager_end_transaction(). The
    ** purpose of this call is to reset the internal state of the pager
    ** sub-system. It doesn't matter if the journal-file is not properly
    ** finalized at this point (since it is not a valid journal file anyway).
    */
    pager_end_transaction(pPager, 0);
  }
  return rc;
}

/*
** Mark a single data page as writeable. The page is written into the 
** main journal or sub-journal as required. If the page is written into
** one of the journals, the corresponding bit is set in the 
** Pager.pInJournal bitvec and the PagerSavepoint.pInSavepoint bitvecs
** of any open savepoints as appropriate.
*/
static int pager_write(PgHdr *pPg){
  void *pData = pPg->pData;
  Pager *pPager = pPg->pPager;
  int rc = SQLITE_OK;

  /* This routine is not called unless a transaction has already been
  /* Check for errors
  ** started.
  */
  if( pPager->errCode ){ 
  assert( pPager->state>=PAGER_RESERVED );
    return pPager->errCode;
  }
  if( pPager->readOnly ){
    return SQLITE_PERM;
  }

  /* If an error has been previously detected, we should not be
  ** calling this routine.  Repeat the error for robustness.
  */
  if( NEVER(pPager->errCode) )  return pPager->errCode;

  /* Higher-level routines never call this function if database is not
  ** writable.  But check anyway, just for robustness. */
  if( NEVER(pPager->readOnly) ) return SQLITE_PERM;

  assert( !pPager->setMaster );

  CHECK_PAGE(pPg);

  /* Mark the page as dirty.  If the page has already been written
  ** to the journal then we can return right away.
  */
  sqlite3PcacheMakeDirty(pPg);
  if( pageInJournal(pPg) && !subjRequiresPage(pPg) ){
    pPager->dbModified = 1;
  }else{

    /* If we get this far, it means that the page needs to be
    ** written to the transaction journal or the ckeckpoint journal
    ** or both.
    **
    ** First check to see that the transaction journal exists and
    ** create it if it does not.
    ** Higher level routines should have already started a transaction,
    ** which means they have acquired the necessary locks and opened
    ** a rollback journal.  Double-check to makes sure this is the case.
    */
    assert( pPager->state!=PAGER_UNLOCK );
    rc = sqlite3PagerBegin(pPager, 0, pPager->subjInMemory);
    if( rc!=SQLITE_OK ){
    if( NEVER(rc!=SQLITE_OK) ){
      return rc;
    }
    assert( pPager->state>=PAGER_RESERVED );
    if( !isOpen(pPager->jfd) && pPager->useJournal
          && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
    if( !isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
      assert( pPager->useJournal );
      rc = pager_open_journal(pPager);
      if( rc!=SQLITE_OK ) return rc;
    }
    pPager->dbModified = 1;
  
    /* The transaction journal now exists and we have a RESERVED or an
    ** EXCLUSIVE lock on the main database file.  Write the current page to
4390
4391
4392
4393
4394
4395
4396
4397

4398
4399

4400
4401
4402
4403
4404
4405
4406
4347
4348
4349
4350
4351
4352
4353

4354
4355

4356
4357
4358
4359
4360
4361
4362
4363







-
+

-
+








    /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages 
    ** starting at pg1, then it needs to be set for all of them. Because
    ** writing to any of these nPage pages may damage the others, the
    ** journal file must contain sync()ed copies of all of them
    ** before any of them can be written out to the database file.
    */
    if( needSync ){
    if( rc==SQLITE_OK && needSync ){
      assert( !MEMDB && pPager->noSync==0 );
      for(ii=0; ii<nPage && needSync; ii++){
      for(ii=0; ii<nPage; ii++){
        PgHdr *pPage = pager_lookup(pPager, pg1+ii);
        if( pPage ){
          pPage->flags |= PGHDR_NEED_SYNC;
          sqlite3PagerUnref(pPage);
        }
      }
      assert(pPager->needSync);
4421
4422
4423
4424
4425
4426
4427

4428
4429
4430
4431
4432
4433
4434
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392







+







*/
#ifndef NDEBUG
int sqlite3PagerIswriteable(DbPage *pPg){
  return pPg->flags&PGHDR_DIRTY;
}
#endif

#ifndef SQLITE_SECURE_DELETE
/*
** A call to this routine tells the pager that it is not necessary to
** write the information on page pPg back to the disk, even though
** that page might be marked as dirty.  This happens, for example, when
** the page has been added as a leaf of the freelist and so its
** content no longer matters.
**
4446
4447
4448
4449
4450
4451
4452

4453
4454
4455
4456
4457
4458
4459

4460
4461
4462
4463
4464

4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484

4485
4486
4487
4488

4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503



4504
4505

4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516

4517
4518
4519


4520
4521


4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542

4543

4544
4545
4546
4547
4548
4549
4550
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417

4418
4419
4420
4421
4422

4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442

4443
4444
4445
4446

4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461

4462
4463
4464
4465

4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476

4477
4478
4479
4480
4481
4482


4483
4484


4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504

4505
4506
4507
4508
4509
4510
4511
4512







+






-
+




-
+



















-
+



-
+














-
+
+
+

-
+










-
+



+
+
-
-
+
+
-
-



















+
-
+







    IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
    pPg->flags |= PGHDR_DONT_WRITE;
#ifdef SQLITE_CHECK_PAGES
    pPg->pageHash = pager_pagehash(pPg);
#endif
  }
}
#endif /* !defined(SQLITE_SECURE_DELETE) */

/*
** This routine is called to increment the value of the database file 
** change-counter, stored as a 4-byte big-endian integer starting at 
** byte offset 24 of the pager file.
**
** If the isDirect flag is zero, then this is done by calling 
** If the isDirectMode flag is zero, then this is done by calling 
** sqlite3PagerWrite() on page 1, then modifying the contents of the
** page data. In this case the file will be updated when the current
** transaction is committed.
**
** The isDirect flag may only be non-zero if the library was compiled
** The isDirectMode flag may only be non-zero if the library was compiled
** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case,
** if isDirect is non-zero, then the database file is updated directly
** by writing an updated version of page 1 using a call to the 
** sqlite3OsWrite() function.
*/
static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
  int rc = SQLITE_OK;

  /* Declare and initialize constant integer 'isDirect'. If the
  ** atomic-write optimization is enabled in this build, then isDirect
  ** is initialized to the value passed as the isDirectMode parameter
  ** to this function. Otherwise, it is always set to zero.
  **
  ** The idea is that if the atomic-write optimization is not
  ** enabled at compile time, the compiler can omit the tests of
  ** 'isDirect' below, as well as the block enclosed in the
  ** "if( isDirect )" condition.
  */
#ifndef SQLITE_ENABLE_ATOMIC_WRITE
  const int isDirect = 0;
# define DIRECT_MODE 0
  assert( isDirectMode==0 );
  UNUSED_PARAMETER(isDirectMode);
#else
  const int isDirect = isDirectMode;
# define DIRECT_MODE isDirectMode
#endif

  assert( pPager->state>=PAGER_RESERVED );
  if( !pPager->changeCountDone && pPager->dbSize>0 ){
    PgHdr *pPgHdr;                /* Reference to page 1 */
    u32 change_counter;           /* Initial value of change-counter field */

    assert( !pPager->tempFile && isOpen(pPager->fd) );

    /* Open page 1 of the file for writing. */
    rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
    assert( pPgHdr==0 || rc==SQLITE_OK );

    /* If page one was fetched successfully, and this function is not
    ** operating in direct-mode, make page 1 writable.
    ** operating in direct-mode, make page 1 writable.  When not in 
    ** direct mode, page 1 is always held in cache and hence the PagerGet()
    ** above is always successful - hence the ALWAYS on rc==SQLITE_OK.
    */
    if( rc==SQLITE_OK && !isDirect ){
    if( !DIRECT_MODE && ALWAYS(rc==SQLITE_OK) ){
      rc = sqlite3PagerWrite(pPgHdr);
    }

    if( rc==SQLITE_OK ){
      /* Increment the value just read and write it back to byte 24. */
      change_counter = sqlite3Get4byte((u8*)pPager->dbFileVers);
      change_counter++;
      put32bits(((char*)pPgHdr->pData)+24, change_counter);

      /* If running in direct mode, write the contents of page 1 to the file. */
      if( isDirect ){
      if( DIRECT_MODE ){
        const void *zBuf = pPgHdr->pData;
        assert( pPager->dbFileSize>0 );
        rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
        if( rc==SQLITE_OK ){
          pPager->changeCountDone = 1;
      }

        }
      }else{
      /* If everything worked, set the changeCountDone flag. */
      if( rc==SQLITE_OK ){
        pPager->changeCountDone = 1;
      }
    }

    /* Release the page reference. */
    sqlite3PagerUnref(pPgHdr);
  }
  return rc;
}

/*
** Sync the pager file to disk. This is a no-op for in-memory files
** or pages with the Pager.noSync flag set.
**
** If successful, or called on a pager for which it is a no-op, this
** function returns SQLITE_OK. Otherwise, an IO error code is returned.
*/
int sqlite3PagerSync(Pager *pPager){
  int rc;                              /* Return code */
  assert( !MEMDB );
  if( MEMDB || pPager->noSync ){
  if( pPager->noSync ){
    rc = SQLITE_OK;
  }else{
    rc = sqlite3OsSync(pPager->fd, pPager->sync_flags);
  }
  return rc;
}

4577
4578
4579
4580
4581
4582
4583
4584
4585
4586







4587
4588
4589
4590

4591
4592
4593




4594
4595
4596
4597
4598
4599
4600
4601
4539
4540
4541
4542
4543
4544
4545



4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557



4558
4559
4560
4561

4562
4563
4564
4565
4566
4567
4568







-
-
-
+
+
+
+
+
+
+




+
-
-
-
+
+
+
+
-







int sqlite3PagerCommitPhaseOne(
  Pager *pPager,                  /* Pager object */
  const char *zMaster,            /* If not NULL, the master journal name */
  int noSync                      /* True to omit the xSync on the db file */
){
  int rc = SQLITE_OK;             /* Return code */

  if( pPager->errCode ){
    return pPager->errCode;
  }
  /* The dbOrigSize is never set if journal_mode=OFF */
  assert( pPager->journalMode!=PAGER_JOURNALMODE_OFF || pPager->dbOrigSize==0 );

  /* If a prior error occurred, this routine should not be called.  ROLLBACK
  ** is the appropriate response to an error, not COMMIT.  Guard against
  ** coding errors by repeating the prior error. */
  if( NEVER(pPager->errCode) ) return pPager->errCode;

  PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", 
      pPager->zFilename, zMaster, pPager->dbSize));

  if( MEMDB && pPager->dbModified ){
  /* If this is an in-memory db, or no pages have been written to, or this
  ** function has already been called, it is a no-op.
  */
    /* If this is an in-memory db, or no pages have been written to, or this
    ** function has already been called, it is mostly a no-op.  However, any
    ** backup in progress needs to be restarted.
    */
  if( MEMDB && pPager->dbModified ){
    sqlite3BackupRestart(pPager->pBackup);
  }else if( pPager->state!=PAGER_SYNCED && pPager->dbModified ){

    /* The following block updates the change-counter. Exactly how it
    ** does this depends on whether or not the atomic-update optimization
    ** was enabled at compile time, and if this transaction meets the 
    ** runtime criteria to use the operation: 
4649
4650
4651
4652
4653
4654
4655



4656
4657
4658
4659


4660
4661
4662
4663
4664
4665
4666
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627


4628
4629
4630
4631
4632
4633
4634
4635
4636







+
+
+


-
-
+
+







    ** file. This can only happen in auto-vacuum mode.
    **
    ** Before reading the pages with page numbers larger than the 
    ** current value of Pager.dbSize, set dbSize back to the value
    ** that it took at the start of the transaction. Otherwise, the
    ** calls to sqlite3PagerGet() return zeroed pages instead of 
    ** reading data from the database file.
    **
    ** When journal_mode==OFF the dbOrigSize is always zero, so this
    ** block never runs if journal_mode=OFF.
    */
#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pPager->dbSize<pPager->dbOrigSize
     && pPager->journalMode!=PAGER_JOURNALMODE_OFF 
    if( pPager->dbSize<pPager->dbOrigSize 
     && ALWAYS(pPager->journalMode!=PAGER_JOURNALMODE_OFF)
    ){
      Pgno i;                                   /* Iterator variable */
      const Pgno iSkip = PAGER_MJ_PGNO(pPager); /* Pending lock page */
      const Pgno dbSize = pPager->dbSize;       /* Database image size */ 
      pPager->dbSize = pPager->dbOrigSize;
      for( i=dbSize+1; i<=pPager->dbOrigSize; i++ ){
        if( !sqlite3BitvecTest(pPager->pInJournal, i) && i!=iSkip ){
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4684
4685
4686
4687
4688
4689
4690








4691
4692
4693
4694
4695
4696
4697







-
-
-
-
-
-
-
-







    }
    IOTRACE(("DBSYNC %p\n", pPager))

    pPager->state = PAGER_SYNCED;
  }

commit_phase_one_exit:
  if( rc==SQLITE_IOERR_BLOCKED ){
    /* pager_incr_changecounter() may attempt to obtain an exclusive
    ** lock to spill the cache and return IOERR_BLOCKED. But since 
    ** there is no chance the cache is inconsistent, it is
    ** better to return SQLITE_BUSY.
    **/
    rc = SQLITE_BUSY;
  }
  return rc;
}


/*
** When this function is called, the database file has been completely
** updated to reflect the changes made by the current transaction and
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753




4754
4755
4756
4757
4758

4759
4760

4761
4762
4763
4764
4765
4766
4767
4768
4769
4706
4707
4708
4709
4710
4711
4712



4713
4714
4715
4716

4717
4718
4719

4720
4721

4722


4723
4724
4725
4726
4727
4728
4729







-
-
-
+
+
+
+
-



-
+

-
+
-
-







**
** If an error occurs, an IO error code is returned and the pager
** moves into the error state. Otherwise, SQLITE_OK is returned.
*/
int sqlite3PagerCommitPhaseTwo(Pager *pPager){
  int rc = SQLITE_OK;                  /* Return code */

  /* Do not proceed if the pager is already in the error state. */
  if( pPager->errCode ){
    return pPager->errCode;
  /* This routine should not be called if a prior error has occurred.
  ** But if (due to a coding error elsewhere in the system) it does get
  ** called, just return the same error code without doing anything. */
  if( NEVER(pPager->errCode) ) return pPager->errCode;
  }

  /* This function should not be called if the pager is not in at least
  ** PAGER_RESERVED state. And indeed SQLite never does this. But it is
  ** nice to have this defensive block here anyway.
  ** nice to have this defensive test here anyway.
  */
  if( NEVER(pPager->state<PAGER_RESERVED) ){
  if( NEVER(pPager->state<PAGER_RESERVED) ) return SQLITE_ERROR;
    return SQLITE_ERROR;
  }

  /* An optimization. If the database was not actually modified during
  ** this transaction, the pager is running in exclusive-mode and is
  ** using persistent journals, then this function is a no-op.
  **
  ** The start of the journal file currently contains a single journal 
  ** header with the nRec field set to 0. If such a journal is used as
4950
4951
4952
4953
4954
4955
4956
4957

4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970

4971
4972
4973
4974
4975
4976
4977
4910
4911
4912
4913
4914
4915
4916

4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938







-
+













+







    pPager->aSavepoint = aNew;
    pPager->nSavepoint = nSavepoint;

    /* Populate the PagerSavepoint structures just allocated. */
    for(ii=nCurrent; ii<nSavepoint; ii++){
      assert( pPager->dbSizeValid );
      aNew[ii].nOrig = pPager->dbSize;
      if( isOpen(pPager->jfd) && pPager->journalOff>0 ){
      if( isOpen(pPager->jfd) && ALWAYS(pPager->journalOff>0) ){
        aNew[ii].iOffset = pPager->journalOff;
      }else{
        aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager);
      }
      aNew[ii].iSubRec = pPager->nSubRec;
      aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize);
      if( !aNew[ii].pInSavepoint ){
        return SQLITE_NOMEM;
      }
    }

    /* Open the sub-journal, if it is not already opened. */
    rc = openSubJournal(pPager);
    assertTruncateConstraint(pPager);
  }

  return rc;
}

/*
** This function is called to rollback or release (commit) a savepoint.
5091
5092
5093
5094
5095
5096
5097
5098

5099
5100
5101
5102
5103
5104
5105
5052
5053
5054
5055
5056
5057
5058

5059
5060
5061
5062
5063
5064
5065
5066







-
+







  Pager *pPager,
  void *(*xCodec)(void*,void*,Pgno,int),
  void (*xCodecSizeChng)(void*,int,int),
  void (*xCodecFree)(void*),
  void *pCodec
){
  if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
  pPager->xCodec = xCodec;
  pPager->xCodec = pPager->memDb ? 0 : xCodec;
  pPager->xCodecSizeChng = xCodecSizeChng;
  pPager->xCodecFree = xCodecFree;
  pPager->pCodec = pCodec;
  pagerReportSize(pPager);
}
static void *sqlite3PagerGetCodec(Pager *pPager){
  return pPager->pCodec;
5219
5220
5221
5222
5223
5224
5225
5226

5227
5228
5229
5230
5231
5232
5233
5180
5181
5182
5183
5184
5185
5186

5187
5188
5189
5190
5191
5192
5193
5194







-
+







    ** The sqlite3PagerGet() call may cause the journal to sync. So make
    ** sure the Pager.needSync flag is set too.
    */
    PgHdr *pPgHdr;
    assert( pPager->needSync );
    rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
    if( rc!=SQLITE_OK ){
      if( pPager->pInJournal && needSyncPgno<=pPager->dbOrigSize ){
      if( needSyncPgno<=pPager->dbOrigSize ){
        assert( pPager->pTmpSpace!=0 );
        sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace);
      }
      return rc;
    }
    pPager->needSync = 1;
    assert( pPager->noSync==0 && !MEMDB );
5241
5242
5243
5244
5245
5246
5247
5248




5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270

5271
5272
5273
5274
5275
5276
5277
5202
5203
5204
5205
5206
5207
5208

5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232


5233
5234
5235
5236
5237
5238
5239
5240







-
+
+
+
+




















-
-
+







  ** to exist, in case the transaction needs to roll back.  We allocate
  ** the page now, instead of at rollback, because we can better deal
  ** with an out-of-memory error now.  Ticket #3761.
  */
  if( MEMDB ){
    DbPage *pNew;
    rc = sqlite3PagerAcquire(pPager, origPgno, &pNew, 1);
    if( rc!=SQLITE_OK ) return rc;
    if( rc!=SQLITE_OK ){
      sqlite3PcacheMove(pPg, origPgno);
      return rc;
    }
    sqlite3PagerUnref(pNew);
  }

  return SQLITE_OK;
}
#endif

/*
** Return a pointer to the data for the specified page.
*/
void *sqlite3PagerGetData(DbPage *pPg){
  assert( pPg->nRef>0 || pPg->pPager->memDb );
  return pPg->pData;
}

/*
** Return a pointer to the Pager.nExtra bytes of "extra" space 
** allocated along with the specified page.
*/
void *sqlite3PagerGetExtra(DbPage *pPg){
  Pager *pPager = pPg->pPager;
  return (pPager?pPg->pExtra:0);
  return pPg->pExtra;
}

/*
** Get/set the locking-mode for this pager. Parameter eMode must be one
** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or 
** PAGER_LOCKINGMODE_EXCLUSIVE. If the parameter is not _QUERY, then
** the locking-mode is set to the value specified.
Changes to src/pager.h.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
8
9
10
11
12
13
14


15
16
17
18
19
20
21







-
-







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite page cache
** subsystem.  The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback.
**
** @(#) $Id: pager.h,v 1.102 2009/06/18 17:22:39 drh Exp $
*/

#ifndef _PAGER_H_
#define _PAGER_H_

/*
** Default maximum size for persistent journal files. A negative 
82
83
84
85
86
87
88
89









90
91
92
93
94
95
96
97
98
99
100
101
102
80
81
82
83
84
85
86

87
88
89
90
91
92
93
94
95
96
97
98
99
100

101
102
103
104
105
106
107







-
+
+
+
+
+
+
+
+
+





-







/*
** The remainder of this file contains the declarations of the functions
** that make up the Pager sub-system API. See source code comments for 
** a detailed description of each routine.
*/

/* Open and close a Pager connection. */ 
int sqlite3PagerOpen(sqlite3_vfs *, Pager **ppPager, const char*, int,int,int);
int sqlite3PagerOpen(
  sqlite3_vfs*,
  Pager **ppPager,
  const char*,
  int,
  int,
  int,
  void(*)(DbPage*)
);
int sqlite3PagerClose(Pager *pPager);
int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);

/* Functions used to configure a Pager object. */
void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
void sqlite3PagerSetReiniter(Pager*, void(*)(DbPage*));
int sqlite3PagerSetPagesize(Pager*, u16*, int);
int sqlite3PagerMaxPageCount(Pager*, int);
void sqlite3PagerSetCachesize(Pager*, int);
void sqlite3PagerSetSafetyLevel(Pager*,int,int);
int sqlite3PagerLockingMode(Pager *, int);
int sqlite3PagerJournalMode(Pager *, int);
i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
122
123
124
125
126
127
128

129
130
131
132
133
134
135
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141







+







int sqlite3PagerBegin(Pager*, int exFlag, int);
int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int);
int sqlite3PagerSync(Pager *pPager);
int sqlite3PagerCommitPhaseTwo(Pager*);
int sqlite3PagerRollback(Pager*);
int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
int sqlite3PagerSharedLock(Pager *pPager);

/* Functions used to query pager state and configuration. */
u8 sqlite3PagerIsreadonly(Pager*);
int sqlite3PagerRefcount(Pager*);
const char *sqlite3PagerFilename(Pager*);
const sqlite3_vfs *sqlite3PagerVfs(Pager*);
sqlite3_file *sqlite3PagerFile(Pager*);
Changes to src/parse.y.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
9
10
11
12
13
14
15


16
17
18
19
20
21
22







-
-







**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.283 2009/06/19 14:06:03 drh Exp $
*/

// All token codes are small integers with #defines that begin with "TK_"
%token_prefix TK_

// The type of the data attached to each token is Token.  This is also the
// default type for non-terminals.
192
193
194
195
196
197
198
199
200
201



202
203
204
205
206
207
208
190
191
192
193
194
195
196



197
198
199
200
201
202
203
204
205
206







-
-
-
+
+
+







id(A) ::= INDEXED(X).    {A = X;}

// The following directive causes tokens ABORT, AFTER, ASC, etc. to
// fallback to ID if they will not parse as their original value.
// This obviates the need for the "id" nonterminal.
//
%fallback ID
  ABORT AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW CONFLICT
  DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR
  IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH PLAN
  ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW
  CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR
  IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN
  QUERY KEY OF OFFSET PRAGMA RAISE RELEASE REPLACE RESTRICT ROW ROLLBACK
  SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL
%ifdef SQLITE_OMIT_COMPOUND_SELECT
  EXCEPT INTERSECT UNION
%endif SQLITE_OMIT_COMPOUND_SELECT
  REINDEX RENAME CTIME_KW IF
  .
226
227
228
229
230
231
232
233

234
235
236
237
238
239
240
224
225
226
227
228
229
230

231
232
233
234
235
236
237
238







-
+







%left GT LE LT GE.
%right ESCAPE.
%left BITAND BITOR LSHIFT RSHIFT.
%left PLUS MINUS.
%left STAR SLASH REM.
%left CONCAT.
%left COLLATE.
%right UMINUS UPLUS BITNOT.
%right BITNOT.

// And "ids" is an identifer-or-string.
//
%type ids {Token}
ids(A) ::= ID|STRING(X).   {A = X;}

// The name of a column or table can be any of the following:
310
311
312
313
314
315
316
317

318
319
320
321
322
323
324
325
326
327
328





329
330

331
332
333
334
335
336
337
308
309
310
311
312
313
314

315
316
317
318
319
320

321




322
323
324
325
326
327

328
329
330
331
332
333
334
335







-
+





-

-
-
-
-
+
+
+
+
+

-
+








// The next group of rules parses the arguments to a REFERENCES clause
// that determine if the referential integrity checking is deferred or
// or immediate and which determine what action to take if a ref-integ
// check fails.
//
%type refargs {int}
refargs(A) ::= .                     { A = OE_Restrict * 0x010101; }
refargs(A) ::= .                  { A = OE_None*0x0101; /* EV: R-19803-45884 */}
refargs(A) ::= refargs(X) refarg(Y). { A = (X & ~Y.mask) | Y.value; }
%type refarg {struct {int value; int mask;}}
refarg(A) ::= MATCH nm.              { A.value = 0;     A.mask = 0x000000; }
refarg(A) ::= ON DELETE refact(X).   { A.value = X;     A.mask = 0x0000ff; }
refarg(A) ::= ON UPDATE refact(X).   { A.value = X<<8;  A.mask = 0x00ff00; }
refarg(A) ::= ON INSERT refact(X).   { A.value = X<<16; A.mask = 0xff0000; }
%type refact {int}
refact(A) ::= SET NULL.              { A = OE_SetNull; }
refact(A) ::= SET DEFAULT.           { A = OE_SetDflt; }
refact(A) ::= CASCADE.               { A = OE_Cascade; }
refact(A) ::= RESTRICT.              { A = OE_Restrict; }
refact(A) ::= SET NULL.              { A = OE_SetNull;  /* EV: R-33326-45252 */}
refact(A) ::= SET DEFAULT.           { A = OE_SetDflt;  /* EV: R-33326-45252 */}
refact(A) ::= CASCADE.               { A = OE_Cascade;  /* EV: R-33326-45252 */}
refact(A) ::= RESTRICT.              { A = OE_Restrict; /* EV: R-33326-45252 */}
refact(A) ::= NO ACTION.             { A = OE_None;     /* EV: R-33326-45252 */}
%type defer_subclause {int}
defer_subclause(A) ::= NOT DEFERRABLE init_deferred_pred_opt(X).  {A = X;}
defer_subclause(A) ::= NOT DEFERRABLE init_deferred_pred_opt.     {A = 0;}
defer_subclause(A) ::= DEFERRABLE init_deferred_pred_opt(X).      {A = X;}
%type init_deferred_pred_opt {int}
init_deferred_pred_opt(A) ::= .                       {A = 0;}
init_deferred_pred_opt(A) ::= INITIALLY DEFERRED.     {A = 1;}
init_deferred_pred_opt(A) ::= INITIALLY IMMEDIATE.    {A = 0;}

// For the time being, the only constraint we care about is the primary
358
359
360
361
362
363
364
365

366
367
368
369
370

371
372
373
374
375
376
377
356
357
358
359
360
361
362

363
364
365
366
367

368
369
370
371
372
373
374
375







-
+




-
+







defer_subclause_opt(A) ::= .                    {A = 0;}
defer_subclause_opt(A) ::= defer_subclause(X).  {A = X;}

// The following is a non-standard extension that allows us to declare the
// default behavior when there is a constraint conflict.
//
%type onconf {int}
%type orconf {int}
%type orconf {u8}
%type resolvetype {int}
onconf(A) ::= .                              {A = OE_Default;}
onconf(A) ::= ON CONFLICT resolvetype(X).    {A = X;}
orconf(A) ::= .                              {A = OE_Default;}
orconf(A) ::= OR resolvetype(X).             {A = X;}
orconf(A) ::= OR resolvetype(X).             {A = (u8)X;}
resolvetype(A) ::= raisetype(X).             {A = X;}
resolvetype(A) ::= IGNORE.                   {A = OE_Ignore;}
resolvetype(A) ::= REPLACE.                  {A = OE_Replace;}

////////////////////////// The DROP TABLE /////////////////////////////////////
//
cmd ::= DROP TABLE ifexists(E) fullname(X). {
500
501
502
503
504
505
506
507

508
509
510
511
512
513
514
515
516
498
499
500
501
502
503
504

505


506
507
508
509
510
511
512







-
+
-
-







%ifndef SQLITE_OMIT_SUBQUERY
  seltablist(A) ::= stl_prefix(X) LP select(S) RP
                    as(Z) on_opt(N) using_opt(U). {
    A = sqlite3SrcListAppendFromTerm(pParse,X,0,0,&Z,S,N,U);
  }
  seltablist(A) ::= stl_prefix(X) LP seltablist(F) RP
                    as(Z) on_opt(N) using_opt(U). {
    if( X==0 ){
    if( X==0 && Z.n==0 && N==0 && U==0 ){
      sqlite3ExprDelete(pParse->db, N);
      sqlite3IdListDelete(pParse->db, U);
      A = F;
    }else{
      Select *pSubquery;
      sqlite3SrcListShiftJoinType(F);
      pSubquery = sqlite3SelectNew(pParse,0,F,0,0,0,0,0,0,0);
      A = sqlite3SrcListAppendFromTerm(pParse,X,0,0,&Z,pSubquery,N,U);
    }
685
686
687
688
689
690
691
692

693
694
695
696
697
698
699
681
682
683
684
685
686
687

688
689
690
691
692
693
694
695







-
+







        VALUES LP itemlist(Y) RP.
            {sqlite3Insert(pParse, X, Y, 0, F, R);}
cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) select(S).
            {sqlite3Insert(pParse, X, 0, S, F, R);}
cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) DEFAULT VALUES.
            {sqlite3Insert(pParse, X, 0, 0, F, R);}

%type insert_cmd {int}
%type insert_cmd {u8}
insert_cmd(A) ::= INSERT orconf(R).   {A = R;}
insert_cmd(A) ::= REPLACE.            {A = OE_Replace;}


%type itemlist {ExprList*}
%destructor itemlist {sqlite3ExprListDelete(pParse->db, $$);}

882
883
884
885
886
887
888
889
890







891
892












893
894
895
896
897
898
899
878
879
880
881
882
883
884

885
886
887
888
889
890
891
892


893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911







-

+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+







    pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
    pOut->zStart = pOperand->zStart;
    pOut->zEnd = &pPostOp->z[pPostOp->n];
  }                           
}

expr(A) ::= expr(X) ISNULL|NOTNULL(E).   {spanUnaryPostfix(&A,pParse,@E,&X,&E);}
expr(A) ::= expr(X) IS NULL(E).   {spanUnaryPostfix(&A,pParse,TK_ISNULL,&X,&E);}
expr(A) ::= expr(X) NOT NULL(E). {spanUnaryPostfix(&A,pParse,TK_NOTNULL,&X,&E);}

//    expr1 IS expr2
//    expr1 IS NOT expr2
//
// If expr2 is NULL then code as TK_ISNULL or TK_NOTNULL.  If expr2
// is any other expression, code as TK_IS or TK_ISNOT.
// 
expr(A) ::= expr(X) IS NOT NULL(E).
                                 {spanUnaryPostfix(&A,pParse,TK_NOTNULL,&X,&E);}
expr(A) ::= expr(X) IS expr(Y).     {
  spanBinaryExpr(&A,pParse,TK_IS,&X,&Y);
  if( pParse->db->mallocFailed==0  && Y.pExpr->op==TK_NULL ){
    A.pExpr->op = TK_ISNULL;
  }
}
expr(A) ::= expr(X) IS NOT expr(Y). {
  spanBinaryExpr(&A,pParse,TK_ISNOT,&X,&Y);
  if( pParse->db->mallocFailed==0  && Y.pExpr->op==TK_NULL ){
    A.pExpr->op = TK_NOTNULL;
  }
}

%include {
  /* Construct an expression node for a unary prefix operator
  */
  static void spanUnaryPrefix(
    ExprSpan *pOut,        /* Write the new expression node here */
    Parse *pParse,         /* Parsing context to record errors */
907
908
909
910
911
912
913
914

915
916

917
918
919
920
921
922
923
919
920
921
922
923
924
925

926
927

928
929
930
931
932
933
934
935







-
+

-
+







  }
}



expr(A) ::= NOT(B) expr(X).    {spanUnaryPrefix(&A,pParse,@B,&X,&B);}
expr(A) ::= BITNOT(B) expr(X). {spanUnaryPrefix(&A,pParse,@B,&X,&B);}
expr(A) ::= MINUS(B) expr(X). [UMINUS]
expr(A) ::= MINUS(B) expr(X). [BITNOT]
                               {spanUnaryPrefix(&A,pParse,TK_UMINUS,&X,&B);}
expr(A) ::= PLUS(B) expr(X). [UPLUS]
expr(A) ::= PLUS(B) expr(X). [BITNOT]
                               {spanUnaryPrefix(&A,pParse,TK_UPLUS,&X,&B);}

%type between_op {int}
between_op(A) ::= BETWEEN.     {A = 0;}
between_op(A) ::= NOT BETWEEN. {A = 1;}
expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
  ExprList *pList = sqlite3ExprListAppend(pParse,0, X.pExpr);
1176
1177
1178
1179
1180
1181
1182
1183































1184
1185
1186
1187
1188



1189
1190
1191
1192
1193



1194
1195

1196
1197
1198
1199

1200
1201
1202
1203
1204
1205
1206
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229


1230
1231
1232
1233
1234



1235
1236
1237
1238

1239
1240
1241
1242

1243
1244
1245
1246
1247
1248
1249
1250








+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
-
+
+
+


-
-
-
+
+
+

-
+



-
+







  A = Y;
}
trigger_cmd_list(A) ::= trigger_cmd(X) SEMI. { 
  assert( X!=0 );
  X->pLast = X;
  A = X;
}

// Disallow qualified table names on INSERT, UPDATE, and DELETE statements
// within a trigger.  The table to INSERT, UPDATE, or DELETE is always in 
// the same database as the table that the trigger fires on.
//
%type trnm {Token}
trnm(A) ::= nm(X).   {A = X;}
trnm(A) ::= nm DOT nm(X). {
  A = X;
  sqlite3ErrorMsg(pParse, 
        "qualified table names are not allowed on INSERT, UPDATE, and DELETE "
        "statements within triggers");
}

// Disallow the INDEX BY and NOT INDEXED clauses on UPDATE and DELETE
// statements within triggers.  We make a specific error message for this
// since it is an exception to the default grammar rules.
//
tridxby ::= .
tridxby ::= INDEXED BY nm. {
  sqlite3ErrorMsg(pParse,
        "the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
        "within triggers");
}
tridxby ::= NOT INDEXED. {
  sqlite3ErrorMsg(pParse,
        "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
        "within triggers");
}



%type trigger_cmd {TriggerStep*}
%destructor trigger_cmd {sqlite3DeleteTriggerStep(pParse->db, $$);}
// UPDATE 
trigger_cmd(A) ::= UPDATE orconf(R) nm(X) SET setlist(Y) where_opt(Z).  
               { A = sqlite3TriggerUpdateStep(pParse->db, &X, Y, Z, R); }
trigger_cmd(A) ::=
   UPDATE orconf(R) trnm(X) tridxby SET setlist(Y) where_opt(Z).  
   { A = sqlite3TriggerUpdateStep(pParse->db, &X, Y, Z, R); }

// INSERT
trigger_cmd(A) ::= insert_cmd(R) INTO nm(X) inscollist_opt(F) 
                   VALUES LP itemlist(Y) RP.  
               {A = sqlite3TriggerInsertStep(pParse->db, &X, F, Y, 0, R);}
trigger_cmd(A) ::=
   insert_cmd(R) INTO trnm(X) inscollist_opt(F) VALUES LP itemlist(Y) RP.  
   {A = sqlite3TriggerInsertStep(pParse->db, &X, F, Y, 0, R);}

trigger_cmd(A) ::= insert_cmd(R) INTO nm(X) inscollist_opt(F) select(S).
trigger_cmd(A) ::= insert_cmd(R) INTO trnm(X) inscollist_opt(F) select(S).
               {A = sqlite3TriggerInsertStep(pParse->db, &X, F, 0, S, R);}

// DELETE
trigger_cmd(A) ::= DELETE FROM nm(X) where_opt(Y).
trigger_cmd(A) ::= DELETE FROM trnm(X) tridxby where_opt(Y).
               {A = sqlite3TriggerDeleteStep(pParse->db, &X, Y);}

// SELECT
trigger_cmd(A) ::= select(X).  {A = sqlite3TriggerSelectStep(pParse->db, X); }

// The special RAISE expression that may occur in trigger programs
expr(A) ::= RAISE(X) LP IGNORE RP(Y).  {
Changes to src/pcache.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19












-
-







/*
** 2008 August 05
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file implements that page cache.
**
** @(#) $Id: pcache.c,v 1.44 2009/03/31 01:32:18 drh Exp $
*/
#include "sqliteInt.h"

/*
** A complete page cache is an instance of this structure.
*/
struct PCache {
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
236
237
238
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226

227



228
229
230
231
232
233
234







+

















-
+
-
-
-







  int createFlag,       /* If true, create page if it does not exist already */
  PgHdr **ppPage        /* Write the page here */
){
  PgHdr *pPage = 0;
  int eCreate;

  assert( pCache!=0 );
  assert( createFlag==1 || createFlag==0 );
  assert( pgno>0 );

  /* If the pluggable cache (sqlite3_pcache*) has not been allocated,
  ** allocate it now.
  */
  if( !pCache->pCache && createFlag ){
    sqlite3_pcache *p;
    int nByte;
    nByte = pCache->szPage + pCache->szExtra + sizeof(PgHdr);
    p = sqlite3GlobalConfig.pcache.xCreate(nByte, pCache->bPurgeable);
    if( !p ){
      return SQLITE_NOMEM;
    }
    sqlite3GlobalConfig.pcache.xCachesize(p, pCache->nMax);
    pCache->pCache = p;
  }

  eCreate = createFlag ? 1 : 0;
  eCreate = createFlag * (1 + (!pCache->bPurgeable || !pCache->pDirty));
  if( eCreate && (!pCache->bPurgeable || !pCache->pDirty) ){
    eCreate = 2;
  }
  if( pCache->pCache ){
    pPage = sqlite3GlobalConfig.pcache.xFetch(pCache->pCache, pgno, eCreate);
  }

  if( !pPage && eCreate==1 ){
    PgHdr *pPg;

466
467
468
469
470
471
472





473
474

475
476
477
478
479
480
481
482
483

484
485
486
487
488
489
490

491
492
493
494
495
496
497
498
499
500
501



502
503
504
505
506
507
508
509
510
462
463
464
465
466
467
468
469
470
471
472
473
474

475







476

477
478
479
480
481
482
483

484
485
486
487
488
489
490
491
492



493
494
495


496
497
498
499
500
501
502







+
+
+
+
+

-
+
-
-
-
-
-
-
-

-
+






-
+








-
-
-
+
+
+
-
-







  return result.pDirty;
}

/*
** Sort the list of pages in accending order by pgno.  Pages are
** connected by pDirty pointers.  The pDirtyPrev pointers are
** corrupted by this sort.
**
** Since there cannot be more than 2^31 distinct pages in a database,
** there cannot be more than 31 buckets required by the merge sorter.
** One extra bucket is added to catch overflow in case something
** ever changes to make the previous sentence incorrect.
*/
#define N_SORT_BUCKET_ALLOC 25
#define N_SORT_BUCKET  32
#define N_SORT_BUCKET       25
#ifdef SQLITE_TEST
  int sqlite3_pager_n_sort_bucket = 0;
  #undef N_SORT_BUCKET
  #define N_SORT_BUCKET \
   (sqlite3_pager_n_sort_bucket?sqlite3_pager_n_sort_bucket:N_SORT_BUCKET_ALLOC)
#endif
static PgHdr *pcacheSortDirtyList(PgHdr *pIn){
  PgHdr *a[N_SORT_BUCKET_ALLOC], *p;
  PgHdr *a[N_SORT_BUCKET], *p;
  int i;
  memset(a, 0, sizeof(a));
  while( pIn ){
    p = pIn;
    pIn = p->pDirty;
    p->pDirty = 0;
    for(i=0; i<N_SORT_BUCKET-1; i++){
    for(i=0; ALWAYS(i<N_SORT_BUCKET-1); i++){
      if( a[i]==0 ){
        a[i] = p;
        break;
      }else{
        p = pcacheMergeDirtyList(a[i], p);
        a[i] = 0;
      }
    }
    if( i==N_SORT_BUCKET-1 ){
      /* Coverage: To get here, there need to be 2^(N_SORT_BUCKET) 
      ** elements in the input list. This is possible, but impractical.
    if( NEVER(i==N_SORT_BUCKET-1) ){
      /* To get here, there need to be 2^(N_SORT_BUCKET) elements in
      ** the input list.  But that is impossible.
      ** Testing this line is the point of global variable
      ** sqlite3_pager_n_sort_bucket.
      */
      a[i] = pcacheMergeDirtyList(a[i], p);
    }
  }
  p = a[0];
  for(i=1; i<N_SORT_BUCKET; i++){
    p = pcacheMergeDirtyList(p, a[i]);
563
564
565
566
567
568
569
570

571
572
573
574
575
576
577
578
579
580
581
582
555
556
557
558
559
560
561

562
563
564
565
566
567
568
569
570
571
572
573
574







-
+












void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
  pCache->nMax = mxPage;
  if( pCache->pCache ){
    sqlite3GlobalConfig.pcache.xCachesize(pCache->pCache, mxPage);
  }
}

#ifdef SQLITE_CHECK_PAGES
#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
/*
** For all dirty pages currently in the cache, invoke the specified
** callback. This is only used if the SQLITE_CHECK_PAGES macro is
** defined.
*/
void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)){
  PgHdr *pDirty;
  for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext){
    xIter(pDirty);
  }
}
#endif
Changes to src/pcache.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2008 August 05
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite page cache
** subsystem. 
**
** @(#) $Id: pcache.h,v 1.19 2009/01/20 17:06:27 danielk1977 Exp $
*/

#ifndef _PCACHE_H_

typedef struct PgHdr PgHdr;
typedef struct PCache PCache;

120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
118
119
120
121
122
123
124

125
126
127
128
129
130
131
132







-
+







void sqlite3PcacheRef(PgHdr*);

int sqlite3PcachePageRefcount(PgHdr*);

/* Return the total number of pages stored in the cache */
int sqlite3PcachePagecount(PCache*);

#ifdef SQLITE_CHECK_PAGES
#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
/* Iterate through all dirty pages currently stored in the cache. This
** interface is only available if SQLITE_CHECK_PAGES is defined when the 
** library is built.
*/
void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *));
#endif

Changes to src/pcache1.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
11
12
13
14
15
16
17


18
19
20
21
22
23
24







-
-







*************************************************************************
**
** This file implements the default page cache implementation (the
** sqlite3_pcache interface). It also contains part of the implementation
** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features.
** If the default page cache implementation is overriden, then neither of
** these two features are available.
**
** @(#) $Id: pcache1.c,v 1.17 2009/06/09 18:58:53 shane Exp $
*/

#include "sqliteInt.h"

typedef struct PCache1 PCache1;
typedef struct PgHdr1 PgHdr1;
typedef struct PgFreeslot PgFreeslot;
214
215
216
217
218
219
220




221
222
223

224
225
226
227
228
229
230
212
213
214
215
216
217
218
219
220
221
222
223
224

225
226
227
228
229
230
231
232







+
+
+
+


-
+







    p = 0;
  }
  return p;
}

/*
** Free a page object allocated by pcache1AllocPage().
**
** The pointer is allowed to be NULL, which is prudent.  But it turns out
** that the current implementation happens to never call this routine
** with a NULL pointer, so we mark the NULL test with ALWAYS().
*/
static void pcache1FreePage(PgHdr1 *p){
  if( p ){
  if( ALWAYS(p) ){
    if( p->pCache->bPurgeable ){
      pcache1.nCurrentPage--;
    }
    pcache1Free(PGHDR1_TO_PAGE(p));
  }
}

404
405
406
407
408
409
410


411
412
413
414
415
416
417
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421







+
+







  }
  pcache1.isInit = 1;
  return SQLITE_OK;
}

/*
** Implementation of the sqlite3_pcache.xShutdown method.
** Note that the static mutex allocated in xInit does 
** not need to be freed.
*/
static void pcache1Shutdown(void *NotUsed){
  UNUSED_PARAMETER(NotUsed);
  assert( pcache1.isInit!=0 );
  memset(&pcache1, 0, sizeof(pcache1));
}

467
468
469
470
471
472
473
474








475
476
477
478
479
480
481
482
483
484
485
486


487
488
489
490
491
492
493
494
471
472
473
474
475
476
477

478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495


496
497

498
499
500
501
502
503
504







-
+
+
+
+
+
+
+
+










-
-
+
+
-








/*
** Implementation of the sqlite3_pcache.xFetch method. 
**
** Fetch a page by key value.
**
** Whether or not a new page may be allocated by this function depends on
** the value of the createFlag argument.
** the value of the createFlag argument.  0 means do not allocate a new
** page.  1 means allocate a new page if space is easily available.  2 
** means to try really hard to allocate a new page.
**
** For a non-purgeable cache (a cache used as the storage for an in-memory
** database) there is really no difference between createFlag 1 and 2.  So
** the calling function (pcache.c) will never have a createFlag of 1 on
** a non-purgable cache.
**
** There are three different approaches to obtaining space for a page,
** depending on the value of parameter createFlag (which may be 0, 1 or 2).
**
**   1. Regardless of the value of createFlag, the cache is searched for a 
**      copy of the requested page. If one is found, it is returned.
**
**   2. If createFlag==0 and the page is not already in the cache, NULL is
**      returned.
**
**   3. If createFlag is 1, the cache is marked as purgeable and the page is 
**      not already in the cache, and if either of the following are true, 
**   3. If createFlag is 1, and the page is not already in the cache,
**      and if either of the following are true, return NULL:
**      return NULL:
**
**       (a) the number of pages pinned by the cache is greater than
**           PCache1.nMax, or
**       (b) the number of pages pinned by the cache is greater than
**           the sum of nMax for all purgeable caches, less the sum of 
**           nMin for all other purgeable caches. 
**
509
510
511
512
513
514
515

516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532

533
534
535
536
537
538
539
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542

543
544
545
546
547
548
549
550







+
















-
+







**   5. Otherwise, allocate and return a new page buffer.
*/
static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){
  unsigned int nPinned;
  PCache1 *pCache = (PCache1 *)p;
  PgHdr1 *pPage = 0;

  assert( pCache->bPurgeable || createFlag!=1 );
  pcache1EnterMutex();
  if( createFlag==1 ) sqlite3BeginBenignMalloc();

  /* Search the hash table for an existing entry. */
  if( pCache->nHash>0 ){
    unsigned int h = iKey % pCache->nHash;
    for(pPage=pCache->apHash[h]; pPage&&pPage->iKey!=iKey; pPage=pPage->pNext);
  }

  if( pPage || createFlag==0 ){
    pcache1PinPage(pPage);
    goto fetch_out;
  }

  /* Step 3 of header comment. */
  nPinned = pCache->nPage - pCache->nRecyclable;
  if( createFlag==1 && pCache->bPurgeable && (
  if( createFlag==1 && (
        nPinned>=(pcache1.nMaxPage+pCache->nMin-pcache1.nMinPage)
     || nPinned>=(pCache->nMax * 9 / 10)
  )){
    goto fetch_out;
  }

  if( pCache->nPage>=pCache->nHash && pcache1ResizeHash(pCache) ){
651
652
653
654
655
656
657







658

659
660
661
662
663
664
665
662
663
664
665
666
667
668
669
670
671
672
673
674
675

676
677
678
679
680
681
682
683







+
+
+
+
+
+
+
-
+







  *pp = pPage->pNext;

  h = iNew%pCache->nHash;
  pPage->iKey = iNew;
  pPage->pNext = pCache->apHash[h];
  pCache->apHash[h] = pPage;

  /* The xRekey() interface is only used to move pages earlier in the
  ** database file (in order to move all free pages to the end of the
  ** file where they can be truncated off.)  Hence, it is not possible
  ** for the new page number to be greater than the largest previously
  ** fetched page.  But we retain the following test in case xRekey()
  ** begins to be used in different ways in the future.
  */
  if( iNew>pCache->iMaxKey ){
  if( NEVER(iNew>pCache->iMaxKey) ){
    pCache->iMaxKey = iNew;
  }

  pcache1LeaveMutex();
}

/*
Changes to src/pragma.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19












-
-







/*
** 2003 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.213 2009/06/19 14:06:03 drh Exp $
*/
#include "sqliteInt.h"

/* Ignore this whole file if pragmas are disabled
*/
#if !defined(SQLITE_OMIT_PRAGMA)

186
187
188
189
190
191
192







193
194
195
196
197
198
199
200
201
202
203
204
205







206
207

208
209

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229

230
231
232
233
234
235
236
237






238
239
240

241
242
243
244
245
246
247
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218

219
220

221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245





246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262







+
+
+
+
+
+
+













+
+
+
+
+
+
+

-
+

-
+




















+



-
-
-
-
-
+
+
+
+
+
+



+







    /* The following is VERY experimental */
    { "writable_schema",          SQLITE_WriteSchema|SQLITE_RecoveryMode },
    { "omit_readlock",            SQLITE_NoReadlock    },

    /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted
    ** flag if there are any active statements. */
    { "read_uncommitted",         SQLITE_ReadUncommitted },
    { "recursive_triggers",       SQLITE_RecTriggers },

    /* This flag may only be set if both foreign-key and trigger support
    ** are present in the build.  */
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
    { "foreign_keys",             SQLITE_ForeignKeys },
#endif
  };
  int i;
  const struct sPragmaType *p;
  for(i=0, p=aPragma; i<ArraySize(aPragma); i++, p++){
    if( sqlite3StrICmp(zLeft, p->zName)==0 ){
      sqlite3 *db = pParse->db;
      Vdbe *v;
      v = sqlite3GetVdbe(pParse);
      assert( v!=0 );  /* Already allocated by sqlite3Pragma() */
      if( ALWAYS(v) ){
        if( zRight==0 ){
          returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 );
        }else{
          int mask = p->mask;          /* Mask of bits to set or clear. */
          if( db->autoCommit==0 ){
            /* Foreign key support may not be enabled or disabled while not
            ** in auto-commit mode.  */
            mask &= ~(SQLITE_ForeignKeys);
          }

          if( getBoolean(zRight) ){
            db->flags |= p->mask;
            db->flags |= mask;
          }else{
            db->flags &= ~p->mask;
            db->flags &= ~mask;
          }

          /* Many of the flag-pragmas modify the code generated by the SQL 
          ** compiler (eg. count_changes). So add an opcode to expire all
          ** compiled SQL statements after modifying a pragma value.
          */
          sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
        }
      }

      return 1;
    }
  }
  return 0;
}
#endif /* SQLITE_OMIT_FLAG_PRAGMAS */

/*
** Return a human-readable name for a constraint resolution action.
*/
#ifndef SQLITE_OMIT_FOREIGN_KEY
static const char *actionName(u8 action){
  const char *zName;
  switch( action ){
    case OE_SetNull:  zName = "SET NULL";            break;
    case OE_SetDflt:  zName = "SET DEFAULT";         break;
    case OE_Cascade:  zName = "CASCADE";             break;
    default:          zName = "RESTRICT";  
                      assert( action==OE_Restrict ); break;
    case OE_SetNull:  zName = "SET NULL";        break;
    case OE_SetDflt:  zName = "SET DEFAULT";     break;
    case OE_Cascade:  zName = "CASCADE";         break;
    case OE_Restrict: zName = "RESTRICT";        break;
    default:          zName = "NO ACTION";  
                      assert( action==OE_None ); break;
  }
  return zName;
}
#endif

/*
** Process a pragma statement.  
**
** Pragmas are of this form:
**
**      PRAGMA [database.]id [= value]
314
315
316
317
318
319
320

321
322


323
324
325
326


327
328
329
330
331
332
333
334
335
336
337
338


339
340
341
342
343
344
345
329
330
331
332
333
334
335
336


337
338
339
340


341
342
343
344
345
346
347
348
349
350
351
352
353

354
355
356
357
358
359
360
361
362







+
-
-
+
+


-
-
+
+











-
+
+







  ** database file.  The cache size is actually the absolute value of
  ** this memory location.  The sign of meta-value 2 determines the
  ** synchronous setting.  A negative value means synchronous is off
  ** and a positive value means synchronous is on.
  */
  if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
    static const VdbeOpList getCacheSize[] = {
      { OP_Transaction, 0, 0,        0},                         /* 0 */
      { OP_ReadCookie,  0, 1,        BTREE_DEFAULT_CACHE_SIZE},  /* 0 */
      { OP_IfPos,       1, 6,        0},
      { OP_ReadCookie,  0, 1,        BTREE_DEFAULT_CACHE_SIZE},  /* 1 */
      { OP_IfPos,       1, 7,        0},
      { OP_Integer,     0, 2,        0},
      { OP_Subtract,    1, 2,        1},
      { OP_IfPos,       1, 6,        0},
      { OP_Integer,     0, 1,        0},  /* 5 */
      { OP_IfPos,       1, 7,        0},
      { OP_Integer,     0, 1,        0},                         /* 6 */
      { OP_ResultRow,   1, 1,        0},
    };
    int addr;
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    sqlite3VdbeUsesBtree(v, iDb);
    if( !zRight ){
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", SQLITE_STATIC);
      pParse->nMem += 2;
      addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
      sqlite3VdbeChangeP1(v, addr, iDb);
      sqlite3VdbeChangeP1(v, addr+5, SQLITE_DEFAULT_CACHE_SIZE);
      sqlite3VdbeChangeP1(v, addr+1, iDb);
      sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE);
    }else{
      int size = atoi(zRight);
      if( size<0 ) size = -size;
      sqlite3BeginWriteOperation(pParse, 0, iDb);
      sqlite3VdbeAddOp2(v, OP_Integer, size, 1);
      sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 2, BTREE_DEFAULT_CACHE_SIZE);
      addr = sqlite3VdbeAddOp2(v, OP_IfPos, 2, 0);
958
959
960
961
962
963
964
965
966


967
968
969
970
971
972
973
975
976
977
978
979
980
981


982
983
984
985
986
987
988
989
990







-
-
+
+







        sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "on_update", SQLITE_STATIC);
        sqlite3VdbeSetColName(v, 6, COLNAME_NAME, "on_delete", SQLITE_STATIC);
        sqlite3VdbeSetColName(v, 7, COLNAME_NAME, "match", SQLITE_STATIC);
        while(pFK){
          int j;
          for(j=0; j<pFK->nCol; j++){
            char *zCol = pFK->aCol[j].zCol;
            char *zOnUpdate = (char *)actionName(pFK->updateConf);
            char *zOnDelete = (char *)actionName(pFK->deleteConf);
            char *zOnDelete = (char *)actionName(pFK->aAction[0]);
            char *zOnUpdate = (char *)actionName(pFK->aAction[1]);
            sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
            sqlite3VdbeAddOp2(v, OP_Integer, j, 2);
            sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pFK->zTo, 0);
            sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0,
                              pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
            sqlite3VdbeAddOp4(v, zCol ? OP_String8 : OP_Null, 0, 5, 0, zCol, 0);
            sqlite3VdbeAddOp4(v, OP_String8, 0, 6, 0, zOnUpdate, 0);
1298
1299
1300
1301
1302
1303
1304

1305

1306
1307
1308
1309

1310

1311
1312
1313
1314
1315
1316
1317
1315
1316
1317
1318
1319
1320
1321
1322

1323
1324
1325
1326
1327
1328

1329
1330
1331
1332
1333
1334
1335
1336







+
-
+




+
-
+







      sqlite3VdbeChangeP1(v, addr, iDb);
      sqlite3VdbeChangeP1(v, addr+1, atoi(zRight));
      sqlite3VdbeChangeP1(v, addr+2, iDb);
      sqlite3VdbeChangeP2(v, addr+2, iCookie);
    }else{
      /* Read the specified cookie value */
      static const VdbeOpList readCookie[] = {
        { OP_Transaction,     0,  0,  0},    /* 0 */
        { OP_ReadCookie,      0,  1,  0},    /* 0 */
        { OP_ReadCookie,      0,  1,  0},    /* 1 */
        { OP_ResultRow,       1,  1,  0}
      };
      int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie);
      sqlite3VdbeChangeP1(v, addr, iDb);
      sqlite3VdbeChangeP1(v, addr+1, iDb);
      sqlite3VdbeChangeP3(v, addr, iCookie);
      sqlite3VdbeChangeP3(v, addr+1, iCookie);
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT);
    }
  }else
#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
Changes to src/prepare.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33


34
35
36


37
38
39
40
41
42
43
8
9
10
11
12
13
14


15
16
17
18
19
20
21
22
23
24
25
26
27
28
29


30
31
32


33
34
35
36
37
38
39
40
41







-
-















-
-
+
+

-
-
+
+







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the implementation of the sqlite3_prepare()
** interface, and routines that contribute to loading the database schema
** from disk.
**
** $Id: prepare.c,v 1.125 2009/06/25 11:50:21 drh Exp $
*/
#include "sqliteInt.h"

/*
** Fill the InitData structure with an error message that indicates
** that the database is corrupt.
*/
static void corruptSchema(
  InitData *pData,     /* Initialization context */
  const char *zObj,    /* Object being parsed at the point of error */
  const char *zExtra   /* Error information */
){
  sqlite3 *db = pData->db;
  if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){
    if( zObj==0 ) zObj = "?";
    sqlite3SetString(pData->pzErrMsg, pData->db,
       "malformed database schema (%s)", zObj);
    sqlite3SetString(pData->pzErrMsg, db,
      "malformed database schema (%s)", zObj);
    if( zExtra ){
      *pData->pzErrMsg = sqlite3MAppendf(pData->db, *pData->pzErrMsg, "%s - %s",
                                  *pData->pzErrMsg, zExtra);
      *pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg, 
                                 "%s - %s", *pData->pzErrMsg, zExtra);
    }
  }
  pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT;
}

/*
** This is the callback routine for the code that initializes the
76
77
78
79
80
81
82

83
84
85
86



87
88
89
90
91






92
93
94
95
96
97
98
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88





89
90
91
92
93
94
95
96
97
98
99
100
101







+




+
+
+
-
-
-
-
-
+
+
+
+
+
+







    ** structures that describe the table, index, or view.
    */
    char *zErr;
    int rc;
    assert( db->init.busy );
    db->init.iDb = iDb;
    db->init.newTnum = atoi(argv[1]);
    db->init.orphanTrigger = 0;
    rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
    db->init.iDb = 0;
    assert( rc!=SQLITE_OK || zErr==0 );
    if( SQLITE_OK!=rc ){
      if( db->init.orphanTrigger ){
        assert( iDb==1 );
      }else{
      pData->rc = rc;
      if( rc==SQLITE_NOMEM ){
        db->mallocFailed = 1;
      }else if( rc!=SQLITE_INTERRUPT && rc!=SQLITE_LOCKED ){
        corruptSchema(pData, argv[0], zErr);
        pData->rc = rc;
        if( rc==SQLITE_NOMEM ){
          db->mallocFailed = 1;
        }else if( rc!=SQLITE_INTERRUPT && rc!=SQLITE_LOCKED ){
          corruptSchema(pData, argv[0], zErr);
        }
      }
      sqlite3DbFree(db, zErr);
    }
  }else if( argv[0]==0 ){
    corruptSchema(pData, 0, 0);
  }else{
    /* If the SQL column is blank it means this is an index that
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149







-








+







** database.  iDb==1 should never be used.  iDb>=2 is used for
** auxiliary databases.  Return one of the SQLITE_ error codes to
** indicate success or failure.
*/
static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
  int rc;
  int i;
  BtCursor *curMain;
  int size;
  Table *pTab;
  Db *pDb;
  char const *azArg[4];
  int meta[5];
  InitData initData;
  char const *zMasterSchema;
  char const *zMasterName = SCHEMA_TABLE(iDb);
  int openedTransaction = 0;

  /*
  ** The master database table has a structure like this
  */
  static const char master_schema[] = 
     "CREATE TABLE sqlite_master(\n"
     "  type text,\n"
206
207
208
209
210
211
212
213
214
215
216
217




218

219
220







221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240


241
242
243
244
245
246
247
248
249
250
251
209
210
211
212
213
214
215





216
217
218
219
220
221


222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246


247
248




249
250
251
252
253
254
255







-
-
-
-
-
+
+
+
+

+
-
-
+
+
+
+
+
+
+


















-
-
+
+
-
-
-
-







  pDb = &db->aDb[iDb];
  if( pDb->pBt==0 ){
    if( !OMIT_TEMPDB && ALWAYS(iDb==1) ){
      DbSetProperty(db, 1, DB_SchemaLoaded);
    }
    return SQLITE_OK;
  }
  curMain = sqlite3MallocZero(sqlite3BtreeCursorSize());
  if( !curMain ){
    rc = SQLITE_NOMEM;
    goto error_out;
  }

  /* If there is not already a read-only (or read-write) transaction opened
  ** on the b-tree database, open one now. If a transaction is opened, it 
  ** will be closed before this function returns.  */
  sqlite3BtreeEnter(pDb->pBt);
  if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){
  rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, curMain);
  if( rc==SQLITE_EMPTY ) rc = SQLITE_OK;
    rc = sqlite3BtreeBeginTrans(pDb->pBt, 0);
    if( rc!=SQLITE_OK ){
      sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
      goto initone_error_out;
    }
    openedTransaction = 1;
  }

  /* Get the database meta information.
  **
  ** Meta values are as follows:
  **    meta[0]   Schema cookie.  Changes with each schema change.
  **    meta[1]   File format of schema layer.
  **    meta[2]   Size of the page cache.
  **    meta[3]   Largest rootpage (auto/incr_vacuum mode)
  **    meta[4]   Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE
  **    meta[5]   User version
  **    meta[6]   Incremental vacuum mode
  **    meta[7]   unused
  **    meta[8]   unused
  **    meta[9]   unused
  **
  ** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to
  ** the possible values of meta[4].
  */
  for(i=0; rc==SQLITE_OK && i<ArraySize(meta); i++){
    rc = sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
  for(i=0; i<ArraySize(meta); i++){
    sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
  }
  if( rc ){
    sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
    goto initone_error_out;
  }
  pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1];

  /* If opening a non-empty database, check the text encoding. For the
  ** main database, set sqlite3.enc to the encoding of the main database.
  ** For an attached db, it is an error if the encoding is not the same
  ** as sqlite3.enc.
352
353
354
355
356
357
358

359

360

361
362
363
364
365
366
367
356
357
358
359
360
361
362
363

364

365
366
367
368
369
370
371
372







+
-
+
-
+







  }

  /* Jump here for an error that occurs after successfully allocating
  ** curMain and calling sqlite3BtreeEnter(). For an error that occurs
  ** before that point, jump to error_out.
  */
initone_error_out:
  if( openedTransaction ){
  sqlite3BtreeCloseCursor(curMain);
    sqlite3BtreeCommit(pDb->pBt);
  sqlite3_free(curMain);
  }
  sqlite3BtreeLeave(pDb->pBt);

error_out:
  if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
    db->mallocFailed = 1;
  }
  return rc;
431
432
433
434
435
436
437
438


439

440

441
442
443
444
445
446
447

448
449
450


451
452
453
454
455
456
457
458













459
460
461


462
463
464
465
466
467
468












469
470
471
472
473


474
475
476
477
478
479
480
481
436
437
438
439
440
441
442

443
444
445
446

447
448
449

450

451

452



453
454








455
456
457
458
459
460
461
462
463
464
465
466
467



468
469







470
471
472
473
474
475
476
477
478
479
480
481





482
483

484
485
486
487
488
489
490







-
+
+

+
-
+


-

-

-
+
-
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
-







  }
  return rc;
}


/*
** Check schema cookies in all databases.  If any cookie is out
** of date, return 0.  If all schema cookies are current, return 1.
** of date set pParse->rc to SQLITE_SCHEMA.  If all schema cookies
** make no changes to pParse->rc.
*/
static void schemaIsValid(Parse *pParse){
static int schemaIsValid(sqlite3 *db){
  sqlite3 *db = pParse->db;
  int iDb;
  int rc;
  BtCursor *curTemp;
  int cookie;
  int allOk = 1;

  curTemp = (BtCursor *)sqlite3Malloc(sqlite3BtreeCursorSize());
  assert( pParse->checkSchema );
  if( curTemp ){
    assert( sqlite3_mutex_held(db->mutex) );
    for(iDb=0; allOk && iDb<db->nDb; iDb++){
  assert( sqlite3_mutex_held(db->mutex) );
  for(iDb=0; iDb<db->nDb; iDb++){
      Btree *pBt;
      pBt = db->aDb[iDb].pBt;
      if( pBt==0 ) continue;
      memset(curTemp, 0, sqlite3BtreeCursorSize());
      rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, curTemp);
      if( rc==SQLITE_OK ){
        rc = sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie);
        if( ALWAYS(rc==SQLITE_OK)
    int openedTransaction = 0;         /* True if a transaction is opened */
    Btree *pBt = db->aDb[iDb].pBt;     /* Btree database to read cookie from */
    if( pBt==0 ) continue;

    /* If there is not already a read-only (or read-write) transaction opened
    ** on the b-tree database, open one now. If a transaction is opened, it 
    ** will be closed immediately after reading the meta-value. */
    if( !sqlite3BtreeIsInReadTrans(pBt) ){
      rc = sqlite3BtreeBeginTrans(pBt, 0);
      if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
        db->mallocFailed = 1;
      }
      if( rc!=SQLITE_OK ) return;
                && cookie!=db->aDb[iDb].pSchema->schema_cookie ){
          allOk = 0;
        }
      openedTransaction = 1;
    }
        sqlite3BtreeCloseCursor(curTemp);
      }
      if( NEVER(rc==SQLITE_NOMEM) || rc==SQLITE_IOERR_NOMEM ){
        db->mallocFailed = 1;
      }
    }
    sqlite3_free(curTemp);

    /* Read the schema cookie from the database. If it does not match the 
    ** value stored as part of the in the in-memory schema representation,
    ** set Parse.rc to SQLITE_SCHEMA. */
    sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie);
    if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){
      pParse->rc = SQLITE_SCHEMA;
    }

    /* Close the transaction, if one was opened. */
    if( openedTransaction ){
      sqlite3BtreeCommit(pBt);
  }else{
    allOk = 0;
    db->mallocFailed = 1;
  }

    }
  }
  return allOk;
}

/*
** Convert a schema pointer into the iDb index that indicates
** which database file in db->aDb[] the schema refers to.
**
** If the same database is attached more than once, the first
510
511
512
513
514
515
516

517
518
519
520
521
522
523
524
525
526
527
528
529
530

531
532
533
534
535
536
537
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548







+














+







** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
*/
static int sqlite3Prepare(
  sqlite3 *db,              /* Database handle. */
  const char *zSql,         /* UTF-8 encoded SQL statement. */
  int nBytes,               /* Length of zSql in bytes. */
  int saveSqlFlag,          /* True to copy SQL text into the sqlite3_stmt */
  Vdbe *pReprepare,         /* VM being reprepared */
  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
  const char **pzTail       /* OUT: End of parsed string */
){
  Parse *pParse;            /* Parsing context */
  char *zErrMsg = 0;        /* Error message */
  int rc = SQLITE_OK;       /* Result code */
  int i;                    /* Loop counter */

  /* Allocate the parsing context */
  pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
  if( pParse==0 ){
    rc = SQLITE_NOMEM;
    goto end_prepare;
  }
  pParse->pReprepare = pReprepare;

  if( sqlite3SafetyOn(db) ){
    rc = SQLITE_MISUSE;
    goto end_prepare;
  }
  assert( ppStmt && *ppStmt==0 );
  assert( !db->mallocFailed );
571
572
573
574
575
576
577

578
579
580
581
582
583
584
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596







+







        (void)sqlite3SafetyOff(db);
        testcase( db->flags & SQLITE_ReadUncommitted );
        goto end_prepare;
      }
    }
  }

  sqlite3VtabUnlockList(db);

  pParse->db = db;
  if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
    char *zSqlCopy;
    int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
    testcase( nBytes==mxLen );
    testcase( nBytes==mxLen+1 );
600
601
602
603
604
605
606
607
608


609
610
611
612
613
614
615
612
613
614
615
616
617
618


619
620
621
622
623
624
625
626
627







-
-
+
+







    sqlite3RunParser(pParse, zSql, &zErrMsg);
  }

  if( db->mallocFailed ){
    pParse->rc = SQLITE_NOMEM;
  }
  if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK;
  if( pParse->checkSchema && !schemaIsValid(db) ){
    pParse->rc = SQLITE_SCHEMA;
  if( pParse->checkSchema ){
    schemaIsValid(pParse);
  }
  if( pParse->rc==SQLITE_SCHEMA ){
    sqlite3ResetInternalSchema(db, 0);
  }
  if( db->mallocFailed ){
    pParse->rc = SQLITE_NOMEM;
  }
659
660
661
662
663
664
665








666
667
668
669
670
671
672
673
674
675
676
677
678

679
680
681
682
683
684
685
686
687
688
689
690

691
692
693

694
695
696
697
698
699
700
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710

711
712
713

714
715
716
717
718
719
720
721







+
+
+
+
+
+
+
+













+











-
+


-
+








  if( zErrMsg ){
    sqlite3Error(db, rc, "%s", zErrMsg);
    sqlite3DbFree(db, zErrMsg);
  }else{
    sqlite3Error(db, rc, 0);
  }

  /* Delete any TriggerPrg structures allocated while parsing this statement. */
  while( pParse->pTriggerPrg ){
    TriggerPrg *pT = pParse->pTriggerPrg;
    pParse->pTriggerPrg = pT->pNext;
    sqlite3VdbeProgramDelete(db, pT->pProgram, 0);
    sqlite3DbFree(db, pT);
  }

end_prepare:

  sqlite3StackFree(db, pParse);
  rc = sqlite3ApiExit(db, rc);
  assert( (rc&db->errMask)==rc );
  return rc;
}
static int sqlite3LockAndPrepare(
  sqlite3 *db,              /* Database handle. */
  const char *zSql,         /* UTF-8 encoded SQL statement. */
  int nBytes,               /* Length of zSql in bytes. */
  int saveSqlFlag,          /* True to copy SQL text into the sqlite3_stmt */
  Vdbe *pOld,               /* VM being reprepared */
  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
  const char **pzTail       /* OUT: End of parsed string */
){
  int rc;
  assert( ppStmt!=0 );
  *ppStmt = 0;
  if( !sqlite3SafetyCheckOk(db) ){
    return SQLITE_MISUSE;
  }
  sqlite3_mutex_enter(db->mutex);
  sqlite3BtreeEnterAll(db);
  rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, ppStmt, pzTail);
  rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
  if( rc==SQLITE_SCHEMA ){
    sqlite3_finalize(*ppStmt);
    rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, ppStmt, pzTail);
    rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
  }
  sqlite3BtreeLeaveAll(db);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}

/*
712
713
714
715
716
717
718
719

720
721
722
723
724
725
726
733
734
735
736
737
738
739

740
741
742
743
744
745
746
747







-
+







  sqlite3 *db;

  assert( sqlite3_mutex_held(sqlite3VdbeDb(p)->mutex) );
  zSql = sqlite3_sql((sqlite3_stmt *)p);
  assert( zSql!=0 );  /* Reprepare only called for prepare_v2() statements */
  db = sqlite3VdbeDb(p);
  assert( sqlite3_mutex_held(db->mutex) );
  rc = sqlite3LockAndPrepare(db, zSql, -1, 0, &pNew, 0);
  rc = sqlite3LockAndPrepare(db, zSql, -1, 0, p, &pNew, 0);
  if( rc ){
    if( rc==SQLITE_NOMEM ){
      db->mallocFailed = 1;
    }
    assert( pNew==0 );
    return (rc==SQLITE_LOCKED) ? SQLITE_LOCKED : SQLITE_SCHEMA;
  }else{
746
747
748
749
750
751
752
753

754
755
756
757
758
759
760
761
762
763
764
765

766
767
768
769
770
771
772
767
768
769
770
771
772
773

774
775
776
777
778
779
780
781
782
783
784
785

786
787
788
789
790
791
792
793







-
+











-
+







  sqlite3 *db,              /* Database handle. */
  const char *zSql,         /* UTF-8 encoded SQL statement. */
  int nBytes,               /* Length of zSql in bytes. */
  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
  const char **pzTail       /* OUT: End of parsed string */
){
  int rc;
  rc = sqlite3LockAndPrepare(db,zSql,nBytes,0,ppStmt,pzTail);
  rc = sqlite3LockAndPrepare(db,zSql,nBytes,0,0,ppStmt,pzTail);
  assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );  /* VERIFY: F13021 */
  return rc;
}
int sqlite3_prepare_v2(
  sqlite3 *db,              /* Database handle. */
  const char *zSql,         /* UTF-8 encoded SQL statement. */
  int nBytes,               /* Length of zSql in bytes. */
  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
  const char **pzTail       /* OUT: End of parsed string */
){
  int rc;
  rc = sqlite3LockAndPrepare(db,zSql,nBytes,1,ppStmt,pzTail);
  rc = sqlite3LockAndPrepare(db,zSql,nBytes,1,0,ppStmt,pzTail);
  assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );  /* VERIFY: F13021 */
  return rc;
}


#ifndef SQLITE_OMIT_UTF16
/*
792
793
794
795
796
797
798
799

800
801
802
803
804
805
806
813
814
815
816
817
818
819

820
821
822
823
824
825
826
827







-
+







  *ppStmt = 0;
  if( !sqlite3SafetyCheckOk(db) ){
    return SQLITE_MISUSE;
  }
  sqlite3_mutex_enter(db->mutex);
  zSql8 = sqlite3Utf16to8(db, zSql, nBytes);
  if( zSql8 ){
    rc = sqlite3LockAndPrepare(db, zSql8, -1, saveSqlFlag, ppStmt, &zTail8);
    rc = sqlite3LockAndPrepare(db, zSql8, -1, saveSqlFlag, 0, ppStmt, &zTail8);
  }

  if( zTail8 && pzTail ){
    /* If sqlite3_prepare returns a tail pointer, we calculate the
    ** equivalent pointer into the UTF-16 string by counting the unicode
    ** characters between zSql8 and zTail8, and then returning a pointer
    ** the same number of characters into the UTF-16 string.
Changes to src/printf.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1
2
3
4
5
6
7


8
9
10
11
12
13
14







-
-







/*
** The "printf" code that follows dates from the 1980's.  It is in
** the public domain.  The original comments are included here for
** completeness.  They are very out-of-date but might be useful as
** an historical reference.  Most of the "enhancements" have been backed
** out so that the functionality is now the same as standard printf().
**
** $Id: printf.c,v 1.104 2009/06/03 01:24:54 drh Exp $
**
**************************************************************************
**
** The following modules is an enhanced replacement for the "printf" subroutines
** found in the standard C library.  The following enhancements are
** supported:
**
**      +  Additional functions.  The standard set of "printf" functions
Changes to src/random.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
10
11
12
13
14
15
16


17
18
19
20
21
22
23







-
-







**
*************************************************************************
** This file contains code to implement a pseudo-random number
** generator (PRNG) for SQLite.
**
** Random numbers are used by some of the database backends in order
** to generate random integer keys for tables or random filenames.
**
** $Id: random.c,v 1.29 2008/12/10 19:26:24 drh Exp $
*/
#include "sqliteInt.h"


/* All threads share a single random number generator.
** This structure is the current state of the generator.
*/
Changes to src/resolve.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
9
10
11
12
13
14
15


16
17
18
19
20
21
22







-
-







**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains routines used for walking the parser tree and
** resolve all identifiers by associating them with a particular
** table and column.
**
** $Id: resolve.c,v 1.30 2009/06/15 23:15:59 drh Exp $
*/
#include "sqliteInt.h"
#include <stdlib.h>
#include <string.h>

/*
** Turn the pExpr expression into an alias for the iCol-th column of the
133
134
135
136
137
138
139

140
141
142
143
144
145
146
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145







+







  int cnt = 0;                      /* Number of matching column names */
  int cntTab = 0;                   /* Number of matching table names */
  sqlite3 *db = pParse->db;         /* The database connection */
  struct SrcList_item *pItem;       /* Use for looping over pSrcList items */
  struct SrcList_item *pMatch = 0;  /* The matching pSrcList item */
  NameContext *pTopNC = pNC;        /* First namecontext in the list */
  Schema *pSchema = 0;              /* Schema of the expression */
  int isTrigger = 0;

  assert( pNC );     /* the name context cannot be NULL. */
  assert( zCol );    /* The Z in X.Y.Z cannot be NULL */
  assert( ~ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );

  /* Initialize the node to no-match */
  pExpr->iTable = -1;
218
219
220
221
222
223
224
225
226


227
228
229
230



231
232

233
234
235


236
237

238
239
240
241
242
243
244
245
246



247
248
249
250
251















252
253
254
255
256
257
258
259





260
261
262
263
264
265
266
267
217
218
219
220
221
222
223


224
225
226



227
228
229


230



231
232


233

234
235
236
237


238
239
240
241
242





243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259






260
261
262
263
264

265
266
267
268
269
270
271







-
-
+
+

-
-
-
+
+
+
-
-
+
-
-
-
+
+
-
-
+
-




-
-


+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-
-
-
-
-
+
+
+
+
+
-







      }
    }

#ifndef SQLITE_OMIT_TRIGGER
    /* If we have not already resolved the name, then maybe 
    ** it is a new.* or old.* trigger argument reference
    */
    if( zDb==0 && zTab!=0 && cnt==0 && pParse->trigStack!=0 ){
      TriggerStack *pTriggerStack = pParse->trigStack;
    if( zDb==0 && zTab!=0 && cnt==0 && pParse->pTriggerTab!=0 ){
      int op = pParse->eTriggerOp;
      Table *pTab = 0;
      u32 *piColMask = 0;
      if( pTriggerStack->newIdx != -1 && sqlite3StrICmp("new", zTab) == 0 ){
        pExpr->iTable = pTriggerStack->newIdx;
      assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT );
      if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){
        pExpr->iTable = 1;
        assert( pTriggerStack->pTab );
        pTab = pTriggerStack->pTab;
        pTab = pParse->pTriggerTab;
        piColMask = &(pTriggerStack->newColMask);
      }else if( pTriggerStack->oldIdx != -1 && sqlite3StrICmp("old", zTab)==0 ){
        pExpr->iTable = pTriggerStack->oldIdx;
      }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){
        pExpr->iTable = 0;
        assert( pTriggerStack->pTab );
        pTab = pTriggerStack->pTab;
        pTab = pParse->pTriggerTab;
        piColMask = &(pTriggerStack->oldColMask);
      }

      if( pTab ){ 
        int iCol;
        Column *pCol = pTab->aCol;

        pSchema = pTab->pSchema;
        cntTab++;
        if( sqlite3IsRowid(zCol) ){
          iCol = -1;
        }else{
        for(iCol=0; iCol < pTab->nCol; iCol++, pCol++) {
          if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
            cnt++;
            pExpr->iColumn = iCol==pTab->iPKey ? -1 : (i16)iCol;
            pExpr->pTab = pTab;
          for(iCol=0; iCol<pTab->nCol; iCol++){
            Column *pCol = &pTab->aCol[iCol];
            if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
              if( iCol==pTab->iPKey ){
                iCol = -1;
              }
              break;
            }
          }
        }
        if( iCol<pTab->nCol ){
          cnt++;
          if( iCol<0 ){
            pExpr->affinity = SQLITE_AFF_INTEGER;
          }else if( pExpr->iTable==0 ){
            testcase( iCol==31 );
            testcase( iCol==32 );
            if( iCol>=32 ){
              *piColMask = 0xffffffff;
            }else{
              *piColMask |= ((u32)1)<<iCol;
            }
            break;
            pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
          }
          pExpr->iColumn = (i16)iCol;
          pExpr->pTab = pTab;
          isTrigger = 1;
          }
        }
      }
    }
#endif /* !defined(SQLITE_OMIT_TRIGGER) */

    /*
    ** Perhaps the name is a reference to the ROWID
365
366
367
368
369
370
371
372

373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389





















390
391
392
393
394
395
396
369
370
371
372
373
374
375

376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421







-
+

















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








  /* Clean up and return
  */
  sqlite3ExprDelete(db, pExpr->pLeft);
  pExpr->pLeft = 0;
  sqlite3ExprDelete(db, pExpr->pRight);
  pExpr->pRight = 0;
  pExpr->op = TK_COLUMN;
  pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN);
lookupname_end:
  if( cnt==1 ){
    assert( pNC!=0 );
    sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
    /* Increment the nRef value on all name contexts from TopNC up to
    ** the point where the name matched. */
    for(;;){
      assert( pTopNC!=0 );
      pTopNC->nRef++;
      if( pTopNC==pNC ) break;
      pTopNC = pTopNC->pNext;
    }
    return WRC_Prune;
  } else {
    return WRC_Abort;
  }
}

/*
** Allocate and return a pointer to an expression to load the column iCol
** from datasource iSrc datasource in SrcList pSrc.
*/
Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){
  Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
  if( p ){
    struct SrcList_item *pItem = &pSrc->a[iSrc];
    p->pTab = pItem->pTab;
    p->iTable = pItem->iCursor;
    if( p->pTab->iPKey==iCol ){
      p->iColumn = -1;
    }else{
      p->iColumn = (ynVar)iCol;
      pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol);
    }
    ExprSetProperty(p, EP_Resolved);
  }
  return p;
}

/*
** This routine is callback for sqlite3WalkExpr().
**
** Resolve symbolic names into TK_COLUMN operators for the current
** node in the expression tree.  Return 0 to continue the search down
** the tree or 2 to abort the tree walk.
Changes to src/rowset.c.
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
55
56
57
58
59
60
61


62
63
64
65
66
67
68







-
-







** batch number is O(NlogN) where N is the number of elements in the RowSet.
** The cost of a TEST using the same batch number is O(logN).  The cost
** of the first SMALLEST is O(NlogN).  Second and subsequent SMALLEST
** primitives are constant time.  The cost of DESTROY is O(N).
**
** There is an added cost of O(N) when switching between TEST and
** SMALLEST primitives.
**
** $Id: rowset.c,v 1.7 2009/05/22 01:00:13 drh Exp $
*/
#include "sqliteInt.h"


/*
** Target size for allocation chunks.
*/
Changes to src/select.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.524 2009/06/12 03:27:27 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
188
189
190
191
192
193
194

195
196



197
198
199
200
201
202
203





204
205
206
207
208
209




210
211

212
213
214


215

216
217
218



219
220
221
222
223
224
225





226
227
228


229
230
231
232
233
234
235
236
237






238
239

240
241
242
243
244
245
246
186
187
188
189
190
191
192
193


194
195
196







197
198
199
200
201
202
203




204
205
206
207


208



209
210
211
212



213
214
215
216






217
218
219
220
221



222
223









224
225
226
227
228
229
230

231
232
233
234
235
236
237
238







+
-
-
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+


-
-
-
-
+
+
+
+
-
-
+
-
-
-
+
+

+
-
-
-
+
+
+

-
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+

-
+







  for(i=0; i<pTab->nCol; i++){
    if( sqlite3StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i;
  }
  return -1;
}

/*
** This function is used to add terms implied by JOIN syntax to the
** Create an expression node for an identifier with the name of zName
*/
** WHERE clause expression of a SELECT statement. The new term, which
** is ANDed with the existing WHERE clause, is of the form:
**
Expr *sqlite3CreateIdExpr(Parse *pParse, const char *zName){
  return sqlite3Expr(pParse->db, TK_ID, zName);
}

/*
** Add a term to the WHERE expression in *ppExpr that requires the
** zCol column to be equal in the two tables pTab1 and pTab2.
**    (tab1.col1 = tab2.col2)
**
** where tab1 is the iSrc'th table in SrcList pSrc and tab2 is the 
** (iSrc+1)'th. Column col1 is column iColLeft of tab1, and col2 is
** column iColRight of tab2.
*/
static void addWhereTerm(
  Parse *pParse,           /* Parsing context */
  const char *zCol,        /* Name of the column */
  const Table *pTab1,      /* First table */
  const char *zAlias1,     /* Alias for first table.  May be NULL */
  Parse *pParse,                  /* Parsing context */
  SrcList *pSrc,                  /* List of tables in FROM clause */
  int iSrc,                       /* Index of first table to join in pSrc */
  int iColLeft,                   /* Index of column in first table */
  const Table *pTab2,      /* Second table */
  const char *zAlias2,     /* Alias for second table.  May be NULL */
  int iColRight,                  /* Index of column in second table */
  int iRightJoinTable,     /* VDBE cursor for the right table */
  Expr **ppExpr,           /* Add the equality term to this expression */
  int isOuterJoin          /* True if dealing with an OUTER join */
  int isOuterJoin,                /* True if this is an OUTER join */
  Expr **ppWhere                  /* IN/OUT: The WHERE clause to add to */
){
  sqlite3 *db = pParse->db;
  Expr *pE1a, *pE1b, *pE1c;
  Expr *pE2a, *pE2b, *pE2c;
  Expr *pE;
  Expr *pE1;
  Expr *pE2;
  Expr *pEq;

  pE1a = sqlite3CreateIdExpr(pParse, zCol);
  pE2a = sqlite3CreateIdExpr(pParse, zCol);
  if( zAlias1==0 ){
    zAlias1 = pTab1->zName;
  }
  pE1b = sqlite3CreateIdExpr(pParse, zAlias1);
  assert( pSrc->nSrc>(iSrc+1) );
  assert( pSrc->a[iSrc].pTab );
  assert( pSrc->a[iSrc+1].pTab );

  pE1 = sqlite3CreateColumnExpr(db, pSrc, iSrc, iColLeft);
  if( zAlias2==0 ){
    zAlias2 = pTab2->zName;
  }
  pE2 = sqlite3CreateColumnExpr(db, pSrc, iSrc+1, iColRight);

  pE2b = sqlite3CreateIdExpr(pParse, zAlias2);
  pE1c = sqlite3PExpr(pParse, TK_DOT, pE1b, pE1a, 0);
  pE2c = sqlite3PExpr(pParse, TK_DOT, pE2b, pE2a, 0);
  pE = sqlite3PExpr(pParse, TK_EQ, pE1c, pE2c, 0);
  if( pE && isOuterJoin ){
    ExprSetProperty(pE, EP_FromJoin);
    assert( !ExprHasAnyProperty(pE, EP_TokenOnly|EP_Reduced) );
    ExprSetIrreducible(pE);
    pE->iRightJoinTable = (i16)iRightJoinTable;
  pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2, 0);
  if( pEq && isOuterJoin ){
    ExprSetProperty(pEq, EP_FromJoin);
    assert( !ExprHasAnyProperty(pEq, EP_TokenOnly|EP_Reduced) );
    ExprSetIrreducible(pEq);
    pEq->iRightJoinTable = (i16)pE2->iTable;
  }
  *ppExpr = sqlite3ExprAnd(pParse->db,*ppExpr, pE);
  *ppWhere = sqlite3ExprAnd(db, *ppWhere, pEq);
}

/*
** Set the EP_FromJoin property on all terms of the given expression.
** And set the Expr.iRightJoinTable to iTable for every term in the
** expression.
**
314
315
316
317
318
319
320
321

322
323

324
325

326
327
328
329
330
331
332
306
307
308
309
310
311
312

313


314


315
316
317
318
319
320
321
322







-
+
-
-
+
-
-
+







      if( pRight->pOn || pRight->pUsing ){
        sqlite3ErrorMsg(pParse, "a NATURAL join may not have "
           "an ON or USING clause", 0);
        return 1;
      }
      for(j=0; j<pLeftTab->nCol; j++){
        char *zName = pLeftTab->aCol[j].zName;
        if( columnIndex(pRightTab, zName)>=0 ){
        int iRightCol = columnIndex(pRightTab, zName);
          addWhereTerm(pParse, zName, pLeftTab, pLeft->zAlias, 
                              pRightTab, pRight->zAlias,
        if( iRightCol>=0 ){
                              pRight->iCursor, &p->pWhere, isOuter);
          
          addWhereTerm(pParse, pSrc, i, j, iRightCol, isOuter, &p->pWhere);
        }
      }
    }

    /* Disallow both ON and USING clauses in the same join
    */
    if( pRight->pOn && pRight->pUsing ){
351
352
353
354
355
356
357
358



359
360
361
362
363

364
365
366
367
368
369
370
371
372
341
342
343
344
345
346
347

348
349
350
351
352
353
354

355


356
357
358
359
360
361
362







-
+
+
+




-
+
-
-







    ** Report an error if any column mentioned in the USING clause is
    ** not contained in both tables to be joined.
    */
    if( pRight->pUsing ){
      IdList *pList = pRight->pUsing;
      for(j=0; j<pList->nId; j++){
        char *zName = pList->a[j].zName;
        if( columnIndex(pLeftTab, zName)<0 || columnIndex(pRightTab, zName)<0 ){
        int iLeftCol = columnIndex(pLeftTab, zName);
        int iRightCol = columnIndex(pRightTab, zName);
        if( iLeftCol<0 || iRightCol<0 ){
          sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
            "not present in both tables", zName);
          return 1;
        }
        addWhereTerm(pParse, zName, pLeftTab, pLeft->zAlias, 
        addWhereTerm(pParse, pSrc, i, iLeftCol, iRightCol, isOuter, &p->pWhere);
                            pRightTab, pRight->zAlias,
                            pRight->iCursor, &p->pWhere, isOuter);
      }
    }
  }
  return 0;
}

/*
762
763
764
765
766
767
768

769
770
771




772
773
774
775
776
777
778
779
780
781
782
783
752
753
754
755
756
757
758
759
760
761

762
763
764
765
766
767
768


769
770
771
772
773
774
775







+


-
+
+
+
+



-
-







  int eDest = pDest->eDest;
  int iParm = pDest->iParm;

  int regRow;
  int regRowid;

  iTab = pOrderBy->iECursor;
  regRow = sqlite3GetTempReg(pParse);
  if( eDest==SRT_Output || eDest==SRT_Coroutine ){
    pseudoTab = pParse->nTab++;
    sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, eDest==SRT_Output, nColumn);
    sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, regRow, nColumn);
    regRowid = 0;
  }else{
    regRowid = sqlite3GetTempReg(pParse);
  }
  addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak);
  codeOffset(v, p, addrContinue);
  regRow = sqlite3GetTempReg(pParse);
  regRowid = sqlite3GetTempReg(pParse);
  sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr + 1, regRow);
  switch( eDest ){
    case SRT_Table:
    case SRT_EphemTab: {
      testcase( eDest==SRT_Table );
      testcase( eDest==SRT_EphemTab );
      sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
801
802
803
804
805
806
807
808
809
810
811
812



813
814
815
816
817
818
819
793
794
795
796
797
798
799


800
801
802
803
804
805
806
807
808
809
810
811
812







-
-



+
+
+







    }
#endif
    default: {
      int i;
      assert( eDest==SRT_Output || eDest==SRT_Coroutine ); 
      testcase( eDest==SRT_Output );
      testcase( eDest==SRT_Coroutine );
      sqlite3VdbeAddOp2(v, OP_Integer, 1, regRowid);
      sqlite3VdbeAddOp3(v, OP_Insert, pseudoTab, regRow, regRowid);
      for(i=0; i<nColumn; i++){
        assert( regRow!=pDest->iMem+i );
        sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iMem+i);
        if( i==0 ){
          sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
        }
      }
      if( eDest==SRT_Output ){
        sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn);
        sqlite3ExprCacheAffinityChange(pParse, pDest->iMem, nColumn);
      }else{
        sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
      }
889
890
891
892
893
894
895
896
897
898
899
900





901
902

903
904
905
906










907
908
909
910

911
912
913
914
915
916
917
918
919
920
921
922
923
924

925
926
927
928
929
930
931
882
883
884
885
886
887
888





889
890
891
892
893

894
895




896
897
898
899
900
901
902
903
904
905
906
907
908

909
910
911
912
913
914
915
916
917
918
919
920
921
922

923
924
925
926
927
928
929
930







-
-
-
-
-
+
+
+
+
+
-

+
-
-
-
-
+
+
+
+
+
+
+
+
+
+



-
+













-
+







          pS = pTabList->a[j].pSelect;
        }else{
          pNC = pNC->pNext;
        }
      }

      if( pTab==0 ){
        /* FIX ME:
        ** This can occurs if you have something like "SELECT new.x;" inside
        ** a trigger.  In other words, if you reference the special "new"
        ** table in the result set of a select.  We do not have a good way
        ** to find the actual table type, so call it "TEXT".  This is really
        /* At one time, code such as "SELECT new.x" within a trigger would
        ** cause this condition to run.  Since then, we have restructured how
        ** trigger code is generated and so this condition is no longer 
        ** possible. However, it can still be true for statements like
        ** the following:
        ** something of a bug, but I do not know how to fix it.
        **
        **   CREATE TABLE t1(col INTEGER);
        ** This code does not produce the correct answer - it just prevents
        ** a segfault.  See ticket #1229.
        */
        zType = "TEXT";
        **   SELECT (SELECT t1.col) FROM FROM t1;
        **
        ** when columnType() is called on the expression "t1.col" in the 
        ** sub-select. In this case, set the column type to NULL, even
        ** though it should really be "INTEGER".
        **
        ** This is not a problem, as the column type of "t1.col" is never
        ** used. When columnType() is called on the expression 
        ** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT
        ** branch below.  */
        break;
      }

      assert( pTab );
      assert( pTab && pExpr->pTab==pTab );
      if( pS ){
        /* The "table" is actually a sub-select or a view in the FROM clause
        ** of the SELECT statement. Return the declaration type and origin
        ** data for the result-set column of the sub-select.
        */
        if( ALWAYS(iCol>=0 && iCol<pS->pEList->nExpr) ){
          /* If iCol is less than zero, then the expression requests the
          ** rowid of the sub-select or view. This expression is legal (see 
          ** test case misc2.2.2) - it always evaluates to NULL.
          */
          NameContext sNC;
          Expr *p = pS->pEList->a[iCol].pExpr;
          sNC.pSrcList = pS->pSrc;
          sNC.pNext = 0;
          sNC.pNext = pNC;
          sNC.pParse = pNC->pParse;
          zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); 
        }
      }else if( ALWAYS(pTab->pSchema) ){
        /* A real table */
        assert( !pS );
        if( iCol<0 ) iCol = pTab->iPKey;
2351
2352
2353
2354
2355
2356
2357



2358
2359
2360
2361
2362
2363
2364
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366







+
+
+







    if( pExpr->iColumn<0 ){
      pExpr->op = TK_NULL;
    }else{
      Expr *pNew;
      assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
      assert( pExpr->pLeft==0 && pExpr->pRight==0 );
      pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
      if( pNew && pExpr->pColl ){
        pNew->pColl = pExpr->pColl;
      }
      sqlite3ExprDelete(db, pExpr);
      pExpr = pNew;
    }
  }else{
    pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
    pExpr->pRight = substExpr(db, pExpr->pRight, iTable, pEList);
    if( ExprHasProperty(pExpr, EP_xIsSelect) ){
2727
2728
2729
2730
2731
2732
2733

2734
2735


2736
2737
2738
2739
2740
2741
2742
2729
2730
2731
2732
2733
2734
2735
2736


2737
2738
2739
2740
2741
2742
2743
2744
2745







+
-
-
+
+







  ** refer to the subquery even after flattening.  Ticket #3346.
  **
  ** pSubitem->pTab is always non-NULL by test restrictions and tests above.
  */
  if( ALWAYS(pSubitem->pTab!=0) ){
    Table *pTabToDel = pSubitem->pTab;
    if( pTabToDel->nRef==1 ){
      Parse *pToplevel = sqlite3ParseToplevel(pParse);
      pTabToDel->pNextZombie = pParse->pZombieTab;
      pParse->pZombieTab = pTabToDel;
      pTabToDel->pNextZombie = pToplevel->pZombieTab;
      pToplevel->pZombieTab = pTabToDel;
    }else{
      pTabToDel->nRef--;
    }
    pSubitem->pTab = 0;
  }

  /* The following loop runs once for each term in a compound-subquery
Changes to src/shell.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code to implement the "sqlite" command line
** utility for accessing SQLite databases.
**
** $Id: shell.c,v 1.210 2009/05/31 17:16:10 drh Exp $
*/
#if defined(_WIN32) || defined(WIN32)
/* This needs to come before any includes for MSVC compiler */
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <stdlib.h>
102
103
104
105
106
107
108

109
110
111












































































112
113
114
115
116
117
118
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193







+



+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    struct rusage sEnd;
    getrusage(RUSAGE_SELF, &sEnd);
    printf("CPU Time: user %f sys %f\n",
       timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
       timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
  }
}

#define BEGIN_TIMER beginTimer()
#define END_TIMER endTimer()
#define HAS_TIMER 1

#elif (defined(_WIN32) || defined(WIN32))

#include <windows.h>

/* Saved resource information for the beginning of an operation */
static HANDLE hProcess;
static FILETIME ftKernelBegin;
static FILETIME ftUserBegin;
typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
static GETPROCTIMES getProcessTimesAddr = NULL;

/* True if the timer is enabled */
static int enableTimer = 0;

/*
** Check to see if we have timer support.  Return 1 if necessary
** support found (or found previously).
*/
static int hasTimer(void){
  if( getProcessTimesAddr ){
    return 1;
  } else {
    /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
    ** See if the version we are running on has it, and if it does, save off
    ** a pointer to it and the current process handle.
    */
    hProcess = GetCurrentProcess();
    if( hProcess ){
      HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
      if( NULL != hinstLib ){
        getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
        if( NULL != getProcessTimesAddr ){
          return 1;
        }
        FreeLibrary(hinstLib); 
      }
    }
  }
  return 0;
}

/*
** Begin timing an operation
*/
static void beginTimer(void){
  if( enableTimer && getProcessTimesAddr ){
    FILETIME ftCreation, ftExit;
    getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
  }
}

/* Return the difference of two FILETIME structs in seconds */
static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
  sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
  sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
  return (double) ((i64End - i64Start) / 10000000.0);
}

/*
** Print the timing results.
*/
static void endTimer(void){
  if( enableTimer && getProcessTimesAddr){
    FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
    getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
    printf("CPU Time: user %f sys %f\n",
       timeDiff(&ftUserBegin, &ftUserEnd),
       timeDiff(&ftKernelBegin, &ftKernelEnd));
  }
}

#define BEGIN_TIMER beginTimer()
#define END_TIMER endTimer()
#define HAS_TIMER hasTimer()

#else
#define BEGIN_TIMER 
#define END_TIMER
#define HAS_TIMER 0
#endif

/*
193
194
195
196
197
198
199
200

201
202
203
204
205
206
207
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282







-
+







"CREATE TABLE x("                                                            \
  "database,"          /* Name of database (i.e. main, temp etc.) */         \
  "triggername,"       /* Name of trigger */                                 \
  "dummy"              /* Unused */                                          \
")"

typedef struct SchemaTable SchemaTable;
struct SchemaTable {
static struct SchemaTable {
  const char *zName;
  const char *zObject;
  const char *zPragma;
  const char *zSchema;
} aSchemaTable[] = {
  { "table_info",       "table", "PRAGMA %Q.table_info(%Q)",       SCHEMA },
  { "foreign_key_list", "table", "PRAGMA %Q.foreign_key_list(%Q)", SCHEMA2 },
650
651
652
653
654
655
656
657

658
659
660
661
662
663
664
725
726
727
728
729
730
731

732
733
734
735
736
737
738
739







-
+







static int invokeCallback(void *p, int nArg, char **azArg, char **azCol){
  GenfkeyCb *pCb = (GenfkeyCb *)p;
  UNUSED_PARAMETER(nArg);
  UNUSED_PARAMETER(azCol);
  return pCb->xData(pCb->pCtx, pCb->eType, azArg[0]);
}

int detectSchemaProblem(
static int detectSchemaProblem(
  sqlite3 *db,                   /* Database connection */
  const char *zMessage,          /* English language error message */
  const char *zSql,              /* SQL statement to run */
  GenfkeyCb *pCb
){
  sqlite3_stmt *pStmt;
  int rc;
847
848
849
850
851
852
853
854

855
856
857
858
859
860
861
922
923
924
925
926
927
928

929
930
931
932
933
934
935
936







-
+







      */
      "CREATE TRIGGER /name/_delete_referenced BEFORE DELETE ON /ref/ WHEN\n"
      "    EXISTS (SELECT 1 FROM /tbl/ WHERE /cond2/)\n"
      "BEGIN\n"
      "  /delete_action/\n"
      "END;\n"

      /* The "BEFORE DELETE ON <referenced>" trigger. This trigger's job 
      /* The "AFTER UPDATE ON <referenced>" trigger. This trigger's job 
      ** is to detect when the key columns of a row in the referenced table 
      ** to which one or more rows in the referencing table correspond are
      ** updated. The action taken depends on the value of the 'ON UPDATE' 
      ** clause.
      */
      "CREATE TRIGGER /name/_update_referenced AFTER\n"
      "    UPDATE OF /fkey_list/ ON /ref/ WHEN \n"
872
873
874
875
876
877
878
879
880


881
882
883
884
885
886
887
888
889
890
891
892
893
894

895
896

897
898
899
900
901
902
903
904
905
906
907
908
909
910
911

912
913

914
915
916
917
918
919
920
947
948
949
950
951
952
953


954
955
956
957
958
959
960
961
962
963
964
965
966
967
968

969
970

971
972
973
974
975
976
977
978
979
980
981
982
983
984
985

986
987

988
989
990
991
992
993
994
995







-
-
+
+













-
+

-
+














-
+

-
+







    ", '/on_update/', on_update"

    ", '/name/',   'genfkey' || min(rowid)"
    ", '/tbl/',    dq(from_tbl)"
    ", '/ref/',    dq(to_tbl)"
    ", '/key_notnull/', sj('new.' || dq(from_col) || ' IS NOT NULL', ' AND ')"

    ", '/fkey_list/', sj(to_col, ', ')"
    ", '/rkey_list/', sj(from_col, ', ')"
    ", '/fkey_list/', sj(dq(to_col), ', ')"
    ", '/rkey_list/', sj(dq(from_col), ', ')"

    ", '/cond1/',  sj(multireplace('new./from/ == /to/'"
                   ", '/from/', dq(from_col)"
                   ", '/to/',   dq(to_col)"
                   "), ' AND ')"
    ", '/cond2/',  sj(multireplace('old./to/ == /from/'"
                   ", '/from/', dq(from_col)"
                   ", '/to/',   dq(to_col)"
                   "), ' AND ')"

    ", '/update_action/', CASE on_update "
      "WHEN 'SET NULL' THEN "
        "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' "
        ", '/setlist/', sj(from_col||' = NULL',', ')"
        ", '/setlist/', sj(dq(from_col)||' = NULL',', ')"
        ", '/tbl/',     dq(from_tbl)"
        ", '/where/',   sj(from_col||' = old.'||dq(to_col),' AND ')"
        ", '/where/',   sj(dq(from_col)||' = old.'||dq(to_col),' AND ')"
        ")"
      "WHEN 'CASCADE' THEN "
        "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' "
        ", '/setlist/', sj(dq(from_col)||' = new.'||dq(to_col),', ')"
        ", '/tbl/',     dq(from_tbl)"
        ", '/where/',   sj(dq(from_col)||' = old.'||dq(to_col),' AND ')"
        ")"
      "ELSE "
      "  'SELECT RAISE(ABORT, ''constraint failed'');'"
      "END "

    ", '/delete_action/', CASE on_delete "
      "WHEN 'SET NULL' THEN "
        "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' "
        ", '/setlist/', sj(from_col||' = NULL',', ')"
        ", '/setlist/', sj(dq(from_col)||' = NULL',', ')"
        ", '/tbl/',     dq(from_tbl)"
        ", '/where/',   sj(from_col||' = old.'||dq(to_col),' AND ')"
        ", '/where/',   sj(dq(from_col)||' = old.'||dq(to_col),' AND ')"
        ")"
      "WHEN 'CASCADE' THEN "
        "multireplace('DELETE FROM /tbl/ WHERE /where/;' "
        ", '/tbl/',     dq(from_tbl)"
        ", '/where/',   sj(dq(from_col)||' = old.'||dq(to_col),' AND ')"
        ")"
      "ELSE "
1178
1179
1180
1181
1182
1183
1184
1185

1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202

1203
1204
1205
1206
1207
1208
1209
1253
1254
1255
1256
1257
1258
1259

1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285







-
+

















+








/*
** An pointer to an instance of this structure is passed from
** the main program to the callback.  This is used to communicate
** state and mode information.
*/
struct callback_data {
  sqlite3 *db;            /* The database */
  sqlite3 *db;           /* The database */
  int echoOn;            /* True to echo input commands */
  int cnt;               /* Number of records displayed so far */
  FILE *out;             /* Write results here */
  int mode;              /* An output mode setting */
  int writableSchema;    /* True if PRAGMA writable_schema=ON */
  int showHeader;        /* True to show column names in List or Column mode */
  char *zDestTable;      /* Name of destination table when MODE_Insert */
  char separator[20];    /* Separator character for MODE_List */
  int colWidth[100];     /* Requested width of each column when in column mode*/
  int actualWidth[100];  /* Actual width of each column */
  char nullvalue[20];    /* The text to print when a NULL comes back from
                         ** the database */
  struct previous_mode_data explainPrev;
                         /* Holds the mode information just before
                         ** .explain ON */
  char outfile[FILENAME_MAX]; /* Filename for *out */
  const char *zDbFilename;    /* name of the database file */
  sqlite3_stmt *pStmt;   /* Current statement if any. */
};

/*
** These are the allowed modes.
*/
#define MODE_Line     0  /* One column per line.  Blank line between records */
#define MODE_Column   1  /* One record per line in neat columns */
1237
1238
1239
1240
1241
1242
1243











1244
1245
1246
1247
1248
1249
1250
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337







+
+
+
+
+
+
+
+
+
+
+







** lower 30 bits of a 32-bit signed integer.
*/
static int strlen30(const char *z){
  const char *z2 = z;
  while( *z2 ){ z2++; }
  return 0x3fffffff & (int)(z2 - z);
}

/*
** Output the given string as a hex-encoded blob (eg. X'1234' )
*/
static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
  int i;
  char *zBlob = (char *)pBlob;
  fprintf(out,"X'");
  for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]); }
  fprintf(out,"'");
}

/*
** Output the given string as a quoted string using SQL quoting conventions.
*/
static void output_quoted_string(FILE *out, const char *z){
  int i;
  int nSingle = 0;
1303
1304
1305
1306
1307
1308
1309
1310







1311
1312
1313
1314
1315
1316
1317






1318
1319
1320
1321
1322
1323
1324
1390
1391
1392
1393
1394
1395
1396

1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423







-
+
+
+
+
+
+
+







+
+
+
+
+
+







/*
** Output the given string with characters that are special to
** HTML escaped.
*/
static void output_html_string(FILE *out, const char *z){
  int i;
  while( *z ){
    for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){}
    for(i=0;   z[i] 
            && z[i]!='<' 
            && z[i]!='&' 
            && z[i]!='>' 
            && z[i]!='\"' 
            && z[i]!='\'';
        i++){}
    if( i>0 ){
      fprintf(out,"%.*s",i,z);
    }
    if( z[i]=='<' ){
      fprintf(out,"&lt;");
    }else if( z[i]=='&' ){
      fprintf(out,"&amp;");
    }else if( z[i]=='>' ){
      fprintf(out,"&gt;");
    }else if( z[i]=='\"' ){
      fprintf(out,"&quot;");
    }else if( z[i]=='\'' ){
      fprintf(out,"&#39;");
    }else{
      break;
    }
    z += i + 1;
  }
}

1390
1391
1392
1393
1394
1395
1396
1397

1398
1399
1400

1401
1402





1403
1404
1405
1406
1407
1408
1409
1489
1490
1491
1492
1493
1494
1495

1496
1497
1498

1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513







-
+


-
+


+
+
+
+
+







  UNUSED_PARAMETER(NotUsed);
  seenInterrupt = 1;
  if( db ) sqlite3_interrupt(db);
}
#endif

/*
** This is the callback routine that the SQLite library
** This is the callback routine that the shell
** invokes for each row of a query result.
*/
static int callback(void *pArg, int nArg, char **azArg, char **azCol){
static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
  int i;
  struct callback_data *p = (struct callback_data*)pArg;

  if( p->echoOn && p->cnt==0  && p->pStmt){
    printf("%s\n", sqlite3_sql(p->pStmt));
  }

  switch( p->mode ){
    case MODE_Line: {
      int w = 5;
      if( azArg==0 ) break;
      for(i=0; i<nArg; i++){
        int len = strlen30(azCol[i] ? azCol[i] : "");
        if( len>w ) w = len;
1491
1492
1493
1494
1495
1496
1497
1498



1499
1500
1501
1502
1503
1504
1505
1595
1596
1597
1598
1599
1600
1601

1602
1603
1604
1605
1606
1607
1608
1609
1610
1611







-
+
+
+







      }
      break;
    }
    case MODE_Html: {
      if( p->cnt++==0 && p->showHeader ){
        fprintf(p->out,"<TR>");
        for(i=0; i<nArg; i++){
          fprintf(p->out,"<TH>%s</TH>",azCol[i]);
          fprintf(p->out,"<TH>");
          output_html_string(p->out, azCol[i]);
          fprintf(p->out,"</TH>\n");
        }
        fprintf(p->out,"</TR>\n");
      }
      if( azArg==0 ) break;
      fprintf(p->out,"<TR>");
      for(i=0; i<nArg; i++){
        fprintf(p->out,"<TD>");
1536
1537
1538
1539
1540
1541
1542

1543
1544
1545
1546
1547

1548










1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561









1562
1563
1564
1565
1566
1567
1568
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653

1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694







+




-
+

+
+
+
+
+
+
+
+
+
+













+
+
+
+
+
+
+
+
+







      for(i=0; i<nArg; i++){
        output_csv(p, azArg[i], i<nArg-1);
      }
      fprintf(p->out,"\n");
      break;
    }
    case MODE_Insert: {
      p->cnt++;
      if( azArg==0 ) break;
      fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
      for(i=0; i<nArg; i++){
        char *zSep = i>0 ? ",": "";
        if( azArg[i]==0 ){
        if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
          fprintf(p->out,"%sNULL",zSep);
        }else if( aiType && aiType[i]==SQLITE_TEXT ){
          if( zSep[0] ) fprintf(p->out,"%s",zSep);
          output_quoted_string(p->out, azArg[i]);
        }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
          fprintf(p->out,"%s%s",zSep, azArg[i]);
        }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
          const void *pBlob = sqlite3_column_blob(p->pStmt, i);
          int nBlob = sqlite3_column_bytes(p->pStmt, i);
          if( zSep[0] ) fprintf(p->out,"%s",zSep);
          output_hex_blob(p->out, pBlob, nBlob);
        }else if( isNumber(azArg[i], 0) ){
          fprintf(p->out,"%s%s",zSep, azArg[i]);
        }else{
          if( zSep[0] ) fprintf(p->out,"%s",zSep);
          output_quoted_string(p->out, azArg[i]);
        }
      }
      fprintf(p->out,");\n");
      break;
    }
  }
  return 0;
}

/*
** This is the callback routine that the SQLite library
** invokes for each row of a query result.
*/
static int callback(void *pArg, int nArg, char **azArg, char **azCol){
  /* since we don't have type info, call the shell_callback with a NULL value */
  return shell_callback(pArg, nArg, azArg, azCol, NULL);
}

/*
** Set the destination table field of the callback_data structure to
** the name of the table given.  Escape any quote characters in the
** table name.
*/
static void set_table_name(struct callback_data *p, const char *zName){
1581
1582
1583
1584
1585
1586
1587
1588

1589
1590
1591
1592
1593
1594
1595
1707
1708
1709
1710
1711
1712
1713

1714
1715
1716
1717
1718
1719
1720
1721







-
+







      needQuote = 1;
      if( zName[i]=='\'' ) n++;
    }
  }
  if( needQuote ) n += 2;
  z = p->zDestTable = malloc( n+1 );
  if( z==0 ){
    fprintf(stderr,"Out of memory!\n");
    fprintf(stderr,"Error: out of memory\n");
    exit(1);
  }
  n = 0;
  if( needQuote ) z[n++] = '\'';
  for(i=0; zName[i]; i++){
    z[n++] = zName[i];
    if( zName[i]=='\'' ) z[n++] = '\'';
1670
1671
1672
1673
1674
1675
1676
















































































































































1677
1678
1679
1680
1681
1682
1683
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







      zFirstRow = 0;
    }
    fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
    rc = sqlite3_step(pSelect);
  }
  return sqlite3_finalize(pSelect);
}

/*
** Allocate space and save off current error string.
*/
static char *save_err_msg(
  sqlite3 *db            /* Database to query */
){
  int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
  char *zErrMsg = sqlite3_malloc(nErrMsg);
  if( zErrMsg ){
    memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
  }
  return zErrMsg;
}

/*
** Execute a statement or set of statements.  Print 
** any result rows/columns depending on the current mode 
** set via the supplied callback.
**
** This is very similar to SQLite's built-in sqlite3_exec() 
** function except it takes a slightly different callback 
** and callback data argument.
*/
static int shell_exec(
  sqlite3 *db,                                /* An open database */
  const char *zSql,                           /* SQL to be evaluated */
  int (*xCallback)(void*,int,char**,char**,int*),   /* Callback function */
                                              /* (not the same as sqlite3_exec) */
  struct callback_data *pArg,                 /* Pointer to struct callback_data */
  char **pzErrMsg                             /* Error msg written here */
){
  sqlite3_stmt *pStmt = NULL;
  int rc = SQLITE_OK;
  int rc2;
  const char *zLeftover;      /* Tail of unprocessed SQL */

  if( pzErrMsg ){
    *pzErrMsg = NULL;
  }

  while( zSql[0] && (SQLITE_OK == rc) ){
    rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
    if( SQLITE_OK != rc ){
      if( pzErrMsg ){
        *pzErrMsg = save_err_msg(db);
      }
    }else{
      if( !pStmt ){
        /* this happens for a comment or white-space */
        zSql = zLeftover;
        while( isspace(zSql[0]) ) zSql++;
        continue;
      }

      /* perform the first step.  this will tell us if we
      ** have a result set or not and how wide it is.
      */
      rc = sqlite3_step(pStmt);
      /* if we have a result set... */
      if( SQLITE_ROW == rc ){
        /* if we have a callback... */
        if( xCallback ){
          /* allocate space for col name ptr, value ptr, and type */
          int nCol = sqlite3_column_count(pStmt);
          void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
          if( !pData ){
            rc = SQLITE_NOMEM;
          }else{
            char **azCols = (char **)pData;      /* Names of result columns */
            char **azVals = &azCols[nCol];       /* Results */
            int *aiTypes = (int *)&azVals[nCol]; /* Result types */
            int i;
            assert(sizeof(int) <= sizeof(char *)); 
            /* save off ptrs to column names */
            for(i=0; i<nCol; i++){
              azCols[i] = (char *)sqlite3_column_name(pStmt, i);
            }
            /* save off the prepared statment handle and reset row count */
            if( pArg ){
              pArg->pStmt = pStmt;
              pArg->cnt = 0;
            }
            do{
              /* extract the data and data types */
              for(i=0; i<nCol; i++){
                azVals[i] = (char *)sqlite3_column_text(pStmt, i);
                aiTypes[i] = sqlite3_column_type(pStmt, i);
                if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
                  rc = SQLITE_NOMEM;
                  break; /* from for */
                }
              } /* end for */

              /* if data and types extracted successfully... */
              if( SQLITE_ROW == rc ){ 
                /* call the supplied callback with the result row data */
                if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
                  rc = SQLITE_ABORT;
                }else{
                  rc = sqlite3_step(pStmt);
                }
              }
            } while( SQLITE_ROW == rc );
            sqlite3_free(pData);
            if( pArg ){
              pArg->pStmt = NULL;
            }
          }
        }else{
          do{
            rc = sqlite3_step(pStmt);
          } while( rc == SQLITE_ROW );
        }
      }

      /* if the last sqlite3_step() didn't complete successfully... */
      if( (SQLITE_OK != rc) && (SQLITE_DONE != rc) ){ 
        if( pzErrMsg ){
          *pzErrMsg = save_err_msg(db);
        }
      }else{
        rc = SQLITE_OK;
      }

      rc2 = sqlite3_finalize(pStmt);
      /* if the last sqlite3_finalize() didn't complete successfully 
      ** AND we don't have a saved error from sqlite3_step ... */
      if( (SQLITE_OK != rc2) && (SQLITE_OK == rc) ){
        rc = rc2;
        if( pzErrMsg ){
          *pzErrMsg = save_err_msg(db);
        }
      }

      if( SQLITE_OK == rc ){ 
        zSql = zLeftover;
        while( isspace(zSql[0]) ) zSql++;
      }
    }
  } /* end while */

  return rc;
}


/*
** This is a different callback routine used for dumping the database.
** Each row received by this callback consists of a table name,
** the table type ("index" or "table") and SQL to create the table.
** This routine should print text sufficient to recreate the table.
1860
1861
1862
1863
1864
1865
1866


1867
1868
1869


1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881



1882
1883
1884
1885
1886
1887
1888
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140

2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153

2154
2155
2156
2157
2158
2159
2160
2161
2162
2163







+
+


-
+
+











-
+
+
+







** Text of a help message
*/
static char zHelp[] =
  ".backup ?DB? FILE      Backup DB (default \"main\") to FILE\n"
  ".bail ON|OFF           Stop after hitting an error.  Default OFF\n"
  ".databases             List names and files of attached databases\n"
  ".dump ?TABLE? ...      Dump the database in an SQL text format\n"
  "                         If TABLE specified, only dump tables matching\n"
  "                         LIKE pattern TABLE.\n"
  ".echo ON|OFF           Turn command echo on or off\n"
  ".exit                  Exit this program\n"
  ".explain ON|OFF        Turn output mode suitable for EXPLAIN on or off.\n"
  ".explain ?ON|OFF?      Turn output mode suitable for EXPLAIN on or off.\n"
  "                         With no args, it turns EXPLAIN on.\n"
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY)
  ".genfkey ?OPTIONS?     Options are:\n"
  "                         --no-drop: Do not drop old fkey triggers.\n"
  "                         --ignore-errors: Ignore tables with fkey errors\n"
  "                         --exec: Execute generated SQL immediately\n"
  "                       See file tool/genfkey.README in the source \n"
  "                       distribution for further information.\n"
#endif
  ".header(s) ON|OFF      Turn display of headers on or off\n"
  ".help                  Show this message\n"
  ".import FILE TABLE     Import data from FILE into TABLE\n"
  ".indices TABLE         Show names of all indices on TABLE\n"
  ".indices ?TABLE?       Show names of all indices\n"
  "                         If TABLE specified, only show indices for tables\n"
  "                         matching LIKE pattern TABLE.\n"
#ifdef SQLITE_ENABLE_IOTRACE
  ".iotrace FILE          Enable I/O diagnostic logging to FILE\n"
#endif
#ifndef SQLITE_OMIT_LOAD_EXTENSION
  ".load FILE ?ENTRY?     Load an extension library\n"
#endif
  ".mode MODE ?TABLE?     Set output mode where MODE is one of:\n"
1898
1899
1900
1901
1902
1903
1904


1905
1906
1907



1908


1909


1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931

1932
1933
1934
1935
1936
1937
1938
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183

2184
2185
2186
2187
2188
2189

2190
2191
2192


2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210

2211
2212
2213
2214
2215
2216
2217
2218







+
+


-
+
+
+

+
+
-
+
+

-
-


















-
+







  ".output FILENAME       Send output to FILENAME\n"
  ".output stdout         Send output to the screen\n"
  ".prompt MAIN CONTINUE  Replace the standard prompts\n"
  ".quit                  Exit this program\n"
  ".read FILENAME         Execute SQL in FILENAME\n"
  ".restore ?DB? FILE     Restore content of DB (default \"main\") from FILE\n"
  ".schema ?TABLE?        Show the CREATE statements\n"
  "                         If TABLE specified, only show tables matching\n"
  "                         LIKE pattern TABLE.\n"
  ".separator STRING      Change separator used by output mode and .import\n"
  ".show                  Show the current values for various settings\n"
  ".tables ?PATTERN?      List names of tables matching a LIKE pattern\n"
  ".tables ?TABLE?        List names of tables\n"
  "                         If TABLE specified, only list tables matching\n"
  "                         LIKE pattern TABLE.\n"
  ".timeout MS            Try opening locked tables for MS milliseconds\n"
  ".width NUM1 NUM2 ...   Set column widths for \"column\" mode\n"
;
#if HAS_TIMER

static char zTimerHelp[] =
  ".timer ON|OFF          Turn the CPU timer measurement on or off\n"
#endif
  ".width NUM NUM ...     Set column widths for \"column\" mode\n"
;

/* Forward reference */
static int process_input(struct callback_data *p, FILE *in);

/*
** Make sure the database is open.  If it is not, then open it.  If
** the database fails to open, print an error message and exit.
*/
static void open_db(struct callback_data *p){
  if( p->db==0 ){
    sqlite3_open(p->zDbFilename, &p->db);
    db = p->db;
    if( db && sqlite3_errcode(db)==SQLITE_OK ){
      sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
          shellstaticFunc, 0, 0);
    }
    if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
      fprintf(stderr,"Unable to open database \"%s\": %s\n", 
      fprintf(stderr,"Error: unable to open database \"%s\": %s\n", 
          p->zDbFilename, sqlite3_errmsg(db));
      exit(1);
    }
#ifndef SQLITE_OMIT_LOAD_EXTENSION
    sqlite3_enable_load_extension(p->db, 1);
#endif
  }
2025
2026
2027
2028
2029
2030
2031
2032

2033
2034
2035

2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050

2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064

2065
2066

2067
2068
2069
2070
2071

2072
2073
2074
2075

2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089

2090
2091
2092
2093

2094
2095




2096
2097
2098
2099
2100
2101
2102
2305
2306
2307
2308
2309
2310
2311

2312
2313
2314

2315
2316
2317
2318
2319

2320
2321
2322
2323
2324
2325
2326
2327
2328

2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342

2343
2344
2345
2346
2347
2348
2349
2350

2351
2352
2353
2354

2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373

2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387







-
+


-
+




-









-
+













-
+


+




-
+



-
+














+



-
+


+
+
+
+







      if( zLine[i] ) zLine[i++] = 0;
      resolve_backslashes(azArg[nArg-1]);
    }
  }

  /* Process the input line.
  */
  if( nArg==0 ) return rc;
  if( nArg==0 ) return 0; /* no tokens, no error */
  n = strlen30(azArg[0]);
  c = azArg[0][0];
  if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 ){
  if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
    const char *zDestFile;
    const char *zDb;
    sqlite3 *pDest;
    sqlite3_backup *pBackup;
    int rc;
    if( nArg==2 ){
      zDestFile = azArg[1];
      zDb = "main";
    }else{
      zDestFile = azArg[2];
      zDb = azArg[1];
    }
    rc = sqlite3_open(zDestFile, &pDest);
    if( rc!=SQLITE_OK ){
      fprintf(stderr, "Error: cannot open %s\n", zDestFile);
      fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
      sqlite3_close(pDest);
      return 1;
    }
    open_db(p);
    pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
    if( pBackup==0 ){
      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
      sqlite3_close(pDest);
      return 1;
    }
    while(  (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
    sqlite3_backup_finish(pBackup);
    if( rc==SQLITE_DONE ){
      rc = SQLITE_OK;
      rc = 0;
    }else{
      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
      rc = 1;
    }
    sqlite3_close(pDest);
  }else

  if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){
  if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
    bail_on_error = booleanValue(azArg[1]);
  }else

  if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
  if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
    struct callback_data data;
    char *zErrMsg = 0;
    open_db(p);
    memcpy(&data, p, sizeof(data));
    data.showHeader = 1;
    data.mode = MODE_Column;
    data.colWidth[0] = 3;
    data.colWidth[1] = 15;
    data.colWidth[2] = 58;
    data.cnt = 0;
    sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
      rc = 1;
    }
  }else

  if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
  if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
    char *zErrMsg = 0;
    open_db(p);
    /* When playing back a "dump", the content might appear in an order
    ** which causes immediate foreign key constraints to be violated.
    ** So disable foreign-key constraint enforcement to prevent problems. */
    fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
    fprintf(p->out, "BEGIN TRANSACTION;\n");
    p->writableSchema = 0;
    sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
    if( nArg==1 ){
      run_schema_dump_query(p, 
        "SELECT name, type, sql FROM sqlite_master "
        "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'", 0
2135
2136
2137
2138
2139
2140
2141
2142

2143
2144
2145
2146

2147
2148
2149
2150

2151
2152
2153
2154
2155
2156
2157
2420
2421
2422
2423
2424
2425
2426

2427
2428
2429
2430

2431
2432
2433
2434

2435
2436
2437
2438
2439
2440
2441
2442







-
+



-
+



-
+







      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
    }else{
      fprintf(p->out, "COMMIT;\n");
    }
  }else

  if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
  if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
    p->echoOn = booleanValue(azArg[1]);
  }else

  if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
  if( c=='e' && strncmp(azArg[0], "exit", n)==0  && nArg==1 ){
    rc = 2;
  }else

  if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
  if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
    int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
    if(val == 1) {
      if(!p->explainPrev.valid) {
        p->explainPrev.valid = 1;
        p->explainPrev.mode = p->mode;
        p->explainPrev.showHeader = p->showHeader;
        memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
2190
2191
2192
2193
2194
2195
2196
2197

2198
2199
2200
2201
2202



2203
2204
2205

2206
2207
2208

2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225


2226
2227
2228




2229
2230
2231
2232

2233
2234
2235

2236
2237
2238

2239

2240

2241
2242




2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255

2256
2257
2258
2259
2260

2261
2262

2263
2264
2265

2266

2267

2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285

2286
2287

2288
2289


2290
2291

2292

2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304

2305
2306

2307
2308
2309
2310
2311
2312
2313

2314
2315
2316
2317
2318
2319











2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330












2331
2332
2333




2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350

2351

2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369

2370
2371
2372
2373
2374
2375
2376

2377
2378

2379
2380

2381
2382

2383
2384

2385
2386

2387
2388

2389
2390

2391
2392

2393
2394
2395

2396
2397
2398

2399
2400
2401
2402
2403

2404
2405
2406

2407













2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426

2427

2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443

2444
2445
2446
2447
2448
2449
2450


2451
2452

2453
2454
2455
2456
2457

2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474

2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494

2495
2496


2497
2498

2499
2500
2501
2502
2503

2504
2505
2506
2507
2508
2509
2510
2475
2476
2477
2478
2479
2480
2481

2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492

2493
2494
2495

2496

2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510


2511
2512
2513
2514

2515
2516
2517
2518
2519
2520
2521
2522
2523
2524


2525


2526
2527
2528
2529

2530
2531

2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547

2548
2549
2550
2551
2552

2553
2554

2555
2556
2557
2558
2559
2560
2561

2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579

2580
2581
2582
2583


2584
2585
2586
2587
2588

2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600

2601
2602

2603
2604
2605
2606
2607
2608
2609

2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627











2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662

2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676

2677
2678
2679
2680
2681

2682
2683
2684
2685
2686
2687
2688

2689
2690

2691
2692

2693
2694

2695
2696

2697
2698

2699
2700

2701
2702

2703
2704

2705
2706
2707

2708
2709
2710

2711
2712




2713

2714

2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747

2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765

2766
2767
2768
2769
2770
2771
2772

2773
2774
2775

2776
2777
2778
2779
2780

2781
2782
2783
2784
2785

2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796

2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816

2817
2818

2819
2820
2821
2822
2823
2824
2825
2826
2827

2828
2829
2830
2831
2832
2833
2834
2835







-
+





+
+
+


-
+


-
+
-














-
-
+
+


-
+
+
+
+




+

-
-
+
-
-

+

+
-
+

-
+
+
+
+












-
+




-
+

-
+



+

+
-
+

















-
+


+
-
-
+
+


+
-
+











-
+

-
+






-
+






+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+



+
+
+
+
















-
+

+











-





-
+






-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+


-
+


-
+

-
-
-
-
+
-

-
+

+
+
+
+
+
+
+
+
+
+
+
+
+


















-
+

+















-
+






-
+
+

-
+




-
+




-











-
+



















-
+

-
+
+


+




-
+







      cmd.pCb = p;
      genfkey_create_triggers(p->db, "main", (void *)&cmd, genfkeyCmdCb);
    }
  }else
#endif

  if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
                 strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
                 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
    p->showHeader = booleanValue(azArg[1]);
  }else

  if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
    fprintf(stderr,"%s",zHelp);
    if( HAS_TIMER ){
      fprintf(stderr,"%s",zTimerHelp);
    }
  }else

  if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){
  if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
    char *zTable = azArg[2];    /* Insert data into this table */
    char *zFile = azArg[1];     /* The file from which to extract data */
    sqlite3_stmt *pStmt;        /* A statement */
    sqlite3_stmt *pStmt = NULL; /* A statement */
    int rc;                     /* Result code */
    int nCol;                   /* Number of columns in the table */
    int nByte;                  /* Number of bytes in an SQL string */
    int i, j;                   /* Loop counters */
    int nSep;                   /* Number of bytes in p->separator[] */
    char *zSql;                 /* An SQL statement */
    char *zLine;                /* A single line of input from the file */
    char **azCol;               /* zLine[] broken up into columns */
    char *zCommit;              /* How to commit changes */   
    FILE *in;                   /* The input file */
    int lineno = 0;             /* Line number of input file */

    open_db(p);
    nSep = strlen30(p->separator);
    if( nSep==0 ){
      fprintf(stderr, "non-null separator required for import\n");
      return 0;
      fprintf(stderr, "Error: non-null separator required for import\n");
      return 1;
    }
    zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
    if( zSql==0 ) return 0;
    if( zSql==0 ){
      fprintf(stderr, "Error: out of memory\n");
      return 1;
    }
    nByte = strlen30(zSql);
    rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
    sqlite3_free(zSql);
    if( rc ){
      if (pStmt) sqlite3_finalize(pStmt);
      fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
      nCol = 0;
      rc = 1;
      return 1;
    }else{
      nCol = sqlite3_column_count(pStmt);
    }
    nCol = sqlite3_column_count(pStmt);
    sqlite3_finalize(pStmt);
    pStmt = 0;
    if( nCol==0 ) return 0;
    if( nCol==0 ) return 0; /* no columns, no error */
    zSql = malloc( nByte + 20 + nCol*2 );
    if( zSql==0 ) return 0;
    if( zSql==0 ){
      fprintf(stderr, "Error: out of memory\n");
      return 1;
    }
    sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
    j = strlen30(zSql);
    for(i=1; i<nCol; i++){
      zSql[j++] = ',';
      zSql[j++] = '?';
    }
    zSql[j++] = ')';
    zSql[j] = 0;
    rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
    free(zSql);
    if( rc ){
      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
      sqlite3_finalize(pStmt);
      if (pStmt) sqlite3_finalize(pStmt);
      return 1;
    }
    in = fopen(zFile, "rb");
    if( in==0 ){
      fprintf(stderr, "cannot open file: %s\n", zFile);
      fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
      sqlite3_finalize(pStmt);
      return 0;
      return 1;
    }
    azCol = malloc( sizeof(azCol[0])*(nCol+1) );
    if( azCol==0 ){
      fprintf(stderr, "Error: out of memory\n");
      fclose(in);
      sqlite3_finalize(pStmt);
      return 0;
      return 1;
    }
    sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
    zCommit = "COMMIT";
    while( (zLine = local_getline(0, in))!=0 ){
      char *z;
      i = 0;
      lineno++;
      azCol[0] = zLine;
      for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
        if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
          *z = 0;
          i++;
          if( i<nCol ){
            azCol[i] = &z[nSep];
            z += nSep-1;
          }
        }
      }
      } /* end for */
      *z = 0;
      if( i+1!=nCol ){
        fprintf(stderr,
        fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
           zFile, lineno, nCol, i+1);
                "Error: %s line %d: expected %d columns of data but found %d\n",
                zFile, lineno, nCol, i+1);
        zCommit = "ROLLBACK";
        free(zLine);
        rc = 1;
        break;
        break; /* from while */
      }
      for(i=0; i<nCol; i++){
        sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
      }
      sqlite3_step(pStmt);
      rc = sqlite3_reset(pStmt);
      free(zLine);
      if( rc!=SQLITE_OK ){
        fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
        zCommit = "ROLLBACK";
        rc = 1;
        break;
        break; /* from while */
      }
    }
    } /* end while */
    free(azCol);
    fclose(in);
    sqlite3_finalize(pStmt);
    sqlite3_exec(p->db, zCommit, 0, 0, 0);
  }else

  if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
  if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
    struct callback_data data;
    char *zErrMsg = 0;
    open_db(p);
    memcpy(&data, p, sizeof(data));
    data.showHeader = 0;
    data.mode = MODE_List;
    if( nArg==1 ){
      rc = sqlite3_exec(p->db,
        "SELECT name FROM sqlite_master "
        "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
        "UNION ALL "
        "SELECT name FROM sqlite_temp_master "
        "WHERE type='index' "
        "ORDER BY 1",
        callback, &data, &zErrMsg
      );
    }else{
    zShellStatic = azArg[1];
    sqlite3_exec(p->db,
      "SELECT name FROM sqlite_master "
      "WHERE type='index' AND tbl_name LIKE shellstatic() "
      "UNION ALL "
      "SELECT name FROM sqlite_temp_master "
      "WHERE type='index' AND tbl_name LIKE shellstatic() "
      "ORDER BY 1",
      callback, &data, &zErrMsg
    );
    zShellStatic = 0;
      zShellStatic = azArg[1];
      rc = sqlite3_exec(p->db,
        "SELECT name FROM sqlite_master "
        "WHERE type='index' AND tbl_name LIKE shellstatic() "
        "UNION ALL "
        "SELECT name FROM sqlite_temp_master "
        "WHERE type='index' AND tbl_name LIKE shellstatic() "
        "ORDER BY 1",
        callback, &data, &zErrMsg
      );
      zShellStatic = 0;
    }
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
      rc = 1;
    }else if( rc != SQLITE_OK ){
      fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
      rc = 1;
    }
  }else

#ifdef SQLITE_ENABLE_IOTRACE
  if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
    extern void (*sqlite3IoTrace)(const char*, ...);
    if( iotrace && iotrace!=stdout ) fclose(iotrace);
    iotrace = 0;
    if( nArg<2 ){
      sqlite3IoTrace = 0;
    }else if( strcmp(azArg[1], "-")==0 ){
      sqlite3IoTrace = iotracePrintf;
      iotrace = stdout;
    }else{
      iotrace = fopen(azArg[1], "w");
      if( iotrace==0 ){
        fprintf(stderr, "cannot open \"%s\"\n", azArg[1]);
        fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
        sqlite3IoTrace = 0;
        rc = 1;
      }else{
        sqlite3IoTrace = iotracePrintf;
      }
    }
  }else
#endif

#ifndef SQLITE_OMIT_LOAD_EXTENSION
  if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
    const char *zFile, *zProc;
    char *zErrMsg = 0;
    int rc;
    zFile = azArg[1];
    zProc = nArg>=3 ? azArg[2] : 0;
    open_db(p);
    rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
    if( rc!=SQLITE_OK ){
      fprintf(stderr, "%s\n", zErrMsg);
      fprintf(stderr, "Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
      rc = 1;
    }
  }else
#endif

  if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
  if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
    int n2 = strlen30(azArg[1]);
    if( strncmp(azArg[1],"line",n2)==0
    if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
        ||
        strncmp(azArg[1],"lines",n2)==0 ){
        (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
      p->mode = MODE_Line;
    }else if( strncmp(azArg[1],"column",n2)==0
    }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
              ||
              strncmp(azArg[1],"columns",n2)==0 ){
              (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
      p->mode = MODE_Column;
    }else if( strncmp(azArg[1],"list",n2)==0 ){
    }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
      p->mode = MODE_List;
    }else if( strncmp(azArg[1],"html",n2)==0 ){
    }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
      p->mode = MODE_Html;
    }else if( strncmp(azArg[1],"tcl",n2)==0 ){
    }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
      p->mode = MODE_Tcl;
    }else if( strncmp(azArg[1],"csv",n2)==0 ){
    }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
      p->mode = MODE_Csv;
      sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
    }else if( strncmp(azArg[1],"tabs",n2)==0 ){
    }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
      p->mode = MODE_List;
      sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
    }else if( strncmp(azArg[1],"insert",n2)==0 ){
    }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
      p->mode = MODE_Insert;
      if( nArg>=3 ){
        set_table_name(p, azArg[2]);
      }else{
        set_table_name(p, "table");
      set_table_name(p, "table");
      }
    }else {
      fprintf(stderr,"mode should be one of: "
      fprintf(stderr,"Error: mode should be one of: "
         "column csv html insert line list tabs tcl\n");
      rc = 1;
    }
  }else

  if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
    int n2 = strlen30(azArg[1]);
    if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
      p->mode = MODE_Insert;
      set_table_name(p, azArg[2]);
    }else {
      fprintf(stderr, "Error: invalid arguments: "
        " \"%s\". Enter \".help\" for help\n", azArg[2]);
      rc = 1;
    }
  }else

  if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
    sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
                     "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
  }else

  if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
    if( p->out!=stdout ){
      fclose(p->out);
    }
    if( strcmp(azArg[1],"stdout")==0 ){
      p->out = stdout;
      sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
    }else{
      p->out = fopen(azArg[1], "wb");
      if( p->out==0 ){
        fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
        fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
        p->out = stdout;
        rc = 1;
      } else {
         sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
      }
    }
  }else

  if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
    if( nArg >= 2) {
      strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
    }
    if( nArg >= 3) {
      strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
    }
  }else

  if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
  if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
    rc = 2;
  }else

  if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
    FILE *alt = fopen(azArg[1], "rb");
    if( alt==0 ){
      fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
      fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
      rc = 1;
    }else{
      process_input(p, alt);
      rc = process_input(p, alt);
      fclose(alt);
    }
  }else

  if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 ){
  if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
    const char *zSrcFile;
    const char *zDb;
    sqlite3 *pSrc;
    sqlite3_backup *pBackup;
    int rc;
    int nTimeout = 0;

    if( nArg==2 ){
      zSrcFile = azArg[1];
      zDb = "main";
    }else{
      zSrcFile = azArg[2];
      zDb = azArg[1];
    }
    rc = sqlite3_open(zSrcFile, &pSrc);
    if( rc!=SQLITE_OK ){
      fprintf(stderr, "Error: cannot open %s\n", zSrcFile);
      fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
      sqlite3_close(pSrc);
      return 1;
    }
    open_db(p);
    pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
    if( pBackup==0 ){
      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
      sqlite3_close(pSrc);
      return 1;
    }
    while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
          || rc==SQLITE_BUSY  ){
      if( rc==SQLITE_BUSY ){
        if( nTimeout++ >= 3 ) break;
        sqlite3_sleep(100);
      }
    }
    sqlite3_backup_finish(pBackup);
    if( rc==SQLITE_DONE ){
      rc = SQLITE_OK;
      rc = 0;
    }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
      fprintf(stderr, "source database is busy\n");
      fprintf(stderr, "Error: source database is busy\n");
      rc = 1;
    }else{
      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
      rc = 1;
    }
    sqlite3_close(pSrc);
  }else

  if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
  if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
    struct callback_data data;
    char *zErrMsg = 0;
    open_db(p);
    memcpy(&data, p, sizeof(data));
    data.showHeader = 0;
    data.mode = MODE_Semi;
    if( nArg>1 ){
2519
2520
2521
2522
2523
2524
2525

2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538

2539
2540
2541

2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552

2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564






2565
2566
2567
2568
2569
2570
2571
2572
2573

2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594

2595
2596

2597
2598
2599
2600
2601
2602

2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613

2614
2615
2616

2617
2618
2619
2620
2621
2622
2623
2624
2625
2626





2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651

2652
2653
2654
2655

2656
2657

2658
2659
2660
2661
2662


2663
2664
2665
2666
2667
2668
2669
2670

2671
2672

2673

2674
2675
2676
2677
2678
2679
2680
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867

2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878

2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905

2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926

2927
2928

2929
2930
2931
2932
2933
2934

2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945

2946
2947
2948

2949
2950
2951
2952
2953
2954
2955
2956
2957


2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980


2981
2982
2983
2984

2985
2986
2987
2988

2989


2990
2991
2992



2993
2994
2995
2996
2997
2998
2999
3000
3001

3002


3003
3004
3005
3006
3007
3008
3009
3010
3011
3012







+













+


-
+










-
+












+
+
+
+
+
+








-
+




















-
+

-
+





-
+










-
+


-
+








-
-
+
+
+
+
+


















-
-




-
+



-
+
-
-
+


-
-
-
+
+







-
+
-
-
+

+







                      "  rootpage integer,\n"
                      "  sql text\n"
                      ")";
        new_argv[1] = 0;
        new_colv[0] = "sql";
        new_colv[1] = 0;
        callback(&data, 1, new_argv, new_colv);
        rc = SQLITE_OK;
      }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
        char *new_argv[2], *new_colv[2];
        new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
                      "  type text,\n"
                      "  name text,\n"
                      "  tbl_name text,\n"
                      "  rootpage integer,\n"
                      "  sql text\n"
                      ")";
        new_argv[1] = 0;
        new_colv[0] = "sql";
        new_colv[1] = 0;
        callback(&data, 1, new_argv, new_colv);
        rc = SQLITE_OK;
      }else{
        zShellStatic = azArg[1];
        sqlite3_exec(p->db,
        rc = sqlite3_exec(p->db,
          "SELECT sql FROM "
          "  (SELECT sql sql, type type, tbl_name tbl_name, name name"
          "     FROM sqlite_master UNION ALL"
          "   SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
          "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
          "ORDER BY substr(type,2,1), name",
          callback, &data, &zErrMsg);
        zShellStatic = 0;
      }
    }else{
      sqlite3_exec(p->db,
      rc = sqlite3_exec(p->db,
         "SELECT sql FROM "
         "  (SELECT sql sql, type type, tbl_name tbl_name, name name"
         "     FROM sqlite_master UNION ALL"
         "   SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
         "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
         "ORDER BY substr(type,2,1), name",
         callback, &data, &zErrMsg
      );
    }
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
      rc = 1;
    }else if( rc != SQLITE_OK ){
      fprintf(stderr,"Error: querying schema information\n");
      rc = 1;
    }else{
      rc = 0;
    }
  }else

  if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
    sqlite3_snprintf(sizeof(p->separator), p->separator,
                     "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
  }else

  if( c=='s' && strncmp(azArg[0], "show", n)==0){
  if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
    int i;
    fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
    fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
    fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
    fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
    fprintf(p->out,"%9.9s: ", "nullvalue");
      output_c_string(p->out, p->nullvalue);
      fprintf(p->out, "\n");
    fprintf(p->out,"%9.9s: %s\n","output",
            strlen30(p->outfile) ? p->outfile : "stdout");
    fprintf(p->out,"%9.9s: ", "separator");
      output_c_string(p->out, p->separator);
      fprintf(p->out, "\n");
    fprintf(p->out,"%9.9s: ","width");
    for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
      fprintf(p->out,"%d ",p->colWidth[i]);
    }
    fprintf(p->out,"\n");
  }else

  if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
  if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
    char **azResult;
    int nRow, rc;
    int nRow;
    char *zErrMsg;
    open_db(p);
    if( nArg==1 ){
      rc = sqlite3_get_table(p->db,
        "SELECT name FROM sqlite_master "
        "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
        "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' "
        "UNION ALL "
        "SELECT name FROM sqlite_temp_master "
        "WHERE type IN ('table','view') "
        "ORDER BY 1",
        &azResult, &nRow, 0, &zErrMsg
      );
    }else{
      zShellStatic = azArg[1];
      rc = sqlite3_get_table(p->db,
        "SELECT name FROM sqlite_master "
        "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
        "WHERE type IN ('table','view') AND name LIKE shellstatic() "
        "UNION ALL "
        "SELECT name FROM sqlite_temp_master "
        "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
        "WHERE type IN ('table','view') AND name LIKE shellstatic() "
        "ORDER BY 1",
        &azResult, &nRow, 0, &zErrMsg
      );
      zShellStatic = 0;
    }
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
    }
    if( rc==SQLITE_OK ){
      rc = 1;
    }else if( rc != SQLITE_OK ){
      fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
      rc = 1;
    }else{
      int len, maxlen = 0;
      int i, j;
      int nPrintCol, nPrintRow;
      for(i=1; i<=nRow; i++){
        if( azResult[i]==0 ) continue;
        len = strlen30(azResult[i]);
        if( len>maxlen ) maxlen = len;
      }
      nPrintCol = 80/(maxlen+2);
      if( nPrintCol<1 ) nPrintCol = 1;
      nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
      for(i=0; i<nPrintRow; i++){
        for(j=i+1; j<=nRow; j+=nPrintRow){
          char *zSp = j<=nPrintRow ? "" : "  ";
          printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
        }
        printf("\n");
      }
    }else{
      rc = 1;
    }
    sqlite3_free_table(azResult);
  }else

  if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
  if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
    open_db(p);
    sqlite3_busy_timeout(p->db, atoi(azArg[1]));
  }else
  
    
#if HAS_TIMER  
  if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg>1 ){
  if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg==2 ){
    enableTimer = booleanValue(azArg[1]);
  }else
#endif

  if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
  
  if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
    int j;
    assert( nArg<=ArraySize(azArg) );
    for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
      p->colWidth[j-1] = atoi(azArg[j]);
    }
  }else


  {
  {
    fprintf(stderr, "unknown command or invalid arguments: "
    fprintf(stderr, "Error: unknown command or invalid arguments: "
      " \"%s\". Enter \".help\" for help\n", azArg[0]);
    rc = 1;
  }

  return rc;
}

/*
** Return TRUE if a semicolon occurs anywhere in the first N characters
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778

2779
2780

2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798

2799
2800
2801
2802
2803
2804
2805
2806
2807
2808

2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820

2821
2822
2823
2824
2825
2826

2827
2828

2829
2830
2831

2832
2833
2834
2835

2836
2837
2838
2839
2840
2841
2842
2843
2844
2845

2846
2847
2848
2849
2850
2851
2852
3101
3102
3103
3104
3105
3106
3107

3108
3109
3110
3111

3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129

3130
3131
3132
3133
3134
3135
3136
3137
3138
3139

3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151

3152
3153
3154
3155
3156
3157

3158
3159

3160
3161
3162

3163
3164
3165
3166

3167
3168
3169
3170
3171
3172
3173
3174
3175
3176

3177
3178
3179
3180
3181
3182
3183
3184







-


+

-
+

















-
+









-
+











-
+





-
+

-
+


-
+



-
+









-
+







      break;  /* We have reached EOF */
    }
    if( seenInterrupt ){
      if( in!=0 ) break;
      seenInterrupt = 0;
    }
    lineno++;
    if( p->echoOn ) printf("%s\n", zLine);
    if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
    if( zLine && zLine[0]=='.' && nSql==0 ){
      if( p->echoOn ) printf("%s\n", zLine);
      rc = do_meta_command(zLine, p);
      if( rc==2 ){
      if( rc==2 ){ /* exit requested */
        break;
      }else if( rc ){
        errCnt++;
      }
      continue;
    }
    if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
      memcpy(zLine,";",2);
    }
    nSqlPrior = nSql;
    if( zSql==0 ){
      int i;
      for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
      if( zLine[i]!=0 ){
        nSql = strlen30(zLine);
        zSql = malloc( nSql+3 );
        if( zSql==0 ){
          fprintf(stderr, "out of memory\n");
          fprintf(stderr, "Error: out of memory\n");
          exit(1);
        }
        memcpy(zSql, zLine, nSql+1);
        startline = lineno;
      }
    }else{
      int len = strlen30(zLine);
      zSql = realloc( zSql, nSql + len + 4 );
      if( zSql==0 ){
        fprintf(stderr,"%s: out of memory!\n", Argv0);
        fprintf(stderr,"Error: out of memory\n");
        exit(1);
      }
      zSql[nSql++] = '\n';
      memcpy(&zSql[nSql], zLine, len+1);
      nSql += len;
    }
    if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
                && sqlite3_complete(zSql) ){
      p->cnt = 0;
      open_db(p);
      BEGIN_TIMER;
      rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
      rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
      END_TIMER;
      if( rc || zErrMsg ){
        char zPrefix[100];
        if( in!=0 || !stdin_is_interactive ){
          sqlite3_snprintf(sizeof(zPrefix), zPrefix, 
                           "SQL error near line %d:", startline);
                           "Error: near line %d:", startline);
        }else{
          sqlite3_snprintf(sizeof(zPrefix), zPrefix, "SQL error:");
          sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
        }
        if( zErrMsg!=0 ){
          printf("%s %s\n", zPrefix, zErrMsg);
          fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
          sqlite3_free(zErrMsg);
          zErrMsg = 0;
        }else{
          printf("%s %s\n", zPrefix, sqlite3_errmsg(p->db));
          fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
        }
        errCnt++;
      }
      free(zSql);
      zSql = 0;
      nSql = 0;
    }
  }
  if( zSql ){
    if( !_all_whitespace(zSql) ) fprintf(stderr, "Incomplete SQL: %s\n", zSql);
    if( !_all_whitespace(zSql) ) fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
    free(zSql);
  }
  free(zLine);
  return errCnt;
}

/*
2910
2911
2912
2913
2914
2915
2916


2917
2918

2919
2920
2921
2922
2923
2924
2925
2926

2927
2928
2929
2930
2931
2932

2933
2934

2935
2936
2937
2938
2939
2940


2941
2942
2943
2944
2945
2946
2947
2948
2949

2950
2951

2952
2953
2954
2955

2956
2957
2958
2959
2960
2961

2962
2963
2964
2965
2966
2967
2968
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251

3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266

3267
3268

3269
3270
3271
3272
3273


3274
3275
3276
3277
3278
3279
3280
3281
3282
3283

3284
3285

3286
3287
3288
3289

3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304







+
+

-
+








+





-
+

-
+




-
-
+
+








-
+

-
+



-
+






+








  return home_dir;
}

/*
** Read input from the file given by sqliterc_override.  Or if that
** parameter is NULL, take input from ~/.sqliterc
**
** Returns the number of errors.
*/
static void process_sqliterc(
static int process_sqliterc(
  struct callback_data *p,        /* Configuration data */
  const char *sqliterc_override   /* Name of config file. NULL to use default */
){
  char *home_dir = NULL;
  const char *sqliterc = sqliterc_override;
  char *zBuf = 0;
  FILE *in = NULL;
  int nBuf;
  int rc = 0;

  if (sqliterc == NULL) {
    home_dir = find_home_dir();
    if( home_dir==0 ){
#if !defined(__RTP__) && !defined(_WRS_KERNEL)
      fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
      fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
#endif
      return;
      return 1;
    }
    nBuf = strlen30(home_dir) + 16;
    zBuf = malloc( nBuf );
    if( zBuf==0 ){
      fprintf(stderr,"%s: out of memory!\n", Argv0);
      exit(1);
      fprintf(stderr,"%s: Error: out of memory\n",Argv0);
      return 1;
    }
    sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
    free(home_dir);
    sqliterc = (const char*)zBuf;
  }
  in = fopen(sqliterc,"rb");
  if( in ){
    if( stdin_is_interactive ){
      printf("-- Loading resources from %s\n",sqliterc);
      fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
    }
    process_input(p,in);
    rc = process_input(p,in);
    fclose(in);
  }
  free(zBuf);
  return;
  return rc;
}

/*
** Show available command line options
*/
static const char zOptions[] = 
  "   -help                show this message\n"
  "   -init filename       read/process named file\n"
  "   -echo                print commands before execution\n"
  "   -[no]header          turn headers on or off\n"
  "   -bail                stop after hitting an error\n"
  "   -interactive         force interactive I/O\n"
  "   -batch               force batch I/O\n"
  "   -column              set output mode to 'column'\n"
3028
3029
3030
3031
3032
3033
3034






3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051





3052
3053
3054
3055
3056
3057
3058


3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075




3076
3077
3078
3079
3080
3081
3082
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403


3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421

3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432







+
+
+
+
+
+

















+
+
+
+
+





-
-
+
+
















-
+
+
+
+







    z = argv[i];
    if( z[0]=='-' && z[1]=='-' ) z++;
    if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
      i++;
    }else if( strcmp(argv[i],"-init")==0 ){
      i++;
      zInitFile = argv[i];
    /* Need to check for batch mode here to so we can avoid printing
    ** informational messages (like from process_sqliterc) before 
    ** we do the actual processing of arguments later in a second pass.
    */
    }else if( strcmp(argv[i],"-batch")==0 ){
      stdin_is_interactive = 0;
    }
  }
  if( i<argc ){
#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
    data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
#else
    data.zDbFilename = argv[i++];
#endif
  }else{
#ifndef SQLITE_OMIT_MEMORYDB
    data.zDbFilename = ":memory:";
#else
    data.zDbFilename = 0;
#endif
  }
  if( i<argc ){
    zFirstCmd = argv[i++];
  }
  if( i<argc ){
    fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
    fprintf(stderr,"Use -help for a list of options.\n");
    return 1;
  }
  data.out = stdout;

#ifdef SQLITE_OMIT_MEMORYDB
  if( data.zDbFilename==0 ){
    fprintf(stderr,"%s: no database filename specified\n", argv[0]);
    exit(1);
    fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
    return 1;
  }
#endif

  /* Go ahead and open the database file if it already exists.  If the
  ** file does not exist, delay opening it.  This prevents empty database
  ** files from being created if a user mistypes the database name argument
  ** to the sqlite command-line tool.
  */
  if( access(data.zDbFilename, 0)==0 ){
    open_db(&data);
  }

  /* Process the initialization file if there is one.  If no -init option
  ** is given on the command line, look for a file named ~/.sqliterc and
  ** try to process it.
  */
  process_sqliterc(&data,zInitFile);
  rc = process_sqliterc(&data,zInitFile);
  if( rc>0 ){
    return rc;
  }

  /* Make a second pass through the command-line argument and set
  ** options.  This second pass is delayed until after the initialization
  ** file is processed so that the command-line arguments will override
  ** settings in the initialization file.
  */
  for(i=1; i<argc && argv[i][0]=='-'; i++){
3093
3094
3095
3096
3097
3098
3099





3100
3101
3102
3103





3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124

3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135


3136
3137
3138
3139
3140
3141
3142







3143
3144
3145
3146
3147
3148
3149
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483

3484
3485
3486
3487
3488
3489
3490
3491
3492
3493


3494
3495
3496

3497




3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511







+
+
+
+
+




+
+
+
+
+




















-
+









-
-
+
+

-

-
-
-
-
+
+
+
+
+
+
+







    }else if( strcmp(z,"-column")==0 ){
      data.mode = MODE_Column;
    }else if( strcmp(z,"-csv")==0 ){
      data.mode = MODE_Csv;
      memcpy(data.separator,",",2);
    }else if( strcmp(z,"-separator")==0 ){
      i++;
      if(i>=argc){
        fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
        fprintf(stderr,"Use -help for a list of options.\n");
        return 1;
      }
      sqlite3_snprintf(sizeof(data.separator), data.separator,
                       "%.*s",(int)sizeof(data.separator)-1,argv[i]);
    }else if( strcmp(z,"-nullvalue")==0 ){
      i++;
      if(i>=argc){
        fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
        fprintf(stderr,"Use -help for a list of options.\n");
        return 1;
      }
      sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
                       "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
    }else if( strcmp(z,"-header")==0 ){
      data.showHeader = 1;
    }else if( strcmp(z,"-noheader")==0 ){
      data.showHeader = 0;
    }else if( strcmp(z,"-echo")==0 ){
      data.echoOn = 1;
    }else if( strcmp(z,"-bail")==0 ){
      bail_on_error = 1;
    }else if( strcmp(z,"-version")==0 ){
      printf("%s\n", sqlite3_libversion());
      return 0;
    }else if( strcmp(z,"-interactive")==0 ){
      stdin_is_interactive = 1;
    }else if( strcmp(z,"-batch")==0 ){
      stdin_is_interactive = 0;
    }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
      usage(1);
    }else{
      fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
      fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
      fprintf(stderr,"Use -help for a list of options.\n");
      return 1;
    }
  }

  if( zFirstCmd ){
    /* Run just the command that follows the database name
    */
    if( zFirstCmd[0]=='.' ){
      do_meta_command(zFirstCmd, &data);
      exit(0);
      rc = do_meta_command(zFirstCmd, &data);
      return rc;
    }else{
      int rc;
      open_db(&data);
      rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
      if( rc!=0 && zErrMsg!=0 ){
        fprintf(stderr,"SQL error: %s\n", zErrMsg);
        exit(1);
      rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
      if( zErrMsg!=0 ){
        fprintf(stderr,"Error: %s\n", zErrMsg);
        return rc!=0 ? rc : 1;
      }else if( rc!=0 ){
        fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
        return rc;
      }
    }
  }else{
    /* Run commands received from standard input
    */
    if( stdin_is_interactive ){
      char *zHome;
3175
3176
3177
3178
3179
3180
3181
3182


3183
3184
3185
3186
3537
3538
3539
3540
3541
3542
3543

3544
3545
3546
3547
3548
3549







-
+
+




    }else{
      rc = process_input(&data, stdin);
    }
  }
  set_table_name(&data, 0);
  if( db ){
    if( sqlite3_close(db)!=SQLITE_OK ){
      fprintf(stderr,"error closing database: %s\n", sqlite3_errmsg(db));
      fprintf(stderr,"Error: cannot close database \"%s\"\n", sqlite3_errmsg(db));
      rc++;
    }
  }
  return rc;
}
Changes to src/sqlite.h.in.
14
15
16
17
18
19
20
21
22


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
14
15
16
17
18
19
20


21
22
23
24
25
26
27
28
29
30
31


32
33
34
35
36
37
38







-
-
+
+









-
-







** or constant definition does not appear in this file, then it is
** not a published API of SQLite, is subject to change without
** notice, and should not be referenced by programs that use SQLite.
**
** Some of the definitions that are in this file are marked as
** "experimental".  Experimental interfaces are normally new
** features recently added to SQLite.  We do not anticipate changes
** to experimental interfaces but reserve to make minor changes if
** experience from use "in the wild" suggest such changes are prudent.
** to experimental interfaces but reserve the right to make minor changes
** if experience from use "in the wild" suggest such changes are prudent.
**
** The official C-language API documentation for SQLite is derived
** from comments in this file.  This file is the authoritative source
** on how SQLite interfaces are suppose to operate.
**
** The name of this file under configuration management is "sqlite.h.in".
** The makefile makes some minor changes to this file (such as inserting
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
**
** @(#) $Id: sqlite.h.in,v 1.458 2009/06/19 22:50:31 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62







-
+







#ifndef SQLITE_EXTERN
# define SQLITE_EXTERN extern
#endif

/*
** These no-op macros are used in front of interfaces to mark those
** interfaces as either deprecated or experimental.  New applications
** should not use deprecated intrfaces - they are support for backwards
** should not use deprecated interfaces - they are support for backwards
** compatibility only.  Application writers should be aware that
** experimental interfaces are subject to change in point releases.
**
** These macros used to resolve to various kinds of compiler magic that
** would generate warning messages when they were used.  But that
** compiler magic ended up generating such a flurry of bug reports
** that we have taken it all out and gone back to using simple
80
81
82
83
84
85
86
87

88
89
90


91
92

93
94
95
96



97















98



99
100
101
102
103



104
105
106
107
108
109
110
111
112
113
114













115
116
117
118
119





120
121
122
123
124

125
126
127
128
129
130
131

132
133
134
135
136
137
138
139
140
141
142

143
144
145
146
147
148
149
78
79
80
81
82
83
84

85



86
87
88

89
90
91


92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

111
112
113
114
115
116


117
118
119
120
121
122
123
124






125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166
167
168
169

170
171
172
173
174
175
176
177







-
+
-
-
-
+
+

-
+


-
-
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+



-
-
+
+
+





-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+




-
+
+
+
+
+





+






-
+










-
+







/*
** CAPI3REF: Compile-Time Library Version Numbers {H10010} <S60100>
**
** The SQLITE_VERSION and SQLITE_VERSION_NUMBER #defines in
** the sqlite3.h file specify the version of SQLite with which
** that header file is associated.
**
** The "version" of SQLite is a string of the form "X.Y.Z".
** The "version" of SQLite is a string of the form "W.X.Y" or "W.X.Y.Z".
** The phrase "alpha" or "beta" might be appended after the Z.
** The X value is major version number always 3 in SQLite3.
** The X value only changes when backwards compatibility is
** The W value is major version number and is always 3 in SQLite3.
** The W value only changes when backwards compatibility is
** broken and we intend to never break backwards compatibility.
** The Y value is the minor version number and only changes when
** The X value is the minor version number and only changes when
** there are major feature enhancements that are forwards compatible
** but not backwards compatible.
** The Z value is the release number and is incremented with
** each release but resets back to 0 whenever Y is incremented.
** The Y value is the release number and is incremented with
** each release but resets back to 0 whenever X is incremented.
** The Z value only appears on branch releases.
**
** The SQLITE_VERSION_NUMBER is an integer that is computed as
** follows:
**
** <blockquote><pre>
** SQLITE_VERSION_NUMBER = W*1000000 + X*1000 + Y
** </pre></blockquote>
**
** Since version 3.6.18, SQLite source code has been stored in the
** <a href="http://www.fossil-scm.org/">fossil configuration management
** system</a>.  The SQLITE_SOURCE_ID
** macro is a string which identifies a particular check-in of SQLite
** within its configuration management system.  The string contains the
** date and time of the check-in (UTC) and an SHA1 hash of the entire
** source tree.
**
** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()].
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
**
** Requirements: [H10011] [H10014]
*/
#define SQLITE_VERSION         "--VERS--"
#define SQLITE_VERSION_NUMBER  --VERSION-NUMBER--
#define SQLITE_VERSION        "--VERS--"
#define SQLITE_VERSION_NUMBER --VERSION-NUMBER--
#define SQLITE_SOURCE_ID      "--SOURCE-ID--"

/*
** CAPI3REF: Run-Time Library Version Numbers {H10020} <S60100>
** KEYWORDS: sqlite3_version
**
** These features provide the same information as the [SQLITE_VERSION]
** and [SQLITE_VERSION_NUMBER] #defines in the header, but are associated
** with the library instead of the header file.  Cautious programmers might
** include a check in their application to verify that
** sqlite3_libversion_number() always returns the value
** [SQLITE_VERSION_NUMBER].
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] #defines in the header,
** but are associated with the library instead of the header file.  Cautious
** programmers might include assert() statements in their application to
** verify that values returned by these interfaces match the macros in
** the header, and thus insure that the application is
** compiled with matching library and header files.
**
** <blockquote><pre>
** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
** assert( strcmp(sqlite3_libversion,SQLITE_VERSION)==0 );
** </pre></blockquote>
**
** The sqlite3_libversion() function returns the same information as is
** in the sqlite3_version[] string constant.  The function is provided
** for use in DLLs since DLL users usually do not have direct access to string
** constants within the DLL.
** constants within the DLL.  Similarly, the sqlite3_sourceid() function
** returns the same information as is in the [SQLITE_SOURCE_ID] #define of
** the header file.
**
** See also: [sqlite_version()] and [sqlite_source_id()].
**
** Requirements: [H10021] [H10022] [H10023]
*/
SQLITE_EXTERN const char sqlite3_version[];
const char *sqlite3_libversion(void);
const char *sqlite3_sourceid(void);
int sqlite3_libversion_number(void);

/*
** CAPI3REF: Test To See If The Library Is Threadsafe {H10100} <S60100>
**
** SQLite can be compiled with or without mutexes.  When
** the [SQLITE_THREADSAFE] C preprocessor macro 1 or 2, mutexes
** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes
** are enabled and SQLite is threadsafe.  When the
** [SQLITE_THREADSAFE] macro is 0, 
** the mutexes are omitted.  Without the mutexes, it is not safe
** to use SQLite concurrently from more than one thread.
**
** Enabling mutexes incurs a measurable performance penalty.
** So if speed is of utmost importance, it makes sense to disable
** the mutexes.  But for maximum safety, mutexes should be enabled.
** The default behavior is for mutexes to be enabled.
**
** This interface can be used by a program to make sure that the
** This interface can be used by an application to make sure that the
** version of SQLite that it is linking against was compiled with
** the desired setting of the [SQLITE_THREADSAFE] macro.
**
** This interface only reports on the compile-time mutex setting
** of the [SQLITE_THREADSAFE] flag.  If SQLite is compiled with
** SQLITE_THREADSAFE=1 then mutexes are enabled by default but
** can be fully or partially disabled using a call to [sqlite3_config()]
208
209
210
211
212
213
214
215

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
236
237
238
239
240
241
242

243
244
245










246
247
248
249
250
251
252







-
+


-
-
-
-
-
-
-
-
-
-







#endif

/*
** CAPI3REF: Closing A Database Connection {H12010} <S30100><S40200>
**
** This routine is the destructor for the [sqlite3] object.
**
** Applications should [sqlite3_finalize | finalize] all [prepared statements]
** Applications must [sqlite3_finalize | finalize] all [prepared statements]
** and [sqlite3_blob_close | close] all [BLOB handles] associated with
** the [sqlite3] object prior to attempting to close the object.
** The [sqlite3_next_stmt()] interface can be used to locate all
** [prepared statements] associated with a [database connection] if desired.
** Typical code might look like this:
**
** <blockquote><pre>
** sqlite3_stmt *pStmt;
** while( (pStmt = sqlite3_next_stmt(db, 0))!=0 ){
** &nbsp;   sqlite3_finalize(pStmt);
** }
** </pre></blockquote>
**
** If [sqlite3_close()] is invoked while a transaction is open,
** the transaction is automatically rolled back.
**
** The C parameter to [sqlite3_close(C)] must be either a NULL
** pointer or an [sqlite3] object pointer obtained
** from [sqlite3_open()], [sqlite3_open16()], or
402
403
404
405
406
407
408


409
410
411
412
413
414
415
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435







+
+







#define SQLITE_OPEN_TRANSIENT_DB     0x00000400  /* VFS only */
#define SQLITE_OPEN_MAIN_JOURNAL     0x00000800  /* VFS only */
#define SQLITE_OPEN_TEMP_JOURNAL     0x00001000  /* VFS only */
#define SQLITE_OPEN_SUBJOURNAL       0x00002000  /* VFS only */
#define SQLITE_OPEN_MASTER_JOURNAL   0x00004000  /* VFS only */
#define SQLITE_OPEN_NOMUTEX          0x00008000  /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_FULLMUTEX        0x00010000  /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_SHAREDCACHE      0x00020000  /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_PRIVATECACHE     0x00040000  /* Ok for sqlite3_open_v2() */

/*
** CAPI3REF: Device Characteristics {H10240} <H11120>
**
** The xDeviceCapabilities method of the [sqlite3_io_methods]
** object returns an integer which is a vector of the these
** bit values expressing I/O characteristics of the mass storage
469
470
471
472
473
474
475
476
477



478
479
480
481
482
483
484
489
490
491
492
493
494
495


496
497
498
499
500
501
502
503
504
505







-
-
+
+
+







#define SQLITE_SYNC_NORMAL        0x00002
#define SQLITE_SYNC_FULL          0x00003
#define SQLITE_SYNC_DATAONLY      0x00010

/*
** CAPI3REF: OS Interface Open File Handle {H11110} <S20110>
**
** An [sqlite3_file] object represents an open file in the OS
** interface layer.  Individual OS interface implementations will
** An [sqlite3_file] object represents an open file in the 
** [sqlite3_vfs | OS interface layer].  Individual OS interface
** implementations will
** want to subclass this object by appending additional fields
** for their own use.  The pMethods entry is a pointer to an
** [sqlite3_io_methods] object that defines methods for performing
** I/O operations on the open file.
*/
typedef struct sqlite3_file sqlite3_file;
struct sqlite3_file {
795
796
797
798
799
800
801



802
803
804
805
806
807
808
809
810
811
812
813

814






815

816
817

818
819
820
821
822
823
824
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836

837
838
839
840
841
842
843
844

845
846

847
848
849
850
851
852
853
854







+
+
+











-
+

+
+
+
+
+
+
-
+

-
+








/*
** CAPI3REF: Initialize The SQLite Library {H10130} <S20000><S30100>
**
** The sqlite3_initialize() routine initializes the
** SQLite library.  The sqlite3_shutdown() routine
** deallocates any resources that were allocated by sqlite3_initialize().
** These routines are designed to aid in process initialization and
** shutdown on embedded systems.  Workstation applications using
** SQLite normally do not need to invoke either of these routines.
**
** A call to sqlite3_initialize() is an "effective" call if it is
** the first time sqlite3_initialize() is invoked during the lifetime of
** the process, or if it is the first time sqlite3_initialize() is invoked
** following a call to sqlite3_shutdown().  Only an effective call
** of sqlite3_initialize() does any initialization.  All other calls
** are harmless no-ops.
**
** A call to sqlite3_shutdown() is an "effective" call if it is the first
** call to sqlite3_shutdown() since the last sqlite3_initialize().  Only
** an effective call to sqlite3_shutdown() does any deinitialization.
** All other calls to sqlite3_shutdown() are harmless no-ops.
** All other valid calls to sqlite3_shutdown() are harmless no-ops.
**
** The sqlite3_initialize() interface is threadsafe, but sqlite3_shutdown()
** is not.  The sqlite3_shutdown() interface must only be called from a
** single thread.  All open [database connections] must be closed and all
** other SQLite resources must be deallocated prior to invoking
** sqlite3_shutdown().
**
** Among other things, sqlite3_initialize() shall invoke
** Among other things, sqlite3_initialize() will invoke
** sqlite3_os_init().  Similarly, sqlite3_shutdown()
** shall invoke sqlite3_os_end().
** will invoke sqlite3_os_end().
**
** The sqlite3_initialize() routine returns [SQLITE_OK] on success.
** If for some reason, sqlite3_initialize() is unable to initialize
** the library (perhaps it is unable to allocate a needed resource such
** as a mutex) it returns an [error code] other than [SQLITE_OK].
**
** The sqlite3_initialize() routine is called internally by many other
846
847
848
849
850
851
852
853
854



855
856
857
858
859
860
861
876
877
878
879
880
881
882


883
884
885
886
887
888
889
890
891
892







-
-
+
+
+







**
** The application should never invoke either sqlite3_os_init()
** or sqlite3_os_end() directly.  The application should only invoke
** sqlite3_initialize() and sqlite3_shutdown().  The sqlite3_os_init()
** interface is called automatically by sqlite3_initialize() and
** sqlite3_os_end() is called by sqlite3_shutdown().  Appropriate
** implementations for sqlite3_os_init() and sqlite3_os_end()
** are built into SQLite when it is compiled for unix, windows, or os/2.
** When built for other platforms (using the [SQLITE_OS_OTHER=1] compile-time
** are built into SQLite when it is compiled for Unix, Windows, or OS/2.
** When [custom builds | built for other platforms]
** (using the [SQLITE_OS_OTHER=1] compile-time
** option) the application must supply a suitable implementation for
** sqlite3_os_init() and sqlite3_os_end().  An application-supplied
** implementation of sqlite3_os_init() or sqlite3_os_end()
** must return [SQLITE_OK] on success and some other [error code] upon
** failure.
*/
int sqlite3_initialize(void);
928
929
930
931
932
933
934

935
936
937
938





939
940
941


942
943
944
945
946
947
948
949
950










951
952
953
954
955
956
957
958
959



960
961
962
963
964
965
966














967
968
969
970
971
972
973
959
960
961
962
963
964
965
966




967
968
969
970
971
972


973
974
975
976
977
978
979
980
981


982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031







+
-
-
-
-
+
+
+
+
+

-
-
+
+







-
-
+
+
+
+
+
+
+
+
+
+









+
+
+







+
+
+
+
+
+
+
+
+
+
+
+
+
+







**
** An instance of this object defines the interface between SQLite
** and low-level memory allocation routines.
**
** This object is used in only one place in the SQLite interface.
** A pointer to an instance of this object is the argument to
** [sqlite3_config()] when the configuration option is
** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC].  
** [SQLITE_CONFIG_MALLOC].  By creating an instance of this object
** and passing it to [sqlite3_config()] during configuration, an
** application can specify an alternative memory allocation subsystem
** for SQLite to use for all of its dynamic memory needs.
** By creating an instance of this object
** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC])
** during configuration, an application can specify an alternative
** memory allocation subsystem for SQLite to use for all of its
** dynamic memory needs.
**
** Note that SQLite comes with a built-in memory allocator that is
** perfectly adequate for the overwhelming majority of applications
** Note that SQLite comes with several [built-in memory allocators]
** that are perfectly adequate for the overwhelming majority of applications
** and that this object is only useful to a tiny minority of applications
** with specialized memory allocation requirements.  This object is
** also used during testing of SQLite in order to specify an alternative
** memory allocator that simulates memory out-of-memory conditions in
** order to verify that SQLite recovers gracefully from such
** conditions.
**
** The xMalloc, xFree, and xRealloc methods must work like the
** malloc(), free(), and realloc() functions from the standard library.
** The xMalloc and xFree methods must work like the
** malloc() and free() functions from the standard C library.
** The xRealloc method must work like realloc() from the standard C library
** with the exception that if the second argument to xRealloc is zero,
** xRealloc must be a no-op - it must not perform any allocation or
** deallocation.  SQLite guaranteeds that the second argument to
** xRealloc is always a value returned by a prior call to xRoundup.
** And so in cases where xRoundup always returns a positive number,
** xRealloc can perform exactly as the standard library realloc() and
** still be in compliance with this specification.
**
** xSize should return the allocated size of a memory allocation
** previously obtained from xMalloc or xRealloc.  The allocated size
** is always at least as big as the requested size but may be larger.
**
** The xRoundup method returns what would be the allocated size of
** a memory allocation given a particular requested size.  Most memory
** allocators round up memory allocations at least to the next multiple
** of 8.  Some allocators round up to a larger multiple or to a power of 2.
** Every memory allocation request coming in through [sqlite3_malloc()]
** or [sqlite3_realloc()] first calls xRoundup.  If xRoundup returns 0, 
** that causes the corresponding memory allocation to fail.
**
** The xInit method initializes the memory allocator.  (For example,
** it might allocate any require mutexes or initialize internal data
** structures.  The xShutdown method is invoked (indirectly) by
** [sqlite3_shutdown()] and should deallocate any resources acquired
** by xInit.  The pAppData pointer is used as the only parameter to
** xInit and xShutdown.
**
** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes
** the xInit method, so the xInit method need not be threadsafe.  The
** xShutdown method is only called from [sqlite3_shutdown()] so it does
** not need to be threadsafe either.  For all other methods, SQLite
** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the
** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which
** it is by default) and so the methods are automatically serialized.
** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other
** methods must be threadsafe or else make their own arrangements for
** serialization.
**
** SQLite will never invoke xInit() more than once without an intervening
** call to xShutdown().
*/
typedef struct sqlite3_mem_methods sqlite3_mem_methods;
struct sqlite3_mem_methods {
  void *(*xMalloc)(int);         /* Memory allocation function */
  void (*xFree)(void*);          /* Free a prior allocation */
  void *(*xRealloc)(void*,int);  /* Resize an allocation */
  int (*xSize)(void*);           /* Return the size of an allocation */
1113
1114
1115
1116
1117
1118
1119
1120

1121
1122




1123
1124
1125
1126
1127
1128
1129
1171
1172
1173
1174
1175
1176
1177

1178
1179

1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190







-
+

-
+
+
+
+







** structure is filled with the currently defined mutex routines.
** This option can be used to overload the default mutex allocation
** routines with a wrapper used to track mutex usage for performance
** profiling or testing, for example.</dd>
**
** <dt>SQLITE_CONFIG_LOOKASIDE</dt>
** <dd>This option takes two arguments that determine the default
** memory allcation lookaside optimization.  The first argument is the
** memory allocation lookaside optimization.  The first argument is the
** size of each lookaside buffer slot and the second is the number of
** slots allocated to each database connection.</dd>
** slots allocated to each database connection.  This option sets the
** <i>default</i> lookaside size.  The [SQLITE_DBCONFIG_LOOKASIDE]
** verb to [sqlite3_db_config()] can be used to change the lookaside
** configuration on individual connections.</dd>
**
** <dt>SQLITE_CONFIG_PCACHE</dt>
** <dd>This option takes a single argument which is a pointer to
** an [sqlite3_pcache_methods] object.  This object specifies the interface
** to a custom page cache implementation.  SQLite makes a copy of the
** object and uses it for page cache memory allocations.</dd>
**
1165
1166
1167
1168
1169
1170
1171
1172

1173
1174
1175
1176
1177




1178
1179
1180
1181
1182
1183
1184
1226
1227
1228
1229
1230
1231
1232

1233
1234
1235
1236
1237

1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248







-
+




-
+
+
+
+







** is invoked.
**
** <dl>
** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
** <dd>This option takes three additional arguments that determine the 
** [lookaside memory allocator] configuration for the [database connection].
** The first argument (the third parameter to [sqlite3_db_config()] is a
** pointer to an 8-byte aligned memory buffer to use for lookaside memory.
** pointer to an memory buffer to use for lookaside memory.
** The first argument may be NULL in which case SQLite will allocate the
** lookaside buffer itself using [sqlite3_malloc()].  The second argument is the
** size of each lookaside buffer slot and the third argument is the number of
** slots.  The size of the buffer in the first argument must be greater than
** or equal to the product of the second and third arguments.</dd>
** or equal to the product of the second and third arguments.  The buffer
** must be aligned to an 8-byte boundary.  If the second argument is not
** a multiple of 8, it is internally rounded down to the next smaller
** multiple of 8.  See also: [SQLITE_CONFIG_LOOKASIDE]</dd>
**
** </dl>
*/
#define SQLITE_DBCONFIG_LOOKASIDE    1001  /* void* int int */


/*
1242
1243
1244
1245
1246
1247
1248

1249
1250


1251
1252
1253
1254
1255
1256
1257
1306
1307
1308
1309
1310
1311
1312
1313


1314
1315
1316
1317
1318
1319
1320
1321
1322







+
-
-
+
+







** CAPI3REF: Count The Number Of Rows Modified {H12240} <S10600>
**
** This function returns the number of database rows that were changed
** or inserted or deleted by the most recently completed SQL statement
** on the [database connection] specified by the first parameter.
** Only changes that are directly specified by the [INSERT], [UPDATE],
** or [DELETE] statement are counted.  Auxiliary changes caused by
** triggers or [foreign key actions] are not counted. Use the
** triggers are not counted. Use the [sqlite3_total_changes()] function
** to find the total number of changes including changes caused by triggers.
** [sqlite3_total_changes()] function to find the total number of changes
** including changes caused by triggers and foreign key actions.
**
** Changes to a view that are simulated by an [INSTEAD OF trigger]
** are not counted.  Only real table changes are counted.
**
** A "row change" is a change to a single row of a single table
** caused by an INSERT, DELETE, or UPDATE statement.  Rows that
** are changed as side effects of [REPLACE] constraint resolution,
1295
1296
1297
1298
1299
1300
1301
1302
1303


1304
1305
1306
1307
1308
1309
1310
1360
1361
1362
1363
1364
1365
1366


1367
1368
1369
1370
1371
1372
1373
1374
1375







-
-
+
+







int sqlite3_changes(sqlite3*);

/*
** CAPI3REF: Total Number Of Rows Modified {H12260} <S10600>
**
** This function returns the number of row changes caused by [INSERT],
** [UPDATE] or [DELETE] statements since the [database connection] was opened.
** The count includes all changes from all 
** [CREATE TRIGGER | trigger] contexts.  However,
** The count includes all changes from all [CREATE TRIGGER | trigger] 
** contexts and changes made by [foreign key actions]. However,
** the count does not include changes used to implement [REPLACE] constraints,
** do rollbacks or ABORT processing, or [DROP TABLE] processing.  The
** count does not include rows of views that fire an [INSTEAD OF trigger],
** though if the INSTEAD OF trigger makes changes of its own, those changes 
** are counted.
** The changes are counted as soon as the statement that makes them is
** completed (when the statement handle is passed to [sqlite3_reset()] or
1574
1575
1576
1577
1578
1579
1580
1581

1582
1583
1584
1585
1586
1587
1588
1639
1640
1641
1642
1643
1644
1645

1646
1647
1648
1649
1650
1651
1652
1653







-
+







  char **pzErrmsg       /* Error msg written here */
);
void sqlite3_free_table(char **result);

/*
** CAPI3REF: Formatted String Printing Functions {H17400} <S70000><S20000>
**
** These routines are workalikes of the "printf()" family of functions
** These routines are work-alikes of the "printf()" family of functions
** from the standard C library.
**
** The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
** results into memory obtained from [sqlite3_malloc()].
** The strings returned by these two routines should be
** released by [sqlite3_free()].  Both routines return a
** NULL pointer if [sqlite3_malloc()] is unable to allocate enough
1861
1862
1863
1864
1865
1866
1867
1868

1869
1870
1871
1872
1873
1874
1875
1926
1927
1928
1929
1930
1931
1932

1933
1934
1935
1936
1937
1938
1939
1940







-
+







**
** The authorizer callback must not do anything that will modify
** the database connection that invoked the authorizer callback.
** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
** database connections for the meaning of "modify" in this paragraph.
**
** When [sqlite3_prepare_v2()] is used to prepare a statement, the
** statement might be reprepared during [sqlite3_step()] due to a 
** statement might be re-prepared during [sqlite3_step()] due to a 
** schema change.  Hence, the application should ensure that the
** correct authorizer callback remains in place during the [sqlite3_step()].
**
** Note that the authorizer callback is invoked only during
** [sqlite3_prepare()] or its variants.  Authorization is not
** performed during statement evaluation in [sqlite3_step()], unless
** as stated in the previous paragraph, sqlite3_step() invokes
2028
2029
2030
2031
2032
2033
2034
2035


2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055


2056
2057
2058
2059
2060
2061
2062
2063





2064
2065
2066
2067
2068
2069
2070
2093
2094
2095
2096
2097
2098
2099

2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120

2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142







-
+
+



















-
+
+








+
+
+
+
+







** associated with the [database connection] handle should be released by
** passing it to [sqlite3_close()] when it is no longer required.
**
** The sqlite3_open_v2() interface works like sqlite3_open()
** except that it accepts two additional parameters for additional control
** over the new database connection.  The flags parameter can take one of
** the following three values, optionally combined with the 
** [SQLITE_OPEN_NOMUTEX] or [SQLITE_OPEN_FULLMUTEX] flags:
** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE],
** and/or [SQLITE_OPEN_PRIVATECACHE] flags:
**
** <dl>
** <dt>[SQLITE_OPEN_READONLY]</dt>
** <dd>The database is opened in read-only mode.  If the database does not
** already exist, an error is returned.</dd>
**
** <dt>[SQLITE_OPEN_READWRITE]</dt>
** <dd>The database is opened for reading and writing if possible, or reading
** only if the file is write protected by the operating system.  In either
** case the database must already exist, otherwise an error is returned.</dd>
**
** <dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt>
** <dd>The database is opened for reading and writing, and is creates it if
** it does not already exist. This is the behavior that is always used for
** sqlite3_open() and sqlite3_open16().</dd>
** </dl>
**
** If the 3rd parameter to sqlite3_open_v2() is not one of the
** combinations shown above or one of the combinations shown above combined
** with the [SQLITE_OPEN_NOMUTEX] or [SQLITE_OPEN_FULLMUTEX] flags,
** with the [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX],
** [SQLITE_OPEN_SHAREDCACHE] and/or [SQLITE_OPEN_SHAREDCACHE] flags,
** then the behavior is undefined.
**
** If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection
** opens in the multi-thread [threading mode] as long as the single-thread
** mode has not been set at compile-time or start-time.  If the
** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens
** in the serialized [threading mode] unless single-thread was
** previously selected at compile-time or start-time.
** The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be
** eligible to use [shared cache mode], regardless of whether or not shared
** cache is enabled using [sqlite3_enable_shared_cache()].  The
** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not
** participate in [shared cache mode] even if it is enabled.
**
** If the filename is ":memory:", then a private, temporary in-memory database
** is created for the connection.  This in-memory database will vanish when
** the database connection is closed.  Future versions of SQLite might
** make use of additional special filenames that begin with the ":" character.
** It is recommended that when a database filename actually does begin with
** a ":" character you should prefix the filename with a pathname such as
2208
2209
2210
2211
2212
2213
2214
2215

2216
2217
2218
2219
2220
2221
2222
2280
2281
2282
2283
2284
2285
2286

2287
2288
2289
2290
2291
2292
2293
2294







-
+







** Requirements:
** [H12762] [H12766] [H12769]
*/
int sqlite3_limit(sqlite3*, int id, int newVal);

/*
** CAPI3REF: Run-Time Limit Categories {H12790} <H12760>
** KEYWORDS: {limit category} {limit categories}
** KEYWORDS: {limit category} {*limit categories}
**
** These constants define various performance limits
** that can be lowered at run-time using [sqlite3_limit()].
** The synopsis of the meanings of the various limits is shown below.
** Additional information is available at [limits | Limits in SQLite].
**
** <dl>
2250
2251
2252
2253
2254
2255
2256



2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268

2269
2270
2271
2272
2273
2274
2275
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351







+
+
+












+







** <dt>SQLITE_LIMIT_LIKE_PATTERN_LENGTH</dt>
** <dd>The maximum length of the pattern argument to the [LIKE] or
** [GLOB] operators.</dd>
**
** <dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt>
** <dd>The maximum number of variables in an SQL statement that can
** be bound.</dd>
**
** <dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
** <dd>The maximum depth of recursion for triggers.</dd>
** </dl>
*/
#define SQLITE_LIMIT_LENGTH                    0
#define SQLITE_LIMIT_SQL_LENGTH                1
#define SQLITE_LIMIT_COLUMN                    2
#define SQLITE_LIMIT_EXPR_DEPTH                3
#define SQLITE_LIMIT_COMPOUND_SELECT           4
#define SQLITE_LIMIT_VDBE_OP                   5
#define SQLITE_LIMIT_FUNCTION_ARG              6
#define SQLITE_LIMIT_ATTACHED                  7
#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH       8
#define SQLITE_LIMIT_VARIABLE_NUMBER           9
#define SQLITE_LIMIT_TRIGGER_DEPTH            10

/*
** CAPI3REF: Compiling An SQL Statement {H13010} <S10000>
** KEYWORDS: {SQL statement compiler}
**
** To execute an SQL query, it must first be compiled into a byte-code
** program using one of these routines.
2310
2311
2312
2313
2314
2315
2316
2317

2318
2319
2320
2321
2322
2323
2324
2386
2387
2388
2389
2390
2391
2392

2393
2394
2395
2396
2397
2398
2399
2400







-
+







**
** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are
** recommended for all new programs. The two older interfaces are retained
** for backwards compatibility, but their use is discouraged.
** In the "v2" interfaces, the prepared statement
** that is returned (the [sqlite3_stmt] object) contains a copy of the
** original SQL text. This causes the [sqlite3_step()] interface to
** behave a differently in two ways:
** behave differently in three ways:
**
** <ol>
** <li>
** If the database schema changes, instead of returning [SQLITE_SCHEMA] as it
** always used to do, [sqlite3_step()] will automatically recompile the SQL
** statement and try to run it again.  If the schema has changed in
** a way that makes the statement no longer valid, [sqlite3_step()] will still
2332
2333
2334
2335
2336
2337
2338








2339
2340
2341
2342
2343
2344
2345
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429







+
+
+
+
+
+
+
+







** When an error occurs, [sqlite3_step()] will return one of the detailed
** [error codes] or [extended error codes].  The legacy behavior was that
** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code
** and you would have to make a second call to [sqlite3_reset()] in order
** to find the underlying cause of the problem. With the "v2" prepare
** interfaces, the underlying reason for the error is returned immediately.
** </li>
**
** <li>
** ^If the value of a [parameter | host parameter] in the WHERE clause might
** change the query plan for a statement, then the statement may be
** automatically recompiled (as if there had been a schema change) on the first 
** [sqlite3_step()] call following any change to the 
** [sqlite3_bind_text | bindings] of the [parameter]. 
** </li>
** </ol>
**
** Requirements:
** [H13011] [H13012] [H13013] [H13014] [H13015] [H13016] [H13019] [H13021]
**
*/
int sqlite3_prepare(
2438
2439
2440
2441
2442
2443
2444
2445


2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456


2457
2458
2459
2460
2461
2462
2463
2522
2523
2524
2525
2526
2527
2528

2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539


2540
2541
2542
2543
2544
2545
2546
2547
2548







-
+
+









-
-
+
+








/*
** CAPI3REF: Binding Values To Prepared Statements {H13500} <S70300>
** KEYWORDS: {host parameter} {host parameters} {host parameter name}
** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
**
** In the SQL strings input to [sqlite3_prepare_v2()] and its variants,
** literals may be replaced by a [parameter] in one of these forms:
** literals may be replaced by a [parameter] that matches one of following
** templates:
**
** <ul>
** <li>  ?
** <li>  ?NNN
** <li>  :VVV
** <li>  @VVV
** <li>  $VVV
** </ul>
**
** In the parameter forms shown above NNN is an integer literal,
** and VVV is an alpha-numeric parameter name. The values of these
** In the templates above, NNN represents an integer literal,
** and VVV represents an alphanumeric identifer.  The values of these
** parameters (also called "host parameter names" or "SQL parameters")
** can be set using the sqlite3_bind_*() routines defined here.
**
** The first argument to the sqlite3_bind_*() routines is always
** a pointer to the [sqlite3_stmt] object returned from
** [sqlite3_prepare_v2()] or its variants.
**
2863
2864
2865
2866
2867
2868
2869


2870
2871
2872
2873
2874
2875
2876
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963







+
+







**
** These routines return information about a single column of the current
** result row of a query.  In every case the first argument is a pointer
** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
** that was returned from [sqlite3_prepare_v2()] or one of its variants)
** and the second argument is the index of the column for which information
** should be returned.  The leftmost column of the result set has the index 0.
** The number of columns in the result can be determined using
** [sqlite3_column_count()].
**
** If the SQL statement does not currently point to a valid row, or if the
** column index is out of range, the result is undefined.
** These routines may only be called when the most recent call to
** [sqlite3_step()] has returned [SQLITE_ROW] and neither
** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently.
** If any of these routines are called after [sqlite3_reset()] or
3101
3102
3103
3104
3105
3106
3107
3108

3109
3110
3111
3112
3113
3114
3115
3188
3189
3190
3191
3192
3193
3194

3195
3196
3197
3198
3199
3200
3201
3202







-
+







** parameter is less than -1 or greater than 127 then the behavior is
** undefined.
**
** The fourth parameter, eTextRep, specifies what
** [SQLITE_UTF8 | text encoding] this SQL function prefers for
** its parameters.  Any SQL function implementation should be able to work
** work with UTF-8, UTF-16le, or UTF-16be.  But some implementations may be
** more efficient with one encoding than another.  It is allowed to
** more efficient with one encoding than another.  An application may
** invoke sqlite3_create_function() or sqlite3_create_function16() multiple
** times with the same function but with different values of eTextRep.
** When multiple implementations of the same function are available, SQLite
** will pick the one that involves the least amount of data conversion.
** If there is only a single implementation which does not care what text
** encoding is used, then the fourth argument should be [SQLITE_ANY].
**
3123
3124
3125
3126
3127
3128
3129
3130

3131
3132
3133
3134
3135
3136
3137
3210
3211
3212
3213
3214
3215
3216

3217
3218
3219
3220
3221
3222
3223
3224







-
+







** parameters. An aggregate SQL function requires an implementation of xStep
** and xFinal and NULL should be passed for xFunc. To delete an existing
** SQL function or aggregate, pass NULL for all three function callbacks.
**
** It is permitted to register multiple implementations of the same
** functions with the same name but with either differing numbers of
** arguments or differing preferred text encodings.  SQLite will use
** the implementation most closely matches the way in which the
** the implementation that most closely matches the way in which the
** SQL function is used.  A function implementation with a non-negative
** nArg parameter is a better match than a function implementation with
** a negative nArg.  A function where the preferred text encoding
** matches the database encoding is a better
** match than a function where the encoding is different.  
** A function where the encoding difference is between UTF16le and UTF16be
** is a closer match than a function where the encoding difference is
3471
3472
3473
3474
3475
3476
3477
3478

3479
3480

3481

3482
3483
3484
3485
3486
3487
3488
3558
3559
3560
3561
3562
3563
3564

3565
3566
3567
3568

3569
3570
3571
3572
3573
3574
3575
3576







-
+


+
-
+







** is non-negative, then as many bytes (not characters) of the text
** pointed to by the 2nd parameter are taken as the application-defined
** function result.
** If the 4th parameter to the sqlite3_result_text* interfaces
** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that
** function as the destructor on the text or BLOB result when it has
** finished using that result.
** If the 4th parameter to the sqlite3_result_text* interfaces or
** If the 4th parameter to the sqlite3_result_text* interfaces or to
** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite
** assumes that the text or BLOB result is in constant space and does not
** copy the content of the parameter nor call a destructor on the content
** copy the it or call a destructor when it has finished using that result.
** when it has finished using that result.
** If the 4th parameter to the sqlite3_result_text* interfaces
** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
** then SQLite makes a copy of the result into space obtained from
** from [sqlite3_malloc()] before it returns.
**
** The sqlite3_result_value() interface sets the result of
** the application-defined function to be a copy the
3864
3865
3866
3867
3868
3869
3870
3871

3872
3873
3874
3875
3876
3877
3878
3952
3953
3954
3955
3956
3957
3958

3959
3960
3961
3962
3963
3964
3965
3966







-
+







  sqlite3*, 
  void(*)(void *,int ,char const *,char const *,sqlite3_int64),
  void*
);

/*
** CAPI3REF: Enable Or Disable Shared Pager Cache {H10330} <S30900>
** KEYWORDS: {shared cache} {shared cache mode}
** KEYWORDS: {shared cache}
**
** This routine enables or disables the sharing of the database cache
** and schema data structures between [database connection | connections]
** to the same database. Sharing is enabled if the argument is true
** and disabled if the argument is false.
**
** Cache sharing is enabled and disabled for an entire process.
4327
4328
4329
4330
4331
4332
4333
4334

4335
4336
4337
4338
4339
4340
4341
4415
4416
4417
4418
4419
4420
4421

4422
4423
4424
4425
4426
4427
4428
4429







-
+







** take care that any prior string is freed by a call to [sqlite3_free()]
** prior to assigning a new string to zErrMsg.  After the error message
** is delivered up to the client application, the string will be automatically
** freed by sqlite3_free() and the zErrMsg field will be zeroed.
*/
struct sqlite3_vtab {
  const sqlite3_module *pModule;  /* The module for this virtual table */
  int nRef;                       /* Used internally */
  int nRef;                       /* NO LONGER USED */
  char *zErrMsg;                  /* Error message from sqlite3_mprintf() */
  /* Virtual table implementations will typically add additional fields */
};

/*
** CAPI3REF: Virtual Table Cursor Object  {H18020} <S20400>
** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor}
4424
4425
4426
4427
4428
4429
4430



4431
4432
4433
4434
4435
4436
4437
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528







+
+
+







**
** <pre>
**     SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
** </pre> {END}
**
** If the flags parameter is non-zero, then the BLOB is opened for read
** and write access. If it is zero, the BLOB is opened for read access.
** It is not possible to open a column that is part of an index or primary 
** key for writing. ^If [foreign key constraints] are enabled, it is 
** not possible to open a column that is part of a [child key] for writing.
**
** Note that the database name is not the filename that contains
** the database but rather the symbolic name of the database that
** is assigned when the database is connected using [ATTACH].
** For the main database file, the database name is "main".
** For TEMP tables, the database name is "temp".
**
4453
4454
4455
4456
4457
4458
4459
4460

4461
4462
4463
4464
4465
4466
4467
4544
4545
4546
4547
4548
4549
4550

4551
4552
4553
4554
4555
4556
4557
4558







-
+







** a expired BLOB handle fail with an return code of [SQLITE_ABORT].
** Changes written into a BLOB prior to the BLOB expiring are not
** rollback by the expiration of the BLOB.  Such changes will eventually
** commit if the transaction continues to completion.
**
** Use the [sqlite3_blob_bytes()] interface to determine the size of
** the opened blob.  The size of a blob may not be changed by this
** underface.  Use the [UPDATE] SQL command to change the size of a
** interface.  Use the [UPDATE] SQL command to change the size of a
** blob.
**
** The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
** and the built-in [zeroblob] SQL function can be used, if desired,
** to create an empty, zero-filled blob in which to read or write using
** this interface.
**
4693
4694
4695
4696
4697
4698
4699
4700

4701
4702
4703
4704
4705
4706
4707
4784
4785
4786
4787
4788
4789
4790

4791
4792
4793
4794
4795
4796
4797
4798







-
+







** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
** not want to.  {H17016} But SQLite will only request a recursive mutex in
** cases where it really needs one.  {END} If a faster non-recursive mutex
** implementation is available on the host platform, the mutex subsystem
** might return such a mutex in response to SQLITE_MUTEX_FAST.
**
** {H17017} The other allowed parameters to sqlite3_mutex_alloc() each return
** a pointer to a static preexisting mutex. {END}  Four static mutexes are
** a pointer to a static preexisting mutex. {END}  Six static mutexes are
** used by the current version of SQLite.  Future versions of SQLite
** may add additional static mutexes.  Static mutexes are for internal
** use by SQLite only.  Applications that use SQLite mutexes should
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
** SQLITE_MUTEX_RECURSIVE.
**
** {H17018} Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
4799
4800
4801
4802
4803
4804
4805















4806
4807
4808
4809
4810
4811
4812
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







** The only difference is that the public sqlite3_XXX functions enumerated
** above silently ignore any invocations that pass a NULL pointer instead
** of a valid mutex handle. The implementations of the methods defined
** by this structure are not required to handle this case, the results
** of passing a NULL pointer instead of a valid mutex handle are undefined
** (i.e. it is acceptable to provide an implementation that segfaults if
** it is passed a NULL pointer).
**
** The xMutexInit() method must be threadsafe.  It must be harmless to
** invoke xMutexInit() mutiple times within the same process and without
** intervening calls to xMutexEnd().  Second and subsequent calls to
** xMutexInit() must be no-ops.
**
** xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
** and its associates).  Similarly, xMutexAlloc() must not use SQLite memory
** allocation for a static mutex.  However xMutexAlloc() may use SQLite
** memory allocation for a fast or recursive mutex.
**
** SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is
** called, but only if the prior call to xMutexInit returned SQLITE_OK.
** If xMutexInit fails in any way, it is expected to clean up after itself
** prior to returning.
*/
typedef struct sqlite3_mutex_methods sqlite3_mutex_methods;
struct sqlite3_mutex_methods {
  int (*xMutexInit)(void);
  int (*xMutexEnd)(void);
  sqlite3_mutex *(*xMutexAlloc)(int);
  void (*xMutexFree)(sqlite3_mutex *);
4941
4942
4943
4944
4945
4946
4947

4948
4949
4950
4951
4952
4953
4954
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061







+







#define SQLITE_TESTCTRL_PRNG_RESET               7
#define SQLITE_TESTCTRL_BITVEC_TEST              8
#define SQLITE_TESTCTRL_FAULT_INSTALL            9
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS     10
#define SQLITE_TESTCTRL_PENDING_BYTE            11
#define SQLITE_TESTCTRL_ASSERT                  12
#define SQLITE_TESTCTRL_ALWAYS                  13
#define SQLITE_TESTCTRL_RESERVE                 14

/*
** CAPI3REF: SQLite Runtime Status {H17200} <S60200>
** EXPERIMENTAL
**
** This interface is used to retrieve runtime status information
** about the preformance of SQLite, and optionally to reset various
4963
4964
4965
4966
4967
4968
4969
4970

4971
4972
4973
4974
4975
4976
4977
5070
5071
5072
5073
5074
5075
5076

5077
5078
5079
5080
5081
5082
5083
5084







-
+







** nothing is written into *pHighwater and the resetFlag is ignored.
** Other parameters record only the highwater mark and not the current
** value.  For these latter parameters nothing is written into *pCurrent.
**
** This routine returns SQLITE_OK on success and a non-zero
** [error code] on failure.
**
** This routine is threadsafe but is not atomic.  This routine can
** This routine is threadsafe but is not atomic.  This routine can be
** called while other threads are running the same or different SQLite
** interfaces.  However the values returned in *pCurrent and
** *pHighwater reflect the status of SQLite at different points in time
** and it is possible that another thread might change the parameter
** in between the times when *pCurrent and *pHighwater are written.
**
** See also: [sqlite3_db_status()]
5086
5087
5088
5089
5090
5091
5092





5093



5094
5095
5096
5097
5098
5099
5100
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204

5205
5206
5207
5208
5209
5210
5211
5212
5213
5214







+
+
+
+
+
-
+
+
+







*/
SQLITE_EXPERIMENTAL int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);

/*
** CAPI3REF: Status Parameters for database connections {H17520} <H17500>
** EXPERIMENTAL
**
** These constants are the available integer "verbs" that can be passed as
** the second argument to the [sqlite3_db_status()] interface.
**
** New verbs may be added in future releases of SQLite. Existing verbs
** might be discontinued. Applications should check the return code from
** Status verbs for [sqlite3_db_status()].
** [sqlite3_db_status()] to make sure that the call worked.
** The [sqlite3_db_status()] interface will return a non-zero error code
** if a discontinued or unsupported verb is invoked.
**
** <dl>
** <dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt>
** <dd>This parameter returns the number of lookaside memory slots currently
** checked out.</dd>
** </dl>
*/
5164
5165
5166
5167
5168
5169
5170

5171
5172
5173
5174
5175
5176

5177
5178
5179
5180


5181
5182
5183
5184
5185




5186
5187
5188
5189
5190
5191
5192
5193





5194









5195



5196
5197
5198
5199









5200
5201
5202





5203
5204
5205
5206
5207
5208
5209


5210
5211
5212

5213
5214
5215
5216
5217
5218

5219
5220
5221
5222
5223
5224





5225
5226
5227

5228
5229

5230
5231
5232
5233
5234
5235
5236

5237
5238

5239
5240
5241
5242

5243
5244
5245
5246
5247

5248







5249
5250
5251
5252
5253
5254
5255
5256

5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290

5291
5292
5293


5294
5295
5296
5297
5298


5299
5300
5301
5302
5303
5304
5305
5306
5307



5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322

5323
5324
5325
5326



5327
5328
5329
5330
5331
5332
5333
5334
5335
5336


5337
5338
5339
5340
5341
5342
5343
5344
5345
5346


5347
5348
5349
5350

5351
5352
5353
5354
5355
5356

5357
5358





5359
5360
5361
5362
5363
5364
5365

5366


5367







5368


5369




5370





5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386

5387



5388
5389
5390
5391
5392
5393
5394







+





-
+


-
-
+
+



-
-
+
+
+
+





-
-
-
+
+
+
+
+

+
+
+
+
+
+
+
+
+
-
+
+
+

-
-
-
+
+
+
+
+
+
+
+
+

-
-
+
+
+
+
+





-
-
+
+


-
+





-
+

-
-
-
-
-
+
+
+
+
+


-
+
-
-
+
-
-
-
-
-
-
-
+
-
-
+
-
-
-
-
+
-
-
-
-
-
+

+
+
+
+
+
+
+







-
+
-
-
-







**
** See [sqlite3_pcache_methods] for additional information.
*/
typedef struct sqlite3_pcache sqlite3_pcache;

/*
** CAPI3REF: Application Defined Page Cache.
** KEYWORDS: {page cache}
** EXPERIMENTAL
**
** The [sqlite3_config]([SQLITE_CONFIG_PCACHE], ...) interface can
** register an alternative page cache implementation by passing in an 
** instance of the sqlite3_pcache_methods structure. The majority of the 
** heap memory used by sqlite is used by the page cache to cache data read 
** heap memory used by SQLite is used by the page cache to cache data read 
** from, or ready to be written to, the database file. By implementing a 
** custom page cache using this API, an application can control more 
** precisely the amount of memory consumed by sqlite, the way in which 
** said memory is allocated and released, and the policies used to 
** precisely the amount of memory consumed by SQLite, the way in which 
** that memory is allocated and released, and the policies used to 
** determine exactly which parts of a database file are cached and for 
** how long.
**
** The contents of the structure are copied to an internal buffer by sqlite
** within the call to [sqlite3_config].
** The contents of the sqlite3_pcache_methods structure are copied to an
** internal buffer by SQLite within the call to [sqlite3_config].  Hence
** the application may discard the parameter after the call to
** [sqlite3_config()] returns.
**
** The xInit() method is called once for each call to [sqlite3_initialize()]
** (usually only once during the lifetime of the process). It is passed
** a copy of the sqlite3_pcache_methods.pArg value. It can be used to set
** up global structures and mutexes required by the custom page cache 
** implementation. The xShutdown() method is called from within 
** [sqlite3_shutdown()], if the application invokes this API. It can be used
** to clean up any outstanding resources before process shutdown, if required.
** implementation. 
**
** The xShutdown() method is called from within [sqlite3_shutdown()], 
** if the application invokes this API. It can be used to clean up 
** any outstanding resources before process shutdown, if required.
**
** SQLite holds a [SQLITE_MUTEX_RECURSIVE] mutex when it invokes
** the xInit method, so the xInit method need not be threadsafe.  The
** xShutdown method is only called from [sqlite3_shutdown()] so it does
** not need to be threadsafe either.  All other methods must be threadsafe
** in multithreaded applications.
**
** SQLite will never invoke xInit() more than once without an intervening
** call to xShutdown().
**
** The xCreate() method is used to construct a new cache instance. The
** The xCreate() method is used to construct a new cache instance.  SQLite
** will typically create one cache instance for each open database file,
** though this is not guaranteed. The
** first parameter, szPage, is the size in bytes of the pages that must
** be allocated by the cache. szPage will not be a power of two. The
** second argument, bPurgeable, is true if the cache being created will
** be used to cache database pages read from a file stored on disk, or
** be allocated by the cache.  szPage will not be a power of two.  szPage
** will the page size of the database file that is to be cached plus an
** increment (here called "R") of about 100 or 200.  SQLite will use the
** extra R bytes on each page to store metadata about the underlying
** database page on disk.  The value of R depends
** on the SQLite version, the target platform, and how SQLite was compiled.
** R is constant for a particular build of SQLite.  The second argument to
** xCreate(), bPurgeable, is true if the cache being created will
** be used to cache database pages of a file stored on disk, or
** false if it is used for an in-memory database. The cache implementation
** does not have to do anything special based on the value of bPurgeable,
** it is purely advisory. 
** does not have to do anything special based with the value of bPurgeable;
** it is purely advisory.  On a cache where bPurgeable is false, SQLite will
** never invoke xUnpin() except to deliberately delete a page.
** In other words, a cache created with bPurgeable set to false will
** never contain any unpinned pages.
**
** The xCachesize() method may be called at any time by SQLite to set the
** suggested maximum cache-size (number of pages stored by) the cache
** instance passed as the first argument. This is the value configured using
** the SQLite "[PRAGMA cache_size]" command. As with the bPurgeable parameter,
** the implementation is not required to do anything special with this
** value, it is advisory only.
** the implementation is not required to do anything with this
** value; it is advisory only.
**
** The xPagecount() method should return the number of pages currently
** stored in the cache supplied as an argument.
** stored in the cache.
** 
** The xFetch() method is used to fetch a page and return a pointer to it. 
** A 'page', in this context, is a buffer of szPage bytes aligned at an
** 8-byte boundary. The page to be fetched is determined by the key. The
** mimimum key value is 1. After it has been retrieved using xFetch, the page 
** is considered to be pinned.
** is considered to be "pinned".
**
** If the requested page is already in the page cache, then a pointer to
** the cached buffer should be returned with its contents intact. If the
** page is not already in the cache, then the expected behaviour of the
** cache is determined by the value of the createFlag parameter passed
** to xFetch, according to the following table:
** If the requested page is already in the page cache, then the page cache
** implementation must return a pointer to the page buffer with its content
** intact.  If the requested page is not already in the cache, then the
** behavior of the cache implementation is determined by the value of the
** createFlag parameter passed to xFetch, according to the following table:
**
** <table border=1 width=85% align=center>
**   <tr><th>createFlag<th>Expected Behaviour
** <tr><th> createFlag <th> Behaviour when page is not already in cache
**   <tr><td>0<td>NULL should be returned. No new cache entry is created.
**   <tr><td>1<td>If createFlag is set to 1, this indicates that 
** <tr><td> 0 <td> Do not allocate a new page.  Return NULL.
**                SQLite is holding pinned pages that can be unpinned
**                by writing their contents to the database file (a
**                relatively expensive operation). In this situation the
**                cache implementation has two choices: it can return NULL,
**                in which case SQLite will attempt to unpin one or more 
**                pages before re-requesting the same page, or it can
**                allocate a new page and return a pointer to it. If a new
** <tr><td> 1 <td> Allocate a new page if it easy and convenient to do so.
**                page is allocated, then the first sizeof(void*) bytes of
**                it (at least) must be zeroed before it is returned.
**                 Otherwise return NULL.
**   <tr><td>2<td>If createFlag is set to 2, then SQLite is not holding any
**                pinned pages associated with the specific cache passed
**                as the first argument to xFetch() that can be unpinned. The
**                cache implementation should attempt to allocate a new
** <tr><td> 2 <td> Make every effort to allocate a new page.  Only return
**                cache entry and return a pointer to it. Again, the first
**                sizeof(void*) bytes of the page should be zeroed before 
**                it is returned. If the xFetch() method returns NULL when 
**                createFlag==2, SQLite assumes that a memory allocation 
**                failed and returns SQLITE_NOMEM to the user.
**                 NULL if allocating a new page is effectively impossible.
** </table>
**
** SQLite will normally invoke xFetch() with a createFlag of 0 or 1.  If
** a call to xFetch() with createFlag==1 returns NULL, then SQLite will
** attempt to unpin one or more cache pages by spilling the content of
** pinned pages to disk and synching the operating system disk cache. After
** attempting to unpin pages, the xFetch() method will be invoked again with
** a createFlag of 2.
**
** xUnpin() is called by SQLite with a pointer to a currently pinned page
** as its second argument. If the third parameter, discard, is non-zero,
** then the page should be evicted from the cache. In this case SQLite 
** assumes that the next time the page is retrieved from the cache using
** the xFetch() method, it will be zeroed. If the discard parameter is
** zero, then the page is considered to be unpinned. The cache implementation
** may choose to reclaim (free or recycle) unpinned pages at any time.
** may choose to evict unpinned pages at any time.
** SQLite assumes that next time the page is retrieved from the cache
** it will either be zeroed, or contain the same data that it did when it
** was unpinned.
**
** The cache is not required to perform any reference counting. A single 
** call to xUnpin() unpins the page regardless of the number of prior calls 
** to xFetch().
**
** The xRekey() method is used to change the key value associated with the
** page passed as the second argument from oldKey to newKey. If the cache
5608
5609
5610
5611
5612
5613
5614












5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766







+
+
+
+
+
+
+
+
+
+
+
+












*/
int sqlite3_unlock_notify(
  sqlite3 *pBlocked,                          /* Waiting connection */
  void (*xNotify)(void **apArg, int nArg),    /* Callback function to invoke */
  void *pNotifyArg                            /* Argument to pass to xNotify */
);


/*
** CAPI3REF: String Comparison
** EXPERIMENTAL
**
** The [sqlite3_strnicmp()] API allows applications and extensions to
** compare the contents of two buffers containing UTF-8 strings in a
** case-indendent fashion, using the same definition of case independence 
** that SQLite uses internally when comparing identifiers.
*/
int sqlite3_strnicmp(const char *, const char *, int);

/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT
# undef double
#endif

#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif
#endif
Changes to src/sqlite3ext.h.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
10
11
12
13
14
15
16


17
18
19
20
21
22
23







-
-







**
*************************************************************************
** This header file defines the SQLite interface for use by
** shared libraries that want to be imported as extensions into
** an SQLite instance.  Shared libraries that intend to be loaded
** as extensions by SQLite should #include this file instead of 
** sqlite3.h.
**
** @(#) $Id: sqlite3ext.h,v 1.25 2008/10/12 00:27:54 shane Exp $
*/
#ifndef _SQLITE3EXT_H_
#define _SQLITE3EXT_H_
#include "sqlite3.h"

typedef struct sqlite3_api_routines sqlite3_api_routines;

Changes to src/sqliteInt.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18



























19
20
21
22
23
24
25
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51













-




+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.890 2009/06/26 15:14:55 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** These #defines should enable >2GB file support on POSIX if the
** underlying operating system supports it.  If the OS lacks
** large file support, or if the OS is windows, these should be no-ops.
**
** Ticket #2739:  The _LARGEFILE_SOURCE macro must appear before any
** system #includes.  Hence, this block of code must be the very first
** code in all source files.
**
** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
** on the compiler command line.  This is necessary if you are compiling
** on a recent machine (ex: Red Hat 7.2) but you want your code to work
** on an older machine (ex: Red Hat 6.0).  If you compile on Red Hat 7.2
** without this option, LFS is enable.  But LFS does not exist in the kernel
** in Red Hat 6.0, so the code won't work.  Hence, for maximum binary
** portability you should omit LFS.
**
** Similar is true for Mac OS X.  LFS is only supported on Mac OS X 9 and later.
*/
#ifndef SQLITE_DISABLE_LFS
# define _LARGE_FILE       1
# ifndef _FILE_OFFSET_BITS
#   define _FILE_OFFSET_BITS 64
# endif
# define _LARGEFILE_SOURCE 1
#endif

/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build
*/
#ifdef _HAVE_SQLITE_CONFIG_H
#include "config.h"
#endif
46
47
48
49
50
51
52


53
54
55
56
57
58
59
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87







+
+







#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif

#define SQLITE_INDEX_SAMPLES 10

/*
** This macro is used to "hide" some ugliness in casting an int
** value to a ptr value under the MSVC 64-bit compiler.   Casting
** non 64-bit values to ptr types results in a "hard" error with 
** the MSVC 64-bit compiler which this attempts to avoid.  
**
** A simple compiler pragma or casting sequence could not be found
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
106
107
108
109
110
111
112



























113
114
115
116
117
118
119







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







#   define SQLITE_PTR_TO_INT(X)  ((int)(X))
# endif
#else
# define SQLITE_INT_TO_PTR(X)   ((void*)&((char*)0)[X])
# define SQLITE_PTR_TO_INT(X)   ((int)(((char*)X)-(char*)0))
#endif

/*
** These #defines should enable >2GB file support on POSIX if the
** underlying operating system supports it.  If the OS lacks
** large file support, or if the OS is windows, these should be no-ops.
**
** Ticket #2739:  The _LARGEFILE_SOURCE macro must appear before any
** system #includes.  Hence, this block of code must be the very first
** code in all source files.
**
** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
** on the compiler command line.  This is necessary if you are compiling
** on a recent machine (ex: Red Hat 7.2) but you want your code to work
** on an older machine (ex: Red Hat 6.0).  If you compile on Red Hat 7.2
** without this option, LFS is enable.  But LFS does not exist in the kernel
** in Red Hat 6.0, so the code won't work.  Hence, for maximum binary
** portability you should omit LFS.
**
** Similar is true for Mac OS X.  LFS is only supported on Mac OS X 9 and later.
*/
#ifndef SQLITE_DISABLE_LFS
# define _LARGE_FILE       1
# ifndef _FILE_OFFSET_BITS
#   define _FILE_OFFSET_BITS 64
# endif
# define _LARGEFILE_SOURCE 1
#endif


/*
** The SQLITE_THREADSAFE macro must be defined as either 0 or 1.
** Older versions of SQLite used an optional THREADSAFE macro.
** We support that for legacy
*/
#if !defined(SQLITE_THREADSAFE)
301
302
303
304
305
306
307
308

309
310
311
312
313
314
315
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316







-
+







** If compiling for a processor that lacks floating point support,
** substitute integer for floating-point
*/
#ifdef SQLITE_OMIT_FLOATING_POINT
# define double sqlite_int64
# define LONGDOUBLE_TYPE sqlite_int64
# ifndef SQLITE_BIG_DBL
#   define SQLITE_BIG_DBL (((sqlite3_int64)1)<<60)
#   define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50)
# endif
# define SQLITE_OMIT_DATETIME_FUNCS 1
# define SQLITE_OMIT_TRACE 1
# undef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
# undef SQLITE_HAVE_ISNAN
#endif
#ifndef SQLITE_BIG_DBL
347
348
349
350
351
352
353




354
355
356
357
358
359
360
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365







+
+
+
+







** the default file format for new databases and the maximum file format
** that the library can read.
*/
#define SQLITE_MAX_FILE_FORMAT 4
#ifndef SQLITE_DEFAULT_FILE_FORMAT
# define SQLITE_DEFAULT_FILE_FORMAT 1
#endif

#ifndef SQLITE_DEFAULT_RECURSIVE_TRIGGERS
# define SQLITE_DEFAULT_RECURSIVE_TRIGGERS 0
#endif

/*
** Provide a default value for SQLITE_TEMP_STORE in case it is not specified
** on the command-line
*/
#ifndef SQLITE_TEMP_STORE
# define SQLITE_TEMP_STORE 1
591
592
593
594
595
596
597

598
599
600
601
602
603
604
605
606
607
608
609
610
611
612

613
614
615

616
617
618
619
620
621
622
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617

618
619
620
621
622
623
624
625
626
627
628
629







+














-
+



+







typedef struct ExprList ExprList;
typedef struct ExprSpan ExprSpan;
typedef struct FKey FKey;
typedef struct FuncDef FuncDef;
typedef struct FuncDefHash FuncDefHash;
typedef struct IdList IdList;
typedef struct Index Index;
typedef struct IndexSample IndexSample;
typedef struct KeyClass KeyClass;
typedef struct KeyInfo KeyInfo;
typedef struct Lookaside Lookaside;
typedef struct LookasideSlot LookasideSlot;
typedef struct Module Module;
typedef struct NameContext NameContext;
typedef struct Parse Parse;
typedef struct Savepoint Savepoint;
typedef struct Select Select;
typedef struct SrcList SrcList;
typedef struct StrAccum StrAccum;
typedef struct Table Table;
typedef struct TableLock TableLock;
typedef struct Token Token;
typedef struct TriggerStack TriggerStack;
typedef struct TriggerPrg TriggerPrg;
typedef struct TriggerStep TriggerStep;
typedef struct Trigger Trigger;
typedef struct UnpackedRecord UnpackedRecord;
typedef struct VTable VTable;
typedef struct Walker Walker;
typedef struct WherePlan WherePlan;
typedef struct WhereInfo WhereInfo;
typedef struct WhereLevel WhereLevel;

/*
** Defer sourcing vdbe.h and btree.h until after the "u8" and 
659
660
661
662
663
664
665

666
667
668
669
670
671
672
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680







+







** statements.
*/
struct Schema {
  int schema_cookie;   /* Database schema version number for this file */
  Hash tblHash;        /* All tables indexed by name */
  Hash idxHash;        /* All (named) indices indexed by name */
  Hash trigHash;       /* All triggers indexed by name */
  Hash fkeyHash;       /* All foreign keys by referenced table name */
  Table *pSeqTab;      /* The sqlite_sequence table used by AUTOINCREMENT */
  u8 file_format;      /* Schema format version for this file */
  u8 enc;              /* Text encoding used by this database */
  u16 flags;           /* Flags associated with this schema */
  int cache_size;      /* Number of pages to use in the cache */
#ifndef SQLITE_OMIT_VIRTUALTABLE
  sqlite3 *db;         /* "Owner" connection. See comment above */
696
697
698
699
700
701
702
703

704
705
706
707
708
709
710
704
705
706
707
708
709
710

711
712
713
714
715
716
717
718







-
+







#define DB_UnresetViews    0x0002  /* Some views have defined column names */
#define DB_Empty           0x0004  /* The file is empty (length 0 bytes) */

/*
** The number of different kinds of things that can be limited
** using the sqlite3_limit() interface.
*/
#define SQLITE_N_LIMIT (SQLITE_LIMIT_VARIABLE_NUMBER+1)
#define SQLITE_N_LIMIT (SQLITE_LIMIT_TRIGGER_DEPTH+1)

/*
** Lookaside malloc is a set of fixed-size buffers that can be used
** to satisfy small transient memory allocation requests for objects
** associated with a particular database connection.  The use of
** lookaside malloc provides a significant performance enhancement
** (approx 10%) by avoiding numerous malloc/free requests while parsing
795
796
797
798
799
800
801

802
803
804
805
806
807
808
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817







+







  int nTotalChange;             /* Value returned by sqlite3_total_changes() */
  sqlite3_mutex *mutex;         /* Connection mutex */
  int aLimit[SQLITE_N_LIMIT];   /* Limits */
  struct sqlite3InitInfo {      /* Information used during initialization */
    int iDb;                    /* When back is being initialized */
    int newTnum;                /* Rootpage of table being initialized */
    u8 busy;                    /* TRUE if currently initializing */
    u8 orphanTrigger;           /* Last statement is orphaned TEMP trigger */
  } init;
  int nExtension;               /* Number of loaded extensions */
  void **aExtension;            /* Array of shared library handles */
  struct Vdbe *pVdbe;           /* List of active virtual machines */
  int activeVdbeCnt;            /* Number of VDBEs currently executing */
  int writeVdbeCnt;             /* Number of active VDBEs that are writing */
  void (*xTrace)(void*,const char*);        /* Trace function */
835
836
837
838
839
840
841
842

843

844
845
846
847
848
849
850
851
852
853

854
855
856
857
858
859
860
844
845
846
847
848
849
850

851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871







-
+

+










+







  int (*xProgress)(void *);     /* The progress callback */
  void *pProgressArg;           /* Argument to the progress callback */
  int nProgressOps;             /* Number of opcodes for progress callback */
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
  Hash aModule;                 /* populated by sqlite3_create_module() */
  Table *pVTab;                 /* vtab with active Connect/Create method */
  sqlite3_vtab **aVTrans;       /* Virtual tables with open transactions */
  VTable **aVTrans;             /* Virtual tables with open transactions */
  int nVTrans;                  /* Allocated size of aVTrans */
  VTable *pDisconnect;    /* Disconnect these in next sqlite3_prepare() */
#endif
  FuncDefHash aFunc;            /* Hash table of connection functions */
  Hash aCollSeq;                /* All collating sequences */
  BusyHandler busyHandler;      /* Busy callback */
  int busyTimeout;              /* Busy handler timeout, in msec */
  Db aDbStatic[2];              /* Static space for the 2 default backends */
  Savepoint *pSavepoint;        /* List of active savepoints */
  int nSavepoint;               /* Number of non-transaction savepoints */
  int nStatement;               /* Number of nested statement-transactions  */
  u8 isTransactionSavepoint;    /* True if the outermost savepoint is a TS */
  i64 nDeferredCons;            /* Net deferred constraints this transaction. */

#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
  /* The following variables are all protected by the STATIC_MASTER 
  ** mutex, not by sqlite3.mutex. They are used by code in notify.c. 
  **
  ** When X.pUnlockConnection==Y, that means that X is waiting for Y to
  ** unlock so that it can proceed.
901
902
903
904
905
906
907
908
909
910



911
912
913
914
915
916
917
912
913
914
915
916
917
918



919
920
921
922
923
924
925
926
927
928







-
-
-
+
+
+







#define SQLITE_IgnoreChecks   0x00002000  /* Do not enforce check constraints */
#define SQLITE_ReadUncommitted 0x00004000 /* For shared-cache mode */
#define SQLITE_LegacyFileFmt  0x00008000  /* Create new databases in format 1 */
#define SQLITE_FullFSync      0x00010000  /* Use full fsync on the backend */
#define SQLITE_LoadExtension  0x00020000  /* Enable load_extension */

#define SQLITE_RecoveryMode   0x00040000  /* Ignore schema errors */
#define SQLITE_SharedCache    0x00080000  /* Cache sharing is enabled */
#define SQLITE_CommitBusy     0x00200000  /* In the process of committing */
#define SQLITE_ReverseOrder   0x00400000  /* Reverse unordered SELECTs */
#define SQLITE_ReverseOrder   0x00100000  /* Reverse unordered SELECTs */
#define SQLITE_RecTriggers    0x00200000  /* Enable recursive triggers */
#define SQLITE_ForeignKeys    0x00400000  /* Enforce foreign key constraints  */

/*
** Possible values for the sqlite.magic field.
** The numbers are obtained at random and have no special meaning, other
** than being distinct from one another.
*/
#define SQLITE_MAGIC_OPEN     0xa029a697  /* Database is open */
944
945
946
947
948
949
950

951
952
953
954
955
956
957
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969







+







*/
#define SQLITE_FUNC_LIKE     0x01 /* Candidate for the LIKE optimization */
#define SQLITE_FUNC_CASE     0x02 /* Case-sensitive LIKE-type function */
#define SQLITE_FUNC_EPHEM    0x04 /* Ephemeral.  Delete with VDBE */
#define SQLITE_FUNC_NEEDCOLL 0x08 /* sqlite3GetFuncCollSeq() might be called */
#define SQLITE_FUNC_PRIVATE  0x10 /* Allowed for internal use only */
#define SQLITE_FUNC_COUNT    0x20 /* Built-in count(*) aggregate */
#define SQLITE_FUNC_COALESCE 0x40 /* Built-in coalesce() or ifnull() function */

/*
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
** used to create the initializers for the FuncDef structures.
**
**   FUNCTION(zName, nArg, iArg, bNC, xFunc)
**     Used to create a scalar function definition of a function zName 
990
991
992
993
994
995
996

997
998
999
1000
1001
1002
1003
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016







+







** All current savepoints are stored in a linked list starting at
** sqlite3.pSavepoint. The first element in the list is the most recently
** opened savepoint. Savepoints are added to the list by the vdbe
** OP_Savepoint instruction.
*/
struct Savepoint {
  char *zName;                        /* Savepoint name (nul-terminated) */
  i64 nDeferredCons;                  /* Number of deferred fk violations */
  Savepoint *pNext;                   /* Parent savepoint (if any) */
};

/*
** The following are used as the second parameter to sqlite3Savepoint(),
** and as the P1 argument to the OP_Savepoint instruction.
*/
1110
1111
1112
1113
1114
1115
1116



















































1117
1118
1119
1120
1121
1122
1123
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








/*
** Additional bit values that can be ORed with an affinity without
** changing the affinity.
*/
#define SQLITE_JUMPIFNULL   0x08  /* jumps if either operand is NULL */
#define SQLITE_STOREP2      0x10  /* Store result in reg[P2] rather than jump */
#define SQLITE_NULLEQ       0x80  /* NULL=NULL */

/*
** An object of this type is created for each virtual table present in
** the database schema. 
**
** If the database schema is shared, then there is one instance of this
** structure for each database connection (sqlite3*) that uses the shared
** schema. This is because each database connection requires its own unique
** instance of the sqlite3_vtab* handle used to access the virtual table 
** implementation. sqlite3_vtab* handles can not be shared between 
** database connections, even when the rest of the in-memory database 
** schema is shared, as the implementation often stores the database
** connection handle passed to it via the xConnect() or xCreate() method
** during initialization internally. This database connection handle may
** then used by the virtual table implementation to access real tables 
** within the database. So that they appear as part of the callers 
** transaction, these accesses need to be made via the same database 
** connection as that used to execute SQL operations on the virtual table.
**
** All VTable objects that correspond to a single table in a shared
** database schema are initially stored in a linked-list pointed to by
** the Table.pVTable member variable of the corresponding Table object.
** When an sqlite3_prepare() operation is required to access the virtual
** table, it searches the list for the VTable that corresponds to the
** database connection doing the preparing so as to use the correct
** sqlite3_vtab* handle in the compiled query.
**
** When an in-memory Table object is deleted (for example when the
** schema is being reloaded for some reason), the VTable objects are not 
** deleted and the sqlite3_vtab* handles are not xDisconnect()ed 
** immediately. Instead, they are moved from the Table.pVTable list to
** another linked list headed by the sqlite3.pDisconnect member of the
** corresponding sqlite3 structure. They are then deleted/xDisconnected 
** next time a statement is prepared using said sqlite3*. This is done
** to avoid deadlock issues involving multiple sqlite3.mutex mutexes.
** Refer to comments above function sqlite3VtabUnlockList() for an
** explanation as to why it is safe to add an entry to an sqlite3.pDisconnect
** list without holding the corresponding sqlite3.mutex mutex.
**
** The memory for objects of this type is always allocated by 
** sqlite3DbMalloc(), using the connection handle stored in VTable.db as 
** the first argument.
*/
struct VTable {
  sqlite3 *db;              /* Database connection associated with this table */
  Module *pMod;             /* Pointer to module implementation */
  sqlite3_vtab *pVtab;      /* Pointer to vtab instance */
  int nRef;                 /* Number of pointers to this structure */
  VTable *pNext;            /* Next in linked list (see above) */
};

/*
** Each SQL table is represented in memory by an instance of the
** following structure.
**
** Table.zName is the name of the table.  The case of the original
** CREATE TABLE statement is stored, but case is not significant for
1162
1163
1164
1165
1166
1167
1168
1169

1170
1171
1172
1173
1174
1175
1176
1177
1226
1227
1228
1229
1230
1231
1232

1233

1234
1235
1236
1237
1238
1239
1240







-
+
-







#ifndef SQLITE_OMIT_CHECK
  Expr *pCheck;        /* The AND of all CHECK constraints */
#endif
#ifndef SQLITE_OMIT_ALTERTABLE
  int addColOffset;    /* Offset in CREATE TABLE stmt to add a new column */
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
  Module *pMod;        /* Pointer to the implementation of the module */
  VTable *pVTable;     /* List of VTable objects. */
  sqlite3_vtab *pVtab; /* Pointer to the module instance */
  int nModuleArg;      /* Number of arguments to the module */
  char **azModuleArg;  /* Text of all module args. [0] is module name */
#endif
  Trigger *pTrigger;   /* List of triggers stored in pSchema */
  Schema *pSchema;     /* Schema that contains this table */
  Table *pNextZombie;  /* Next on the Parse.pZombieTab list */
};
1217
1218
1219
1220
1221
1222
1223
1224

1225
1226



1227

1228
1229

1230
1231

1232
1233
1234
1235
1236
1237
1238
1280
1281
1282
1283
1284
1285
1286

1287
1288

1289
1290
1291
1292
1293
1294

1295


1296
1297
1298
1299
1300
1301
1302
1303







-
+

-
+
+
+

+

-
+
-
-
+







** For foreign key "fk1", the from-table is "ex1" and the to-table is "ex2".
**
** Each REFERENCES clause generates an instance of the following structure
** which is attached to the from-table.  The to-table need not exist when
** the from-table is created.  The existence of the to-table is not checked.
*/
struct FKey {
  Table *pFrom;     /* The table that contains the REFERENCES clause */
  Table *pFrom;     /* Table containing the REFERENCES clause (aka: Child) */
  FKey *pNextFrom;  /* Next foreign key in pFrom */
  char *zTo;        /* Name of table that the key points to */
  char *zTo;        /* Name of table that the key points to (aka: Parent) */
  FKey *pNextTo;    /* Next foreign key on table named zTo */
  FKey *pPrevTo;    /* Previous foreign key on table named zTo */
  int nCol;         /* Number of columns in this key */
  /* EV: R-30323-21917 */
  u8 isDeferred;    /* True if constraint checking is deferred till COMMIT */
  u8 updateConf;    /* How to resolve conflicts that occur on UPDATE */
  u8 aAction[2];          /* ON DELETE and ON UPDATE actions, respectively */
  u8 deleteConf;    /* How to resolve conflicts that occur on DELETE */
  u8 insertConf;    /* How to resolve conflicts that occur on INSERT */
  Trigger *apTrigger[2];  /* Triggers for aAction[] actions */
  struct sColMap {  /* Mapping of columns in pFrom to columns in zTo */
    int iFrom;         /* Index of column in pFrom */
    char *zCol;        /* Name of column in zTo.  If 0 use PRIMARY KEY */
  } aCol[1];        /* One entry for each of nCol column s */
};

/*
1356
1357
1358
1359
1360
1361
1362














1363
1364
1365
1366
1367
1368
1369
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448







+
+
+
+
+
+
+
+
+
+
+
+
+
+







  u8 onError;      /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  u8 autoIndex;    /* True if is automatically created (ex: by UNIQUE) */
  char *zColAff;   /* String defining the affinity of each column */
  Index *pNext;    /* The next index associated with the same table */
  Schema *pSchema; /* Schema containing this index */
  u8 *aSortOrder;  /* Array of size Index.nColumn. True==DESC, False==ASC */
  char **azColl;   /* Array of collation sequence names for index */
  IndexSample *aSample;    /* Array of SQLITE_INDEX_SAMPLES samples */
};

/*
** Each sample stored in the sqlite_stat2 table is represented in memory 
** using a structure of this type.
*/
struct IndexSample {
  union {
    char *z;        /* Value if eType is SQLITE_TEXT or SQLITE_BLOB */
    double r;       /* Value if eType is SQLITE_FLOAT or SQLITE_INTEGER */
  } u;
  u8 eType;         /* SQLITE_NULL, SQLITE_INTEGER ... etc. */
  u8 nByte;         /* Size in byte of text or blob. */
};

/*
** Each token coming out of the lexer is an instance of
** this structure.  Tokens are also used as part of an expression.
**
** Note if Token.z==0 then Token.dyn and Token.n are undefined and
1415
1416
1417
1418
1419
1420
1421
















1422
1423
1424
1425
1426
1427
1428
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    int iMem;                /* Memory location that acts as accumulator */
    int iDistinct;           /* Ephemeral table used to enforce DISTINCT */
  } *aFunc;
  int nFunc;              /* Number of entries in aFunc[] */
  int nFuncAlloc;         /* Number of slots allocated for aFunc[] */
};

/*
** The datatype ynVar is a signed integer, either 16-bit or 32-bit.
** Usually it is 16-bits.  But if SQLITE_MAX_VARIABLE_NUMBER is greater
** than 32767 we have to make it 32-bit.  16-bit is preferred because
** it uses less memory in the Expr object, which is a big memory user
** in systems with lots of prepared statements.  And few applications
** need more than about 10 or 20 variables.  But some extreme users want
** to have prepared statements with over 32767 variables, and for them
** the option is available (at compile-time).
*/
#if SQLITE_MAX_VARIABLE_NUMBER<=32767
typedef i16 ynVar;
#else
typedef int ynVar;
#endif

/*
** Each node of an expression in the parse tree is an instance
** of this structure.
**
** Expr.op is the opcode. The integer parser token codes are reused
** as opcodes here. For example, the parser defines TK_GE to be an integer
** code representing the ">=" operator. This same integer code is reused
1506
1507
1508
1509
1510
1511
1512
1513
1514




1515
1516
1517


1518
1519
1520
1521
1522
1523
1524
1601
1602
1603
1604
1605
1606
1607


1608
1609
1610
1611
1612
1613

1614
1615
1616
1617
1618
1619
1620
1621
1622







-
-
+
+
+
+


-
+
+








  /* If the EP_Reduced flag is set in the Expr.flags mask, then no
  ** space is allocated for the fields below this point. An attempt to
  ** access them will result in a segfault or malfunction.
  *********************************************************************/

  int iTable;            /* TK_COLUMN: cursor number of table holding column
                         ** TK_REGISTER: register number */
  int iColumn;           /* TK_COLUMN: column index.  -1 for rowid */
                         ** TK_REGISTER: register number
                         ** TK_TRIGGER: 1 -> new, 0 -> old */
  ynVar iColumn;         /* TK_COLUMN: column index.  -1 for rowid.
                         ** TK_VARIABLE: variable number (always >= 1). */
  i16 iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
  i16 iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
  u16 flags2;            /* Second set of flags.  EP2_... */
  u8 flags2;             /* Second set of flags.  EP2_... */
  u8 op2;                /* If a TK_REGISTER, the original value of Expr.op */
  AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
  Table *pTab;           /* Table for TK_COLUMN expressions. */
#if SQLITE_MAX_EXPR_DEPTH>0
  int nHeight;           /* Height of the tree headed by this node */
#endif
};

1944
1945
1946
1947
1948
1949
1950

























1951
1952
1953
1954
1955
1956
1957
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







/*
** Size of the column cache
*/
#ifndef SQLITE_N_COLCACHE
# define SQLITE_N_COLCACHE 10
#endif

/*
** At least one instance of the following structure is created for each 
** trigger that may be fired while parsing an INSERT, UPDATE or DELETE
** statement. All such objects are stored in the linked list headed at
** Parse.pTriggerPrg and deleted once statement compilation has been
** completed.
**
** A Vdbe sub-program that implements the body and WHEN clause of trigger
** TriggerPrg.pTrigger, assuming a default ON CONFLICT clause of
** TriggerPrg.orconf, is stored in the TriggerPrg.pProgram variable.
** The Parse.pTriggerPrg list never contains two entries with the same
** values for both pTrigger and orconf.
**
** The TriggerPrg.oldmask variable is set to a mask of old.* columns
** accessed (or set to 0 for triggers fired as a result of INSERT 
** statements).
*/
struct TriggerPrg {
  Trigger *pTrigger;      /* Trigger this program was coded from */
  int orconf;             /* Default ON CONFLICT policy */
  SubProgram *pProgram;   /* Program implementing pTrigger/orconf */
  u32 oldmask;            /* Mask of old.* columns accessed */
  TriggerPrg *pNext;      /* Next entry in Parse.pTriggerPrg list */
};

/*
** An SQL parser context.  A copy of this structure is passed through
** the parser and down into all the parser action routine in order to
** carry around information that is global to the entire parse.
**
** The structure is divided into two parts.  When the parser and code
** generate call themselves recursively, the first part of the structure
1995
1996
1997
1998
1999
2000
2001


2002
2003
2004
2005
2006
2007
2008
2009
2010









2011
2012
2013
2014
2015
2016
2017
2018

2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039

2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064






2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082

2083
2084
2085
2086
2087
2088
2089
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157

2158
2159

2160
2161
2162

2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192





2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215

2216
2217
2218
2219
2220
2221
2222
2223







+
+









+
+
+
+
+
+
+
+
+








+




-


-



-









+




















-
-
-
-
-
+
+
+
+
+
+

















-
+







    u8 tempReg;           /* iReg is a temp register that needs to be freed */
    int iLevel;           /* Nesting level */
    int iReg;             /* Reg with value of this column. 0 means none. */
    int lru;              /* Least recently used entry has the smallest value */
  } aColCache[SQLITE_N_COLCACHE];  /* One for each column cache entry */
  u32 writeMask;       /* Start a write transaction on these databases */
  u32 cookieMask;      /* Bitmask of schema verified databases */
  u8 isMultiWrite;     /* True if statement may affect/insert multiple rows */
  u8 mayAbort;         /* True if statement may throw an ABORT exception */
  int cookieGoto;      /* Address of OP_Goto to cookie verifier subroutine */
  int cookieValue[SQLITE_MAX_ATTACHED+2];  /* Values of cookies to verify */
#ifndef SQLITE_OMIT_SHARED_CACHE
  int nTableLock;        /* Number of locks in aTableLock */
  TableLock *aTableLock; /* Required table locks for shared-cache mode */
#endif
  int regRowid;        /* Register holding rowid of CREATE TABLE entry */
  int regRoot;         /* Register holding root page number for new objects */
  AutoincInfo *pAinc;  /* Information about AUTOINCREMENT counters */
  int nMaxArg;         /* Max args passed to user function by sub-program */

  /* Information used while coding trigger programs. */
  Parse *pToplevel;    /* Parse structure for main program (or NULL) */
  Table *pTriggerTab;  /* Table triggers are being coded for */
  u32 oldmask;         /* Mask of old.* columns referenced */
  u8 eTriggerOp;       /* TK_UPDATE, TK_INSERT or TK_DELETE */
  u8 eOrconf;          /* Default ON CONFLICT policy for trigger steps */
  u8 disableTriggers;  /* True to disable triggers */

  /* Above is constant between recursions.  Below is reset before and after
  ** each recursion */

  int nVar;            /* Number of '?' variables seen in the SQL so far */
  int nVarExpr;        /* Number of used slots in apVarExpr[] */
  int nVarExprAlloc;   /* Number of allocated slots in apVarExpr[] */
  Expr **apVarExpr;    /* Pointers to :aaa and $aaaa wildcard expressions */
  Vdbe *pReprepare;    /* VM being reprepared (sqlite3Reprepare()) */
  int nAlias;          /* Number of aliased result set columns */
  int nAliasAlloc;     /* Number of allocated slots for aAlias[] */
  int *aAlias;         /* Register used to hold aliased result */
  u8 explain;          /* True if the EXPLAIN flag is found on the query */
  Token sErrToken;     /* The token at which the error occurred */
  Token sNameToken;    /* Token with unqualified schema object name */
  Token sLastToken;    /* The last token parsed */
  const char *zSql;    /* All SQL text */
  const char *zTail;   /* All SQL text past the last semicolon parsed */
  Table *pNewTable;    /* A table being constructed by CREATE TABLE */
  Trigger *pNewTrigger;     /* Trigger under construct by a CREATE TRIGGER */
  TriggerStack *trigStack;  /* Trigger actions being coded */
  const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
#ifndef SQLITE_OMIT_VIRTUALTABLE
  Token sArg;                /* Complete text of a module argument */
  u8 declareVtab;            /* True if inside sqlite3_declare_vtab() */
  int nVtabLock;             /* Number of virtual tables to lock */
  Table **apVtabLock;        /* Pointer to virtual tables needing locking */
#endif
  int nHeight;            /* Expression tree height of current sub-select */
  Table *pZombieTab;      /* List of Table objects to delete after code gen */
  TriggerPrg *pTriggerPrg;    /* Linked list of coded triggers */
};

#ifdef SQLITE_OMIT_VIRTUALTABLE
  #define IN_DECLARE_VTAB 0
#else
  #define IN_DECLARE_VTAB (pParse->declareVtab)
#endif

/*
** An instance of the following structure can be declared on a stack and used
** to save the Parse.zAuthContext value so that it can be restored later.
*/
struct AuthContext {
  const char *zAuthContext;   /* Put saved Parse.zAuthContext here */
  Parse *pParse;              /* The Parse structure */
};

/*
** Bitfield flags for P5 value in OP_Insert and OP_Delete
*/
#define OPFLAG_NCHANGE    1    /* Set to update db->nChange */
#define OPFLAG_LASTROWID  2    /* Set to update db->lastRowid */
#define OPFLAG_ISUPDATE   4    /* This OP_Insert is an sql UPDATE */
#define OPFLAG_APPEND     8    /* This is likely to be an append */
#define OPFLAG_USESEEKRESULT 16    /* Try to avoid a seek in BtreeInsert() */
#define OPFLAG_NCHANGE       0x01    /* Set to update db->nChange */
#define OPFLAG_LASTROWID     0x02    /* Set to update db->lastRowid */
#define OPFLAG_ISUPDATE      0x04    /* This OP_Insert is an sql UPDATE */
#define OPFLAG_APPEND        0x08    /* This is likely to be an append */
#define OPFLAG_USESEEKRESULT 0x10    /* Try to avoid a seek in BtreeInsert() */
#define OPFLAG_CLEARCACHE    0x20    /* Clear pseudo-table cache in OP_Column */

/*
 * Each trigger present in the database schema is stored as an instance of
 * struct Trigger. 
 *
 * Pointers to instances of struct Trigger are stored in two ways.
 * 1. In the "trigHash" hash table (part of the sqlite3* that represents the 
 *    database). This allows Trigger structures to be retrieved by name.
 * 2. All triggers associated with a single table form a linked list, using the
 *    pNext member of struct Trigger. A pointer to the first element of the
 *    linked list is stored as the "pTrigger" member of the associated
 *    struct Table.
 *
 * The "step_list" member points to the first element of a linked list
 * containing the SQL statements specified as the trigger program.
 */
struct Trigger {
  char *name;             /* The name of the trigger                        */
  char *zName;            /* The name of the trigger                        */
  char *table;            /* The table or view to which the trigger applies */
  u8 op;                  /* One of TK_DELETE, TK_UPDATE, TK_INSERT         */
  u8 tr_tm;               /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
  Expr *pWhen;            /* The WHEN clause of the expression (may be NULL) */
  IdList *pColumns;       /* If this is an UPDATE OF <column-list> trigger,
                             the <column-list> is stored here */
  Schema *pSchema;        /* Schema containing the trigger */
2137
2138
2139
2140
2141
2142
2143
2144
2145


2146
2147
2148

2149
2150
2151
2152



2153
2154

2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2271
2272
2273
2274
2275
2276
2277


2278
2279
2280


2281




2282
2283
2284


2285
2286
2287
2288
2289







































2290
2291
2292
2293
2294
2295
2296







-
-
+
+

-
-
+
-
-
-
-
+
+
+
-
-
+




-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







 *              Otherwise NULL.
 * pExprList -> A list of the columns to update and the expressions to update
 *              them to. See sqlite3Update() documentation of "pChanges"
 *              argument.
 * 
 */
struct TriggerStep {
  int op;              /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
  int orconf;          /* OE_Rollback etc. */
  u8 op;               /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
  u8 orconf;           /* OE_Rollback etc. */
  Trigger *pTrig;      /* The trigger that this step is a part of */

  Select *pSelect;     /* Valid for SELECT and sometimes 
  Select *pSelect;     /* SELECT statment or RHS of INSERT INTO .. SELECT ... */
                          INSERT steps (when pExprList == 0) */
  Token target;        /* Target table for DELETE, UPDATE, INSERT.  Quoted */
  Expr *pWhere;        /* Valid for DELETE, UPDATE steps */
  ExprList *pExprList; /* Valid for UPDATE statements and sometimes 
  Token target;        /* Target table for DELETE, UPDATE, INSERT */
  Expr *pWhere;        /* The WHERE clause for DELETE or UPDATE steps */
  ExprList *pExprList; /* SET clause for UPDATE.  VALUES clause for INSERT */
                           INSERT steps (when pSelect == 0)         */
  IdList *pIdList;     /* Valid for INSERT statements only */
  IdList *pIdList;     /* Column names for INSERT */
  TriggerStep *pNext;  /* Next in the link-list */
  TriggerStep *pLast;  /* Last element in link-list. Valid for 1st elem only */
};

/*
 * An instance of struct TriggerStack stores information required during code
 * generation of a single trigger program. While the trigger program is being
 * coded, its associated TriggerStack instance is pointed to by the
 * "pTriggerStack" member of the Parse structure.
 *
 * The pTab member points to the table that triggers are being coded on. The 
 * newIdx member contains the index of the vdbe cursor that points at the temp
 * table that stores the new.* references. If new.* references are not valid
 * for the trigger being coded (for example an ON DELETE trigger), then newIdx
 * is set to -1. The oldIdx member is analogous to newIdx, for old.* references.
 *
 * The ON CONFLICT policy to be used for the trigger program steps is stored 
 * as the orconf member. If this is OE_Default, then the ON CONFLICT clause 
 * specified for individual triggers steps is used.
 *
 * struct TriggerStack has a "pNext" member, to allow linked lists to be
 * constructed. When coding nested triggers (triggers fired by other triggers)
 * each nested trigger stores its parent trigger's TriggerStack as the "pNext" 
 * pointer. Once the nested trigger has been coded, the pNext value is restored
 * to the pTriggerStack member of the Parse stucture and coding of the parent
 * trigger continues.
 *
 * Before a nested trigger is coded, the linked list pointed to by the 
 * pTriggerStack is scanned to ensure that the trigger is not about to be coded
 * recursively. If this condition is detected, the nested trigger is not coded.
 */
struct TriggerStack {
  Table *pTab;         /* Table that triggers are currently being coded on */
  int newIdx;          /* Index of vdbe cursor to "new" temp table */
  int oldIdx;          /* Index of vdbe cursor to "old" temp table */
  u32 newColMask;
  u32 oldColMask;
  int orconf;          /* Current orconf policy */
  int ignoreJump;      /* where to jump to for a RAISE(IGNORE) */
  Trigger *pTrigger;   /* The trigger currently being coded */
  TriggerStack *pNext; /* Next trigger down on the trigger stack */
};

/*
** The following structure contains information used by the sqliteFix...
** routines as they walk the parse tree to make database references
** explicit.  
*/
typedef struct DbFixer DbFixer;
struct DbFixer {
2261
2262
2263
2264
2265
2266
2267

2268

2269
2270
2271
2272
2273
2274
2275
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369







+

+







  int nPage;                        /* Number of pages in pPage[] */
  int mxParserStack;                /* maximum depth of the parser stack */
  int sharedCacheEnabled;           /* true if shared-cache mode enabled */
  /* The above might be initialized to non-zero.  The following need to always
  ** initially be zero, however. */
  int isInit;                       /* True after initialization has finished */
  int inProgress;                   /* True while initialization in progress */
  int isMutexInit;                  /* True after mutexes are initialized */
  int isMallocInit;                 /* True after malloc is initialized */
  int isPCacheInit;                 /* True after malloc is initialized */
  sqlite3_mutex *pInitMutex;        /* Mutex used by sqlite3_initialize() */
  int nRefInitMutex;                /* Number of users of pInitMutex */
};

/*
** Context pointer passed down through the tree-walk.
*/
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362

2363
2364
2365
2366
2367
2368
2369
2447
2448
2449
2450
2451
2452
2453

2454
2455
2456
2457
2458
2459
2460
2461
2462
2463







-


+







# define sqlite3Tolower(x)   tolower((unsigned char)(x))
#endif

/*
** Internal function prototypes
*/
int sqlite3StrICmp(const char *, const char *);
int sqlite3StrNICmp(const char *, const char *, int);
int sqlite3IsNumber(const char*, int*, u8);
int sqlite3Strlen30(const char*);
#define sqlite3StrNICmp sqlite3_strnicmp

int sqlite3MallocInit(void);
void sqlite3MallocEnd(void);
void *sqlite3Malloc(int);
void *sqlite3MallocZero(int);
void *sqlite3DbMallocZero(sqlite3*, int);
void *sqlite3DbMallocRaw(sqlite3*, int);
2515
2516
2517
2518
2519
2520
2521
2522

2523
2524
2525
2526
2527
2528
2529
2609
2610
2611
2612
2613
2614
2615

2616
2617
2618
2619
2620
2621
2622
2623







-
+







                                      Token*, Select*, Expr*, IdList*);
void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
int sqlite3IndexedByLookup(Parse *, struct SrcList_item *);
void sqlite3SrcListShiftJoinType(SrcList*);
void sqlite3SrcListAssignCursors(Parse*, SrcList*);
void sqlite3IdListDelete(sqlite3*, IdList*);
void sqlite3SrcListDelete(sqlite3*, SrcList*);
void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
                        Token*, int, int);
void sqlite3DropIndex(Parse*, SrcList*, int);
int sqlite3Select(Parse*, Select*, SelectDest*);
Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
                         Expr*,ExprList*,int,Expr*,Expr*);
void sqlite3SelectDelete(sqlite3*, Select*);
Table *sqlite3SrcListLookup(Parse*, SrcList*);
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585

2586
2587
2588
2589
2590

2591
2592



2593
2594
2595
2596
2597
2598
2599
2656
2657
2658
2659
2660
2661
2662

2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677

2678
2679
2680
2681
2682

2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695







-















-
+




-
+


+
+
+







void sqlite3Vacuum(Parse*);
int sqlite3RunVacuum(char**, sqlite3*);
char *sqlite3NameFromToken(sqlite3*, Token*);
int sqlite3ExprCompare(Expr*, Expr*);
void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
Vdbe *sqlite3GetVdbe(Parse*);
Expr *sqlite3CreateIdExpr(Parse *, const char*);
void sqlite3PrngSaveState(void);
void sqlite3PrngRestoreState(void);
void sqlite3PrngResetState(void);
void sqlite3RollbackAll(sqlite3*);
void sqlite3CodeVerifySchema(Parse*, int);
void sqlite3BeginTransaction(Parse*, int);
void sqlite3CommitTransaction(Parse*);
void sqlite3RollbackTransaction(Parse*);
void sqlite3Savepoint(Parse*, int, Token*);
void sqlite3CloseSavepoints(sqlite3 *);
int sqlite3ExprIsConstant(Expr*);
int sqlite3ExprIsConstantNotJoin(Expr*);
int sqlite3ExprIsConstantOrFunction(Expr*);
int sqlite3ExprIsInteger(Expr*, int*);
int sqlite3IsRowid(const char*);
void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int);
void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*);
int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int);
void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
                                     int*,int,int,int,int,int*);
void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int,int,int);
void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
void sqlite3BeginWriteOperation(Parse*, int, int);
void sqlite3MultiWrite(Parse*);
void sqlite3MayAbort(Parse*);
void sqlite3HaltConstraint(Parse*, int, char*, int);
Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
IdList *sqlite3IdListDup(sqlite3*,IdList*);
Select *sqlite3SelectDup(sqlite3*,Select*,int);
void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,int);
2619
2620
2621
2622
2623
2624
2625
2626
2627



2628
2629
2630
2631
2632
2633


2634
2635
2636


2637
2638
2639
2640
2641
2642


2643


2644
2645
2646
2647
2648
2649
2650
2651
2652
2653

2654
2655
2656
2657
2658
2659
2660
2661
2662

2663
2664
2665
2666
2667
2668
2669
2715
2716
2717
2718
2719
2720
2721


2722
2723
2724
2725
2726
2727
2728


2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740

2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764

2765
2766
2767
2768
2769
2770
2771
2772







-
-
+
+
+




-
-
+
+



+
+





-
+
+

+
+










+








-
+







  void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*,
                           Expr*,int, int);
  void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*);
  void sqlite3DropTrigger(Parse*, SrcList*, int);
  void sqlite3DropTriggerPtr(Parse*, Trigger*);
  Trigger *sqlite3TriggersExist(Parse *, Table*, int, ExprList*, int *pMask);
  Trigger *sqlite3TriggerList(Parse *, Table *);
  int sqlite3CodeRowTrigger(Parse*, Trigger *, int, ExprList*, int, Table *,
                            int, int, int, int, u32*, u32*);
  void sqlite3CodeRowTrigger(Parse*, Trigger *, int, ExprList*, int, Table *,
                            int, int, int);
  void sqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, int, int, int);
  void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*);
  void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*);
  TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*);
  TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*,
                                        ExprList*,Select*,int);
  TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, int);
                                        ExprList*,Select*,u8);
  TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8);
  TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*);
  void sqlite3DeleteTrigger(sqlite3*, Trigger*);
  void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*);
  u32 sqlite3TriggerOldmask(Parse*,Trigger*,ExprList*,Table*,int);
# define sqlite3ParseToplevel(p) ((p)->pToplevel ? (p)->pToplevel : (p))
#else
# define sqlite3TriggersExist(B,C,D,E,F) 0
# define sqlite3DeleteTrigger(A,B)
# define sqlite3DropTriggerPtr(A,B)
# define sqlite3UnlinkAndDeleteTrigger(A,B,C)
# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I,J,K,L) 0
# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I)
# define sqlite3CodeRowTriggerDirect(A,B,C,D,E,F)
# define sqlite3TriggerList(X, Y) 0
# define sqlite3ParseToplevel(p) p
# define sqlite3TriggerOldmask(A,B,C,D,E) 0
#endif

int sqlite3JoinType(Parse*, Token*, Token*, Token*);
void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int);
void sqlite3DeferForeignKey(Parse*, int);
#ifndef SQLITE_OMIT_AUTHORIZATION
  void sqlite3AuthRead(Parse*,Expr*,Schema*,SrcList*);
  int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*);
  void sqlite3AuthContextPush(Parse*, AuthContext*, const char*);
  void sqlite3AuthContextPop(AuthContext*);
  int sqlite3AuthReadCol(Parse*, const char *, const char *, int);
#else
# define sqlite3AuthRead(a,b,c,d)
# define sqlite3AuthCheck(a,b,c,d,e)    SQLITE_OK
# define sqlite3AuthContextPush(a,b,c)
# define sqlite3AuthContextPop(a)  ((void)(a))
#endif
void sqlite3Attach(Parse*, Expr*, Expr*, Expr*);
void sqlite3Detach(Parse*, Expr*);
int sqlite3BtreeFactory(const sqlite3 *db, const char *zFilename,
int sqlite3BtreeFactory(sqlite3 *db, const char *zFilename,
                       int omitJournal, int nCache, int flags, Btree **ppBtree);
int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
int sqlite3FixSrcList(DbFixer*, SrcList*);
int sqlite3FixSelect(DbFixer*, Select*);
int sqlite3FixExpr(DbFixer*, Expr*);
int sqlite3FixExprList(DbFixer*, ExprList*);
int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
2706
2707
2708
2709
2710
2711
2712
2713

2714
2715
2716
2717
2718
2719
2720
2809
2810
2811
2812
2813
2814
2815

2816
2817
2818
2819
2820
2821
2822
2823







-
+







*/
#define getVarint32(A,B)  (u8)((*(A)<(u8)0x80) ? ((B) = (u32)*(A)),1 : sqlite3GetVarint32((A), (u32 *)&(B)))
#define putVarint32(A,B)  (u8)(((u32)(B)<(u32)0x80) ? (*(A) = (unsigned char)(B)),1 : sqlite3PutVarint32((A), (B)))
#define getVarint    sqlite3GetVarint
#define putVarint    sqlite3PutVarint


void sqlite3IndexAffinityStr(Vdbe *, Index *);
const char *sqlite3IndexAffinityStr(Vdbe *, Index *);
void sqlite3TableAffinityStr(Vdbe *, Table *);
char sqlite3CompareAffinity(Expr *pExpr, char aff2);
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
char sqlite3ExprAffinity(Expr *pExpr);
int sqlite3Atoi64(const char*, i64*);
void sqlite3Error(sqlite3*, int, const char*,...);
void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
2732
2733
2734
2735
2736
2737
2738



2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755

2756
2757
2758
2759
2760

2761
2762
2763

2764
2765
2766
2767
2768
2769

2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788

2789
2790
2791
2792
2793
2794
2795
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860

2861
2862
2863
2864
2865

2866
2867
2868

2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903







+
+
+
















-
+




-
+


-
+






+



















+







const void *sqlite3ValueText(sqlite3_value*, u8);
int sqlite3ValueBytes(sqlite3_value*, u8);
void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, 
                        void(*)(void*));
void sqlite3ValueFree(sqlite3_value*);
sqlite3_value *sqlite3ValueNew(sqlite3 *);
char *sqlite3Utf16to8(sqlite3 *, const void*, int);
#ifdef SQLITE_ENABLE_STAT2
char *sqlite3Utf8to16(sqlite3 *, u8, char *, int, int *);
#endif
int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
#ifndef SQLITE_AMALGAMATION
extern const unsigned char sqlite3UpperToLower[];
extern const unsigned char sqlite3CtypeMap[];
extern SQLITE_WSD struct Sqlite3Config sqlite3Config;
extern SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
extern int sqlite3PendingByte;
#endif
void sqlite3RootPageMoved(Db*, int, int);
void sqlite3Reindex(Parse*, Token*, Token*);
void sqlite3AlterFunctions(sqlite3*);
void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
int sqlite3GetToken(const unsigned char *, int *);
void sqlite3NestedParse(Parse*, const char*, ...);
void sqlite3ExpirePreparedStatements(sqlite3*);
void sqlite3CodeSubselect(Parse *, Expr *, int, int);
int sqlite3CodeSubselect(Parse *, Expr *, int, int);
void sqlite3SelectPrep(Parse*, Select*, NameContext*);
int sqlite3ResolveExprNames(NameContext*, Expr*);
void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
void sqlite3ColumnDefault(Vdbe *, Table *, int);
void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
void sqlite3AlterFinishAddColumn(Parse *, Token *);
void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
CollSeq *sqlite3GetCollSeq(sqlite3*, CollSeq *, const char*);
CollSeq *sqlite3GetCollSeq(sqlite3*, u8, CollSeq *, const char*);
char sqlite3AffinityType(const char*);
void sqlite3Analyze(Parse*, Token*, Token*);
int sqlite3InvokeBusyHandler(BusyHandler*);
int sqlite3FindDb(sqlite3*, Token*);
int sqlite3FindDbName(sqlite3 *, const char *);
int sqlite3AnalysisLoad(sqlite3*,int iDB);
void sqlite3DeleteIndexSamples(Index*);
void sqlite3DefaultRowEst(Index*);
void sqlite3RegisterLikeFunctions(sqlite3*, int);
int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
void sqlite3MinimumFileFormat(Parse*, int, int);
void sqlite3SchemaFree(void *);
Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, 
  void (*)(sqlite3_context*,int,sqlite3_value **),
  void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*));
int sqlite3ApiExit(sqlite3 *db, int);
int sqlite3OpenTempDatabase(Parse *);

void sqlite3StrAccumInit(StrAccum*, char*, int, int);
void sqlite3StrAccumAppend(StrAccum*,const char*,int);
char *sqlite3StrAccumFinish(StrAccum*);
void sqlite3StrAccumReset(StrAccum*);
void sqlite3SelectDestInit(SelectDest*,int,int);
Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);

void sqlite3BackupRestart(sqlite3_backup *);
void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);

/*
** The interface to the LEMON-generated parser
*/
2814
2815
2816
2817
2818
2819
2820
2821

2822
2823
2824
2825



2826
2827
2828
2829
2830



2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843

2844
2845
2846
2847
2848
2849
2850

2851


























2852
2853
2854
2855
2856
2857
2858
2922
2923
2924
2925
2926
2927
2928

2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947


2948
2949
2950
2951
2952
2953
2954

2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997







-
+




+
+
+





+
+
+



-
-







-
+







+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







#endif

#ifdef SQLITE_TEST
  int sqlite3Utf8To8(unsigned char*);
#endif

#ifdef SQLITE_OMIT_VIRTUALTABLE
#  define sqlite3VtabClear(X)
#  define sqlite3VtabClear(Y)
#  define sqlite3VtabSync(X,Y) SQLITE_OK
#  define sqlite3VtabRollback(X)
#  define sqlite3VtabCommit(X)
#  define sqlite3VtabInSync(db) 0
#  define sqlite3VtabLock(X) 
#  define sqlite3VtabUnlock(X)
#  define sqlite3VtabUnlockList(X)
#else
   void sqlite3VtabClear(Table*);
   int sqlite3VtabSync(sqlite3 *db, char **);
   int sqlite3VtabRollback(sqlite3 *db);
   int sqlite3VtabCommit(sqlite3 *db);
   void sqlite3VtabLock(VTable *);
   void sqlite3VtabUnlock(VTable *);
   void sqlite3VtabUnlockList(sqlite3*);
#  define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
#endif
void sqlite3VtabMakeWritable(Parse*,Table*);
void sqlite3VtabLock(sqlite3_vtab*);
void sqlite3VtabUnlock(sqlite3*, sqlite3_vtab*);
void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*);
void sqlite3VtabFinishParse(Parse*, Token*);
void sqlite3VtabArgInit(Parse*);
void sqlite3VtabArgExtend(Parse*, Token*);
int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **);
int sqlite3VtabCallConnect(Parse*, Table*);
int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
int sqlite3VtabBegin(sqlite3 *, sqlite3_vtab *);
int sqlite3VtabBegin(sqlite3 *, VTable *);
FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**);
int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
int sqlite3Reprepare(Vdbe*);
void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
int sqlite3TempInMemory(const sqlite3*);
VTable *sqlite3GetVTable(sqlite3*, Table*);

/* Declarations for functions in fkey.c. All of these are replaced by
** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign
** key functionality is available. If OMIT_TRIGGER is defined but
** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In
** this case foreign keys are parsed, but no other functionality is 
** provided (enforcement of FK constraints requires the triggers sub-system).
*/
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
  void sqlite3FkCheck(Parse*, Table*, int, int);
  void sqlite3FkDropTable(Parse*, SrcList *, Table*);
  void sqlite3FkActions(Parse*, Table*, ExprList*, int);
  int sqlite3FkRequired(Parse*, Table*, int*, int);
  u32 sqlite3FkOldmask(Parse*, Table*);
  FKey *sqlite3FkReferences(Table *);
#else
  #define sqlite3FkActions(a,b,c,d)
  #define sqlite3FkCheck(a,b,c,d)
  #define sqlite3FkDropTable(a,b,c)
  #define sqlite3FkOldmask(a,b)      0
  #define sqlite3FkRequired(a,b,c,d) 0
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
  void sqlite3FkDelete(Table*);
#else
  #define sqlite3FkDelete(a)
#endif


/*
** Available fault injectors.  Should be numbered beginning with 0.
*/
#define SQLITE_FAULTINJECTOR_MALLOC     0
#define SQLITE_FAULTINJECTOR_COUNT      1
Changes to src/sqliteLimit.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2007 May 7
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** 
** This file defines various limits of what SQLite can process.
**
** @(#) $Id: sqliteLimit.h,v 1.10 2009/01/10 16:15:09 danielk1977 Exp $
*/

/*
** The maximum length of a TEXT or BLOB in bytes.   This also
** limits the size of a row in a table or index.
**
** The hard limit is the ability of a 32-bit signed integer
184
185
186
187
188
189
190











182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199







+
+
+
+
+
+
+
+
+
+
+
/*
** Maximum length (in bytes) of the pattern in a LIKE or GLOB
** operator.
*/
#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH
# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000
#endif

/*
** Maximum depth of recursion for triggers.
**
** A value of 1 means that a trigger program will not be able to itself
** fire any triggers. A value of 0 means that no trigger programs at all 
** may be executed.
*/
#ifndef SQLITE_MAX_TRIGGER_DEPTH
# define SQLITE_MAX_TRIGGER_DEPTH 1000
#endif
Changes to src/status.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
8
9
10
11
12
13
14


15
16
17
18
19
20
21







-
-







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This module implements the sqlite3_status() interface and related
** functionality.
**
** $Id: status.c,v 1.9 2008/09/02 00:52:52 drh Exp $
*/
#include "sqliteInt.h"

/*
** Variables in which to record status information.
*/
typedef struct sqlite3StatType sqlite3StatType;
Changes to src/table.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
11
12
13
14
15
16
17


18
19
20
21
22
23
24







-
-







*************************************************************************
** This file contains the sqlite3_get_table() and sqlite3_free_table()
** interface routines.  These are just wrappers around the main
** interface routine of sqlite3_exec().
**
** These routines are in a separate files so that they will not be linked
** if they are not used.
**
** $Id: table.c,v 1.40 2009/04/10 14:28:00 drh Exp $
*/
#include "sqliteInt.h"
#include <stdlib.h>
#include <string.h>

#ifndef SQLITE_OMIT_GET_TABLE

Changes to src/tclsqlite.c.
8
9
10
11
12
13
14
15












16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

31
32
33
34
35
36
37
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48







-
+
+
+
+
+
+
+
+
+
+
+
+













-

+







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** A TCL Interface to SQLite.  Append this file to sqlite3.c and
** compile the whole thing to build a TCL-enabled version of SQLite.
**
** $Id: tclsqlite.c,v 1.241 2009/03/27 12:44:35 drh Exp $
** Compile-time options:
**
**  -DTCLSH=1             Add a "main()" routine that works as a tclsh.
**
**  -DSQLITE_TCLMD5       When used in conjuction with -DTCLSH=1, add
**                        four new commands to the TCL interpreter for
**                        generating MD5 checksums:  md5, md5file,
**                        md5-10x8, and md5file-10x8.
**
**  -DSQLITE_TEST         When used in conjuction with -DTCLSH=1, add
**                        hundreds of new commands used for testing
**                        SQLite.  This option implies -DSQLITE_TCLMD5.
*/
#include "tcl.h"
#include <errno.h>

/*
** Some additional include files are needed if this file is not
** appended to the amalgamation.
*/
#ifndef SQLITE_AMALGAMATION
# include "sqliteInt.h"
# include <stdlib.h>
# include <string.h>
# include <assert.h>
# include <ctype.h>
#endif
#include <ctype.h>

/*
 * Windows needs to know which symbols to export.  Unix does not.
 * BUILD_sqlite should be undefined for Unix.
 */
#ifdef BUILD_sqlite
#undef TCL_STORAGE_CLASS
82
83
84
85
86
87
88


89
90
91
92
93
94
95
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108







+
+







typedef struct SqlPreparedStmt SqlPreparedStmt;
struct SqlPreparedStmt {
  SqlPreparedStmt *pNext;  /* Next in linked list */
  SqlPreparedStmt *pPrev;  /* Previous on the list */
  sqlite3_stmt *pStmt;     /* The prepared statement */
  int nSql;                /* chars in zSql[] */
  const char *zSql;        /* Text of the SQL statement */
  int nParm;               /* Size of apParm array */
  Tcl_Obj **apParm;        /* Array of referenced object pointers */
};

typedef struct IncrblobChannel IncrblobChannel;

/*
** There is one instance of this structure for each SQLite database
** that has been opened by the SQLite TCL interface.
753
754
755
756
757
758
759
760

761
762
763
764
765
766
767
766
767
768
769
770
771
772

773
774
775
776
777
778
779
780







-
+








  if( rc && rc!=TCL_RETURN ){
    sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); 
  }else{
    Tcl_Obj *pVar = Tcl_GetObjResult(p->interp);
    int n;
    u8 *data;
    char *zType = pVar->typePtr ? pVar->typePtr->name : "";
    const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
    char c = zType[0];
    if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){
      /* Only return a BLOB type if the Tcl variable is a bytearray and
      ** has no string representation. */
      data = Tcl_GetByteArrayFromObj(pVar, &n);
      sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT);
    }else if( c=='b' && strcmp(zType,"boolean")==0 ){
930
931
932
933
934
935
936





















937
938
939
940
941
942
943






















































































































































































944










945
946













































































947
948
949
950
951
952




953
954
955
956

957
958
959
960
961




962




963
964
















965






966
967


968
969
970
971
972






973
974
975
976
977
978


979
980
981

982
983
984
985
986
987
988
989
990















































































































































































































991
992
993

994
995
996
997
998
999
1000
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970







971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163


1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243



1244
1245
1246
1247
1248
1249
1250

1251





1252
1253
1254
1255
1256
1257
1258
1259
1260


1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283


1284
1285





1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296

1297
1298
1299
1300

1301
1302
1303
1304
1305





1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513


1514
1515
1516
1517
1518
1519
1520
1521







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
-
-
+
+
+
+



-
+
-
-
-
-
-
+
+
+
+

+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+





-
+
+


-
+




-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
+







  }
  zLine = realloc( zLine, n+1 );
  return zLine;
}


/*
** This function is part of the implementation of the command:
**
**   $db transaction [-deferred|-immediate|-exclusive] SCRIPT
**
** It is invoked after evaluating the script SCRIPT to commit or rollback
** the transaction or savepoint opened by the [transaction] command.
*/
static int DbTransPostCmd(
  ClientData data[],                   /* data[0] is the Sqlite3Db* for $db */
  Tcl_Interp *interp,                  /* Tcl interpreter */
  int result                           /* Result of evaluating SCRIPT */
){
  static const char *azEnd[] = {
    "RELEASE _tcl_transaction",        /* rc==TCL_ERROR, nTransaction!=0 */
    "COMMIT",                          /* rc!=TCL_ERROR, nTransaction==0 */
    "ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction",
    "ROLLBACK"                         /* rc==TCL_ERROR, nTransaction==0 */
  };
  SqliteDb *pDb = (SqliteDb*)data[0];
  int rc = result;
  const char *zEnd;
** Figure out the column names for the data returned by the statement
** passed as the second argument.
**
** If parameter papColName is not NULL, then *papColName is set to point
** at an array allocated using Tcl_Alloc(). It is the callers responsibility
** to free this array using Tcl_Free(), and to decrement the reference
** count of each Tcl_Obj* member of the array.

  pDb->nTransaction--;
  zEnd = azEnd[(rc==TCL_ERROR)*2 + (pDb->nTransaction==0)];

  pDb->disableAuth++;
  if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){
      /* This is a tricky scenario to handle. The most likely cause of an
      ** error is that the exec() above was an attempt to commit the 
      ** top-level transaction that returned SQLITE_BUSY. Or, less likely,
      ** that an IO-error has occured. In either case, throw a Tcl exception
      ** and try to rollback the transaction.
      **
      ** But it could also be that the user executed one or more BEGIN, 
      ** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing
      ** this method's logic. Not clear how this would be best handled.
      */
    if( rc!=TCL_ERROR ){
      Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0);
      rc = TCL_ERROR;
    }
    sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0);
  }
  pDb->disableAuth--;

  return rc;
}

/*
** Search the cache for a prepared-statement object that implements the
** first SQL statement in the buffer pointed to by parameter zIn. If
** no such prepared-statement can be found, allocate and prepare a new
** one. In either case, bind the current values of the relevant Tcl
** variables to any $var, :var or @var variables in the statement. Before
** returning, set *ppPreStmt to point to the prepared-statement object.
**
** Output parameter *pzOut is set to point to the next SQL statement in
** buffer zIn, or to the '\0' byte at the end of zIn if there is no
** next statement.
**
** If successful, TCL_OK is returned. Otherwise, TCL_ERROR is returned
** and an error message loaded into interpreter pDb->interp.
*/
static int dbPrepareAndBind(
  SqliteDb *pDb,                  /* Database object */
  char const *zIn,                /* SQL to compile */
  char const **pzOut,             /* OUT: Pointer to next SQL statement */
  SqlPreparedStmt **ppPreStmt     /* OUT: Object used to cache statement */
){
  const char *zSql = zIn;         /* Pointer to first SQL statement in zIn */
  sqlite3_stmt *pStmt;            /* Prepared statement object */
  SqlPreparedStmt *pPreStmt;      /* Pointer to cached statement */
  int nSql;                       /* Length of zSql in bytes */
  int nVar;                       /* Number of variables in statement */
  int iParm = 0;                  /* Next free entry in apParm */
  int i;
  Tcl_Interp *interp = pDb->interp;

  *ppPreStmt = 0;

  /* Trim spaces from the start of zSql and calculate the remaining length. */
  while( isspace(zSql[0]) ){ zSql++; }
  nSql = strlen30(zSql);

  for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){
    int n = pPreStmt->nSql;
    if( nSql>=n 
        && memcmp(pPreStmt->zSql, zSql, n)==0
        && (zSql[n]==0 || zSql[n-1]==';')
    ){
      pStmt = pPreStmt->pStmt;
      *pzOut = &zSql[pPreStmt->nSql];

      /* When a prepared statement is found, unlink it from the
      ** cache list.  It will later be added back to the beginning
      ** of the cache list in order to implement LRU replacement.
      */
      if( pPreStmt->pPrev ){
        pPreStmt->pPrev->pNext = pPreStmt->pNext;
      }else{
        pDb->stmtList = pPreStmt->pNext;
      }
      if( pPreStmt->pNext ){
        pPreStmt->pNext->pPrev = pPreStmt->pPrev;
      }else{
        pDb->stmtLast = pPreStmt->pPrev;
      }
      pDb->nStmt--;
      nVar = sqlite3_bind_parameter_count(pStmt);
      break;
    }
  }
  
  /* If no prepared statement was found. Compile the SQL text. Also allocate
  ** a new SqlPreparedStmt structure.  */
  if( pPreStmt==0 ){
    int nByte;

    if( SQLITE_OK!=sqlite3_prepare_v2(pDb->db, zSql, -1, &pStmt, pzOut) ){
      Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
      return TCL_ERROR;
    }
    if( pStmt==0 ){
      if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
        /* A compile-time error in the statement. */
        Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
        return TCL_ERROR;
      }else{
        /* The statement was a no-op.  Continue to the next statement
        ** in the SQL string.
        */
        return TCL_OK;
      }
    }

    assert( pPreStmt==0 );
    nVar = sqlite3_bind_parameter_count(pStmt);
    nByte = sizeof(SqlPreparedStmt) + nVar*sizeof(Tcl_Obj *);
    pPreStmt = (SqlPreparedStmt*)Tcl_Alloc(nByte);
    memset(pPreStmt, 0, nByte);

    pPreStmt->pStmt = pStmt;
    pPreStmt->nSql = (*pzOut - zSql);
    pPreStmt->zSql = sqlite3_sql(pStmt);
    pPreStmt->apParm = (Tcl_Obj **)&pPreStmt[1];
  }
  assert( pPreStmt );
  assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql );
  assert( 0==memcmp(pPreStmt->zSql, zSql, pPreStmt->nSql) );

  /* Bind values to parameters that begin with $ or : */  
  for(i=1; i<=nVar; i++){
    const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
    if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){
      Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0);
      if( pVar ){
        int n;
        u8 *data;
        const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
        char c = zType[0];
        if( zVar[0]=='@' ||
           (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){
          /* Load a BLOB type if the Tcl variable is a bytearray and
          ** it has no string representation or the host
          ** parameter name begins with "@". */
          data = Tcl_GetByteArrayFromObj(pVar, &n);
          sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);
          Tcl_IncrRefCount(pVar);
          pPreStmt->apParm[iParm++] = pVar;
        }else if( c=='b' && strcmp(zType,"boolean")==0 ){
          Tcl_GetIntFromObj(interp, pVar, &n);
          sqlite3_bind_int(pStmt, i, n);
        }else if( c=='d' && strcmp(zType,"double")==0 ){
          double r;
          Tcl_GetDoubleFromObj(interp, pVar, &r);
          sqlite3_bind_double(pStmt, i, r);
        }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||
              (c=='i' && strcmp(zType,"int")==0) ){
          Tcl_WideInt v;
          Tcl_GetWideIntFromObj(interp, pVar, &v);
          sqlite3_bind_int64(pStmt, i, v);
        }else{
          data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
          sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC);
          Tcl_IncrRefCount(pVar);
          pPreStmt->apParm[iParm++] = pVar;
        }
      }else{
        sqlite3_bind_null(pStmt, i);
      }
    }
  }
  pPreStmt->nParm = iParm;
  *ppPreStmt = pPreStmt;

  return TCL_OK;
}


/*
** Release a statement reference obtained by calling dbPrepareAndBind().
** There should be exactly one call to this function for each call to
** dbPrepareAndBind().
**
** If the discard parameter is non-zero, then the statement is deleted
** immediately. Otherwise it is added to the LRU list and may be returned
** by a subsequent call to dbPrepareAndBind().
*/
static void dbReleaseStmt(
  SqliteDb *pDb,                  /* Database handle */
  SqlPreparedStmt *pPreStmt,      /* Prepared statement handle to release */
  int discard                     /* True to delete (not cache) the pPreStmt */
){
  int i;
** The return value of this function is the number of columns of data
** returned by pStmt (and hence the size of the *papColName array).

  /* Free the bound string and blob parameters */
  for(i=0; i<pPreStmt->nParm; i++){
    Tcl_DecrRefCount(pPreStmt->apParm[i]);
  }
  pPreStmt->nParm = 0;

  if( pDb->maxStmt<=0 || discard ){
    /* If the cache is turned off, deallocated the statement */
    sqlite3_finalize(pPreStmt->pStmt);
    Tcl_Free((char *)pPreStmt);
  }else{
    /* Add the prepared statement to the beginning of the cache list. */
    pPreStmt->pNext = pDb->stmtList;
    pPreStmt->pPrev = 0;
    if( pDb->stmtList ){
     pDb->stmtList->pPrev = pPreStmt;
    }
    pDb->stmtList = pPreStmt;
    if( pDb->stmtLast==0 ){
      assert( pDb->nStmt==0 );
      pDb->stmtLast = pPreStmt;
    }else{
      assert( pDb->nStmt>0 );
    }
    pDb->nStmt++;
   
    /* If we have too many statement in cache, remove the surplus from 
    ** the end of the cache list.  */
    while( pDb->nStmt>pDb->maxStmt ){
      sqlite3_finalize(pDb->stmtLast->pStmt);
      pDb->stmtLast = pDb->stmtLast->pPrev;
      Tcl_Free((char*)pDb->stmtLast->pNext);
      pDb->stmtLast->pNext = 0;
      pDb->nStmt--;
    }
  }
}

/*
** Structure used with dbEvalXXX() functions:
**
**   dbEvalInit()
**   dbEvalStep()
**   dbEvalFinalize()
**   dbEvalRowInfo()
**   dbEvalColumnValue()
*/
typedef struct DbEvalContext DbEvalContext;
struct DbEvalContext {
  SqliteDb *pDb;                  /* Database handle */
  Tcl_Obj *pSql;                  /* Object holding string zSql */
  const char *zSql;               /* Remaining SQL to execute */
  SqlPreparedStmt *pPreStmt;      /* Current statement */
  int nCol;                       /* Number of columns returned by pStmt */
  Tcl_Obj *pArray;                /* Name of array variable */
  Tcl_Obj **apColName;            /* Array of column names */
};

/*
** Release any cache of column names currently held as part of
** the DbEvalContext structure passed as the first argument.
*/
static void dbReleaseColumnNames(DbEvalContext *p){
  if( p->apColName ){
    int i;
    for(i=0; i<p->nCol; i++){
      Tcl_DecrRefCount(p->apColName[i]);
    }
    Tcl_Free((char *)p->apColName);
    p->apColName = 0;
  }
  p->nCol = 0;
}

/*
** Initialize a DbEvalContext structure.
**
** If pArray is not NULL, then it contains the name of a Tcl array
** variable. The "*" member of this array is set to a list containing
** the names of the columns returned by the statement, in order from
** left to right. e.g. if the names of the returned columns are a, b and
** c, it does the equivalent of the tcl command:
** the names of the columns returned by the statement as part of each
** call to dbEvalStep(), in order from left to right. e.g. if the names 
** of the returned columns are a, b and c, it does the equivalent of the 
** tcl command:
**
**     set ${pArray}(*) {a b c}
*/
static int
static void dbEvalInit(
computeColumnNames(
  Tcl_Interp *interp, 
  sqlite3_stmt *pStmt,              /* SQL statement */
  Tcl_Obj ***papColName,            /* OUT: Array of column names */
  Tcl_Obj *pArray                   /* Name of array variable (may be null) */
  DbEvalContext *p,               /* Pointer to structure to initialize */
  SqliteDb *pDb,                  /* Database handle */
  Tcl_Obj *pSql,                  /* Object containing SQL script */
  Tcl_Obj *pArray                 /* Name of Tcl array to set (*) element of */
){
  memset(p, 0, sizeof(DbEvalContext));
  p->pDb = pDb;
  p->zSql = Tcl_GetString(pSql);
  p->pSql = pSql;
  int nCol;

  Tcl_IncrRefCount(pSql);
  if( pArray ){
    p->pArray = pArray;
    Tcl_IncrRefCount(pArray);
  }
}

/*
** Obtain information about the row that the DbEvalContext passed as the
** first argument currently points to.
*/
static void dbEvalRowInfo(
  DbEvalContext *p,               /* Evaluation context */
  int *pnCol,                     /* OUT: Number of column names */
  Tcl_Obj ***papColName           /* OUT: Array of column names */
){
  /* Compute column names */
  if( 0==p->apColName ){
    sqlite3_stmt *pStmt = p->pPreStmt->pStmt;
    int i;                        /* Iterator variable */
    int nCol;                     /* Number of columns returned by pStmt */
    Tcl_Obj **apColName = 0;      /* Array of column names */

  nCol = sqlite3_column_count(pStmt);
  if( papColName ){
    p->nCol = nCol = sqlite3_column_count(pStmt);
    if( nCol>0 && (papColName || p->pArray) ){
    int i;
    Tcl_Obj **apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );
    for(i=0; i<nCol; i++){
      apColName[i] = dbTextToObj(sqlite3_column_name(pStmt,i));
      Tcl_IncrRefCount(apColName[i]);
      apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );
      for(i=0; i<nCol; i++){
        apColName[i] = dbTextToObj(sqlite3_column_name(pStmt,i));
        Tcl_IncrRefCount(apColName[i]);
      }
      p->apColName = apColName;
    }

    /* If results are being stored in an array variable, then create
    ** the array(*) entry for that array
    */
    if( pArray ){
    if( p->pArray ){
      Tcl_Interp *interp = p->pDb->interp;
      Tcl_Obj *pColList = Tcl_NewObj();
      Tcl_Obj *pStar = Tcl_NewStringObj("*", -1);
      Tcl_IncrRefCount(pColList);

      for(i=0; i<nCol; i++){
        Tcl_ListObjAppendElement(interp, pColList, apColName[i]);
      }
      Tcl_IncrRefCount(pStar);
      Tcl_ObjSetVar2(interp, pArray, pStar, pColList,0);
      Tcl_DecrRefCount(pColList);
      Tcl_DecrRefCount(pStar);
    }
    *papColName = apColName;
      Tcl_ObjSetVar2(interp, p->pArray, pStar, pColList, 0);
      Tcl_DecrRefCount(pStar);
    }
  }

  if( papColName ){
    *papColName = p->apColName;
  }
  if( pnCol ){
    *pnCol = p->nCol;
  }
}

/*
** Return one of TCL_OK, TCL_BREAK or TCL_ERROR. If TCL_ERROR is
** returned, then an error message is stored in the interpreter before
** returning.
**
** A return value of TCL_OK means there is a row of data available. The
** data may be accessed using dbEvalRowInfo() and dbEvalColumnValue(). This
** is analogous to a return of SQLITE_ROW from sqlite3_step(). If TCL_BREAK
** is returned, then the SQL script has finished executing and there are
** no further rows available. This is similar to SQLITE_DONE.
*/
static int dbEvalStep(DbEvalContext *p){
  while( p->zSql[0] || p->pPreStmt ){
    int rc;
    if( p->pPreStmt==0 ){
      rc = dbPrepareAndBind(p->pDb, p->zSql, &p->zSql, &p->pPreStmt);
      if( rc!=TCL_OK ) return rc;
    }else{
      int rcs;
      SqliteDb *pDb = p->pDb;
      SqlPreparedStmt *pPreStmt = p->pPreStmt;
      sqlite3_stmt *pStmt = pPreStmt->pStmt;

      rcs = sqlite3_step(pStmt);
      if( rcs==SQLITE_ROW ){
        return TCL_OK;
      }
      if( p->pArray ){
        dbEvalRowInfo(p, 0, 0);
      }
      rcs = sqlite3_reset(pStmt);

      pDb->nStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_FULLSCAN_STEP,1);
      pDb->nSort = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_SORT,1);
      dbReleaseColumnNames(p);
      p->pPreStmt = 0;

      if( rcs!=SQLITE_OK ){
        /* If a run-time error occurs, report the error and stop reading
        ** the SQL.  */
        Tcl_SetObjResult(pDb->interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
        dbReleaseStmt(pDb, pPreStmt, 1);
        return TCL_ERROR;
      }else{
        dbReleaseStmt(pDb, pPreStmt, 0);
      }
    }
  }

  /* Finished */
  return TCL_BREAK;
}

/*
** Free all resources currently held by the DbEvalContext structure passed
** as the first argument. There should be exactly one call to this function
** for each call to dbEvalInit().
*/
static void dbEvalFinalize(DbEvalContext *p){
  if( p->pPreStmt ){
    sqlite3_reset(p->pPreStmt->pStmt);
    dbReleaseStmt(p->pDb, p->pPreStmt, 0);
    p->pPreStmt = 0;
  }
  if( p->pArray ){
    Tcl_DecrRefCount(p->pArray);
    p->pArray = 0;
  }
  Tcl_DecrRefCount(p->pSql);
  dbReleaseColumnNames(p);
}

/*
** Return a pointer to a Tcl_Obj structure with ref-count 0 that contains
** the value for the iCol'th column of the row currently pointed to by
** the DbEvalContext structure passed as the first argument.
*/
static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){
  sqlite3_stmt *pStmt = p->pPreStmt->pStmt;
  switch( sqlite3_column_type(pStmt, iCol) ){
    case SQLITE_BLOB: {
      int bytes = sqlite3_column_bytes(pStmt, iCol);
      const char *zBlob = sqlite3_column_blob(pStmt, iCol);
      if( !zBlob ) bytes = 0;
      return Tcl_NewByteArrayObj((u8*)zBlob, bytes);
    }
    case SQLITE_INTEGER: {
      sqlite_int64 v = sqlite3_column_int64(pStmt, iCol);
      if( v>=-2147483647 && v<=2147483647 ){
        return Tcl_NewIntObj(v);
      }else{
        return Tcl_NewWideIntObj(v);
      }
    }
    case SQLITE_FLOAT: {
      return Tcl_NewDoubleObj(sqlite3_column_double(pStmt, iCol));
    }
    case SQLITE_NULL: {
      return dbTextToObj(p->pDb->zNull);
    }
  }

  return dbTextToObj((char *)sqlite3_column_text(pStmt, iCol));
}

/*
** If using Tcl version 8.6 or greater, use the NR functions to avoid
** recursive evalution of scripts by the [db eval] and [db trans]
** commands. Even if the headers used while compiling the extension
** are 8.6 or newer, the code still tests the Tcl version at runtime.
** This allows stubs-enabled builds to be used with older Tcl libraries.
*/
#if TCL_MAJOR_VERSION>8 || (TCL_MAJOR_VERSION==8 && TCL_MINOR_VERSION>=6)
# define SQLITE_TCL_NRE 1
static int DbUseNre(void){
  int major, minor;
  Tcl_GetVersion(&major, &minor, 0, 0);
  return( (major==8 && minor>=6) || major>8 );
}
#else
/* 
** Compiling using headers earlier than 8.6. In this case NR cannot be
** used, so DbUseNre() to always return zero. Add #defines for the other
** Tcl_NRxxx() functions to prevent them from causing compilation errors,
** even though the only invocations of them are within conditional blocks 
** of the form:
**
**   if( DbUseNre() ) { ... }
*/
# define SQLITE_TCL_NRE 0
# define DbUseNre() 0
# define Tcl_NRAddCallback(a,b,c,d,e,f) 0
# define Tcl_NREvalObj(a,b,c) 0
# define Tcl_NRCreateCommand(a,b,c,d,e,f) 0
#endif

/*
** This function is part of the implementation of the command:
**
**   $db eval SQL ?ARRAYNAME? SCRIPT
*/
static int DbEvalNextCmd(
  ClientData data[],                   /* data[0] is the (DbEvalContext*) */
  Tcl_Interp *interp,                  /* Tcl interpreter */
  int result                           /* Result so far */
){
  int rc = result;                     /* Return code */

  /* The first element of the data[] array is a pointer to a DbEvalContext
  ** structure allocated using Tcl_Alloc(). The second element of data[]
  ** is a pointer to a Tcl_Obj containing the script to run for each row
  ** returned by the queries encapsulated in data[0]. */
  DbEvalContext *p = (DbEvalContext *)data[0];
  Tcl_Obj *pScript = (Tcl_Obj *)data[1];
  Tcl_Obj *pArray = p->pArray;

  while( (rc==TCL_OK || rc==TCL_CONTINUE) && TCL_OK==(rc = dbEvalStep(p)) ){
    int i;
    int nCol;
    Tcl_Obj **apColName;
    dbEvalRowInfo(p, &nCol, &apColName);
    for(i=0; i<nCol; i++){
      Tcl_Obj *pVal = dbEvalColumnValue(p, i);
      if( pArray==0 ){
        Tcl_ObjSetVar2(interp, apColName[i], 0, pVal, 0);
      }else{
        Tcl_ObjSetVar2(interp, pArray, apColName[i], pVal, 0);
      }
    }

    /* The required interpreter variables are now populated with the data 
    ** from the current row. If using NRE, schedule callbacks to evaluate
    ** script pScript, then to invoke this function again to fetch the next
    ** row (or clean up if there is no next row or the script throws an
    ** exception). After scheduling the callbacks, return control to the 
    ** caller.
    **
    ** If not using NRE, evaluate pScript directly and continue with the
    ** next iteration of this while(...) loop.  */
    if( DbUseNre() ){
      Tcl_NRAddCallback(interp, DbEvalNextCmd, (void*)p, (void*)pScript, 0, 0);
      return Tcl_NREvalObj(interp, pScript, 0);
    }else{
      rc = Tcl_EvalObjEx(interp, pScript, 0);
    }
  }

  Tcl_DecrRefCount(pScript);
  dbEvalFinalize(p);
  Tcl_Free((char *)p);

  if( rc==TCL_OK || rc==TCL_BREAK ){
    Tcl_ResetResult(interp);
    rc = TCL_OK;
  }

  return nCol;
  return rc;
}

/*
** The "sqlite" command below creates a new Tcl command for each
** connection it opens to an SQLite database.  This routine is invoked
** whenever one of those connection-specific commands is executed
** in Tcl.  For example, if you run Tcl code like this:
1598
1599
1600
1601
1602
1603
1604
1605

1606
1607

1608































1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620

1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638




1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751



1752
1753
1754
1755

1756
1757

1758
1759
1760
1761



1762
1763
1764
1765
1766
1767
1768
1769




1770
1771
1772
1773
1774
1775
1776

1777
1778
1779

1780
1781
1782

1783
1784
1785
1786

1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854

1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866


1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884

1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918

1919
1920
1921
1922
1923
1924

1925
1926
1927
1928



1929
1930
1931
1932
1933


1934
1935
1936
1937

1938
1939
1940
1941


1942
1943
1944
1945
1946
1947


1948
1949

1950
1951
1952
1953

1954
1955
1956
1957
1958
1959

1960
1961

1962
1963
1964
1965
1966

1967
1968
1969

1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
2119
2120
2121
2122
2123
2124
2125

2126
2127

2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166



2167


2168


















2169
2170
2171
2172

















































































































2173
2174
2175




2176


2177




2178
2179
2180








2181
2182
2183
2184







2185



2186



2187




2188




































































2189












2190
2191


















2192


































2193






2194




2195
2196
2197





2198
2199




2200




2201
2202






2203
2204


2205




2206






2207


2208





2209



2210




2211
2212
2213
2214
2215
2216
2217







-
+

-
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






-
-
-

-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
+
-
-
+
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
+
-
-
-
+
-
-
-
+
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
+
-
-
-
-
+
+
+
-
-
-
-
-
+
+
-
-
-
-
+
-
-
-
-
+
+
-
-
-
-
-
-
+
+
-
-
+
-
-
-
-
+
-
-
-
-
-
-
+
-
-
+
-
-
-
-
-
+
-
-
-
+
-
-
-
-







  ** Return the numeric error code that was returned by the most recent
  ** call to sqlite3_exec().
  */
  case DB_ERRORCODE: {
    Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_errcode(pDb->db)));
    break;
  }
   

  /*
  **    $db eval $sql ?array? ?{  ...code... }?
  **    $db exists $sql
  **    $db onecolumn $sql
  **
  ** The onecolumn method is the equivalent of:
  **     lindex [$db eval $sql] 0
  */
  case DB_EXISTS: 
  case DB_ONECOLUMN: {
    DbEvalContext sEval;
    if( objc!=3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "SQL");
      return TCL_ERROR;
    }

    dbEvalInit(&sEval, pDb, objv[2], 0);
    rc = dbEvalStep(&sEval);
    if( choice==DB_ONECOLUMN ){
      if( rc==TCL_OK ){
        Tcl_SetObjResult(interp, dbEvalColumnValue(&sEval, 0));
      }
    }else if( rc==TCL_BREAK || rc==TCL_OK ){
      Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc==TCL_OK));
    }
    dbEvalFinalize(&sEval);

    if( rc==TCL_BREAK ){
      rc = TCL_OK;
    }
    break;
  }
   
  /*
  **    $db eval $sql ?array? ?{  ...code... }?
  **
  ** The SQL statement in $sql is evaluated.  For each row, the values are
  ** placed in elements of the array named "array" and ...code... is executed.
  ** If "array" and "code" are omitted, then no callback is every invoked.
  ** If "array" is an empty string, then the values are placed in variables
  ** that have the same name as the fields extracted by the query.
  **
  ** The onecolumn method is the equivalent of:
  **     lindex [$db eval $sql] 0
  */
  case DB_ONECOLUMN:
  case DB_EVAL:
  case DB_EVAL: {
  case DB_EXISTS: {
    char const *zSql;      /* Next SQL statement to execute */
    char const *zLeft;     /* What is left after first stmt in zSql */
    sqlite3_stmt *pStmt;   /* Compiled SQL statment */
    Tcl_Obj *pArray;       /* Name of array into which results are written */
    Tcl_Obj *pScript;      /* Script to run for each result set */
    Tcl_Obj **apParm;      /* Parameters that need a Tcl_DecrRefCount() */
    int nParm;             /* Number of entries used in apParm[] */
    Tcl_Obj *aParm[10];    /* Static space for apParm[] in the common case */
    Tcl_Obj *pRet;         /* Value to be returned */
    SqlPreparedStmt *pPreStmt;  /* Pointer to a prepared statement */
    int rc2;

    if( choice==DB_EVAL ){
      if( objc<3 || objc>5 ){
        Tcl_WrongNumArgs(interp, 2, objv, "SQL ?ARRAY-NAME? ?SCRIPT?");
        return TCL_ERROR;
      }
    if( objc<3 || objc>5 ){
      Tcl_WrongNumArgs(interp, 2, objv, "SQL ?ARRAY-NAME? ?SCRIPT?");
      return TCL_ERROR;
    }
      pRet = Tcl_NewObj();
      Tcl_IncrRefCount(pRet);
    }else{
      if( objc!=3 ){
        Tcl_WrongNumArgs(interp, 2, objv, "SQL");
        return TCL_ERROR;
      }
      if( choice==DB_EXISTS ){
        pRet = Tcl_NewBooleanObj(0);
        Tcl_IncrRefCount(pRet);
      }else{
        pRet = 0;
      }
    }
    if( objc==3 ){
      pArray = pScript = 0;
    }else if( objc==4 ){
      pArray = 0;
      pScript = objv[3];
    }else{
      pArray = objv[3];
      if( Tcl_GetString(pArray)[0]==0 ) pArray = 0;
      pScript = objv[4];
    }

    Tcl_IncrRefCount(objv[2]);
    zSql = Tcl_GetStringFromObj(objv[2], 0);
    while( rc==TCL_OK && zSql[0] ){
      int i;                     /* Loop counter */
      int nVar;                  /* Number of bind parameters in the pStmt */
      int nCol = -1;             /* Number of columns in the result set */
      Tcl_Obj **apColName = 0;   /* Array of column names */
      int len;                   /* String length of zSql */
  
      /* Try to find a SQL statement that has already been compiled and
      ** which matches the next sequence of SQL.
      */
      pStmt = 0;
      len = strlen30(zSql);
      for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){
        int n = pPreStmt->nSql;
        if( len>=n 
            && memcmp(pPreStmt->zSql, zSql, n)==0
            && (zSql[n]==0 || zSql[n-1]==';')
        ){
          pStmt = pPreStmt->pStmt;
          zLeft = &zSql[pPreStmt->nSql];

          /* When a prepared statement is found, unlink it from the
          ** cache list.  It will later be added back to the beginning
          ** of the cache list in order to implement LRU replacement.
          */
          if( pPreStmt->pPrev ){
            pPreStmt->pPrev->pNext = pPreStmt->pNext;
          }else{
            pDb->stmtList = pPreStmt->pNext;
          }
          if( pPreStmt->pNext ){
            pPreStmt->pNext->pPrev = pPreStmt->pPrev;
          }else{
            pDb->stmtLast = pPreStmt->pPrev;
          }
          pDb->nStmt--;
          break;
        }
      }
  
      /* If no prepared statement was found.  Compile the SQL text
      */
      if( pStmt==0 ){
        if( SQLITE_OK!=sqlite3_prepare_v2(pDb->db, zSql, -1, &pStmt, &zLeft) ){
          Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
          rc = TCL_ERROR;
          break;
        }
        if( pStmt==0 ){
          if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
            /* A compile-time error in the statement
            */
            Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
            rc = TCL_ERROR;
            break;
          }else{
            /* The statement was a no-op.  Continue to the next statement
            ** in the SQL string.
            */
            zSql = zLeft;
            continue;
          }
        }
        assert( pPreStmt==0 );
      }

      /* Bind values to parameters that begin with $ or :
      */  
      nVar = sqlite3_bind_parameter_count(pStmt);
      nParm = 0;
      if( nVar>sizeof(aParm)/sizeof(aParm[0]) ){
        apParm = (Tcl_Obj**)Tcl_Alloc(nVar*sizeof(apParm[0]));
      }else{
        apParm = aParm;
      }
      for(i=1; i<=nVar; i++){
        const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
        if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){
          Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0);
          if( pVar ){
            int n;
            u8 *data;
            char *zType = pVar->typePtr ? pVar->typePtr->name : "";
            char c = zType[0];
            if( zVar[0]=='@' ||
               (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){

    if( objc==3 ){
      DbEvalContext sEval;
              /* Load a BLOB type if the Tcl variable is a bytearray and
              ** it has no string representation or the host
              ** parameter name begins with "@". */
              data = Tcl_GetByteArrayFromObj(pVar, &n);
      Tcl_Obj *pRet = Tcl_NewObj();
              sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);
              Tcl_IncrRefCount(pVar);
      Tcl_IncrRefCount(pRet);
              apParm[nParm++] = pVar;
            }else if( c=='b' && strcmp(zType,"boolean")==0 ){
              Tcl_GetIntFromObj(interp, pVar, &n);
              sqlite3_bind_int(pStmt, i, n);
      dbEvalInit(&sEval, pDb, objv[2], 0);
      while( TCL_OK==(rc = dbEvalStep(&sEval)) ){
        int i;
            }else if( c=='d' && strcmp(zType,"double")==0 ){
              double r;
              Tcl_GetDoubleFromObj(interp, pVar, &r);
              sqlite3_bind_double(pStmt, i, r);
            }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||
                  (c=='i' && strcmp(zType,"int")==0) ){
              Tcl_WideInt v;
              Tcl_GetWideIntFromObj(interp, pVar, &v);
        int nCol;
        dbEvalRowInfo(&sEval, &nCol, 0);
        for(i=0; i<nCol; i++){
          Tcl_ListObjAppendElement(interp, pRet, dbEvalColumnValue(&sEval, i));
              sqlite3_bind_int64(pStmt, i, v);
            }else{
              data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
              sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC);
              Tcl_IncrRefCount(pVar);
              apParm[nParm++] = pVar;
            }
        }
          }else{
            sqlite3_bind_null( pStmt, i );
          }
      }
        }
      }

      dbEvalFinalize(&sEval);
      /* Execute the SQL
      */
      while( rc==TCL_OK && pStmt && SQLITE_ROW==sqlite3_step(pStmt) ){

      if( rc==TCL_BREAK ){
	/* Compute column names. This must be done after the first successful
	** call to sqlite3_step(), in case the query is recompiled and the
        ** number or names of the returned columns changes. 
        */
        assert(!pArray||pScript);
        if (nCol < 0) {
          Tcl_Obj ***ap = (pScript?&apColName:0);
          nCol = computeColumnNames(interp, pStmt, ap, pArray);
        }

        for(i=0; i<nCol; i++){
          Tcl_Obj *pVal;
          
          /* Set pVal to contain the i'th column of this row. */
          switch( sqlite3_column_type(pStmt, i) ){
            case SQLITE_BLOB: {
              int bytes = sqlite3_column_bytes(pStmt, i);
              const char *zBlob = sqlite3_column_blob(pStmt, i);
              if( !zBlob ) bytes = 0;
              pVal = Tcl_NewByteArrayObj((u8*)zBlob, bytes);
              break;
            }
            case SQLITE_INTEGER: {
              sqlite_int64 v = sqlite3_column_int64(pStmt, i);
              if( v>=-2147483647 && v<=2147483647 ){
                pVal = Tcl_NewIntObj(v);
              }else{
                pVal = Tcl_NewWideIntObj(v);
              }
              break;
            }
            case SQLITE_FLOAT: {
              double r = sqlite3_column_double(pStmt, i);
              pVal = Tcl_NewDoubleObj(r);
              break;
            }
            case SQLITE_NULL: {
              pVal = dbTextToObj(pDb->zNull);
              break;
            }
            default: {
              pVal = dbTextToObj((char *)sqlite3_column_text(pStmt, i));
              break;
            }
          }
  
          if( pScript ){
            if( pArray==0 ){
              Tcl_ObjSetVar2(interp, apColName[i], 0, pVal, 0);
            }else{
              Tcl_ObjSetVar2(interp, pArray, apColName[i], pVal, 0);
            }
          }else if( choice==DB_ONECOLUMN ){
            assert( pRet==0 );
            if( pRet==0 ){
              pRet = pVal;
              Tcl_IncrRefCount(pRet);
            }
            rc = TCL_BREAK;
            i = nCol;
          }else if( choice==DB_EXISTS ){
            Tcl_DecrRefCount(pRet);
            pRet = Tcl_NewBooleanObj(1);
            Tcl_IncrRefCount(pRet);
            rc = TCL_BREAK;
            i = nCol;
          }else{
            Tcl_ListObjAppendElement(interp, pRet, pVal);
        Tcl_SetObjResult(interp, pRet);
          }
        }
  
        if( pScript ){
          pDb->nStep = sqlite3_stmt_status(pStmt, 
                                  SQLITE_STMTSTATUS_FULLSCAN_STEP, 0);
          pDb->nSort = sqlite3_stmt_status(pStmt,
                                  SQLITE_STMTSTATUS_SORT, 0);
          rc = Tcl_EvalObjEx(interp, pScript, 0);
          if( rc==TCL_CONTINUE ){
            rc = TCL_OK;
          }
        rc = TCL_OK;
      }
        }
      }
      if( rc==TCL_BREAK ){
        rc = TCL_OK;
      }

      /* Free the column name objects */
      if( pScript ){
        /* If the query returned no rows, but an array variable was 
        ** specified, call computeColumnNames() now to populate the 
        ** arrayname(*) variable.
        */
        if (pArray && nCol < 0) {
          Tcl_Obj ***ap = (pScript?&apColName:0);
          nCol = computeColumnNames(interp, pStmt, ap, pArray);
        }
        for(i=0; i<nCol; i++){
          Tcl_DecrRefCount(apColName[i]);
      Tcl_DecrRefCount(pRet);
        }
        Tcl_Free((char*)apColName);
      }

      /* Free the bound string and blob parameters */
      for(i=0; i<nParm; i++){
        Tcl_DecrRefCount(apParm[i]);
      }
      if( apParm!=aParm ){
        Tcl_Free((char*)apParm);
      }

      /* Reset the statement.  If the result code is SQLITE_SCHEMA, then
      ** flush the statement cache and try the statement again.
      */
      rc2 = sqlite3_reset(pStmt);
      pDb->nStep = sqlite3_stmt_status(pStmt, 
                                  SQLITE_STMTSTATUS_FULLSCAN_STEP, 1);
      pDb->nSort = sqlite3_stmt_status(pStmt,
                                  SQLITE_STMTSTATUS_SORT, 1);
      if( SQLITE_OK!=rc2 ){
        /* If a run-time error occurs, report the error and stop reading
        ** the SQL
        */
        Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
        sqlite3_finalize(pStmt);
        rc = TCL_ERROR;
        if( pPreStmt ) Tcl_Free((char*)pPreStmt);
        break;
      }else if( pDb->maxStmt<=0 ){
        /* If the cache is turned off, deallocated the statement */
        if( pPreStmt ) Tcl_Free((char*)pPreStmt);
        sqlite3_finalize(pStmt);
      }else{
    }else{
        /* Everything worked and the cache is operational.
        ** Create a new SqlPreparedStmt structure if we need one.
        ** (If we already have one we can just reuse it.)
        */
        if( pPreStmt==0 ){
          len = zLeft - zSql;
      ClientData cd[2];
          pPreStmt = (SqlPreparedStmt*)Tcl_Alloc( sizeof(*pPreStmt) );
          if( pPreStmt==0 ) return TCL_ERROR;
          pPreStmt->pStmt = pStmt;
          pPreStmt->nSql = len;
      DbEvalContext *p;
      Tcl_Obj *pArray = 0;
      Tcl_Obj *pScript;
          pPreStmt->zSql = sqlite3_sql(pStmt);
          assert( strlen30(pPreStmt->zSql)==len );
          assert( 0==memcmp(pPreStmt->zSql, zSql, len) );
        }


      if( objc==5 && *(char *)Tcl_GetString(objv[3]) ){
        /* Add the prepared statement to the beginning of the cache list
        */
        pPreStmt->pNext = pDb->stmtList;
        pPreStmt->pPrev = 0;
        pArray = objv[3];
        if( pDb->stmtList ){
         pDb->stmtList->pPrev = pPreStmt;
        }
        pDb->stmtList = pPreStmt;
      }
      pScript = objv[objc-1];
        if( pDb->stmtLast==0 ){
          assert( pDb->nStmt==0 );
          pDb->stmtLast = pPreStmt;
        }else{
          assert( pDb->nStmt>0 );
        }
      Tcl_IncrRefCount(pScript);
      
        pDb->nStmt++;
   
      p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext));
        /* If we have too many statement in cache, remove the surplus from the
        ** end of the cache list.
        */
        while( pDb->nStmt>pDb->maxStmt ){
      dbEvalInit(p, pDb, objv[2], pArray);
          sqlite3_finalize(pDb->stmtLast->pStmt);
          pDb->stmtLast = pDb->stmtLast->pPrev;
          Tcl_Free((char*)pDb->stmtLast->pNext);
          pDb->stmtLast->pNext = 0;
          pDb->nStmt--;
        }

      }

      cd[0] = (void *)p;
      /* Proceed to the next statement */
      zSql = zLeft;
    }
    Tcl_DecrRefCount(objv[2]);

      cd[1] = (void *)pScript;
    if( pRet ){
      if( rc==TCL_OK ){
        Tcl_SetObjResult(interp, pRet);
      rc = DbEvalNextCmd(cd, interp, TCL_OK);
      }
      Tcl_DecrRefCount(pRet);
    }else if( rc==TCL_OK ){
      Tcl_ResetResult(interp);
    }
    break;
  }

  /*
  **     $db function NAME [-argcount N] SCRIPT
  **
2119
2120
2121
2122
2123
2124
2125
2126

2127
2128
2129
2130
2131
2132
2133
2356
2357
2358
2359
2360
2361
2362

2363
2364
2365
2366
2367
2368
2369
2370







-
+







    rowid = sqlite3_last_insert_rowid(pDb->db);
    pResult = Tcl_GetObjResult(interp);
    Tcl_SetWideIntObj(pResult, rowid);
    break;
  }

  /*
  ** The DB_ONECOLUMN method is implemented together with DB_EVAL.
  ** The DB_ONECOLUMN method is implemented together with DB_EXISTS.
  */

  /*    $db progress ?N CALLBACK?
  ** 
  ** Invoke the given callback every N virtual machine opcodes while executing
  ** queries.
  */
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411

2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432

2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449








2450
2451
2452
2453
2454
2455
2456
2457
2458

2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474

2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2635
2636
2637
2638
2639
2640
2641

2642
2643
2644
2645
2646

2647


2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674

2675


2676





2677
2678
2679
2680
2681
2682
2683
2684

2685







2686
















2687




2688
2689
2690
2691
2692
2693
2694







-





-
+
-
-



















+







-

-
-

-
-
-
-
-
+
+
+
+
+
+
+
+
-

-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-







  **
  ** This command was inspired by Dave Thomas's talk on Ruby at the
  ** 2005 O'Reilly Open Source Convention (OSCON).
  */
  case DB_TRANSACTION: {
    Tcl_Obj *pScript;
    const char *zBegin = "SAVEPOINT _tcl_transaction";
    const char *zEnd;
    if( objc!=3 && objc!=4 ){
      Tcl_WrongNumArgs(interp, 2, objv, "[TYPE] SCRIPT");
      return TCL_ERROR;
    }

    if( pDb->nTransaction ){
    if( pDb->nTransaction==0 && objc==4 ){
      zBegin = "SAVEPOINT _tcl_transaction";
    }else if( pDb->nTransaction==0 && objc==4 ){
      static const char *TTYPE_strs[] = {
        "deferred",   "exclusive",  "immediate", 0
      };
      enum TTYPE_enum {
        TTYPE_DEFERRED, TTYPE_EXCLUSIVE, TTYPE_IMMEDIATE
      };
      int ttype;
      if( Tcl_GetIndexFromObj(interp, objv[2], TTYPE_strs, "transaction type",
                              0, &ttype) ){
        return TCL_ERROR;
      }
      switch( (enum TTYPE_enum)ttype ){
        case TTYPE_DEFERRED:    /* no-op */;                 break;
        case TTYPE_EXCLUSIVE:   zBegin = "BEGIN EXCLUSIVE";  break;
        case TTYPE_IMMEDIATE:   zBegin = "BEGIN IMMEDIATE";  break;
      }
    }
    pScript = objv[objc-1];

    /* Run the SQLite BEGIN command to open a transaction or savepoint. */
    pDb->disableAuth++;
    rc = sqlite3_exec(pDb->db, zBegin, 0, 0, 0);
    pDb->disableAuth--;
    if( rc!=SQLITE_OK ){
      Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0);
      return TCL_ERROR;
    }

    pDb->nTransaction++;
    rc = Tcl_EvalObjEx(interp, pScript, 0);
    pDb->nTransaction--;

    if( rc!=TCL_ERROR ){
      if( pDb->nTransaction ){
        zEnd = "RELEASE _tcl_transaction";
      }else{
        zEnd = "COMMIT";
    /* If using NRE, schedule a callback to invoke the script pScript, then
    ** a second callback to commit (or rollback) the transaction or savepoint
    ** opened above. If not using NRE, evaluate the script directly, then
    ** call function DbTransPostCmd() to commit (or rollback) the transaction 
    ** or savepoint.  */
    if( DbUseNre() ){
      Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0);
      Tcl_NREvalObj(interp, pScript, 0);
      }
    }else{
      if( pDb->nTransaction ){
        zEnd = "ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction";
      }else{
        zEnd = "ROLLBACK";
      }
    }

      rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0));
    pDb->disableAuth++;
    if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){
      /* This is a tricky scenario to handle. The most likely cause of an
      ** error is that the exec() above was an attempt to commit the 
      ** top-level transaction that returned SQLITE_BUSY. Or, less likely,
      ** that an IO-error has occured. In either case, throw a Tcl exception
      ** and try to rollback the transaction.
      **
      ** But it could also be that the user executed one or more BEGIN, 
      ** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing
      ** this method's logic. Not clear how this would be best handled.
      */
      if( rc!=TCL_ERROR ){
        Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0);
        rc = TCL_ERROR;
      }
    }
      sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0);
    }
    pDb->disableAuth--;

    break;
  }

  /*
  **    $db unlock_notify ?script?
  */
  case DB_UNLOCK_NOTIFY: {
2567
2568
2569
2570
2571
2572
2573















2574
2575
2576
2577
2578
2579
2580
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







  }


  } /* End of the SWITCH statement */
  return rc;
}

#if SQLITE_TCL_NRE
/*
** Adaptor that provides an objCmd interface to the NRE-enabled
** interface implementation.
*/
static int DbObjCmdAdaptor(
  void *cd,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *const*objv
){
  return Tcl_NRCallObjProc(interp, DbObjCmd, cd, objc, objv);
}
#endif /* SQLITE_TCL_NRE */

/*
**   sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN?
**                           ?-create BOOLEAN? ?-nomutex BOOLEAN?
**
** This is the main Tcl command.  When the "sqlite" Tcl command is
** invoked, this routine runs to process that command.
**
2709
2710
2711
2712
2713
2714
2715




2716


2717
2718
2719
2720
2721
2722
2723
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943

2944
2945
2946
2947
2948
2949
2950
2951
2952







+
+
+
+
-
+
+







    Tcl_Free((char*)p);
    sqlite3_free(zErrMsg);
    return TCL_ERROR;
  }
  p->maxStmt = NUM_PREPARED_STMTS;
  p->interp = interp;
  zArg = Tcl_GetStringFromObj(objv[1], 0);
  if( DbUseNre() ){
    Tcl_NRCreateCommand(interp, zArg, DbObjCmdAdaptor, DbObjCmd,
                        (char*)p, DbDeleteCmd);
  }else{
  Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd);
    Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd);
  }
  return TCL_OK;
}

/*
** Provide a dummy Tcl_InitStubs if we are using this as a static
** library.
*/
2770
2771
2772
2773
2774
2775
2776
2777
2778


























































































































































































































































































































































































2779

































2780
2781
2782
2783
2784
2785
2786
2999
3000
3001
3002
3003
3004
3005


3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424







-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







EXTERN int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
EXTERN int Sqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK; }
EXTERN int Tclsqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK;}
#endif

#ifdef TCLSH
/*****************************************************************************
** The code that follows is used to build standalone TCL interpreters
** that are statically linked with SQLite.  
** All of the code that follows is used to build standalone TCL interpreters
** that are statically linked with SQLite.  Enable these by compiling
** with -DTCLSH=n where n can be 1 or 2.  An n of 1 generates a standard
** tclsh but with SQLite built in.  An n of 2 generates the SQLite space
** analysis program.
*/

#if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5)
/*
 * This code implements the MD5 message-digest algorithm.
 * The algorithm is due to Ron Rivest.  This code was
 * written by Colin Plumb in 1993, no copyright is claimed.
 * This code is in the public domain; do with it what you wish.
 *
 * Equivalent code is available from RSA Data Security, Inc.
 * This code has been tested against that, and is equivalent,
 * except that you don't need to include two pages of legalese
 * with every copy.
 *
 * To compute the message digest of a chunk of bytes, declare an
 * MD5Context structure, pass it to MD5Init, call MD5Update as
 * needed on buffers full of bytes, and then call MD5Final, which
 * will fill a supplied 16-byte array with the digest.
 */

/*
 * If compiled on a machine that doesn't have a 32-bit integer,
 * you just set "uint32" to the appropriate datatype for an
 * unsigned 32-bit integer.  For example:
 *
 *       cc -Duint32='unsigned long' md5.c
 *
 */
#ifndef uint32
#  define uint32 unsigned int
#endif

struct MD5Context {
  int isInit;
  uint32 buf[4];
  uint32 bits[2];
  unsigned char in[64];
};
typedef struct MD5Context MD5Context;

/*
 * Note: this code is harmless on little-endian machines.
 */
static void byteReverse (unsigned char *buf, unsigned longs){
        uint32 t;
        do {
                t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
                            ((unsigned)buf[1]<<8 | buf[0]);
                *(uint32 *)buf = t;
                buf += 4;
        } while (--longs);
}
/* The four core functions - F1 is optimized somewhat */

/* #define F1(x, y, z) (x & y | ~x & z) */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))

/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f, w, x, y, z, data, s) \
        ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )

/*
 * The core of the MD5 algorithm, this alters an existing MD5 hash to
 * reflect the addition of 16 longwords of new data.  MD5Update blocks
 * the data and converts bytes into longwords for this routine.
 */
static void MD5Transform(uint32 buf[4], const uint32 in[16]){
        register uint32 a, b, c, d;

        a = buf[0];
        b = buf[1];
        c = buf[2];
        d = buf[3];

        MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);
        MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
        MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
        MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
        MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);
        MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
        MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
        MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
        MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);
        MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
        MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
        MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
        MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);
        MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
        MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
        MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);

        MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);
        MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);
        MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
        MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
        MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);
        MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);
        MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
        MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
        MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);
        MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);
        MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
        MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
        MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);
        MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);
        MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
        MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);

        MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);
        MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
        MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
        MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
        MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);
        MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
        MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
        MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
        MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);
        MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
        MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
        MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
        MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);
        MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
        MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
        MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);

        MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);
        MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
        MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
        MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
        MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);
        MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
        MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
        MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
        MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);
        MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
        MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
        MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
        MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);
        MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
        MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
        MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);

        buf[0] += a;
        buf[1] += b;
        buf[2] += c;
        buf[3] += d;
}

/*
 * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
 * initialization constants.
 */
static void MD5Init(MD5Context *ctx){
        ctx->isInit = 1;
        ctx->buf[0] = 0x67452301;
        ctx->buf[1] = 0xefcdab89;
        ctx->buf[2] = 0x98badcfe;
        ctx->buf[3] = 0x10325476;
        ctx->bits[0] = 0;
        ctx->bits[1] = 0;
}

/*
 * Update context to reflect the concatenation of another buffer full
 * of bytes.
 */
static 
void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){
        uint32 t;

        /* Update bitcount */

        t = ctx->bits[0];
        if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
                ctx->bits[1]++; /* Carry from low to high */
        ctx->bits[1] += len >> 29;

        t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */

        /* Handle any leading odd-sized chunks */

        if ( t ) {
                unsigned char *p = (unsigned char *)ctx->in + t;

                t = 64-t;
                if (len < t) {
                        memcpy(p, buf, len);
                        return;
                }
                memcpy(p, buf, t);
                byteReverse(ctx->in, 16);
                MD5Transform(ctx->buf, (uint32 *)ctx->in);
                buf += t;
                len -= t;
        }

        /* Process data in 64-byte chunks */

        while (len >= 64) {
                memcpy(ctx->in, buf, 64);
                byteReverse(ctx->in, 16);
                MD5Transform(ctx->buf, (uint32 *)ctx->in);
                buf += 64;
                len -= 64;
        }

        /* Handle any remaining bytes of data. */

        memcpy(ctx->in, buf, len);
}

/*
 * Final wrapup - pad to 64-byte boundary with the bit pattern 
 * 1 0* (64-bit count of bits processed, MSB-first)
 */
static void MD5Final(unsigned char digest[16], MD5Context *ctx){
        unsigned count;
        unsigned char *p;

        /* Compute number of bytes mod 64 */
        count = (ctx->bits[0] >> 3) & 0x3F;

        /* Set the first char of padding to 0x80.  This is safe since there is
           always at least one byte free */
        p = ctx->in + count;
        *p++ = 0x80;

        /* Bytes of padding needed to make 64 bytes */
        count = 64 - 1 - count;

        /* Pad out to 56 mod 64 */
        if (count < 8) {
                /* Two lots of padding:  Pad the first block to 64 bytes */
                memset(p, 0, count);
                byteReverse(ctx->in, 16);
                MD5Transform(ctx->buf, (uint32 *)ctx->in);

                /* Now fill the next block with 56 bytes */
                memset(ctx->in, 0, 56);
        } else {
                /* Pad block to 56 bytes */
                memset(p, 0, count-8);
        }
        byteReverse(ctx->in, 14);

        /* Append length in bits and transform */
        ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];
        ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];

        MD5Transform(ctx->buf, (uint32 *)ctx->in);
        byteReverse((unsigned char *)ctx->buf, 4);
        memcpy(digest, ctx->buf, 16);
        memset(ctx, 0, sizeof(ctx));    /* In case it is sensitive */
}

/*
** Convert a 128-bit MD5 digest into a 32-digit base-16 number.
*/
static void MD5DigestToBase16(unsigned char *digest, char *zBuf){
  static char const zEncode[] = "0123456789abcdef";
  int i, j;

  for(j=i=0; i<16; i++){
    int a = digest[i];
    zBuf[j++] = zEncode[(a>>4)&0xf];
    zBuf[j++] = zEncode[a & 0xf];
  }
  zBuf[j] = 0;
}


/*
** Convert a 128-bit MD5 digest into sequency of eight 5-digit integers
** each representing 16 bits of the digest and separated from each
** other by a "-" character.
*/
static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){
  int i, j;
  unsigned int x;
  for(i=j=0; i<16; i+=2){
    x = digest[i]*256 + digest[i+1];
    if( i>0 ) zDigest[j++] = '-';
    sprintf(&zDigest[j], "%05u", x);
    j += 5;
  }
  zDigest[j] = 0;
}

/*
** A TCL command for md5.  The argument is the text to be hashed.  The
** Result is the hash in base64.  
*/
static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){
  MD5Context ctx;
  unsigned char digest[16];
  char zBuf[50];
  void (*converter)(unsigned char*, char*);

  if( argc!=2 ){
    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], 
        " TEXT\"", 0);
    return TCL_ERROR;
  }
  MD5Init(&ctx);
  MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1]));
  MD5Final(digest, &ctx);
  converter = (void(*)(unsigned char*,char*))cd;
  converter(digest, zBuf);
  Tcl_AppendResult(interp, zBuf, (char*)0);
  return TCL_OK;
}

/*
** A TCL command to take the md5 hash of a file.  The argument is the
** name of the file.
*/
static int md5file_cmd(void*cd, Tcl_Interp*interp, int argc, const char **argv){
  FILE *in;
  MD5Context ctx;
  void (*converter)(unsigned char*, char*);
  unsigned char digest[16];
  char zBuf[10240];

  if( argc!=2 ){
    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], 
        " FILENAME\"", 0);
    return TCL_ERROR;
  }
  in = fopen(argv[1],"rb");
  if( in==0 ){
    Tcl_AppendResult(interp,"unable to open file \"", argv[1], 
         "\" for reading", 0);
    return TCL_ERROR;
  }
  MD5Init(&ctx);
  for(;;){
    int n;
    n = fread(zBuf, 1, sizeof(zBuf), in);
    if( n<=0 ) break;
    MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n);
  }
  fclose(in);
  MD5Final(digest, &ctx);
  converter = (void(*)(unsigned char*,char*))cd;
  converter(digest, zBuf);
  Tcl_AppendResult(interp, zBuf, (char*)0);
  return TCL_OK;
}

/*
** Register the four new TCL commands for generating MD5 checksums
** with the TCL interpreter.
*/
int Md5_Init(Tcl_Interp *interp){
  Tcl_CreateCommand(interp, "md5", (Tcl_CmdProc*)md5_cmd,
                    MD5DigestToBase16, 0);
  Tcl_CreateCommand(interp, "md5-10x8", (Tcl_CmdProc*)md5_cmd,
                    MD5DigestToBase10x8, 0);
  Tcl_CreateCommand(interp, "md5file", (Tcl_CmdProc*)md5file_cmd,
                    MD5DigestToBase16, 0);
  Tcl_CreateCommand(interp, "md5file-10x8", (Tcl_CmdProc*)md5file_cmd,
                    MD5DigestToBase10x8, 0);
  return TCL_OK;
}
#endif /* defined(SQLITE_TEST) || defined(SQLITE_TCLMD5) */

#if defined(SQLITE_TEST)
/*
** During testing, the special md5sum() aggregate function is available.
** inside SQLite.  The following routines implement that function.
*/
static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){
  MD5Context *p;
  int i;
  if( argc<1 ) return;
  p = sqlite3_aggregate_context(context, sizeof(*p));
  if( p==0 ) return;
  if( !p->isInit ){
    MD5Init(p);
  }
  for(i=0; i<argc; i++){
    const char *zData = (char*)sqlite3_value_text(argv[i]);
    if( zData ){
      MD5Update(p, (unsigned char*)zData, strlen(zData));
    }
  }
}
static void md5finalize(sqlite3_context *context){
  MD5Context *p;
  unsigned char digest[16];
  char zBuf[33];
  p = sqlite3_aggregate_context(context, sizeof(*p));
  MD5Final(digest,p);
  MD5DigestToBase16(digest, zBuf);
  sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
}
int Md5_Register(sqlite3 *db){
  int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0, 
                                 md5step, md5finalize);
  sqlite3_overload_function(db, "md5sum", -1);  /* To exercise this API */
  return rc;
}
#endif /* defined(SQLITE_TEST) */


/*
** If the macro TCLSH is one, then put in code this for the
** "main" routine that will initialize Tcl and take input from
** standard input, or if a file is named on the command line
** the TCL interpreter reads and evaluates that file.
*/
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833



2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850

2851
2852
2853
2854
2855
2856
2857
2858
2859

2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875

2876
2877
2878
2879
2880
2881
2882
2883

2884
2885
2886
2887
2888
2889
2890

2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901

2902
2903
2904
2905
2906
2907
2908

2909
2910
2911
2912
2913
3443
3444
3445
3446
3447
3448
3449










3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466

3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492

3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522

3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533

3534
3535
3536
3537
3538
3539
3540

3541
3542
3543
3544
3545
3546







-
-
-
-
-
-
-
-
-
-












+
+
+


-














+









+

-














+








+






-
+










-
+






-
+





    "} else {\n"
      "append line \\n\n"
    "}\n"
  "}\n"
;
#endif

/*
** If the macro TCLSH is two, then get the main loop code out of
** the separate file "spaceanal_tcl.h".
*/
#if TCLSH==2
static char zMainloop[] = 
#include "spaceanal_tcl.h"
;
#endif

#define TCLSH_MAIN main   /* Needed to fake out mktclapp */
int TCLSH_MAIN(int argc, char **argv){
  Tcl_Interp *interp;
  
  /* Call sqlite3_shutdown() once before doing anything else. This is to
  ** test that sqlite3_shutdown() can be safely called by a process before
  ** sqlite3_initialize() is. */
  sqlite3_shutdown();

  Tcl_FindExecutable(argv[0]);
  interp = Tcl_CreateInterp();
  Sqlite3_Init(interp);
#if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5)
  Md5_Init(interp);
#endif
#ifdef SQLITE_TEST
  {
    extern int Md5_Init(Tcl_Interp*);
    extern int Sqliteconfig_Init(Tcl_Interp*);
    extern int Sqlitetest1_Init(Tcl_Interp*);
    extern int Sqlitetest2_Init(Tcl_Interp*);
    extern int Sqlitetest3_Init(Tcl_Interp*);
    extern int Sqlitetest4_Init(Tcl_Interp*);
    extern int Sqlitetest5_Init(Tcl_Interp*);
    extern int Sqlitetest6_Init(Tcl_Interp*);
    extern int Sqlitetest7_Init(Tcl_Interp*);
    extern int Sqlitetest8_Init(Tcl_Interp*);
    extern int Sqlitetest9_Init(Tcl_Interp*);
    extern int Sqlitetestasync_Init(Tcl_Interp*);
    extern int Sqlitetest_autoext_Init(Tcl_Interp*);
    extern int Sqlitetest_func_Init(Tcl_Interp*);
    extern int Sqlitetest_hexio_Init(Tcl_Interp*);
    extern int Sqlitetest_init_Init(Tcl_Interp*);
    extern int Sqlitetest_malloc_Init(Tcl_Interp*);
    extern int Sqlitetest_mutex_Init(Tcl_Interp*);
    extern int Sqlitetestschema_Init(Tcl_Interp*);
    extern int Sqlitetestsse_Init(Tcl_Interp*);
    extern int Sqlitetesttclvar_Init(Tcl_Interp*);
    extern int SqlitetestThread_Init(Tcl_Interp*);
    extern int SqlitetestOnefile_Init();
    extern int SqlitetestOsinst_Init(Tcl_Interp*);
    extern int Sqlitetestbackup_Init(Tcl_Interp*);
    extern int Sqlitetestintarray_Init(Tcl_Interp*);

    Md5_Init(interp);
    Sqliteconfig_Init(interp);
    Sqlitetest1_Init(interp);
    Sqlitetest2_Init(interp);
    Sqlitetest3_Init(interp);
    Sqlitetest4_Init(interp);
    Sqlitetest5_Init(interp);
    Sqlitetest6_Init(interp);
    Sqlitetest7_Init(interp);
    Sqlitetest8_Init(interp);
    Sqlitetest9_Init(interp);
    Sqlitetestasync_Init(interp);
    Sqlitetest_autoext_Init(interp);
    Sqlitetest_func_Init(interp);
    Sqlitetest_hexio_Init(interp);
    Sqlitetest_init_Init(interp);
    Sqlitetest_malloc_Init(interp);
    Sqlitetest_mutex_Init(interp);
    Sqlitetestschema_Init(interp);
    Sqlitetesttclvar_Init(interp);
    SqlitetestThread_Init(interp);
    SqlitetestOnefile_Init(interp);
    SqlitetestOsinst_Init(interp);
    Sqlitetestbackup_Init(interp);
    Sqlitetestintarray_Init(interp);

#ifdef SQLITE_SSE
    Sqlitetestsse_Init(interp);
#endif
  }
#endif
  if( argc>=2 || TCLSH==2 ){
  if( argc>=2 ){
    int i;
    char zArgc[32];
    sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-(3-TCLSH));
    Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY);
    Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY);
    Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
    for(i=3-TCLSH; i<argc; i++){
      Tcl_SetVar(interp, "argv", argv[i],
          TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE);
    }
    if( TCLSH==1 && Tcl_EvalFile(interp, argv[1])!=TCL_OK ){
    if( Tcl_EvalFile(interp, argv[1])!=TCL_OK ){
      const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
      if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp);
      fprintf(stderr,"%s: %s\n", *argv, zInfo);
      return 1;
    }
  }
  if( argc<=1 || TCLSH==2 ){
  if( argc<=1 ){
    Tcl_GlobalEval(interp, zMainloop);
  }
  return 0;
}
#endif /* TCLSH */
Changes to src/test1.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
8
9
10
11
12
13
14


15
16
17
18
19
20
21







-
-







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.353 2009/05/03 20:23:54 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*
1095
1096
1097
1098
1099
1100
1101

1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108

1109
1110
1111
1112
1113
1114
1115







+








-







      sqlite3_result_error(context, "x_count totals to 42", -1);
    }else{
      sqlite3_result_int(context, p ? p->n : 0);
    }
  }
}

#ifndef SQLITE_OMIT_DEPRECATED
static void legacyCountStep(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  /* no-op */
}

#ifndef SQLITE_OMIT_DEPRECATED
static void legacyCountFinalize(sqlite3_context *context){
  sqlite3_result_int(context, sqlite3_aggregate_count(context));
}
#endif

/*
** Usage:  sqlite3_create_aggregate DB
2305
2306
2307
2308
2309
2310
2311

2312

2313
2314
2315
2316
2317
2318
2319
2320
2321











2322
2323
2324
2325
2326
2327
2328
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312









2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330







+

+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+







    case SQLITE_UTF16BE:
      Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16BE",-1));
      break;
    default:
      assert(0);
  }

  sqlite3BeginBenignMalloc();
  pVal = sqlite3ValueNew(0);
  if( pVal ){
  sqlite3ValueSetStr(pVal, nA, zA, encin, SQLITE_STATIC);
  n = sqlite3_value_bytes(pVal);
  Tcl_ListObjAppendElement(i,pX,
      Tcl_NewStringObj((char*)sqlite3_value_text(pVal),n));
  sqlite3ValueSetStr(pVal, nB, zB, encin, SQLITE_STATIC);
  n = sqlite3_value_bytes(pVal);
  Tcl_ListObjAppendElement(i,pX,
      Tcl_NewStringObj((char*)sqlite3_value_text(pVal),n));
  sqlite3ValueFree(pVal);
    sqlite3ValueSetStr(pVal, nA, zA, encin, SQLITE_STATIC);
    n = sqlite3_value_bytes(pVal);
    Tcl_ListObjAppendElement(i,pX,
        Tcl_NewStringObj((char*)sqlite3_value_text(pVal),n));
    sqlite3ValueSetStr(pVal, nB, zB, encin, SQLITE_STATIC);
    n = sqlite3_value_bytes(pVal);
    Tcl_ListObjAppendElement(i,pX,
        Tcl_NewStringObj((char*)sqlite3_value_text(pVal),n));
    sqlite3ValueFree(pVal);
  }
  sqlite3EndBenignMalloc();

  Tcl_EvalObjEx(i, pX, 0);
  Tcl_DecrRefCount(pX);
  Tcl_GetIntFromObj(i, Tcl_GetObjResult(i), &res);
  return res;
}
static int test_collate(
3295
3296
3297
3298
3299
3300
3301

3302
3303
3304
3305
3306
3307
3308
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311







+







    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  zSql = Tcl_GetString(objv[2]);
  if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;

  rc = sqlite3_prepare(db, zSql, bytes, &pStmt, objc>=5 ? &zTail : 0);
  Tcl_ResetResult(interp);
  if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
  if( zTail && objc>=5 ){
    if( bytes>=0 ){
      bytes = bytes - (zTail-zSql);
    }
    if( strlen(zTail)<bytes ){
      bytes = strlen(zTail);
3352
3353
3354
3355
3356
3357
3358

3359
3360
3361
3362
3363
3364
3365
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369







+







  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  zSql = Tcl_GetString(objv[2]);
  if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;

  rc = sqlite3_prepare_v2(db, zSql, bytes, &pStmt, objc>=5 ? &zTail : 0);
  assert(rc==SQLITE_OK || pStmt==0);
  Tcl_ResetResult(interp);
  if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
  if( zTail && objc>=5 ){
    if( bytes>=0 ){
      bytes = bytes - (zTail-zSql);
    }
    Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0);
  }
4713
4714
4715
4716
4717
4718
4719

4720
4721
4722
4723

4724
4725
4726
4727
4728
4729
4730
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727

4728
4729
4730
4731
4732
4733
4734
4735







+



-
+







    { "SQLITE_LIMIT_EXPR_DEPTH",          SQLITE_LIMIT_EXPR_DEPTH           },
    { "SQLITE_LIMIT_COMPOUND_SELECT",     SQLITE_LIMIT_COMPOUND_SELECT      },
    { "SQLITE_LIMIT_VDBE_OP",             SQLITE_LIMIT_VDBE_OP              },
    { "SQLITE_LIMIT_FUNCTION_ARG",        SQLITE_LIMIT_FUNCTION_ARG         },
    { "SQLITE_LIMIT_ATTACHED",            SQLITE_LIMIT_ATTACHED             },
    { "SQLITE_LIMIT_LIKE_PATTERN_LENGTH", SQLITE_LIMIT_LIKE_PATTERN_LENGTH  },
    { "SQLITE_LIMIT_VARIABLE_NUMBER",     SQLITE_LIMIT_VARIABLE_NUMBER      },
    { "SQLITE_LIMIT_TRIGGER_DEPTH",       SQLITE_LIMIT_TRIGGER_DEPTH        },
    
    /* Out of range test cases */
    { "SQLITE_LIMIT_TOOSMALL",            -1,                               },
    { "SQLITE_LIMIT_TOOBIG",              SQLITE_LIMIT_VARIABLE_NUMBER+1    },
    { "SQLITE_LIMIT_TOOBIG",              SQLITE_LIMIT_TRIGGER_DEPTH+1      },
  };
  int i, id;
  int val;
  const char *zId;

  if( objc!=4 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"",
4858
4859
4860
4861
4862
4863
4864































4865
4866
4867
4868
4869
4870

4871
4872
4873
4874
4875
4876
4877
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






+







  }
  rc = sqlite3_unlock_notify(db, test_unlock_notify_cb, (void *)interp);
  Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
  return TCL_OK;
}
#endif


/*
**     tcl_objproc COMMANDNAME ARGS...
**
** Run a TCL command using its objProc interface.  Throw an error if
** the command has no objProc interface.
*/
static int runAsObjProc(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  Tcl_CmdInfo cmdInfo;
  if( objc<2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "COMMAND ...");
    return TCL_ERROR;
  }
  if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
    Tcl_AppendResult(interp, "command not found: ",
           Tcl_GetString(objv[1]), (char*)0);
    return TCL_ERROR;
  }
  if( cmdInfo.objProc==0 ){
    Tcl_AppendResult(interp, "command has no objProc: ",
           Tcl_GetString(objv[1]), (char*)0);
    return TCL_ERROR;
  }
  return cmdInfo.objProc(cmdInfo.objClientData, interp, objc-1, objv+1);
}


/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest1_Init(Tcl_Interp *interp){
  extern int sqlite3_search_count;
  extern int sqlite3_found_count;
  extern int sqlite3_interrupt_count;
  extern int sqlite3_open_file_count;
  extern int sqlite3_sort_count;
  extern int sqlite3_current_time;
#if SQLITE_OS_UNIX && defined(__APPLE__)
  extern int sqlite3_hostid_num;
#endif
4974
4975
4976
4977
4978
4979
4980

4981
4982
4983
4984
4985
4986
4987
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025







+







     { "sqlite3_enable_load_extension", test_enable_load,        0},
     { "sqlite3_extended_result_codes", test_extended_result_codes, 0},
     { "sqlite3_limit",                 test_limit,                 0},

     { "save_prng_state",               save_prng_state,    0 },
     { "restore_prng_state",            restore_prng_state, 0 },
     { "reset_prng_state",              reset_prng_state,   0 },
     { "tcl_objproc",                   runAsObjProc,       0 },

     /* sqlite3_column_*() API */
     { "sqlite3_column_count",          test_column_count  ,0 },
     { "sqlite3_data_count",            test_data_count    ,0 },
     { "sqlite3_column_type",           test_column_type   ,0 },
     { "sqlite3_column_blob",           test_column_blob   ,0 },
     { "sqlite3_column_double",         test_column_double ,0 },
5084
5085
5086
5087
5088
5089
5090


5091
5092
5093
5094
5095
5096
5097
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137







+
+







  }
  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, 
        aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
  }
  Tcl_LinkVar(interp, "sqlite_search_count", 
      (char*)&sqlite3_search_count, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_found_count", 
      (char*)&sqlite3_found_count, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_sort_count", 
      (char*)&sqlite3_sort_count, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite3_max_blobsize", 
      (char*)&sqlite3_max_blobsize, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_like_count", 
      (char*)&sqlite3_like_count, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_interrupt_count", 
Changes to src/test2.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
8
9
10
11
12
13
14


15
16
17
18
19
20
21







-
-







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the pager.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test2.c,v 1.71 2009/06/18 17:22:39 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

51
52
53
54
55
56
57







58
59
60
61
62
63
64
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69







+
+
+
+
+
+
+







  return zName;
}

/*
** Page size and reserved size used for testing.
*/
static int test_pagesize = 1024;

/*
** Dummy page reinitializer
*/
static void pager_test_reiniter(DbPage *pNotUsed){
  return;
}

/*
** Usage:   pager_open FILENAME N-PAGE
**
** Open a new pager
*/
static int pager_open(
75
76
77
78
79
80
81
82


83
84
85
86
87
88
89
80
81
82
83
84
85
86

87
88
89
90
91
92
93
94
95







-
+
+







  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " FILENAME N-PAGE\"", 0);
    return TCL_ERROR;
  }
  if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR;
  rc = sqlite3PagerOpen(sqlite3_vfs_find(0), &pPager, argv[1], 0, 0,
      SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB);
      SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB,
      pager_test_reiniter);
  if( rc!=SQLITE_OK ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  sqlite3PagerSetCachesize(pPager, nPage);
  pageSize = test_pagesize;
  sqlite3PagerSetPagesize(pPager, &pageSize, -1);
338
339
340
341
342
343
344


345


346
347
348
349
350
351
352
344
345
346
347
348
349
350
351
352

353
354
355
356
357
358
359
360
361







+
+
-
+
+







  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID PGNO\"", 0);
    return TCL_ERROR;
  }
  pPager = sqlite3TestTextToPtr(argv[1]);
  if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
  rc = sqlite3PagerSharedLock(pPager);
  if( rc==SQLITE_OK ){
  rc = sqlite3PagerGet(pPager, pgno, &pPage);
    rc = sqlite3PagerGet(pPager, pgno, &pPage);
  }
  if( rc!=SQLITE_OK ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPage);
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
628
629
630
631
632
633
634

635
636
637
638
639
640
641







-







int Sqlitetest2_Init(Tcl_Interp *interp){
  extern int sqlite3_io_error_persist;
  extern int sqlite3_io_error_pending;
  extern int sqlite3_io_error_hit;
  extern int sqlite3_io_error_hardhit;
  extern int sqlite3_diskfull_pending;
  extern int sqlite3_diskfull;
  extern int sqlite3_pager_n_sort_bucket;
  static struct {
    char *zName;
    Tcl_CmdProc *xProc;
  } aCmd[] = {
    { "pager_open",              (Tcl_CmdProc*)pager_open          },
    { "pager_close",             (Tcl_CmdProc*)pager_close         },
    { "pager_commit",            (Tcl_CmdProc*)pager_commit        },
664
665
666
667
668
669
670
671
672
673
674
672
673
674
675
676
677
678


679
680







-
-


     (char*)&sqlite3_io_error_hardhit, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_diskfull_pending",
     (char*)&sqlite3_diskfull_pending, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_diskfull",
     (char*)&sqlite3_diskfull, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_pending_byte",
     (char*)&sqlite3PendingByte, TCL_LINK_INT | TCL_LINK_READ_ONLY);
  Tcl_LinkVar(interp, "sqlite_pager_n_sort_bucket",
     (char*)&sqlite3_pager_n_sort_bucket, TCL_LINK_INT);
  return TCL_OK;
}
Changes to src/test3.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
8
9
10
11
12
13
14


15
16
17
18
19
20
21







-
-







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the btree.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test3.c,v 1.104 2009/05/04 11:42:30 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "btreeInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
151
152
153
154
155
156
157































































































































































































































































































































158
159
160
161
162
163
164







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







  if( rc!=SQLITE_OK ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** Usage:   btree_rollback ID
**
** Rollback changes
*/
static int btree_rollback(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Btree *pBt;
  int rc;
  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TestTextToPtr(argv[1]);
  sqlite3BtreeEnter(pBt);
  rc = sqlite3BtreeRollback(pBt);
  sqlite3BtreeLeave(pBt);
  if( rc!=SQLITE_OK ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** Usage:   btree_commit ID
**
** Commit all changes
*/
static int btree_commit(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Btree *pBt;
  int rc;
  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TestTextToPtr(argv[1]);
  sqlite3BtreeEnter(pBt);
  rc = sqlite3BtreeCommit(pBt);
  sqlite3BtreeLeave(pBt);
  if( rc!=SQLITE_OK ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** Usage:   btree_begin_statement ID
**
** Start a new statement transaction
*/
static int btree_begin_statement(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Btree *pBt;
  int rc;
  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TestTextToPtr(argv[1]);
  sqlite3BtreeEnter(pBt);
  rc = sqlite3BtreeBeginStmt(pBt, 1);
  sqlite3BtreeLeave(pBt);
  if( rc!=SQLITE_OK ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** Usage:   btree_rollback_statement ID
**
** Rollback changes
*/
static int btree_rollback_statement(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Btree *pBt;
  int rc;
  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TestTextToPtr(argv[1]);
  sqlite3BtreeEnter(pBt);
  rc = sqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, 0);
  if( rc==SQLITE_OK ){
    rc = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, 0);
  }
  sqlite3BtreeLeave(pBt);
  if( rc!=SQLITE_OK ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** Usage:   btree_commit_statement ID
**
** Commit all changes
*/
static int btree_commit_statement(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Btree *pBt;
  int rc;
  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TestTextToPtr(argv[1]);
  sqlite3BtreeEnter(pBt);
  rc = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, 0);
  sqlite3BtreeLeave(pBt);
  if( rc!=SQLITE_OK ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** Usage:   btree_create_table ID FLAGS
**
** Create a new table in the database
*/
static int btree_create_table(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Btree *pBt;
  int rc, iTable, flags;
  char zBuf[30];
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID FLAGS\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TestTextToPtr(argv[1]);
  if( Tcl_GetInt(interp, argv[2], &flags) ) return TCL_ERROR;
  sqlite3BtreeEnter(pBt);
  rc = sqlite3BtreeCreateTable(pBt, &iTable, flags);
  sqlite3BtreeLeave(pBt);
  if( rc!=SQLITE_OK ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", iTable);
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;
}

/*
** Usage:   btree_drop_table ID TABLENUM
**
** Delete an entire table from the database
*/
static int btree_drop_table(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Btree *pBt;
  int iTable;
  int rc;
  int notUsed1;
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID TABLENUM\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TestTextToPtr(argv[1]);
  if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR;
  sqlite3BtreeEnter(pBt);
  rc = sqlite3BtreeDropTable(pBt, iTable, &notUsed1);
  sqlite3BtreeLeave(pBt);
  if( rc!=SQLITE_OK ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** Usage:   btree_clear_table ID TABLENUM
**
** Remove all entries from the given table but keep the table around.
*/
static int btree_clear_table(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Btree *pBt;
  int iTable;
  int rc;
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID TABLENUM\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TestTextToPtr(argv[1]);
  if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR;
  sqlite3BtreeEnter(pBt);
  rc = sqlite3BtreeClearTable(pBt, iTable, 0);
  sqlite3BtreeLeave(pBt);
  if( rc!=SQLITE_OK ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** Usage:   btree_get_meta ID
**
** Return meta data
*/
static int btree_get_meta(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Btree *pBt;
  int rc;
  int i;
  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TestTextToPtr(argv[1]);
  for(i=0; i<SQLITE_N_BTREE_META; i++){
    char zBuf[30];
    u32 v;
    sqlite3BtreeEnter(pBt);
    rc = sqlite3BtreeGetMeta(pBt, i, &v);
    sqlite3BtreeLeave(pBt);
    if( rc!=SQLITE_OK ){
      Tcl_AppendResult(interp, errorName(rc), 0);
      return TCL_ERROR;
    }
    sqlite3_snprintf(sizeof(zBuf), zBuf,"%d",v);
    Tcl_AppendElement(interp, zBuf);
  }
  return TCL_OK;
}

/*
** Usage:   btree_update_meta ID METADATA...
**
** Return meta data
*/
static int btree_update_meta(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Btree *pBt;
  int rc;
  int i;
  int aMeta[SQLITE_N_BTREE_META];

  if( argc!=2+SQLITE_N_BTREE_META ){
    char zBuf[30];
    sqlite3_snprintf(sizeof(zBuf), zBuf,"%d",SQLITE_N_BTREE_META);
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID METADATA...\" (METADATA is ", zBuf, " integers)", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TestTextToPtr(argv[1]);
  for(i=1; i<SQLITE_N_BTREE_META; i++){
    if( Tcl_GetInt(interp, argv[i+2], &aMeta[i]) ) return TCL_ERROR;
  }
  for(i=1; i<SQLITE_N_BTREE_META; i++){
    sqlite3BtreeEnter(pBt);
    rc = sqlite3BtreeUpdateMeta(pBt, i, aMeta[i]);
    sqlite3BtreeLeave(pBt);
    if( rc!=SQLITE_OK ){
      Tcl_AppendResult(interp, errorName(rc), 0);
      return TCL_ERROR;
    }
  }
  return TCL_OK;
}

/*
** Usage:   btree_pager_stats ID
**
** Returns pager statistics
*/
static int btree_pager_stats(
  void *NotUsed,
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
201
202
203
204
205
206
207







































































208
209
210
211
212
213
214







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







  sqlite3BtreeLeave(pBt);

  /* Release the mutex on the SQLite handle that controls this b-tree */
  sqlite3_mutex_leave(pBt->db->mutex);
  return TCL_OK;
}

/*
** Usage:   btree_integrity_check ID ROOT ...
**
** Look through every page of the given BTree file to verify correct
** formatting and linkage.  Return a line of text for each problem found.
** Return an empty string if everything worked.
*/
static int btree_integrity_check(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Btree *pBt;
  int nRoot;
  int *aRoot;
  int i;
  int nErr;
  char *zResult;

  if( argc<3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID ROOT ...\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TestTextToPtr(argv[1]);
  nRoot = argc-2;
  aRoot = (int*)sqlite3_malloc( sizeof(int)*(argc-2) );
  for(i=0; i<argc-2; i++){
    if( Tcl_GetInt(interp, argv[i+2], &aRoot[i]) ) return TCL_ERROR;
  }
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
  sqlite3BtreeEnter(pBt);
  zResult = sqlite3BtreeIntegrityCheck(pBt, aRoot, nRoot, 10000, &nErr);
  sqlite3BtreeLeave(pBt);
#else
  zResult = 0;
#endif
  sqlite3_free((void*)aRoot);
  if( zResult ){
    Tcl_AppendResult(interp, zResult, 0);
    sqlite3_free(zResult); 
  }
  return TCL_OK;
}

/*
** Usage:   btree_cursor_list ID
**
** Print information about all cursors to standard output for debugging.
*/
static int btree_cursor_list(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Btree *pBt;

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TestTextToPtr(argv[1]);
  sqlite3BtreeEnter(pBt);
  sqlite3BtreeCursorList(pBt);
  sqlite3BtreeLeave(pBt);
  return SQLITE_OK;
}

/*
** Usage:   btree_cursor ID TABLENUM WRITEABLE
**
** Create a new cursor.  Return the ID for the cursor.
*/
static int btree_cursor(
  void *NotUsed,
622
623
624
625
626
627
628


629


630
631
632
633
634
635
636
230
231
232
233
234
235
236
237
238

239
240
241
242
243
244
245
246
247







+
+
-
+
+







  }
  pBt = sqlite3TestTextToPtr(argv[1]);
  if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR;
  if( Tcl_GetBoolean(interp, argv[3], &wrFlag) ) return TCL_ERROR;
  pCur = (BtCursor *)ckalloc(sqlite3BtreeCursorSize());
  memset(pCur, 0, sqlite3BtreeCursorSize());
  sqlite3BtreeEnter(pBt);
  rc = sqlite3BtreeLockTable(pBt, iTable, wrFlag);
  if( rc==SQLITE_OK ){
  rc = sqlite3BtreeCursor(pBt, iTable, wrFlag, 0, pCur);
    rc = sqlite3BtreeCursor(pBt, iTable, wrFlag, 0, pCur);
  }
  sqlite3BtreeLeave(pBt);
  if( rc ){
    ckfree((char *)pCur);
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  sqlite3_snprintf(sizeof(zBuf), zBuf,"%p", pCur);
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
278
279
280
281
282
283
284

































































































































285
286
287
288
289
290
291







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







  if( rc ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  return SQLITE_OK;
}

/*
** Usage:   btree_move_to ID KEY
**
** Move the cursor to the entry with the given key.
*/
static int btree_move_to(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  BtCursor *pCur;
  int rc;
  int res;
  char zBuf[20];

  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID KEY\"", 0);
    return TCL_ERROR;
  }
  pCur = sqlite3TestTextToPtr(argv[1]);
  sqlite3BtreeEnter(pCur->pBtree);
  if( sqlite3BtreeFlags(pCur) & BTREE_INTKEY ){
    int iKey;
    if( Tcl_GetInt(interp, argv[2], &iKey) ){
      sqlite3BtreeLeave(pCur->pBtree);
      return TCL_ERROR;
    }
    rc = sqlite3BtreeMovetoUnpacked(pCur, 0, iKey, 0, &res);
  }else{
    rc = sqlite3BtreeMoveto(pCur, argv[2], strlen(argv[2]), 0, &res);  
  }
  sqlite3BtreeLeave(pCur->pBtree);
  if( rc ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  if( res<0 ) res = -1;
  if( res>0 ) res = 1;
  sqlite3_snprintf(sizeof(zBuf), zBuf,"%d",res);
  Tcl_AppendResult(interp, zBuf, 0);
  return SQLITE_OK;
}

/*
** Usage:   btree_delete ID
**
** Delete the entry that the cursor is pointing to
*/
static int btree_delete(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  BtCursor *pCur;
  int rc;

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pCur = sqlite3TestTextToPtr(argv[1]);
  sqlite3BtreeEnter(pCur->pBtree);
  rc = sqlite3BtreeDelete(pCur);
  sqlite3BtreeLeave(pCur->pBtree);
  if( rc ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  return SQLITE_OK;
}

/*
** Usage:   btree_insert ID KEY DATA ?NZERO?
**
** Create a new entry with the given key and data.  If an entry already
** exists with the same key the old entry is overwritten.
*/
static int btree_insert(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  BtCursor *pCur;
  int rc;
  int nZero;

  if( objc!=4 && objc!=5 ){
    Tcl_WrongNumArgs(interp, 1, objv, "ID KEY DATA ?NZERO?");
    return TCL_ERROR;
  }
  pCur = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
  if( objc==5 ){
    if( Tcl_GetIntFromObj(interp, objv[4], &nZero) ) return TCL_ERROR;
  }else{
    nZero = 0;
  }
  sqlite3BtreeEnter(pCur->pBtree);
  if( sqlite3BtreeFlags(pCur) & BTREE_INTKEY ){
    i64 iKey;
    int len;
    unsigned char *pBuf;
    if( Tcl_GetWideIntFromObj(interp, objv[2], &iKey) ){
      sqlite3BtreeLeave(pCur->pBtree);
      return TCL_ERROR;
    }
    pBuf = Tcl_GetByteArrayFromObj(objv[3], &len);
    rc = sqlite3BtreeInsert(pCur, 0, iKey, pBuf, len, nZero, 0, 0);
  }else{
    int keylen;
    int dlen;
    unsigned char *pKBuf;
    unsigned char *pDBuf;
    pKBuf = Tcl_GetByteArrayFromObj(objv[2], &keylen);
    pDBuf = Tcl_GetByteArrayFromObj(objv[3], &dlen);
    rc = sqlite3BtreeInsert(pCur, pKBuf, keylen, pDBuf, dlen, nZero, 0, 0);
  }
  sqlite3BtreeLeave(pCur->pBtree);
  if( rc ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  return SQLITE_OK;
}

/*
** Usage:   btree_next ID
**
** Move the cursor to the next entry in the table.  Return 0 on success
** or 1 if the cursor was already on the last entry in the table or if
** the table is empty.
*/
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
306
307
308
309
310
311
312




































313
314
315
316
317
318
319







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    return TCL_ERROR;
  }
  pCur = sqlite3TestTextToPtr(argv[1]);
  sqlite3BtreeEnter(pCur->pBtree);
  rc = sqlite3BtreeNext(pCur, &res);
  sqlite3BtreeLeave(pCur->pBtree);
  if( rc ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",res);
  Tcl_AppendResult(interp, zBuf, 0);
  return SQLITE_OK;
}

/*
** Usage:   btree_prev ID
**
** Move the cursor to the previous entry in the table.  Return 0 on
** success and 1 if the cursor was already on the first entry in
** the table or if the table was empty.
*/
static int btree_prev(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  BtCursor *pCur;
  int rc;
  int res = 0;
  char zBuf[100];

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pCur = sqlite3TestTextToPtr(argv[1]);
  sqlite3BtreeEnter(pCur->pBtree);
  rc = sqlite3BtreePrevious(pCur, &res);
  sqlite3BtreeLeave(pCur->pBtree);
  if( rc ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",res);
  Tcl_AppendResult(interp, zBuf, 0);
  return SQLITE_OK;
}
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
349
350
351
352
353
354
355



































356
357
358
359
360
361
362







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    return TCL_ERROR;
  }
  sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",res);
  Tcl_AppendResult(interp, zBuf, 0);
  return SQLITE_OK;
}

/*
** Usage:   btree_last ID
**
** Move the cursor to the last entry in the table.  Return 0 if the
** cursor was left point to something and 1 if the table is empty.
*/
static int btree_last(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  BtCursor *pCur;
  int rc;
  int res = 0;
  char zBuf[100];

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pCur = sqlite3TestTextToPtr(argv[1]);
  sqlite3BtreeEnter(pCur->pBtree);
  rc = sqlite3BtreeLast(pCur, &res);
  sqlite3BtreeLeave(pCur->pBtree);
  if( rc ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",res);
  Tcl_AppendResult(interp, zBuf, 0);
  return SQLITE_OK;
}

/*
** Usage:   btree_eof ID
**
** Return TRUE if the given cursor is not pointing at a valid entry.
** Return FALSE if the cursor does point to a valid entry.
*/
static int btree_eof(
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
379
380
381
382
383
384
385




































































































































































































386
387
388
389
390
391
392







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







  rc = sqlite3BtreeEof(pCur);
  sqlite3BtreeLeave(pCur->pBtree);
  sqlite3_snprintf(sizeof(zBuf),zBuf, "%d", rc);
  Tcl_AppendResult(interp, zBuf, 0);
  return SQLITE_OK;
}

/*
** Usage:   btree_keysize ID
**
** Return the number of bytes of key.  For an INTKEY table, this
** returns the key itself.
*/
static int btree_keysize(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  BtCursor *pCur;
  u64 n;
  char zBuf[50];

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pCur = sqlite3TestTextToPtr(argv[1]);
  sqlite3BtreeEnter(pCur->pBtree);
  sqlite3BtreeKeySize(pCur, (i64*)&n);
  sqlite3BtreeLeave(pCur->pBtree);
  sqlite3_snprintf(sizeof(zBuf),zBuf, "%llu", n);
  Tcl_AppendResult(interp, zBuf, 0);
  return SQLITE_OK;
}

/*
** Usage:   btree_key ID
**
** Return the key for the entry at which the cursor is pointing.
*/
static int btree_key(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  BtCursor *pCur;
  int rc;
  u64 n;
  char *zBuf;

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pCur = sqlite3TestTextToPtr(argv[1]);
  sqlite3BtreeEnter(pCur->pBtree);
  sqlite3BtreeKeySize(pCur, (i64*)&n);
  if( sqlite3BtreeFlags(pCur) & BTREE_INTKEY ){
    char zBuf2[60];
    sqlite3_snprintf(sizeof(zBuf2),zBuf2, "%llu", n);
    Tcl_AppendResult(interp, zBuf2, 0);
  }else{
    zBuf = sqlite3_malloc( n+1 );
    rc = sqlite3BtreeKey(pCur, 0, n, zBuf);
    if( rc ){
      sqlite3BtreeLeave(pCur->pBtree);
      Tcl_AppendResult(interp, errorName(rc), 0);
      return TCL_ERROR;
    }
    zBuf[n] = 0;
    Tcl_AppendResult(interp, zBuf, 0);
    sqlite3_free(zBuf);
  }
  sqlite3BtreeLeave(pCur->pBtree);
  return SQLITE_OK;
}

/*
** Usage:   btree_data ID ?N?
**
** Return the data for the entry at which the cursor is pointing.
*/
static int btree_data(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  BtCursor *pCur;
  int rc;
  u32 n;
  char *zBuf;

  if( argc!=2 && argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pCur = sqlite3TestTextToPtr(argv[1]);
  sqlite3BtreeEnter(pCur->pBtree);
  if( argc==2 ){
    sqlite3BtreeDataSize(pCur, &n);
  }else{
    n = atoi(argv[2]);
  }
  zBuf = sqlite3_malloc( n+1 );
  rc = sqlite3BtreeData(pCur, 0, n, zBuf);
  sqlite3BtreeLeave(pCur->pBtree);
  if( rc ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    sqlite3_free(zBuf);
    return TCL_ERROR;
  }
  zBuf[n] = 0;
  Tcl_AppendResult(interp, zBuf, 0);
  sqlite3_free(zBuf);
  return SQLITE_OK;
}

/*
** Usage:   btree_fetch_key ID AMT
**
** Use the sqlite3BtreeKeyFetch() routine to get AMT bytes of the key.
** If sqlite3BtreeKeyFetch() fails, return an empty string.
*/
static int btree_fetch_key(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  BtCursor *pCur;
  int n;
  int amt;
  u64 nKey;
  const char *zBuf;
  char zStatic[1000];

  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID AMT\"", 0);
    return TCL_ERROR;
  }
  pCur = sqlite3TestTextToPtr(argv[1]);
  if( Tcl_GetInt(interp, argv[2], &n) ) return TCL_ERROR;
  sqlite3BtreeEnter(pCur->pBtree);
  sqlite3BtreeKeySize(pCur, (i64*)&nKey);
  zBuf = sqlite3BtreeKeyFetch(pCur, &amt);
  if( zBuf && amt>=n ){
    assert( nKey<sizeof(zStatic) );
    if( n>0 ) nKey = n;
    memcpy(zStatic, zBuf, (int)nKey); 
    zStatic[nKey] = 0;
    Tcl_AppendResult(interp, zStatic, 0);
  }
  sqlite3BtreeLeave(pCur->pBtree);
  return TCL_OK;
}

/*
** Usage:   btree_fetch_data ID AMT
**
** Use the sqlite3BtreeDataFetch() routine to get AMT bytes of the key.
** If sqlite3BtreeDataFetch() fails, return an empty string.
*/
static int btree_fetch_data(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  BtCursor *pCur;
  int n;
  int amt;
  u32 nData;
  const char *zBuf;
  char zStatic[1000];

  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID AMT\"", 0);
    return TCL_ERROR;
  }
  pCur = sqlite3TestTextToPtr(argv[1]);
  if( Tcl_GetInt(interp, argv[2], &n) ) return TCL_ERROR;
  sqlite3BtreeEnter(pCur->pBtree);
  sqlite3BtreeDataSize(pCur, &nData);
  zBuf = sqlite3BtreeDataFetch(pCur, &amt);
  if( zBuf && amt>=n ){
    assert( nData<sizeof(zStatic) );
    if( n>0 ) nData = n;
    memcpy(zStatic, zBuf, (int)nData); 
    zStatic[nData] = 0;
    Tcl_AppendResult(interp, zStatic, 0);
  }
  sqlite3BtreeLeave(pCur->pBtree);
  return TCL_OK;
}

/*
** Usage:   btree_payload_size ID
**
** Return the number of bytes of payload
*/
static int btree_payload_size(
  void *NotUsed,
1187
1188
1189
1190
1191
1192
1193
1194





1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
402
403
404
405
406
407
408

409
410
411
412
413
414
415
416
417

418
419
420
421
422
423

























































































































































424
425
426
427
428
429
430







-
+
+
+
+
+




-






-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pCur = sqlite3TestTextToPtr(argv[1]);
  sqlite3BtreeEnter(pCur->pBtree);
  if( sqlite3BtreeFlags(pCur) & BTREE_INTKEY ){

  /* The cursor may be in "require-seek" state. If this is the case, the
  ** call to BtreeDataSize() will fix it. */
  sqlite3BtreeDataSize(pCur, (u32*)&n2);
  if( pCur->apPage[pCur->iPage]->intKey ){
    n1 = 0;
  }else{
    sqlite3BtreeKeySize(pCur, (i64*)&n1);
  }
  sqlite3BtreeDataSize(pCur, (u32*)&n2);
  sqlite3BtreeLeave(pCur->pBtree);
  sqlite3_snprintf(sizeof(zBuf),zBuf, "%d", (int)(n1+n2));
  Tcl_AppendResult(interp, zBuf, 0);
  return SQLITE_OK;
}

/*
** Usage:   btree_cursor_info ID ?UP-CNT?
**
** Return integers containing information about the entry the
** cursor is pointing to:
**
**   aResult[0] =  The page number
**   aResult[1] =  The entry number
**   aResult[2] =  Total number of entries on this page
**   aResult[3] =  Cell size (local payload + header)
**   aResult[4] =  Number of free bytes on this page
**   aResult[5] =  Number of free blocks on the page
**   aResult[6] =  Total payload size (local + overflow)
**   aResult[7] =  Header size in bytes
**   aResult[8] =  Local payload size
**   aResult[9] =  Parent page number
**   aResult[10]=  Page number of the first overflow page
*/
static int btree_cursor_info(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  BtCursor *pCur;
  int rc;
  int i, j;
  int up;
  int aResult[11];
  char zBuf[400];

  if( argc!=2 && argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID ?UP-CNT?\"", 0);
    return TCL_ERROR;
  }
  pCur = sqlite3TestTextToPtr(argv[1]);
  if( argc==3 ){
    if( Tcl_GetInt(interp, argv[2], &up) ) return TCL_ERROR;
  }else{
    up = 0;
  }
  sqlite3BtreeEnter(pCur->pBtree);
  rc = sqlite3BtreeCursorInfo(pCur, aResult, up);
  if( rc ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    sqlite3BtreeLeave(pCur->pBtree);
    return TCL_ERROR;
  }
  j = 0;
  for(i=0; i<sizeof(aResult)/sizeof(aResult[0]); i++){
    sqlite3_snprintf(40,&zBuf[j]," %d", aResult[i]);
    j += strlen(&zBuf[j]);
  }
  sqlite3BtreeLeave(pCur->pBtree);
  Tcl_AppendResult(interp, &zBuf[1], 0);
  return SQLITE_OK;
}

/*
** Copied from btree.c:
*/
static u32 t4Get4byte(unsigned char *p){
  return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
}

/*
**   btree_ovfl_info  BTREE  CURSOR
**
** Given a cursor, return the sequence of pages number that form the
** overflow pages for the data of the entry that the cursor is point
** to.
*/ 
static int btree_ovfl_info(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Btree *pBt;
  BtCursor *pCur;
  Pager *pPager;
  int rc;
  int n;
  int dataSize;
  u32 pgno;
  void *pPage;
  int aResult[11];
  char zElem[100];
  Tcl_DString str;

  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
                    " BTREE CURSOR", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TestTextToPtr(argv[1]);
  pCur = sqlite3TestTextToPtr(argv[2]);
  if( (*(void**)pCur) != (void*)pBt ){
    Tcl_AppendResult(interp, "Cursor ", argv[2], " does not belong to btree ",
       argv[1], 0);
    return TCL_ERROR;
  }
  sqlite3BtreeEnter(pBt);
  pPager = sqlite3BtreePager(pBt);
  rc = sqlite3BtreeCursorInfo(pCur, aResult, 0);
  if( rc ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    sqlite3BtreeLeave(pBt);
    return TCL_ERROR;
  }
  dataSize = pBt->pBt->usableSize;
  Tcl_DStringInit(&str);
  n = aResult[6] - aResult[8];
  n = (n + dataSize - 1)/dataSize;
  pgno = (u32)aResult[10];
  while( pgno && n-- ){
    DbPage *pDbPage;
    sprintf(zElem, "%d", pgno);
    Tcl_DStringAppendElement(&str, zElem);
    if( sqlite3PagerGet(pPager, pgno, &pDbPage)!=SQLITE_OK ){
      Tcl_DStringFree(&str);
      Tcl_AppendResult(interp, "unable to get page ", zElem, 0);
      sqlite3BtreeLeave(pBt);
      return TCL_ERROR;
    }
    pPage = sqlite3PagerGetData(pDbPage);
    pgno = t4Get4byte((unsigned char*)pPage);
    sqlite3PagerUnref(pDbPage);
  }
  sqlite3BtreeLeave(pBt);
  Tcl_DStringResult(interp, &str);
  return SQLITE_OK;
}

/*
** The command is provided for the purpose of setting breakpoints.
** in regression test scripts.
**
** By setting a GDB breakpoint on this procedure and executing the
** btree_breakpoint command in a test script, we can stop GDB at
** the point in the script where the btree_breakpoint command is
** inserted.  This is useful for debugging.
*/
static int btree_breakpoint(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  return TCL_OK;
}

/*
** usage:   varint_test  START  MULTIPLIER  COUNT  INCREMENT
**
** This command tests the putVarint() and getVarint()
** routines, both for accuracy and for speed.
**
** An integer is written using putVarint() and read back with
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
545
546
547
548
549
550
551
































552
553
554
555
556
557
558







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-








  pBt = db->aDb[iDb].pBt;
  sqlite3_snprintf(sizeof(zBuf), zBuf, "%p", pBt);
  Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
  return TCL_OK;
}


/*
** usage:   btree_set_cache_size ID NCACHE
**
** Set the size of the cache used by btree $ID.
*/
static int btree_set_cache_size(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  int nCache;
  Btree *pBt;

  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " BT NCACHE\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TestTextToPtr(argv[1]);
  if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR;

  sqlite3_mutex_enter(pBt->db->mutex);
  sqlite3BtreeEnter(pBt);
  sqlite3BtreeSetCacheSize(pBt, nCache);
  sqlite3BtreeLeave(pBt);
  sqlite3_mutex_leave(pBt->db->mutex);

  return TCL_OK;
}

/*
** Usage:   btree_ismemdb ID
**
** Return true if the B-Tree is in-memory.
*/
static int btree_ismemdb(
  void *NotUsed,
1541
1542
1543
1544
1545
1546
1547































1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594

1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623







624
625
626


627

628





629
630



631



632




633
634
635
636
637
638
639
640
641





642
643







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+












-
-
-
-
-
-
-



-
-

-

-
-
-
-
-


-
-
-

-
-
-

-
-
-
-

+







-
-
-
-
-


  res = sqlite3PagerIsMemdb(sqlite3BtreePager(pBt));
  sqlite3BtreeLeave(pBt);
  sqlite3_mutex_leave(pBt->db->mutex);
  Tcl_SetObjResult(interp, Tcl_NewBooleanObj(res));
  return SQLITE_OK;
}

/*
** usage:   btree_set_cache_size ID NCACHE
**
** Set the size of the cache used by btree $ID.
*/
static int btree_set_cache_size(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  int nCache;
  Btree *pBt;
  
  if( argc!=3 ){
    Tcl_AppendResult(
        interp, "wrong # args: should be \"", argv[0], " BT NCACHE\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TestTextToPtr(argv[1]);
  if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR;

  sqlite3_mutex_enter(pBt->db->mutex);
  sqlite3BtreeEnter(pBt);
  sqlite3BtreeSetCacheSize(pBt, nCache);
  sqlite3BtreeLeave(pBt);
  sqlite3_mutex_leave(pBt->db->mutex);
  return TCL_OK;
}      



/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest3_Init(Tcl_Interp *interp){
  static struct {
     char *zName;
     Tcl_CmdProc *xProc;
  } aCmd[] = {
     { "btree_open",               (Tcl_CmdProc*)btree_open               },
     { "btree_close",              (Tcl_CmdProc*)btree_close              },
     { "btree_begin_transaction",  (Tcl_CmdProc*)btree_begin_transaction  },
     { "btree_commit",             (Tcl_CmdProc*)btree_commit             },
     { "btree_rollback",           (Tcl_CmdProc*)btree_rollback           },
     { "btree_create_table",       (Tcl_CmdProc*)btree_create_table       },
     { "btree_drop_table",         (Tcl_CmdProc*)btree_drop_table         },
     { "btree_clear_table",        (Tcl_CmdProc*)btree_clear_table        },
     { "btree_get_meta",           (Tcl_CmdProc*)btree_get_meta           },
     { "btree_update_meta",        (Tcl_CmdProc*)btree_update_meta        },
     { "btree_pager_stats",        (Tcl_CmdProc*)btree_pager_stats        },
     { "btree_cursor",             (Tcl_CmdProc*)btree_cursor             },
     { "btree_close_cursor",       (Tcl_CmdProc*)btree_close_cursor       },
     { "btree_move_to",            (Tcl_CmdProc*)btree_move_to            },
     { "btree_delete",             (Tcl_CmdProc*)btree_delete             },
     { "btree_next",               (Tcl_CmdProc*)btree_next               },
     { "btree_prev",               (Tcl_CmdProc*)btree_prev               },
     { "btree_eof",                (Tcl_CmdProc*)btree_eof                },
     { "btree_keysize",            (Tcl_CmdProc*)btree_keysize            },
     { "btree_key",                (Tcl_CmdProc*)btree_key                },
     { "btree_data",               (Tcl_CmdProc*)btree_data               },
     { "btree_fetch_key",          (Tcl_CmdProc*)btree_fetch_key          },
     { "btree_fetch_data",         (Tcl_CmdProc*)btree_fetch_data         },
     { "btree_payload_size",       (Tcl_CmdProc*)btree_payload_size       },
     { "btree_first",              (Tcl_CmdProc*)btree_first              },
     { "btree_last",               (Tcl_CmdProc*)btree_last               },
     { "btree_integrity_check",    (Tcl_CmdProc*)btree_integrity_check    },
     { "btree_breakpoint",         (Tcl_CmdProc*)btree_breakpoint         },
     { "btree_varint_test",        (Tcl_CmdProc*)btree_varint_test        },
     { "btree_begin_statement",    (Tcl_CmdProc*)btree_begin_statement    },
     { "btree_commit_statement",   (Tcl_CmdProc*)btree_commit_statement   },
     { "btree_rollback_statement", (Tcl_CmdProc*)btree_rollback_statement },
     { "btree_from_db",            (Tcl_CmdProc*)btree_from_db            },
     { "btree_set_cache_size",     (Tcl_CmdProc*)btree_set_cache_size     },
     { "btree_cursor_info",        (Tcl_CmdProc*)btree_cursor_info        },
     { "btree_ovfl_info",          (Tcl_CmdProc*)btree_ovfl_info          },
     { "btree_cursor_list",        (Tcl_CmdProc*)btree_cursor_list        },
     { "btree_ismemdb",            (Tcl_CmdProc*)btree_ismemdb            },
     { "btree_set_cache_size",     (Tcl_CmdProc*)btree_set_cache_size     }
  };
  int i;

  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }

  /* The btree_insert command is implemented using the tcl 'object'
  ** interface, not the string interface like the other commands in this
  ** file. This is so binary data can be inserted into btree tables.
  */
  Tcl_CreateObjCommand(interp, "btree_insert", btree_insert, 0, 0);
  return TCL_OK;
}
Changes to src/test4.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19












-
-







/*
** 2003 December 18
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the the SQLite library in a multithreaded environment.
**
** $Id: test4.c,v 1.24 2008/10/12 00:27:54 shane Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#if defined(SQLITE_OS_UNIX) && OS_UNIX==1 && SQLITE_THREADSAFE
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
645
646
647
648
649
650
651






























652
653
654
655
656
657
658
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







  }
  thread_wait(&threadset[i]);
  sqlite3TestMakePointerStr(interp, zBuf, threadset[i].db);
  threadset[i].db = 0;
  Tcl_AppendResult(interp, zBuf, (char*)0);
  return TCL_OK;
}

/*
** Usage: thread_db_put ID DB
**
*/
static int tcl_thread_db_put(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  int i;
  extern int sqlite3TestMakePointerStr(Tcl_Interp*, char*, void*);
  extern void *sqlite3TestTextToPtr(const char *);
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID DB", 0);
    return TCL_ERROR;
  }
  i = parse_thread_id(interp, argv[1]);
  if( i<0 ) return TCL_ERROR;
  if( !threadset[i].busy ){
    Tcl_AppendResult(interp, "no such thread", 0);
    return TCL_ERROR;
  }
  thread_wait(&threadset[i]);
  assert( !threadset[i].db );
  threadset[i].db = (sqlite3*)sqlite3TestTextToPtr(argv[2]);
  return TCL_OK;
}

/*
** Usage: thread_stmt_get ID
**
** Return the database stmt pointer for the given thread.  Then
** remove the pointer from the thread itself. 
*/
700
701
702
703
704
705
706

707
708
709
710
711
712
713
714
715
716
717
718
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747







+












     { "thread_result",     (Tcl_CmdProc*)tcl_thread_result     },
     { "thread_error",      (Tcl_CmdProc*)tcl_thread_error      },
     { "thread_compile",    (Tcl_CmdProc*)tcl_thread_compile    },
     { "thread_step",       (Tcl_CmdProc*)tcl_thread_step       },
     { "thread_finalize",   (Tcl_CmdProc*)tcl_thread_finalize   },
     { "thread_swap",       (Tcl_CmdProc*)tcl_thread_swap       },
     { "thread_db_get",     (Tcl_CmdProc*)tcl_thread_db_get     },
     { "thread_db_put",     (Tcl_CmdProc*)tcl_thread_db_put     },
     { "thread_stmt_get",   (Tcl_CmdProc*)tcl_thread_stmt_get   },
  };
  int i;

  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }
  return TCL_OK;
}
#else
int Sqlitetest4_Init(Tcl_Interp *interp){ return TCL_OK; }
#endif /* SQLITE_OS_UNIX */
Changes to src/test5.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
10
11
12
13
14
15
16


17
18
19
20
21
22
23







-
-







**
*************************************************************************
** Code for testing the utf.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library. Specifically, the code in this file
** is used for testing the SQLite routines for converting between
** the various supported unicode encodings.
**
** $Id: test5.c,v 1.22 2008/08/12 15:04:59 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

Changes to src/test6.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
9
10
11
12
13
14
15


16
17
18
19
20
21
22







-
-







**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains code that modified the OS layer in order to simulate
** the effect on the database file of an OS crash or power failure.  This
** is used to test the ability of SQLite to recover from those situations.
**
** $Id: test6.c,v 1.43 2009/02/11 14:27:04 danielk1977 Exp $
*/
#if SQLITE_TEST          /* This file is used for testing only */
#include "sqliteInt.h"
#include "tcl.h"

#ifndef SQLITE_OMIT_DISKIO  /* This file is a no-op if disk I/O is disabled */

Changes to src/test7.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2006 January 09
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the client/server version of the SQLite library.
** Derived from test4.c.
**
** $Id: test7.c,v 1.13 2008/10/12 00:27:54 shane Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"

/*
** This test only works on UNIX with a SQLITE_THREADSAFE build that includes
** the SQLITE_SERVER option.
Changes to src/test8.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
8
9
10
11
12
13
14


15
16
17
18
19
20
21







-
-







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the virtual table interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test8.c,v 1.78 2009/04/29 11:50:54 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

#ifndef SQLITE_OMIT_VIRTUALTABLE
Changes to src/test9.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
9
10
11
12
13
14
15


16
17
18
19
20
21
22







-
-







**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains obscure tests of the C-interface required
** for completeness. Test code is written in C for these cases
** as there is not much point in binding to Tcl.
**
** $Id: test9.c,v 1.7 2009/04/02 18:32:27 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*
Changes to src/test_async.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19












-
-







/*
** 2005 December 14
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** $Id: test_async.c,v 1.62 2009/04/28 13:01:09 drh Exp $
**
** This file contains a binding of the asynchronous IO extension interface
** (defined in ext/async/sqlite3async.h) to Tcl.
*/

#define TCL_THREADS 
#include <tcl.h>

Changes to src/test_autoext.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19












-
-







/*
** 2006 August 23
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Test extension for testing the sqlite3_auto_extension() function.
**
** $Id: test_autoext.c,v 1.5 2008/07/08 02:12:37 drh Exp $
*/
#include "tcl.h"
#include "sqlite3ext.h"

#ifndef SQLITE_OMIT_LOAD_EXTENSION
static SQLITE_EXTENSION_INIT1

Changes to src/test_backup.c.
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20











+

-







/*
** 2009 January 28
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains test logic for the sqlite3_backup() interface.
**
** $Id: test_backup.c,v 1.3 2009/03/30 12:56:52 drh Exp $
*/

#include "tcl.h"
#include <sqlite3.h>
#include <assert.h>

/* These functions are implemented in test1.c. */
Changes to src/test_btree.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
8
9
10
11
12
13
14


15
16
17
18
19
20
21







-
-







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the btree.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test_btree.c,v 1.8 2008/09/29 11:49:48 danielk1977 Exp $
*/
#include "btreeInt.h"
#include <tcl.h>

/*
** Usage: sqlite3_shared_cache_report
**
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
56
57
58
59
60
61
62





















































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
       pCur, pCur->pgnoRoot, zMode,
       pPage ? pPage->pgno : 0, pCur->aiIdx[pCur->iPage],
       (pCur->eState==CURSOR_VALID) ? "" : " eof"
    );
  }
#endif
}


/*
** Fill aResult[] with information about the entry and page that the
** cursor is pointing to.
** 
**   aResult[0] =  The page number
**   aResult[1] =  The entry number
**   aResult[2] =  Total number of entries on this page
**   aResult[3] =  Cell size (local payload + header)
**   aResult[4] =  Number of free bytes on this page
**   aResult[5] =  Number of free blocks on the page
**   aResult[6] =  Total payload size (local + overflow)
**   aResult[7] =  Header size in bytes
**   aResult[8] =  Local payload size
**   aResult[9] =  Parent page number
**   aResult[10]=  Page number of the first overflow page
**
** This routine is used for testing and debugging only.
*/
int sqlite3BtreeCursorInfo(BtCursor *pCur, int *aResult, int upCnt){
#if 0
  int cnt, idx;
  MemPage *pPage = pCur->apPage[pCur->iPage];
  BtCursor tmpCur;
  int rc;

  if( pCur->eState==CURSOR_REQUIRESEEK ){
    rc = sqlite3BtreeRestoreCursorPosition(pCur);
    if( rc!=SQLITE_OK ){
      return rc;
    }
  }

  assert( pPage->isInit );
  sqlite3BtreeGetTempCursor(pCur, &tmpCur);
  while( upCnt-- ){
    sqlite3BtreeMoveToParent(&tmpCur);
  }
  pPage = tmpCur.pPage;
  aResult[0] = sqlite3PagerPagenumber(pPage->pDbPage);
  assert( aResult[0]==pPage->pgno );
  aResult[1] = tmpCur.idx;
  aResult[2] = pPage->nCell;
  if( tmpCur.idx>=0 && tmpCur.idx<pPage->nCell ){
    sqlite3BtreeParseCell(tmpCur.pPage, tmpCur.idx, &tmpCur.info);
    aResult[3] = tmpCur.info.nSize;
    aResult[6] = tmpCur.info.nData;
    aResult[7] = tmpCur.info.nHeader;
    aResult[8] = tmpCur.info.nLocal;
  }else{
    aResult[3] = 0;
    aResult[6] = 0;
    aResult[7] = 0;
    aResult[8] = 0;
  }
  aResult[4] = pPage->nFree;
  cnt = 0;
  idx = get2byte(&pPage->aData[pPage->hdrOffset+1]);
  while( idx>0 && idx<pPage->pBt->usableSize ){
    cnt++;
    idx = get2byte(&pPage->aData[idx]);
  }
  aResult[5] = cnt;
  if( pPage->pParent==0 || sqlite3BtreeIsRootPage(pPage) ){
    aResult[9] = 0;
  }else{
    aResult[9] = pPage->pParent->pgno;
  }
  if( tmpCur.info.iOverflow ){
    aResult[10] = get4byte(&tmpCur.info.pCell[tmpCur.info.iOverflow]);
  }else{
    aResult[10] = 0;
  }
  sqlite3BtreeReleaseTempCursor(&tmpCur);
#endif
  return SQLITE_OK;
}
Changes to src/test_config.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
11
12
13
14
15
16
17


18
19
20
21
22
23
24







-
-







*************************************************************************
** 
** This file contains code used for testing the SQLite system.
** None of the code in this file goes into a deliverable build.
** 
** The focus of this file is providing the TCL testing layer
** access to compile-time constants.
**
** $Id: test_config.c,v 1.50 2009/06/19 14:06:03 drh Exp $
*/

#include "sqliteLimit.h"

#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
391
392
393
394
395
396
397






398
399
400
401
402
403
404
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408







+
+
+
+
+
+







#endif

#ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
  Tcl_SetVar2(interp, "sqlite_options", "schema_version", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_ENABLE_STAT2
  Tcl_SetVar2(interp, "sqlite_options", "stat2", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "stat2", "0", TCL_GLOBAL_ONLY);
#endif

#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
#  if defined(__APPLE__)
#    define SQLITE_ENABLE_LOCKING_STYLE 1
#  else
#    define SQLITE_ENABLE_LOCKING_STYLE 0
#  endif
527
528
529
530
531
532
533

534
535
536
537
538
539
540
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545







+







  LINKVAR( MAX_COMPOUND_SELECT );
  LINKVAR( MAX_VDBE_OP );
  LINKVAR( MAX_FUNCTION_ARG );
  LINKVAR( MAX_VARIABLE_NUMBER );
  LINKVAR( MAX_PAGE_SIZE );
  LINKVAR( MAX_PAGE_COUNT );
  LINKVAR( MAX_LIKE_PATTERN_LENGTH );
  LINKVAR( MAX_TRIGGER_DEPTH );
  LINKVAR( DEFAULT_TEMP_CACHE_SIZE );
  LINKVAR( DEFAULT_CACHE_SIZE );
  LINKVAR( DEFAULT_PAGE_SIZE );
  LINKVAR( DEFAULT_FILE_FORMAT );
  LINKVAR( MAX_ATTACHED );

  {
Changes to src/test_devsym.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
9
10
11
12
13
14
15


16
17
18
19
20
21
22







-
-







**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains code that modified the OS layer in order to simulate
** different device types (by overriding the return values of the 
** xDeviceCharacteristics() and xSectorSize() methods).
**
** $Id: test_devsym.c,v 1.9 2008/12/09 01:32:03 drh Exp $
*/
#if SQLITE_TEST          /* This file is used for testing only */

#include "sqlite3.h"
#include "sqliteInt.h"

/*
Changes to src/test_func.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2008 March 19
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces.  This code
** implements new SQL functions used by the test scripts.
**
** $Id: test_func.c,v 1.15 2009/05/07 13:43:49 drh Exp $
*/
#include "sqlite3.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

152
153
154
155
156
157
158

159
160
161
162
163
164
165

166
167
168
169
170
171
172
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172







+







+







** API function.
*/
void sqlite3BeginBenignMalloc(void);
void sqlite3EndBenignMalloc(void);
static void test_agg_errmsg16_step(sqlite3_context *a, int b,sqlite3_value **c){
}
static void test_agg_errmsg16_final(sqlite3_context *ctx){
#ifndef SQLITE_OMIT_UTF16
  const void *z;
  sqlite3 * db = sqlite3_context_db_handle(ctx);
  sqlite3_aggregate_context(ctx, 2048);
  sqlite3BeginBenignMalloc();
  z = sqlite3_errmsg16(db);
  sqlite3EndBenignMalloc();
  sqlite3_result_text16(ctx, z, -1, SQLITE_TRANSIENT);
#endif
}

/*
** Routines for testing the sqlite3_get_auxdata() and sqlite3_set_auxdata()
** interface.
**
** The test_auxdata() SQL function attempts to register each of its arguments
306
307
308
309
310
311
312






































































































313
314
315
316
317
318
319
320
321
322
323
324


325

326
327
328
329
330
331
332
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+












+
+

+







    assert( pStmt==0 );
    zErr = sqlite3_mprintf("sqlite3_prepare_v2() error: %s",sqlite3_errmsg(db));
    sqlite3_result_text(pCtx, zErr, -1, sqlite3_free);
    sqlite3_result_error_code(pCtx, rc);
  }
}


/*
** convert one character from hex to binary
*/
static int testHexChar(char c){
  if( c>='0' && c<='9' ){
    return c - '0';
  }else if( c>='a' && c<='f' ){
    return c - 'a' + 10;
  }else if( c>='A' && c<='F' ){
    return c - 'A' + 10;
  }
  return 0;
}

/*
** Convert hex to binary.
*/
static void testHexToBin(const char *zIn, char *zOut){
  while( zIn[0] && zIn[1] ){
    *(zOut++) = (testHexChar(zIn[0])<<4) + testHexChar(zIn[1]);
    zIn += 2;
  }
}

/*
**      hex_to_utf16be(HEX)
**
** Convert the input string from HEX into binary.  Then return the
** result using sqlite3_result_text16le().
*/
static void testHexToUtf16be(
  sqlite3_context *pCtx, 
  int nArg,
  sqlite3_value **argv
){
  int n;
  const char *zIn;
  char *zOut;
  assert( nArg==1 );
  n = sqlite3_value_bytes(argv[0]);
  zIn = (const char*)sqlite3_value_text(argv[0]);
  zOut = sqlite3_malloc( n/2 );
  if( zOut==0 ){
    sqlite3_result_error_nomem(pCtx);
  }else{
    testHexToBin(zIn, zOut);
    sqlite3_result_text16be(pCtx, zOut, n/2, sqlite3_free);
  }
}

/*
**      hex_to_utf8(HEX)
**
** Convert the input string from HEX into binary.  Then return the
** result using sqlite3_result_text16le().
*/
static void testHexToUtf8(
  sqlite3_context *pCtx, 
  int nArg,
  sqlite3_value **argv
){
  int n;
  const char *zIn;
  char *zOut;
  assert( nArg==1 );
  n = sqlite3_value_bytes(argv[0]);
  zIn = (const char*)sqlite3_value_text(argv[0]);
  zOut = sqlite3_malloc( n/2 );
  if( zOut==0 ){
    sqlite3_result_error_nomem(pCtx);
  }else{
    testHexToBin(zIn, zOut);
    sqlite3_result_text(pCtx, zOut, n/2, sqlite3_free);
  }
}

/*
**      hex_to_utf16le(HEX)
**
** Convert the input string from HEX into binary.  Then return the
** result using sqlite3_result_text16le().
*/
static void testHexToUtf16le(
  sqlite3_context *pCtx, 
  int nArg,
  sqlite3_value **argv
){
  int n;
  const char *zIn;
  char *zOut;
  assert( nArg==1 );
  n = sqlite3_value_bytes(argv[0]);
  zIn = (const char*)sqlite3_value_text(argv[0]);
  zOut = sqlite3_malloc( n/2 );
  if( zOut==0 ){
    sqlite3_result_error_nomem(pCtx);
  }else{
    testHexToBin(zIn, zOut);
    sqlite3_result_text16le(pCtx, zOut, n/2, sqlite3_free);
  }
}

static int registerTestFunctions(sqlite3 *db){
  static const struct {
     char *zName;
     signed char nArg;
     unsigned char eTextRep; /* 1: UTF-16.  0: UTF-8 */
     void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
  } aFuncs[] = {
    { "randstr",               2, SQLITE_UTF8, randStr    },
    { "test_destructor",       1, SQLITE_UTF8, test_destructor},
#ifndef SQLITE_OMIT_UTF16
    { "test_destructor16",     1, SQLITE_UTF8, test_destructor16},
    { "hex_to_utf16be",        1, SQLITE_UTF8, testHexToUtf16be},
    { "hex_to_utf16le",        1, SQLITE_UTF8, testHexToUtf16le},
#endif
    { "hex_to_utf8",           1, SQLITE_UTF8, testHexToUtf8},
    { "test_destructor_count", 0, SQLITE_UTF8, test_destructor_count},
    { "test_auxdata",         -1, SQLITE_UTF8, test_auxdata},
    { "test_error",            1, SQLITE_UTF8, test_error},
    { "test_error",            2, SQLITE_UTF8, test_error},
    { "test_eval",             1, SQLITE_UTF8, test_eval},
    { "test_isolation",        2, SQLITE_UTF8, test_isolation},
    { "test_counter",          1, SQLITE_UTF8, counterFunc},
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
545
546
547
548
549
550
551


552
553
554
555
556
557
558







-
-







  return TCL_OK;

abuse_err:
  Tcl_AppendResult(interp, "sqlite3_create_function abused test failed", 
                   (char*)0);
  return TCL_ERROR;
}



/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest_func_Init(Tcl_Interp *interp){
  static struct {
     char *zName;
Changes to src/test_hexio.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
12
13
14
15
16
17
18


19
20
21
22
23
24
25







-
-







** Code for testing all sorts of SQLite interfaces.  This code
** implements TCL commands for reading and writing the binary
** database files and displaying the content of those files as
** hexadecimal.  We could, in theory, use the built-in "binary"
** command of TCL to do a lot of this, but there are some issues
** with historical versions of the "binary" command.  So it seems
** easier and safer to build our own mechanism.
**
** $Id: test_hexio.c,v 1.7 2008/05/12 16:17:42 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

Added src/test_init.c.































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
** 2009 August 17
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** The code in this file is used for testing SQLite. It is not part of
** the source code used in production systems.
**
** Specifically, this file tests the effect of errors while initializing
** the various pluggable sub-systems from within sqlite3_initialize().
** If an error occurs in sqlite3_initialize() the following should be
** true:
**
**   1) An error code is returned to the user, and
**   2) A subsequent call to sqlite3_shutdown() calls the shutdown method
**      of those subsystems that were initialized, and
**   3) A subsequent call to sqlite3_initialize() attempts to initialize
**      the remaining, uninitialized, subsystems.
*/

#include "sqliteInt.h"
#include <string.h>
#include <tcl.h>

static struct Wrapped {
  sqlite3_pcache_methods pcache;
  sqlite3_mem_methods    mem;
  sqlite3_mutex_methods  mutex;

  int mem_init;                /* True if mem subsystem is initalized */
  int mem_fail;                /* True to fail mem subsystem inialization */
  int mutex_init;              /* True if mutex subsystem is initalized */
  int mutex_fail;              /* True to fail mutex subsystem inialization */
  int pcache_init;             /* True if pcache subsystem is initalized */
  int pcache_fail;             /* True to fail pcache subsystem inialization */
} wrapped;

static int wrMemInit(void *pAppData){
  int rc;
  if( wrapped.mem_fail ){
    rc = SQLITE_ERROR;
  }else{
    rc = wrapped.mem.xInit(wrapped.mem.pAppData);
  }
  if( rc==SQLITE_OK ){
    wrapped.mem_init = 1;
  }
  return rc;
}
static void wrMemShutdown(void *pAppData){
  wrapped.mem.xShutdown(wrapped.mem.pAppData);
  wrapped.mem_init = 0;
}
static void *wrMemMalloc(int n)           {return wrapped.mem.xMalloc(n);}
static void wrMemFree(void *p)            {wrapped.mem.xFree(p);}
static void *wrMemRealloc(void *p, int n) {return wrapped.mem.xRealloc(p, n);}
static int wrMemSize(void *p)             {return wrapped.mem.xSize(p);}
static int wrMemRoundup(int n)            {return wrapped.mem.xRoundup(n);}


static int wrMutexInit(void){
  int rc;
  if( wrapped.mutex_fail ){
    rc = SQLITE_ERROR;
  }else{
    rc = wrapped.mutex.xMutexInit();
  }
  if( rc==SQLITE_OK ){
    wrapped.mutex_init = 1;
  }
  return rc;
}
static int wrMutexEnd(void){
  wrapped.mutex.xMutexEnd();
  wrapped.mutex_init = 0;
  return SQLITE_OK;
}
static sqlite3_mutex *wrMutexAlloc(int e){
  return wrapped.mutex.xMutexAlloc(e);
}
static void wrMutexFree(sqlite3_mutex *p){
  wrapped.mutex.xMutexFree(p);
}
static void wrMutexEnter(sqlite3_mutex *p){
  wrapped.mutex.xMutexEnter(p);
}
static int wrMutexTry(sqlite3_mutex *p){
  return wrapped.mutex.xMutexTry(p);
}
static void wrMutexLeave(sqlite3_mutex *p){
  wrapped.mutex.xMutexLeave(p);
}
static int wrMutexHeld(sqlite3_mutex *p){
  return wrapped.mutex.xMutexHeld(p);
}
static int wrMutexNotheld(sqlite3_mutex *p){
  return wrapped.mutex.xMutexNotheld(p);
}



static int wrPCacheInit(void *pArg){
  int rc;
  if( wrapped.pcache_fail ){
    rc = SQLITE_ERROR;
  }else{
    rc = wrapped.pcache.xInit(wrapped.pcache.pArg);
  }
  if( rc==SQLITE_OK ){
    wrapped.pcache_init = 1;
  }
  return rc;
}
static void wrPCacheShutdown(void *pArg){
  wrapped.pcache.xShutdown(wrapped.pcache.pArg);
  wrapped.pcache_init = 0;
}

static sqlite3_pcache *wrPCacheCreate(int a, int b){
  return wrapped.pcache.xCreate(a, b);
}  
static void wrPCacheCachesize(sqlite3_pcache *p, int n){
  wrapped.pcache.xCachesize(p, n);
}  
static int wrPCachePagecount(sqlite3_pcache *p){
  return wrapped.pcache.xPagecount(p);
}  
static void *wrPCacheFetch(sqlite3_pcache *p, unsigned a, int b){
  return wrapped.pcache.xFetch(p, a, b);
}  
static void wrPCacheUnpin(sqlite3_pcache *p, void *a, int b){
  wrapped.pcache.xUnpin(p, a, b);
}  
static void wrPCacheRekey(sqlite3_pcache *p, void *a, unsigned b, unsigned c){
  wrapped.pcache.xRekey(p, a, b, c);
}  
static void wrPCacheTruncate(sqlite3_pcache *p, unsigned a){
  wrapped.pcache.xTruncate(p, a);
}  
static void wrPCacheDestroy(sqlite3_pcache *p){
  wrapped.pcache.xDestroy(p);
}  

static void installInitWrappers(void){
  sqlite3_mutex_methods mutexmethods = {
    wrMutexInit,  wrMutexEnd,   wrMutexAlloc,
    wrMutexFree,  wrMutexEnter, wrMutexTry,
    wrMutexLeave, wrMutexHeld,  wrMutexNotheld
  };
  sqlite3_pcache_methods pcachemethods = {
    0,
    wrPCacheInit,      wrPCacheShutdown,  wrPCacheCreate, 
    wrPCacheCachesize, wrPCachePagecount, wrPCacheFetch,
    wrPCacheUnpin,     wrPCacheRekey,     wrPCacheTruncate,  
    wrPCacheDestroy
  };
  sqlite3_mem_methods memmethods = {
    wrMemMalloc,   wrMemFree,    wrMemRealloc,
    wrMemSize,     wrMemRoundup, wrMemInit,
    wrMemShutdown,
    0
  };

  memset(&wrapped, 0, sizeof(wrapped));

  sqlite3_shutdown();
  sqlite3_config(SQLITE_CONFIG_GETMUTEX, &wrapped.mutex);
  sqlite3_config(SQLITE_CONFIG_GETMALLOC, &wrapped.mem);
  sqlite3_config(SQLITE_CONFIG_GETPCACHE, &wrapped.pcache);
  sqlite3_config(SQLITE_CONFIG_MUTEX, &mutexmethods);
  sqlite3_config(SQLITE_CONFIG_MALLOC, &memmethods);
  sqlite3_config(SQLITE_CONFIG_PCACHE, &pcachemethods);
}

static int init_wrapper_install(
  ClientData clientData, /* Unused */
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  int i;
  installInitWrappers();
  for(i=1; i<objc; i++){
    char *z = Tcl_GetString(objv[i]);
    if( strcmp(z, "mem")==0 ){
      wrapped.mem_fail = 1;
    }else if( strcmp(z, "mutex")==0 ){
      wrapped.mutex_fail = 1;
    }else if( strcmp(z, "pcache")==0 ){
      wrapped.pcache_fail = 1;
    }else{
      Tcl_AppendResult(interp, "Unknown argument: \"", z, "\"");
      return TCL_ERROR;
    }
  }
  return TCL_OK;
}

static int init_wrapper_uninstall(
  ClientData clientData, /* Unused */
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  if( objc!=1 ){
    Tcl_WrongNumArgs(interp, 1, objv, "");
    return TCL_ERROR;
  }

  memset(&wrapped, 0, sizeof(&wrapped));
  sqlite3_shutdown();
  sqlite3_config(SQLITE_CONFIG_MUTEX, &wrapped.mutex);
  sqlite3_config(SQLITE_CONFIG_MALLOC, &wrapped.mem);
  sqlite3_config(SQLITE_CONFIG_PCACHE, &wrapped.pcache);
  return TCL_OK;
}

static int init_wrapper_clear(
  ClientData clientData, /* Unused */
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  if( objc!=1 ){
    Tcl_WrongNumArgs(interp, 1, objv, "");
    return TCL_ERROR;
  }

  wrapped.mem_fail = 0;
  wrapped.mutex_fail = 0;
  wrapped.pcache_fail = 0;
  return TCL_OK;
}

static int init_wrapper_query(
  ClientData clientData, /* Unused */
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  Tcl_Obj *pRet;

  if( objc!=1 ){
    Tcl_WrongNumArgs(interp, 1, objv, "");
    return TCL_ERROR;
  }

  pRet = Tcl_NewObj();
  if( wrapped.mutex_init ){
    Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("mutex", -1));
  }
  if( wrapped.mem_init ){
    Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("mem", -1));
  }
  if( wrapped.pcache_init ){
    Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("pcache", -1));
  }

  Tcl_SetObjResult(interp, pRet);
  return TCL_OK;
}

int Sqlitetest_init_Init(Tcl_Interp *interp){
  static struct {
     char *zName;
     Tcl_ObjCmdProc *xProc;
  } aObjCmd[] = {
    {"init_wrapper_install",   init_wrapper_install},
    {"init_wrapper_query",     init_wrapper_query  },
    {"init_wrapper_uninstall", init_wrapper_uninstall},
    {"init_wrapper_clear",     init_wrapper_clear}
  };
  int i;

  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
  }

  return TCL_OK;
}
Added src/test_intarray.c.























































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
** 2009 November 10
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file implements a read-only VIRTUAL TABLE that contains the
** content of a C-language array of integer values.  See the corresponding
** header file for full details.
*/
#include "test_intarray.h"
#include <string.h>
#include <assert.h>


/*
** Definition of the sqlite3_intarray object.
**
** The internal representation of an intarray object is subject
** to change, is not externally visible, and should be used by
** the implementation of intarray only.  This object is opaque
** to users.
*/
struct sqlite3_intarray {
  int n;                    /* Number of elements in the array */
  sqlite3_int64 *a;         /* Contents of the array */
  void (*xFree)(void*);     /* Function used to free a[] */
};

/* Objects used internally by the virtual table implementation */
typedef struct intarray_vtab intarray_vtab;
typedef struct intarray_cursor intarray_cursor;

/* A intarray table object */
struct intarray_vtab {
  sqlite3_vtab base;            /* Base class */
  sqlite3_intarray *pContent;   /* Content of the integer array */
};

/* A intarray cursor object */
struct intarray_cursor {
  sqlite3_vtab_cursor base;    /* Base class */
  int i;                       /* Current cursor position */
};

/*
** None of this works unless we have virtual tables.
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE

/*
** Free an sqlite3_intarray object.
*/
static void intarrayFree(sqlite3_intarray *p){
  if( p->xFree ){
    p->xFree(p->a);
  }
  sqlite3_free(p);
}

/*
** Table destructor for the intarray module.
*/
static int intarrayDestroy(sqlite3_vtab *p){
  intarray_vtab *pVtab = (intarray_vtab*)p;
  sqlite3_free(pVtab);
  return 0;
}

/*
** Table constructor for the intarray module.
*/
static int intarrayCreate(
  sqlite3 *db,              /* Database where module is created */
  void *pAux,               /* clientdata for the module */
  int argc,                 /* Number of arguments */
  const char *const*argv,   /* Value for all arguments */
  sqlite3_vtab **ppVtab,    /* Write the new virtual table object here */
  char **pzErr              /* Put error message text here */
){
  int rc = SQLITE_NOMEM;
  intarray_vtab *pVtab = sqlite3_malloc(sizeof(intarray_vtab));

  if( pVtab ){
    memset(pVtab, 0, sizeof(intarray_vtab));
    pVtab->pContent = (sqlite3_intarray*)pAux;
    rc = sqlite3_declare_vtab(db, "CREATE TABLE x(value INTEGER PRIMARY KEY)");
  }
  *ppVtab = (sqlite3_vtab *)pVtab;
  return rc;
}

/*
** Open a new cursor on the intarray table.
*/
static int intarrayOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
  int rc = SQLITE_NOMEM;
  intarray_cursor *pCur;
  pCur = sqlite3_malloc(sizeof(intarray_cursor));
  if( pCur ){
    memset(pCur, 0, sizeof(intarray_cursor));
    *ppCursor = (sqlite3_vtab_cursor *)pCur;
    rc = SQLITE_OK;
  }
  return rc;
}

/*
** Close a intarray table cursor.
*/
static int intarrayClose(sqlite3_vtab_cursor *cur){
  intarray_cursor *pCur = (intarray_cursor *)cur;
  sqlite3_free(pCur);
  return SQLITE_OK;
}

/*
** Retrieve a column of data.
*/
static int intarrayColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
  intarray_cursor *pCur = (intarray_cursor*)cur;
  intarray_vtab *pVtab = (intarray_vtab*)cur->pVtab;
  if( pCur->i>=0 && pCur->i<pVtab->pContent->n ){
    sqlite3_result_int64(ctx, pVtab->pContent->a[pCur->i]);
  }
  return SQLITE_OK;
}

/*
** Retrieve the current rowid.
*/
static int intarrayRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
  intarray_cursor *pCur = (intarray_cursor *)cur;
  *pRowid = pCur->i;
  return SQLITE_OK;
}

static int intarrayEof(sqlite3_vtab_cursor *cur){
  intarray_cursor *pCur = (intarray_cursor *)cur;
  intarray_vtab *pVtab = (intarray_vtab *)cur->pVtab;
  return pCur->i>=pVtab->pContent->n;
}

/*
** Advance the cursor to the next row.
*/
static int intarrayNext(sqlite3_vtab_cursor *cur){
  intarray_cursor *pCur = (intarray_cursor *)cur;
  pCur->i++;
  return SQLITE_OK;
}

/*
** Reset a intarray table cursor.
*/
static int intarrayFilter(
  sqlite3_vtab_cursor *pVtabCursor, 
  int idxNum, const char *idxStr,
  int argc, sqlite3_value **argv
){
  intarray_cursor *pCur = (intarray_cursor *)pVtabCursor;
  pCur->i = 0;
  return SQLITE_OK;
}

/*
** Analyse the WHERE condition.
*/
static int intarrayBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
  return SQLITE_OK;
}

/*
** A virtual table module that merely echos method calls into TCL
** variables.
*/
static sqlite3_module intarrayModule = {
  0,                           /* iVersion */
  intarrayCreate,              /* xCreate - create a new virtual table */
  intarrayCreate,              /* xConnect - connect to an existing vtab */
  intarrayBestIndex,           /* xBestIndex - find the best query index */
  intarrayDestroy,             /* xDisconnect - disconnect a vtab */
  intarrayDestroy,             /* xDestroy - destroy a vtab */
  intarrayOpen,                /* xOpen - open a cursor */
  intarrayClose,               /* xClose - close a cursor */
  intarrayFilter,              /* xFilter - configure scan constraints */
  intarrayNext,                /* xNext - advance a cursor */
  intarrayEof,                 /* xEof */
  intarrayColumn,              /* xColumn - read data */
  intarrayRowid,               /* xRowid - read data */
  0,                           /* xUpdate */
  0,                           /* xBegin */
  0,                           /* xSync */
  0,                           /* xCommit */
  0,                           /* xRollback */
  0,                           /* xFindMethod */
  0,                           /* xRename */
};

#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */

/*
** Invoke this routine to create a specific instance of an intarray object.
** The new intarray object is returned by the 3rd parameter.
**
** Each intarray object corresponds to a virtual table in the TEMP table
** with a name of zName.
**
** Destroy the intarray object by dropping the virtual table.  If not done
** explicitly by the application, the virtual table will be dropped implicitly
** by the system when the database connection is closed.
*/
int sqlite3_intarray_create(
  sqlite3 *db,
  const char *zName,
  sqlite3_intarray **ppReturn
){
  int rc;
  sqlite3_intarray *p;

  *ppReturn = p = sqlite3_malloc( sizeof(*p) );
  if( p==0 ){
    return SQLITE_NOMEM;
  }
  memset(p, 0, sizeof(*p));
  rc = sqlite3_create_module_v2(db, zName, &intarrayModule, p,
                                (void(*)(void*))intarrayFree);
  if( rc==SQLITE_OK ){
    char *zSql;
    zSql = sqlite3_mprintf("CREATE VIRTUAL TABLE temp.%Q USING %Q",
                           zName, zName);
    rc = sqlite3_exec(db, zSql, 0, 0, 0);
    sqlite3_free(zSql);
  }
  return rc;
}

/*
** Bind a new array array of integers to a specific intarray object.
**
** The array of integers bound must be unchanged for the duration of
** any query against the corresponding virtual table.  If the integer
** array does change or is deallocated undefined behavior will result.
*/
int sqlite3_intarray_bind(
  sqlite3_intarray *pIntArray,   /* The intarray object to bind to */
  int nElements,                 /* Number of elements in the intarray */
  sqlite3_int64 *aElements,      /* Content of the intarray */
  void (*xFree)(void*)           /* How to dispose of the intarray when done */
){
  if( pIntArray->xFree ){
    pIntArray->xFree(pIntArray->a);
  }
  pIntArray->n = nElements;
  pIntArray->a = aElements;
  pIntArray->xFree = xFree;
  return SQLITE_OK;
}


/*****************************************************************************
** Everything below is interface for testing this module.
*/
#ifdef SQLITE_TEST
#include <tcl.h>

/*
** Routines to encode and decode pointers
*/
extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);
extern int sqlite3TestTextToPtr(const char*);
extern int sqlite3TestMakePointerStr(Tcl_Interp*, char *zPtr, void*);
extern const char *sqlite3TestErrorName(int);

/*
**    sqlite3_intarray_create  DB  NAME
**
** Invoke the sqlite3_intarray_create interface.  A string that becomes
** the first parameter to sqlite3_intarray_bind.
*/
static int test_intarray_create(
  ClientData clientData, /* Not used */
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  sqlite3 *db;
  const char *zName;
  sqlite3_intarray *pArray;
  int rc;
  char zPtr[100];

  if( objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "DB");
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  zName = Tcl_GetString(objv[2]);
  rc = sqlite3_intarray_create(db, zName, &pArray);
  if( rc!=SQLITE_OK ){
    assert( pArray==0 );
    Tcl_AppendResult(interp, sqlite3TestErrorName(rc), (char*)0);
    return TCL_ERROR;
  }
  sqlite3TestMakePointerStr(interp, zPtr, pArray);
  Tcl_AppendResult(interp, zPtr, (char*)0);
  return TCL_OK;
}

/*
**    sqlite3_intarray_bind  INTARRAY  ?VALUE ...?
**
** Invoke the sqlite3_intarray_bind interface on the given array of integers.
*/
static int test_intarray_bind(
  ClientData clientData, /* Not used */
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  sqlite3_intarray *pArray;
  int rc;
  int i, n;
  sqlite3_int64 *a;

  if( objc<2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "INTARRAY");
    return TCL_ERROR;
  }
  pArray = (sqlite3_intarray*)sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
  n = objc - 2;
  a = sqlite3_malloc( sizeof(a[0])*n );
  if( a==0 ){
    Tcl_AppendResult(interp, "SQLITE_NOMEM", (char*)0);
    return TCL_ERROR;
  }
  for(i=0; i<n; i++){
    a[i] = 0;
    Tcl_GetWideIntFromObj(0, objv[i+2], &a[i]);
  }
  rc = sqlite3_intarray_bind(pArray, n, a, sqlite3_free);
  if( rc!=SQLITE_OK ){
    Tcl_AppendResult(interp, sqlite3TestErrorName(rc), (char*)0);
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** Register commands with the TCL interpreter.
*/
int Sqlitetestintarray_Init(Tcl_Interp *interp){
  static struct {
     char *zName;
     Tcl_ObjCmdProc *xProc;
     void *clientData;
  } aObjCmd[] = {
     { "sqlite3_intarray_create", test_intarray_create, 0 },
     { "sqlite3_intarray_bind", test_intarray_bind, 0 },
  };
  int i;
  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, 
        aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
  }
  return TCL_OK;
}

#endif /* SQLITE_TEST */
Added src/test_intarray.h.


















































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
** 2009 November 10
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This is the C-language interface definition for the "intarray" or
** integer array virtual table for SQLite.
**
** The intarray virtual table is designed to facilitate using an
** array of integers as the right-hand side of an IN operator.  So
** instead of doing a prepared statement like this:
**
**     SELECT * FROM table WHERE x IN (?,?,?,...,?);
**
** And then binding indivdual integers to each of ? slots, a C-language
** application can create an intarray object (named "ex1" in the following
** example), prepare a statement like this:
**
**     SELECT * FROM table WHERE x IN ex1;
**
** Then bind an ordinary C/C++ array of integer values to the ex1 object
** to run the statement.
**
** USAGE:
**
** One or more intarray objects can be created as follows:
**
**      sqlite3_intarray *p1, *p2, *p3;
**      sqlite3_intarray_create(db, "ex1", &p1);
**      sqlite3_intarray_create(db, "ex2", &p2);
**      sqlite3_intarray_create(db, "ex3", &p3);
**
** Each call to sqlite3_intarray_create() generates a new virtual table
** module and a singleton of that virtual table module in the TEMP
** database.  Both the module and the virtual table instance use the
** name given by the second parameter.  The virtual tables can then be
** used in prepared statements:
**
**      SELECT * FROM t1, t2, t3
**       WHERE t1.x IN ex1
**         AND t2.y IN ex2
**         AND t3.z IN ex3;
**
** Each integer array is initially empty.  New arrays can be bound to
** an integer array as follows:
**
**     sqlite3_int64 a1[] = { 1, 2, 3, 4 };
**     sqlite3_int64 a2[] = { 5, 6, 7, 8, 9, 10, 11 };
**     sqlite3_int64 *a3 = sqlite3_malloc( 100*sizeof(sqlite3_int64) );
**     // Fill in content of a3[]
**     sqlite3_intarray_bind(p1, 4, a1, 0);
**     sqlite3_intarray_bind(p2, 7, a2, 0);
**     sqlite3_intarray_bind(p3, 100, a3, sqlite3_free);
**
** A single intarray object can be rebound multiple times.  But do not
** attempt to change the bindings of an intarray while it is in the middle
** of a query.
**
** The array that holds the integers is automatically freed by the function
** in the fourth parameter to sqlite3_intarray_bind() when the array is no
** longer needed.  The application must not change the intarray values
** while an intarray is in the middle of a query.
**
** The intarray object is automatically destroyed when its corresponding
** virtual table is dropped.  Since the virtual tables are created in the
** TEMP database, they are automatically dropped when the database connection
** closes so the application does not normally need to take any special
** action to free the intarray objects.
*/
#include "sqlite3.h"

/*
** An sqlite3_intarray is an abstract type to stores an instance of
** an integer array.
*/
typedef struct sqlite3_intarray sqlite3_intarray;

/*
** Invoke this routine to create a specific instance of an intarray object.
** The new intarray object is returned by the 3rd parameter.
**
** Each intarray object corresponds to a virtual table in the TEMP table
** with a name of zName.
**
** Destroy the intarray object by dropping the virtual table.  If not done
** explicitly by the application, the virtual table will be dropped implicitly
** by the system when the database connection is closed.
*/
int sqlite3_intarray_create(
  sqlite3 *db,
  const char *zName,
  sqlite3_intarray **ppReturn
);

/*
** Bind a new array array of integers to a specific intarray object.
**
** The array of integers bound must be unchanged for the duration of
** any query against the corresponding virtual table.  If the integer
** array does change or is deallocated undefined behavior will result.
*/
int sqlite3_intarray_bind(
  sqlite3_intarray *pIntArray,   /* The intarray object to bind to */
  int nElements,                 /* Number of elements in the intarray */
  sqlite3_int64 *aElements,      /* Content of the intarray */
  void (*xFree)(void*)           /* How to dispose of the intarray when done */
);
Changes to src/test_journal.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
10
11
12
13
14
15
16


17
18
19
20
21
22
23







-
-







**
******************************************************************************
**
** This file contains code for a VFS layer that acts as a wrapper around
** an existing VFS. The code in this file attempts to verify that SQLite
** correctly populates and syncs a journal file before writing to a
** corresponding database file.
**
** $Id: test_journal.c,v 1.17 2009/06/26 10:39:36 danielk1977 Exp $
*/
#if SQLITE_TEST          /* This file is used for testing only */

#include "sqlite3.h"
#include "sqliteInt.h"

/*
Changes to src/test_loadext.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19












-
-







/*
** 2006 June 14
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Test extension for testing the sqlite3_load_extension() function.
**
** $Id: test_loadext.c,v 1.3 2008/08/02 03:50:39 drh Exp $
*/
#include <string.h>
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1

/*
** The half() SQL function returns half of its input value.
Changes to src/test_malloc.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
8
9
10
11
12
13
14


15
16
17
18
19
20
21







-
-







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code used to implement test interfaces to the
** memory allocation subsystem.
**
** $Id: test_malloc.c,v 1.54 2009/04/07 11:21:29 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

1337
1338
1339
1340
1341
1342
1343


















1344
1345
1346
1347
1348
1349
1350
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







  if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[1], &isInstall) ){
    return TCL_ERROR;
  }
  rc = faultsimInstall(isInstall);
  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
  return TCL_OK;
}

/*
** sqlite3_install_memsys3
*/
static int test_install_memsys3(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int rc = SQLITE_MISUSE;
#ifdef SQLITE_ENABLE_MEMSYS3
  const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
  rc = sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetMemsys3());
#endif
  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
  return TCL_OK;
}

/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest_malloc_Init(Tcl_Interp *interp){
  static struct {
     char *zName;
1374
1375
1376
1377
1378
1379
1380

1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406







+









     { "sqlite3_config_heap",        test_config_heap              ,0 },
     { "sqlite3_config_memstatus",   test_config_memstatus         ,0 },
     { "sqlite3_config_lookaside",   test_config_lookaside         ,0 },
     { "sqlite3_config_error",       test_config_error             ,0 },
     { "sqlite3_db_config_lookaside",test_db_config_lookaside      ,0 },
     { "sqlite3_dump_memsys3",       test_dump_memsys3             ,3 },
     { "sqlite3_dump_memsys5",       test_dump_memsys3             ,5 },
     { "sqlite3_install_memsys3",    test_install_memsys3          ,0 },
  };
  int i;
  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
    ClientData c = (ClientData)aObjCmd[i].clientData;
    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, c, 0);
  }
  return TCL_OK;
}
#endif
Deleted src/test_md5.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395











































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/*
** SQLite uses this code for testing only.  It is not a part of
** the SQLite library.  This file implements two new TCL commands
** "md5" and "md5file" that compute md5 checksums on arbitrary text
** and on complete files.  These commands are used by the "testfixture"
** program to help verify the correct operation of the SQLite library.
**
** The original use of these TCL commands was to test the ROLLBACK
** feature of SQLite.  First compute the MD5-checksum of the database.
** Then make some changes but rollback the changes rather than commit
** them.  Compute a second MD5-checksum of the file and verify that the
** two checksums are the same.  Such is the original use of this code.
** New uses may have been added since this comment was written.
**
** $Id: test_md5.c,v 1.10 2009/02/03 19:52:59 shane Exp $
*/
/*
 * This code implements the MD5 message-digest algorithm.
 * The algorithm is due to Ron Rivest.  This code was
 * written by Colin Plumb in 1993, no copyright is claimed.
 * This code is in the public domain; do with it what you wish.
 *
 * Equivalent code is available from RSA Data Security, Inc.
 * This code has been tested against that, and is equivalent,
 * except that you don't need to include two pages of legalese
 * with every copy.
 *
 * To compute the message digest of a chunk of bytes, declare an
 * MD5Context structure, pass it to MD5Init, call MD5Update as
 * needed on buffers full of bytes, and then call MD5Final, which
 * will fill a supplied 16-byte array with the digest.
 */
#include <tcl.h>
#include <string.h>
#include "sqlite3.h"

/*
 * If compiled on a machine that doesn't have a 32-bit integer,
 * you just set "uint32" to the appropriate datatype for an
 * unsigned 32-bit integer.  For example:
 *
 *       cc -Duint32='unsigned long' md5.c
 *
 */
#ifndef uint32
#  define uint32 unsigned int
#endif

struct Context {
  int isInit;
  uint32 buf[4];
  uint32 bits[2];
  unsigned char in[64];
};
typedef struct Context MD5Context;

/*
 * Note: this code is harmless on little-endian machines.
 */
static void byteReverse (unsigned char *buf, unsigned longs){
        uint32 t;
        do {
                t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
                            ((unsigned)buf[1]<<8 | buf[0]);
                *(uint32 *)buf = t;
                buf += 4;
        } while (--longs);
}
/* The four core functions - F1 is optimized somewhat */

/* #define F1(x, y, z) (x & y | ~x & z) */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))

/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f, w, x, y, z, data, s) \
        ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )

/*
 * The core of the MD5 algorithm, this alters an existing MD5 hash to
 * reflect the addition of 16 longwords of new data.  MD5Update blocks
 * the data and converts bytes into longwords for this routine.
 */
static void MD5Transform(uint32 buf[4], const uint32 in[16]){
        register uint32 a, b, c, d;

        a = buf[0];
        b = buf[1];
        c = buf[2];
        d = buf[3];

        MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);
        MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
        MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
        MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
        MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);
        MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
        MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
        MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
        MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);
        MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
        MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
        MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
        MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);
        MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
        MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
        MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);

        MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);
        MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);
        MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
        MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
        MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);
        MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);
        MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
        MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
        MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);
        MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);
        MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
        MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
        MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);
        MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);
        MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
        MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);

        MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);
        MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
        MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
        MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
        MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);
        MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
        MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
        MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
        MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);
        MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
        MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
        MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
        MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);
        MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
        MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
        MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);

        MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);
        MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
        MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
        MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
        MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);
        MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
        MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
        MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
        MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);
        MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
        MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
        MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
        MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);
        MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
        MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
        MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);

        buf[0] += a;
        buf[1] += b;
        buf[2] += c;
        buf[3] += d;
}

/*
 * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
 * initialization constants.
 */
static void MD5Init(MD5Context *ctx){
        ctx->isInit = 1;
        ctx->buf[0] = 0x67452301;
        ctx->buf[1] = 0xefcdab89;
        ctx->buf[2] = 0x98badcfe;
        ctx->buf[3] = 0x10325476;
        ctx->bits[0] = 0;
        ctx->bits[1] = 0;
}

/*
 * Update context to reflect the concatenation of another buffer full
 * of bytes.
 */
static 
void MD5Update(MD5Context *pCtx, const unsigned char *buf, unsigned int len){
        struct Context *ctx = (struct Context *)pCtx;
        uint32 t;

        /* Update bitcount */

        t = ctx->bits[0];
        if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
                ctx->bits[1]++; /* Carry from low to high */
        ctx->bits[1] += len >> 29;

        t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */

        /* Handle any leading odd-sized chunks */

        if ( t ) {
                unsigned char *p = (unsigned char *)ctx->in + t;

                t = 64-t;
                if (len < t) {
                        memcpy(p, buf, len);
                        return;
                }
                memcpy(p, buf, t);
                byteReverse(ctx->in, 16);
                MD5Transform(ctx->buf, (uint32 *)ctx->in);
                buf += t;
                len -= t;
        }

        /* Process data in 64-byte chunks */

        while (len >= 64) {
                memcpy(ctx->in, buf, 64);
                byteReverse(ctx->in, 16);
                MD5Transform(ctx->buf, (uint32 *)ctx->in);
                buf += 64;
                len -= 64;
        }

        /* Handle any remaining bytes of data. */

        memcpy(ctx->in, buf, len);
}

/*
 * Final wrapup - pad to 64-byte boundary with the bit pattern 
 * 1 0* (64-bit count of bits processed, MSB-first)
 */
static void MD5Final(unsigned char digest[16], MD5Context *pCtx){
        struct Context *ctx = (struct Context *)pCtx;
        unsigned count;
        unsigned char *p;

        /* Compute number of bytes mod 64 */
        count = (ctx->bits[0] >> 3) & 0x3F;

        /* Set the first char of padding to 0x80.  This is safe since there is
           always at least one byte free */
        p = ctx->in + count;
        *p++ = 0x80;

        /* Bytes of padding needed to make 64 bytes */
        count = 64 - 1 - count;

        /* Pad out to 56 mod 64 */
        if (count < 8) {
                /* Two lots of padding:  Pad the first block to 64 bytes */
                memset(p, 0, count);
                byteReverse(ctx->in, 16);
                MD5Transform(ctx->buf, (uint32 *)ctx->in);

                /* Now fill the next block with 56 bytes */
                memset(ctx->in, 0, 56);
        } else {
                /* Pad block to 56 bytes */
                memset(p, 0, count-8);
        }
        byteReverse(ctx->in, 14);

        /* Append length in bits and transform */
        ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];
        ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];

        MD5Transform(ctx->buf, (uint32 *)ctx->in);
        byteReverse((unsigned char *)ctx->buf, 4);
        memcpy(digest, ctx->buf, 16);
        memset(ctx, 0, sizeof(ctx));    /* In case it is sensitive */
}

/*
** Convert a digest into base-16.  digest should be declared as
** "unsigned char digest[16]" in the calling function.  The MD5
** digest is stored in the first 16 bytes.  zBuf should
** be "char zBuf[33]".
*/
static void DigestToBase16(unsigned char *digest, char *zBuf){
  static char const zEncode[] = "0123456789abcdef";
  int i, j;

  for(j=i=0; i<16; i++){
    int a = digest[i];
    zBuf[j++] = zEncode[(a>>4)&0xf];
    zBuf[j++] = zEncode[a & 0xf];
  }
  zBuf[j] = 0;
}

/*
** A TCL command for md5.  The argument is the text to be hashed.  The
** Result is the hash in base64.  
*/
static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){
  MD5Context ctx;
  unsigned char digest[16];
  char zBuf[33];

  if( argc!=2 ){
    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], 
        " TEXT\"", 0);
    return TCL_ERROR;
  }
  MD5Init(&ctx);
  MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1]));
  MD5Final(digest, &ctx);
  DigestToBase16(digest, zBuf);
  Tcl_AppendResult(interp, zBuf, (char*)0);
  return TCL_OK;
}

/*
** A TCL command to take the md5 hash of a file.  The argument is the
** name of the file.
*/
static int md5file_cmd(void*cd, Tcl_Interp*interp, int argc, const char **argv){
  FILE *in;
  MD5Context ctx;
  unsigned char digest[16];
  char zBuf[10240];

  if( argc!=2 ){
    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], 
        " FILENAME\"", 0);
    return TCL_ERROR;
  }
  in = fopen(argv[1],"rb");
  if( in==0 ){
    Tcl_AppendResult(interp,"unable to open file \"", argv[1], 
         "\" for reading", 0);
    return TCL_ERROR;
  }
  MD5Init(&ctx);
  for(;;){
    int n;
    n = fread(zBuf, 1, sizeof(zBuf), in);
    if( n<=0 ) break;
    MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n);
  }
  fclose(in);
  MD5Final(digest, &ctx);
  DigestToBase16(digest, zBuf);
  Tcl_AppendResult(interp, zBuf, (char*)0);
  return TCL_OK;
}

/*
** Register the two TCL commands above with the TCL interpreter.
*/
int Md5_Init(Tcl_Interp *interp){
  Tcl_CreateCommand(interp, "md5", (Tcl_CmdProc*)md5_cmd, 0, 0);
  Tcl_CreateCommand(interp, "md5file", (Tcl_CmdProc*)md5file_cmd, 0, 0);
  return TCL_OK;
}

/*
** During testing, the special md5sum() aggregate function is available.
** inside SQLite.  The following routines implement that function.
*/
static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){
  MD5Context *p;
  int i;
  if( argc<1 ) return;
  p = sqlite3_aggregate_context(context, sizeof(*p));
  if( p==0 ) return;
  if( !p->isInit ){
    MD5Init(p);
  }
  for(i=0; i<argc; i++){
    const char *zData = (char*)sqlite3_value_text(argv[i]);
    if( zData ){
      MD5Update(p, (unsigned char*)zData, strlen(zData));
    }
  }
}
static void md5finalize(sqlite3_context *context){
  MD5Context *p;
  unsigned char digest[16];
  char zBuf[33];
  p = sqlite3_aggregate_context(context, sizeof(*p));
  MD5Final(digest,p);
  DigestToBase16(digest, zBuf);
  sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
}
int Md5_Register(sqlite3 *db){
  int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0, 
                                 md5step, md5finalize);
  sqlite3_overload_function(db, "md5sum", -1);  /* To exercise this API */
  return rc;
}
Changes to src/test_mutex.c.
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11


12
13
14
15
16
17
18
19











-
-
+







/*
** 2008 June 18
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** 
** $Id: test_mutex.c,v 1.15 2009/03/20 13:15:30 drh Exp $
** This file contains test logic for the sqlite3_mutex interfaces.
*/

#include "tcl.h"
#include "sqlite3.h"
#include "sqliteInt.h"
#include <stdlib.h>
#include <assert.h>
Changes to src/test_onefile.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19












-
-







/*
** 2007 September 14
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** $Id: test_onefile.c,v 1.12 2009/04/07 11:21:29 danielk1977 Exp $
**
** OVERVIEW:
**
**   This file contains some example code demonstrating how the SQLite 
**   vfs feature can be used to have SQLite operate directly on an 
**   embedded media, without using an intermediate file system.
**
**   Because this is only a demo designed to run on a workstation, the
Changes to src/test_osinst.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
9
10
11
12
13
14
15


16
17
18
19
20
21
22







-
-







**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains the implementation of an SQLite vfs wrapper that
** adds instrumentation to all vfs and file methods. C and Tcl interfaces
** are provided to control the instrumentation.
**
** $Id: test_osinst.c,v 1.19 2009/01/08 17:57:32 danielk1977 Exp $
*/

#ifdef SQLITE_ENABLE_INSTVFS
/*
** C interface:
**
**   sqlite3_instvfs_create()
Changes to src/test_pcache.c.
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
16
17
18
19
20
21
22


23
24
25
26
27
28
29







-
-







** This file contains an application-defined pager cache
** implementation that can be plugged in in place of the
** default pcache.  This alternative pager cache will throw
** some errors that the default cache does not.
**
** This pagecache implementation is designed for simplicity
** not speed.  
**
** $Id: test_pcache.c,v 1.3 2009/04/11 11:38:54 drh Exp $
*/
#include "sqlite3.h"
#include <string.h>
#include <assert.h>

/*
** Global data used by this test implementation.  There is no
Changes to src/test_schema.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
8
9
10
11
12
13
14


15
16
17
18
19
20
21







-
-







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the virtual table interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test_schema.c,v 1.15 2008/07/07 14:50:14 drh Exp $
*/

/* The code in this file defines a sqlite3 virtual-table module that
** provides a read-only view of the current database schema. There is one
** row in the schema table for each column in the database schema.
*/
#define SCHEMA \
Changes to src/test_server.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19












-
-







/*
** 2006 January 07
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** $Id: test_server.c,v 1.8 2008/06/26 10:41:19 danielk1977 Exp $
**
** This file contains demonstration code.  Nothing in this file gets compiled
** or linked into the SQLite library unless you use a non-standard option:
**
**      -DSQLITE_SERVER=1
**
** The configure script will never generate a Makefile with the option
** above.  You will need to manually modify the Makefile if you want to
Changes to src/test_tclvar.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
11
12
13
14
15
16
17


18
19
20
21
22
23
24







-
-







*************************************************************************
** Code for testing the virtual table interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** The emphasis of this file is a virtual table that provides
** access to TCL variables.
**
** $Id: test_tclvar.c,v 1.17 2008/08/12 14:48:41 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

#ifndef SQLITE_OMIT_VIRTUALTABLE
Changes to src/test_thread.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
9
10
11
12
13
14
15


16
17
18
19
20
21
22







-
-







**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains the implementation of some Tcl commands used to
** test that sqlite3 database handles may be concurrently accessed by 
** multiple threads. Right now this only works on unix.
**
** $Id: test_thread.c,v 1.15 2009/03/27 12:32:56 drh Exp $
*/

#include "sqliteInt.h"
#include <tcl.h>

#if SQLITE_THREADSAFE

Changes to src/test_wsd.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
9
10
11
12
13
14
15


16
17
18
19
20
21
22







-
-







**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** The code in this file contains sample implementations of the 
** sqlite3_wsd_init() and sqlite3_wsd_find() functions required if the
** SQLITE_OMIT_WSD symbol is defined at build time.
**
** $Id: test_wsd.c,v 1.4 2009/03/23 04:33:33 danielk1977 Exp $
*/

#if defined(SQLITE_OMIT_WSD) && defined(SQLITE_TEST)

#include "sqliteInt.h"

#define PLS_HASHSIZE 43
Changes to src/tokenize.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
10
11
12
13
14
15
16


17
18
19
20
21
22
23







-
-







**
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.162 2009/06/23 20:28:54 drh Exp $
*/
#include "sqliteInt.h"
#include <stdlib.h>

/*
** The charMap() macro maps alphabetic characters into their
** lower-case ASCII equivalent.  On ASCII machines, this is just
406
407
408
409
410
411
412
413

414
415
416
417
418
419
420
404
405
406
407
408
409
410

411
412
413
414
415
416
417
418







-
+









  mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
  if( db->activeVdbeCnt==0 ){
    db->u1.isInterrupted = 0;
  }
  pParse->rc = SQLITE_OK;
  pParse->zTail = pParse->zSql = zSql;
  pParse->zTail = zSql;
  i = 0;
  assert( pzErrMsg!=0 );
  pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3Malloc);
  if( pEngine==0 ){
    db->mallocFailed = 1;
    return SQLITE_NOMEM;
  }
Changes to src/trigger.c.
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10

11


12
13
14
15
16
17
18










-
+
-
-







/*
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains the implementation for TRIGGERs
**
** $Id: trigger.c,v 1.141 2009/05/28 01:00:55 drh Exp $
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_TRIGGER
/*
** Delete a linked list of TriggerStep structures.
*/
45
46
47
48
49
50
51




52
53
54
55
56
57
58
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60







+
+
+
+







** To state it another way:  This routine returns a list of all triggers
** that fire off of pTab.  The list will include any TEMP triggers on
** pTab as well as the triggers lised in pTab->pTrigger.
*/
Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
  Schema * const pTmpSchema = pParse->db->aDb[1].pSchema;
  Trigger *pList = 0;                  /* List of triggers to return */

  if( pParse->disableTriggers ){
    return 0;
  }

  if( pTmpSchema!=pTab->pSchema ){
    HashElem *p;
    for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){
      Trigger *pTrig = (Trigger *)sqliteHashData(p);
      if( pTrig->pTabSchema==pTab->pSchema
       && 0==sqlite3StrICmp(pTrig->table, pTab->zName) 
82
83
84
85
86
87
88
89
90


91
92

93
94
95
96


97
98
99
100
101
102
103
84
85
86
87
88
89
90


91
92
93

94
95
96


97
98
99
100
101
102
103
104
105







-
-
+
+

-
+


-
-
+
+







  int op,             /* One of TK_INSERT, TK_UPDATE, TK_DELETE */
  IdList *pColumns,   /* column list if this is an UPDATE OF trigger */
  SrcList *pTableName,/* The name of the table/view the trigger applies to */
  Expr *pWhen,        /* WHEN clause */
  int isTemp,         /* True if the TEMPORARY keyword is present */
  int noErr           /* Suppress errors if the trigger already exists */
){
  Trigger *pTrigger = 0;
  Table *pTab;
  Trigger *pTrigger = 0;  /* The new trigger */
  Table *pTab;            /* Table that the trigger fires off of */
  char *zName = 0;        /* Name of the trigger */
  sqlite3 *db = pParse->db;
  sqlite3 *db = pParse->db;  /* The database connection */
  int iDb;                /* The database to store the trigger in */
  Token *pName;           /* The unqualified db name */
  DbFixer sFix;
  int iTabDb;
  DbFixer sFix;           /* State vector for the DB fixer */
  int iTabDb;             /* Index of the database holding pTab */

  assert( pName1!=0 );   /* pName1->z might be NULL, but not pName1 itself */
  assert( pName2!=0 );
  assert( op==TK_INSERT || op==TK_UPDATE || op==TK_DELETE );
  assert( op>0 && op<0xff );
  if( isTemp ){
    /* If TEMP was specified, then the trigger name may not be qualified. */
134
135
136
137
138
139
140











141
142
143
144
145
146
147
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160







+
+
+
+
+
+
+
+
+
+
+







  if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) && 
      sqlite3FixSrcList(&sFix, pTableName) ){
    goto trigger_cleanup;
  }
  pTab = sqlite3SrcListLookup(pParse, pTableName);
  if( !pTab ){
    /* The table does not exist. */
    if( db->init.iDb==1 ){
      /* Ticket #3810.
      ** Normally, whenever a table is dropped, all associated triggers are
      ** dropped too.  But if a TEMP trigger is created on a non-TEMP table
      ** and the table is dropped by a different database connection, the
      ** trigger is not visible to the database connection that does the
      ** drop so the trigger cannot be dropped.  This results in an
      ** "orphaned trigger" - a trigger whose associated table is missing.
      */
      db->init.orphanTrigger = 1;
    }
    goto trigger_cleanup;
  }
  if( IsVirtual(pTab) ){
    sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables");
    goto trigger_cleanup;
  }

204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
217
218
219
220
221
222
223

224
225
226
227
228
229
230
231







-
+







  if (tr_tm == TK_INSTEAD){
    tr_tm = TK_BEFORE;
  }

  /* Build the Trigger object */
  pTrigger = (Trigger*)sqlite3DbMallocZero(db, sizeof(Trigger));
  if( pTrigger==0 ) goto trigger_cleanup;
  pTrigger->name = zName;
  pTrigger->zName = zName;
  zName = 0;
  pTrigger->table = sqlite3DbStrDup(db, pTableName->a[0].zName);
  pTrigger->pSchema = db->aDb[iDb].pSchema;
  pTrigger->pTabSchema = pTab->pSchema;
  pTrigger->op = (u8)op;
  pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
  pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
247
248
249
250
251
252
253
254

255
256
257
258
259
260
261

262
263
264
265
266
267
268
260
261
262
263
264
265
266

267
268
269
270
271
272
273

274
275
276
277
278
279
280
281







-
+






-
+







  DbFixer sFix;
  int iDb;                                 /* Database containing the trigger */
  Token nameToken;           /* Trigger name for error reporting */

  pTrig = pParse->pNewTrigger;
  pParse->pNewTrigger = 0;
  if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup;
  zName = pTrig->name;
  zName = pTrig->zName;
  iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
  pTrig->step_list = pStepList;
  while( pStepList ){
    pStepList->pTrig = pTrig;
    pStepList = pStepList->pNext;
  }
  nameToken.z = pTrig->name;
  nameToken.z = pTrig->zName;
  nameToken.n = sqlite3Strlen30(nameToken.z);
  if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken) 
          && sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){
    goto triggerfinish_cleanup;
  }

  /* if we are not initializing, and this trigger is not on a TEMP table, 
333
334
335
336
337
338
339
340

341
342
343
344
345
346
347
346
347
348
349
350
351
352

353
354
355
356
357
358
359
360







-
+







** Allocate space to hold a new trigger step.  The allocated space
** holds both the TriggerStep object and the TriggerStep.target.z string.
**
** If an OOM error occurs, NULL is returned and db->mallocFailed is set.
*/
static TriggerStep *triggerStepAllocate(
  sqlite3 *db,                /* Database connection */
  int op,                     /* Trigger opcode */
  u8 op,                      /* Trigger opcode */
  Token *pName                /* The target name */
){
  TriggerStep *pTriggerStep;

  pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n);
  if( pTriggerStep ){
    char *z = (char*)&pTriggerStep[1];
362
363
364
365
366
367
368
369

370
371
372
373
374
375
376
375
376
377
378
379
380
381

382
383
384
385
386
387
388
389







-
+







*/
TriggerStep *sqlite3TriggerInsertStep(
  sqlite3 *db,        /* The database connection */
  Token *pTableName,  /* Name of the table into which we insert */
  IdList *pColumn,    /* List of columns in pTableName to insert into */
  ExprList *pEList,   /* The VALUE clause: a list of values to be inserted */
  Select *pSelect,    /* A SELECT statement that supplies values */
  int orconf          /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
  u8 orconf           /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
){
  TriggerStep *pTriggerStep;

  assert(pEList == 0 || pSelect == 0);
  assert(pEList != 0 || pSelect != 0 || db->mallocFailed);

  pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName);
394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
407
408
409
410
411
412
413

414
415
416
417
418
419
420
421







-
+







** sees an UPDATE statement inside the body of a CREATE TRIGGER.
*/
TriggerStep *sqlite3TriggerUpdateStep(
  sqlite3 *db,         /* The database connection */
  Token *pTableName,   /* Name of the table to be updated */
  ExprList *pEList,    /* The SET clause: list of column and new values */
  Expr *pWhere,        /* The WHERE clause */
  int orconf           /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
  u8 orconf            /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
){
  TriggerStep *pTriggerStep;

  pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName);
  if( pTriggerStep ){
    pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
    pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
436
437
438
439
440
441
442
443

444
445
446
447
448
449
450
449
450
451
452
453
454
455

456
457
458
459
460
461
462
463







-
+








/* 
** Recursively delete a Trigger structure
*/
void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){
  if( pTrigger==0 ) return;
  sqlite3DeleteTriggerStep(db, pTrigger->step_list);
  sqlite3DbFree(db, pTrigger->name);
  sqlite3DbFree(db, pTrigger->zName);
  sqlite3DbFree(db, pTrigger->table);
  sqlite3ExprDelete(db, pTrigger->pWhen);
  sqlite3IdListDelete(db, pTrigger->pColumns);
  sqlite3DbFree(db, pTrigger);
}

/*
516
517
518
519
520
521
522
523

524
525
526
527
528
529
530
529
530
531
532
533
534
535

536
537
538
539
540
541
542
543







-
+







  assert( pTable->pSchema==pTrigger->pSchema || iDb==1 );
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_DROP_TRIGGER;
    const char *zDb = db->aDb[iDb].zName;
    const char *zTab = SCHEMA_TABLE(iDb);
    if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER;
    if( sqlite3AuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||
    if( sqlite3AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) ||
      sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
      return;
    }
  }
#endif

  /* Generate code to destroy the database record of the trigger.
543
544
545
546
547
548
549
550

551
552
553
554

555
556
557
558
559
560
561
556
557
558
559
560
561
562

563
564
565
566

567
568
569
570
571
572
573
574







-
+



-
+







      { OP_Delete,     0, 0,        0},
      { OP_Next,       0, ADDR(1),  0}, /* 8 */
    };

    sqlite3BeginWriteOperation(pParse, 0, iDb);
    sqlite3OpenMasterTable(pParse, iDb);
    base = sqlite3VdbeAddOpList(v,  ArraySize(dropTrigger), dropTrigger);
    sqlite3VdbeChangeP4(v, base+1, pTrigger->name, 0);
    sqlite3VdbeChangeP4(v, base+1, pTrigger->zName, 0);
    sqlite3VdbeChangeP4(v, base+4, "trigger", P4_STATIC);
    sqlite3ChangeCookie(pParse, iDb);
    sqlite3VdbeAddOp2(v, OP_Close, 0, 0);
    sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->name, 0);
    sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);
    if( pParse->nMem<3 ){
      pParse->nMem = 3;
    }
  }
}

/*
651
652
653
654
655
656
657
658
659


660
661
662
663
664

665
666

667
668
669
670

671

672
673
674
675






676
677
678
679











680
681
682
683
684
685
686




687


688
689
690
691
692
693
694
695
696
697





698


699
700
701
702
703
704
705
706



707

708
709
710

711
712
713
714
715
716
717





718
719
720
721
722
723



724
725

726
727
728



















































































































































































































729
730
731
732
733
734





735
736
737


738
739
740
741
742




743
744
745
746
747










748
749
750
751




752
753
754




755




756
757

758
759
760
761
762
763
764

765
766
767

768
769
770
771

772
773
774
775
776
777

778
779
780


781
782
783
784
785
786
787
788
789
790
791


792
793
794
795
796
797



798
799

800
801
802
803

804
805
806
807
808
809

810
811
812
813
814
815









816
817
818









819
820


821
822
823
824
825
826
827
828




829
830
831
832



833
834


835
836

837
838

839
840
841
842
843
844
845


846
847
848
849






850
851
852
853

854
855
856


857
858
859

860

861
664
665
666
667
668
669
670


671
672
673
674
675
676

677
678

679

680
681
682
683

684
685



686
687
688
689
690
691




692
693
694
695
696
697
698
699
700
701
702
703






704
705
706
707

708
709
710
711
712







713
714
715
716
717

718
719
720
721
722





723
724
725

726
727
728

729







730
731
732
733
734

735
736
737


738
739
740


741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957




958
959
960
961
962
963


964
965
966




967
968
969
970
971




972
973
974
975
976
977
978
979
980
981
982



983
984
985
986



987
988
989
990
991
992
993
994
995
996

997
998
999
1000
1001
1002
1003

1004

1005

1006


1007

1008


1009



1010



1011
1012

1013
1014

1015
1016
1017
1018
1019
1020

1021
1022
1023
1024




1025
1026
1027
1028

1029




1030






1031






1032
1033
1034
1035
1036
1037
1038
1039
1040



1041
1042
1043
1044
1045
1046
1047
1048
1049


1050
1051








1052
1053
1054
1055




1056
1057
1058


1059
1060


1061


1062







1063
1064




1065
1066
1067
1068
1069
1070




1071



1072
1073



1074
1075
1076
1077







-
-
+
+




-
+

-
+
-



+
-
+

-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
-
+
+
+
+
-
+
+



-
-
-
-
-
-
-
+
+
+
+
+
-
+
+



-
-
-
-
-
+
+
+
-
+


-
+
-
-
-
-
-
-
-
+
+
+
+
+
-



-
-
+
+
+
-
-
+



+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-
-
-
+
+
+
+
+

-
-
+
+

-
-
-
-
+
+
+
+

-
-
-
-
+
+
+
+
+
+
+
+
+
+

-
-
-
+
+
+
+
-
-
-
+
+
+
+

+
+
+
+

-
+






-
+
-

-
+
-
-

-
+
-
-

-
-
-
+
-
-
-
+
+
-


-






-
+
+


-
-
-
-
+
+
+

-
+
-
-
-
-
+
-
-
-
-
-
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
-
-
+
+
-
-
+
-
-
+
-
-
-
-
-
-
-
+
+
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
-
-
-
+
+
-
-
-
+

+

      pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
    }
  }
  return pSrc;
}

/*
** Generate VDBE code for zero or more statements inside the body of a
** trigger.  
** Generate VDBE code for the statements inside the body of a single 
** trigger.
*/
static int codeTriggerProgram(
  Parse *pParse,            /* The parser context */
  TriggerStep *pStepList,   /* List of statements inside the trigger body */
  int orconfin              /* Conflict algorithm. (OE_Abort, etc) */  
  int orconf                /* Conflict algorithm. (OE_Abort, etc) */  
){
  TriggerStep * pTriggerStep = pStepList;
  TriggerStep *pStep;
  int orconf;
  Vdbe *v = pParse->pVdbe;
  sqlite3 *db = pParse->db;

  assert( pParse->pTriggerTab && pParse->pToplevel );
  assert( pTriggerStep!=0 );
  assert( pStepList );
  assert( v!=0 );
  sqlite3VdbeAddOp2(v, OP_ContextPush, 0, 0);
  VdbeComment((v, "begin trigger %s", pStepList->pTrig->name));
  while( pTriggerStep ){
  for(pStep=pStepList; pStep; pStep=pStep->pNext){
    /* Figure out the ON CONFLICT policy that will be used for this step
    ** of the trigger program. If the statement that caused this trigger
    ** to fire had an explicit ON CONFLICT, then use it. Otherwise, use
    ** the ON CONFLICT policy that was specified as part of the trigger
    ** step statement. Example:
    sqlite3ExprCacheClear(pParse);
    orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
    pParse->trigStack->orconf = orconf;
    switch( pTriggerStep->op ){
    **
    **   CREATE TRIGGER AFTER INSERT ON t1 BEGIN;
    **     INSERT OR REPLACE INTO t2 VALUES(new.a, new.b);
    **   END;
    **
    **   INSERT INTO t1 ... ;            -- insert into t2 uses REPLACE policy
    **   INSERT OR IGNORE INTO t1 ... ;  -- insert into t2 uses IGNORE policy
    */
    pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;

    switch( pStep->op ){
      case TK_UPDATE: {
        SrcList *pSrc;
        pSrc = targetSrcList(pParse, pTriggerStep);
        sqlite3VdbeAddOp2(v, OP_ResetCount, 0, 0);
        sqlite3Update(pParse, pSrc,
                sqlite3ExprListDup(db, pTriggerStep->pExprList, 0), 
                sqlite3ExprDup(db, pTriggerStep->pWhere, 0), orconf);
        sqlite3Update(pParse, 
          targetSrcList(pParse, pStep),
          sqlite3ExprListDup(db, pStep->pExprList, 0), 
          sqlite3ExprDup(db, pStep->pWhere, 0), 
        sqlite3VdbeAddOp2(v, OP_ResetCount, 1, 0);
          pParse->eOrconf
        );
        break;
      }
      case TK_INSERT: {
        SrcList *pSrc;
        pSrc = targetSrcList(pParse, pTriggerStep);
        sqlite3VdbeAddOp2(v, OP_ResetCount, 0, 0);
        sqlite3Insert(pParse, pSrc,
          sqlite3ExprListDup(db, pTriggerStep->pExprList, 0), 
          sqlite3SelectDup(db, pTriggerStep->pSelect, 0), 
          sqlite3IdListDup(db, pTriggerStep->pIdList), orconf);
        sqlite3Insert(pParse, 
          targetSrcList(pParse, pStep),
          sqlite3ExprListDup(db, pStep->pExprList, 0), 
          sqlite3SelectDup(db, pStep->pSelect, 0), 
          sqlite3IdListDup(db, pStep->pIdList), 
        sqlite3VdbeAddOp2(v, OP_ResetCount, 1, 0);
          pParse->eOrconf
        );
        break;
      }
      case TK_DELETE: {
        SrcList *pSrc;
        sqlite3VdbeAddOp2(v, OP_ResetCount, 0, 0);
        pSrc = targetSrcList(pParse, pTriggerStep);
        sqlite3DeleteFrom(pParse, pSrc, 
                          sqlite3ExprDup(db, pTriggerStep->pWhere, 0));
        sqlite3DeleteFrom(pParse, 
          targetSrcList(pParse, pStep),
          sqlite3ExprDup(db, pStep->pWhere, 0)
        sqlite3VdbeAddOp2(v, OP_ResetCount, 1, 0);
        );
        break;
      }
      default: assert( pTriggerStep->op==TK_SELECT ); {
      default: assert( pStep->op==TK_SELECT ); {
        Select *ss = sqlite3SelectDup(db, pTriggerStep->pSelect, 0);
        if( ss ){
          SelectDest dest;

          sqlite3SelectDestInit(&dest, SRT_Discard, 0);
          sqlite3Select(pParse, ss, &dest);
          sqlite3SelectDelete(db, ss);
        SelectDest sDest;
        Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0);
        sqlite3SelectDestInit(&sDest, SRT_Discard, 0);
        sqlite3Select(pParse, pSelect, &sDest);
        sqlite3SelectDelete(db, pSelect);
        }
        break;
      }
    } 
    pTriggerStep = pTriggerStep->pNext;
  }
    if( pStep->op!=TK_SELECT ){
      sqlite3VdbeAddOp0(v, OP_ResetCount);
    }
  sqlite3VdbeAddOp2(v, OP_ContextPop, 0, 0);
  VdbeComment((v, "end trigger %s", pStepList->pTrig->name));
  }

  return 0;
}

#ifdef SQLITE_DEBUG
/*
** This function is used to add VdbeComment() annotations to a VDBE
** program. It is not used in production code, only for debugging.
*/
static const char *onErrorText(int onError){
  switch( onError ){
    case OE_Abort:    return "abort";
    case OE_Rollback: return "rollback";
    case OE_Fail:     return "fail";
    case OE_Replace:  return "replace";
    case OE_Ignore:   return "ignore";
    case OE_Default:  return "default";
  }
  return "n/a";
}
#endif

/*
** Parse context structure pFrom has just been used to create a sub-vdbe
** (trigger program). If an error has occurred, transfer error information
** from pFrom to pTo.
*/
static void transferParseError(Parse *pTo, Parse *pFrom){
  assert( pFrom->zErrMsg==0 || pFrom->nErr );
  assert( pTo->zErrMsg==0 || pTo->nErr );
  if( pTo->nErr==0 ){
    pTo->zErrMsg = pFrom->zErrMsg;
    pTo->nErr = pFrom->nErr;
  }else{
    sqlite3DbFree(pFrom->db, pFrom->zErrMsg);
  }
}

/*
** Create and populate a new TriggerPrg object with a sub-program 
** implementing trigger pTrigger with ON CONFLICT policy orconf.
*/
static TriggerPrg *codeRowTrigger(
  Parse *pParse,       /* Current parse context */
  Trigger *pTrigger,   /* Trigger to code */
  Table *pTab,         /* The table pTrigger is attached to */
  int orconf           /* ON CONFLICT policy to code trigger program with */
){
  Parse *pTop = sqlite3ParseToplevel(pParse);
  sqlite3 *db = pParse->db;   /* Database handle */
  TriggerPrg *pPrg;           /* Value to return */
  Expr *pWhen = 0;            /* Duplicate of trigger WHEN expression */
  Vdbe *v;                    /* Temporary VM */
  NameContext sNC;            /* Name context for sub-vdbe */
  SubProgram *pProgram = 0;   /* Sub-vdbe for trigger program */
  Parse *pSubParse;           /* Parse context for sub-vdbe */
  int iEndTrigger = 0;        /* Label to jump to if WHEN is false */

  assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) );

  /* Allocate the TriggerPrg and SubProgram objects. To ensure that they
  ** are freed if an error occurs, link them into the Parse.pTriggerPrg 
  ** list of the top-level Parse object sooner rather than later.  */
  pPrg = sqlite3DbMallocZero(db, sizeof(TriggerPrg));
  if( !pPrg ) return 0;
  pPrg->pNext = pTop->pTriggerPrg;
  pTop->pTriggerPrg = pPrg;
  pPrg->pProgram = pProgram = sqlite3DbMallocZero(db, sizeof(SubProgram));
  if( !pProgram ) return 0;
  pProgram->nRef = 1;
  pPrg->pTrigger = pTrigger;
  pPrg->orconf = orconf;
  pPrg->oldmask = 0xffffffff;

  /* Allocate and populate a new Parse context to use for coding the 
  ** trigger sub-program.  */
  pSubParse = sqlite3StackAllocZero(db, sizeof(Parse));
  if( !pSubParse ) return 0;
  memset(&sNC, 0, sizeof(sNC));
  sNC.pParse = pSubParse;
  pSubParse->db = db;
  pSubParse->pTriggerTab = pTab;
  pSubParse->pToplevel = pTop;
  pSubParse->zAuthContext = pTrigger->zName;
  pSubParse->eTriggerOp = pTrigger->op;

  v = sqlite3GetVdbe(pSubParse);
  if( v ){
    VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", 
      pTrigger->zName, onErrorText(orconf),
      (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"),
        (pTrigger->op==TK_UPDATE ? "UPDATE" : ""),
        (pTrigger->op==TK_INSERT ? "INSERT" : ""),
        (pTrigger->op==TK_DELETE ? "DELETE" : ""),
      pTab->zName
    ));
#ifndef SQLITE_OMIT_TRACE
    sqlite3VdbeChangeP4(v, -1, 
      sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC
    );
#endif

    /* If one was specified, code the WHEN clause. If it evaluates to false
    ** (or NULL) the sub-vdbe is immediately halted by jumping to the 
    ** OP_Halt inserted at the end of the program.  */
    if( pTrigger->pWhen ){
      pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0);
      if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) 
       && db->mallocFailed==0 
      ){
        iEndTrigger = sqlite3VdbeMakeLabel(v);
        sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
      }
      sqlite3ExprDelete(db, pWhen);
    }

    /* Code the trigger program into the sub-vdbe. */
    codeTriggerProgram(pSubParse, pTrigger->step_list, orconf);

    /* Insert an OP_Halt at the end of the sub-program. */
    if( iEndTrigger ){
      sqlite3VdbeResolveLabel(v, iEndTrigger);
    }
    sqlite3VdbeAddOp0(v, OP_Halt);
    VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf)));

    transferParseError(pParse, pSubParse);
    if( db->mallocFailed==0 ){
      pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg);
    }
    pProgram->nMem = pSubParse->nMem;
    pProgram->nCsr = pSubParse->nTab;
    pProgram->token = (void *)pTrigger;
    pPrg->oldmask = pSubParse->oldmask;
    sqlite3VdbeDelete(v);
  }

  assert( !pSubParse->pAinc       && !pSubParse->pZombieTab );
  assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg );
  sqlite3StackFree(db, pSubParse);

  return pPrg;
}
    
/*
** Return a pointer to a TriggerPrg object containing the sub-program for
** trigger pTrigger with default ON CONFLICT algorithm orconf. If no such
** TriggerPrg object exists, a new object is allocated and populated before
** being returned.
*/
static TriggerPrg *getRowTrigger(
  Parse *pParse,       /* Current parse context */
  Trigger *pTrigger,   /* Trigger to code */
  Table *pTab,         /* The table trigger pTrigger is attached to */
  int orconf           /* ON CONFLICT algorithm. */
){
  Parse *pRoot = sqlite3ParseToplevel(pParse);
  TriggerPrg *pPrg;

  assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) );

  /* It may be that this trigger has already been coded (or is in the
  ** process of being coded). If this is the case, then an entry with
  ** a matching TriggerPrg.pTrigger field will be present somewhere
  ** in the Parse.pTriggerPrg list. Search for such an entry.  */
  for(pPrg=pRoot->pTriggerPrg; 
      pPrg && (pPrg->pTrigger!=pTrigger || pPrg->orconf!=orconf); 
      pPrg=pPrg->pNext
  );

  /* If an existing TriggerPrg could not be located, create a new one. */
  if( !pPrg ){
    pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf);
  }

  return pPrg;
}

/*
** Generate code for the trigger program associated with trigger p on 
** table pTab. The reg, orconf and ignoreJump parameters passed to this
** function are the same as those described in the header function for
** sqlite3CodeRowTrigger()
*/
void sqlite3CodeRowTriggerDirect(
  Parse *pParse,       /* Parse context */
  Trigger *p,          /* Trigger to code */
  Table *pTab,         /* The table to code triggers from */
  int reg,             /* Reg array containing OLD.* and NEW.* values */
  int orconf,          /* ON CONFLICT policy */
  int ignoreJump       /* Instruction to jump to for RAISE(IGNORE) */
){
  Vdbe *v = sqlite3GetVdbe(pParse); /* Main VM */
  TriggerPrg *pPrg;
  pPrg = getRowTrigger(pParse, p, pTab, orconf);
  assert( pPrg || pParse->nErr || pParse->db->mallocFailed );

  /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program 
  ** is a pointer to the sub-vdbe containing the trigger program.  */
  if( pPrg ){
    sqlite3VdbeAddOp3(v, OP_Program, reg, ignoreJump, ++pParse->nMem);
    pPrg->pProgram->nRef++;
    sqlite3VdbeChangeP4(v, -1, (const char *)pPrg->pProgram, P4_SUBPROGRAM);
    VdbeComment(
        (v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf)));

    /* Set the P5 operand of the OP_Program instruction to non-zero if
    ** recursive invocation of this trigger program is disallowed. Recursive
    ** invocation is disallowed if (a) the sub-program is really a trigger,
    ** not a foreign key action, and (b) the flag to enable recursive triggers
    ** is clear.  */
    sqlite3VdbeChangeP5(v, (u8)(p->zName && !(pParse->db->flags&SQLITE_RecTriggers)));
  }
}

/*
** This is called to code FOR EACH ROW triggers.
**
** When the code that this function generates is executed, the following 
** must be true:
** This is called to code the required FOR EACH ROW triggers for an operation
** on table pTab. The operation to code triggers for (INSERT, UPDATE or DELETE)
** is given by the op paramater. The tr_tm parameter determines whether the
** BEFORE or AFTER triggers are coded. If the operation is an UPDATE, then
** parameter pChanges is passed the list of columns being modified.
**
** 1. No cursors may be open in the main database.  (But newIdx and oldIdx
**    can be indices of cursors in temporary tables.  See below.)
** If there are no triggers that fire at the specified time for the specified
** operation on pTab, this function is a no-op.
**
** 2. If the triggers being coded are ON INSERT or ON UPDATE triggers, then
**    a temporary vdbe cursor (index newIdx) must be open and pointing at
**    a row containing values to be substituted for new.* expressions in the
**    trigger program(s).
** The reg argument is the address of the first in an array of registers 
** that contain the values substituted for the new.* and old.* references
** in the trigger program. If N is the number of columns in table pTab
** (a copy of pTab->nCol), then registers are populated as follows:
**
** 3. If the triggers being coded are ON DELETE or ON UPDATE triggers, then
**    a temporary vdbe cursor (index oldIdx) must be open and pointing at
**    a row containing values to be substituted for old.* expressions in the
**    trigger program(s).
**   Register       Contains
**   ------------------------------------------------------
**   reg+0          OLD.rowid
**   reg+1          OLD.* value of left-most column of pTab
**   ...            ...
**   reg+N          OLD.* value of right-most column of pTab
**   reg+N+1        NEW.rowid
**   reg+N+2        OLD.* value of left-most column of pTab
**   ...            ...
**   reg+N+N+1      NEW.* value of right-most column of pTab
**
** If they are not NULL, the piOldColMask and piNewColMask output variables
** are set to values that describe the columns used by the trigger program
** in the OLD.* and NEW.* tables respectively. If column N of the 
** For ON DELETE triggers, the registers containing the NEW.* values will
** never be accessed by the trigger program, so they are not allocated or 
** populated by the caller (there is no data to populate them with anyway). 
** Similarly, for ON INSERT triggers the values stored in the OLD.* registers
** pseudo-table is read at least once, the corresponding bit of the output
** mask is set. If a column with an index greater than 32 is read, the
** output mask is set to the special value 0xffffffff.
** are never accessed, and so are not allocated by the caller. So, for an
** ON INSERT trigger, the value passed to this function as parameter reg
** is not a readable register, although registers (reg+N) through 
** (reg+N+N+1) are.
**
** Parameter orconf is the default conflict resolution algorithm for the
** trigger program to use (REPLACE, IGNORE etc.). Parameter ignoreJump
** is the instruction that control should jump to if a trigger program
** raises an IGNORE exception.
*/
int sqlite3CodeRowTrigger(
void sqlite3CodeRowTrigger(
  Parse *pParse,       /* Parse context */
  Trigger *pTrigger,   /* List of triggers on table pTab */
  int op,              /* One of TK_UPDATE, TK_INSERT, TK_DELETE */
  ExprList *pChanges,  /* Changes list for any UPDATE OF triggers */
  int tr_tm,           /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
  Table *pTab,         /* The table to code triggers from */
  int newIdx,          /* The indice of the "new" row to access */
  int reg,             /* The first in an array of registers (see above) */
  int oldIdx,          /* The indice of the "old" row to access */
  int orconf,          /* ON CONFLICT policy */
  int ignoreJump,      /* Instruction to jump to for RAISE(IGNORE) */
  int ignoreJump       /* Instruction to jump to for RAISE(IGNORE) */
  u32 *piOldColMask,   /* OUT: Mask of columns used from the OLD.* table */
  u32 *piNewColMask    /* OUT: Mask of columns used from the NEW.* table */
){
  Trigger *p;
  Trigger *p;          /* Used to iterate through pTrigger list */
  sqlite3 *db = pParse->db;
  TriggerStack trigStackEntry;

  trigStackEntry.oldColMask = 0;
  trigStackEntry.newColMask = 0;

  assert( op==TK_UPDATE || op==TK_INSERT || op==TK_DELETE );
  assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE);
  assert(tr_tm == TRIGGER_BEFORE || tr_tm == TRIGGER_AFTER );

  assert( tr_tm==TRIGGER_BEFORE || tr_tm==TRIGGER_AFTER );
  assert( (op==TK_UPDATE)==(pChanges!=0) );
  assert(newIdx != -1 || oldIdx != -1);

  for(p=pTrigger; p; p=p->pNext){
    int fire_this = 0;

    /* Sanity checking:  The schema for the trigger and for the table are
    ** always defined.  The trigger must be in the same schema as the table
    ** or else it must be a TEMP trigger. */
    assert( p->pSchema!=0 );
    assert( p->pTabSchema!=0 );
    assert( p->pSchema==p->pTabSchema || p->pSchema==db->aDb[1].pSchema );
    assert( p->pSchema==p->pTabSchema 
         || p->pSchema==pParse->db->aDb[1].pSchema );

    /* Determine whether we should code this trigger */
    if( 
      p->op==op && 
      p->tr_tm==tr_tm && 
      checkColumnOverlap(p->pColumns,pChanges)
    if( p->op==op 
     && p->tr_tm==tr_tm 
     && checkColumnOverlap(p->pColumns, pChanges)
    ){
      TriggerStack *pS;      /* Pointer to trigger-stack entry */
      sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump);
      for(pS=pParse->trigStack; pS && p!=pS->pTrigger; pS=pS->pNext){}
      if( !pS ){
        fire_this = 1;
      }
    }
#if 0    /* Give no warning for recursive triggers.  Just do not do them */
      else{
        sqlite3ErrorMsg(pParse, "recursive triggers not supported (%s)",
            p->name);
        return SQLITE_ERROR;
      }
  }
#endif
    }
 
    if( fire_this ){
      int endTrigger;
      Expr * whenExpr;
}

/*
** Triggers fired by UPDATE or DELETE statements may access values stored
** in the old.* pseudo-table. This function returns a 32-bit bitmask
** indicating which columns of the old.* table actually are used by
** triggers. This information may be used by the caller to avoid having
** to load the entire old.* record into memory when executing an UPDATE
** or DELETE command.
      AuthContext sContext;
      NameContext sNC;

**
** Bit 0 of the returned mask is set if the left-most column of the
** table may be accessed using an old.<col> reference. Bit 1 is set if
** the second leftmost column value is required, and so on. If there
** are more than 32 columns in the table, and at least one of the columns
** with an index greater than 32 may be accessed, 0xffffffff is returned.
**
** It is not possible to determine if the old.rowid column is accessed
** by triggers. The caller must always assume that it is.
#ifndef SQLITE_OMIT_TRACE
      sqlite3VdbeAddOp4(pParse->pVdbe, OP_Trace, 0, 0, 0,
**
** There is no equivalent function for new.* references.
                        sqlite3MPrintf(db, "-- TRIGGER %s", p->name),
                        P4_DYNAMIC);
#endif
      memset(&sNC, 0, sizeof(sNC));
      sNC.pParse = pParse;

      /* Push an entry on to the trigger stack */
      trigStackEntry.pTrigger = p;
*/
u32 sqlite3TriggerOldmask(
  Parse *pParse,       /* Parse context */
  Trigger *pTrigger,   /* List of triggers on table pTab */
      trigStackEntry.newIdx = newIdx;
      trigStackEntry.oldIdx = oldIdx;
      trigStackEntry.pTab = pTab;
      trigStackEntry.pNext = pParse->trigStack;
  ExprList *pChanges,  /* Changes list for any UPDATE OF triggers */
  Table *pTab,         /* The table to code triggers from */
  int orconf           /* Default ON CONFLICT policy for trigger steps */
      trigStackEntry.ignoreJump = ignoreJump;
      pParse->trigStack = &trigStackEntry;
){
  const int op = pChanges ? TK_UPDATE : TK_DELETE;
      sqlite3AuthContextPush(pParse, &sContext, p->name);

  u32 mask = 0;
      /* code the WHEN clause */
      endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe);
  Trigger *p;
      whenExpr = sqlite3ExprDup(db, p->pWhen, 0);
      if( db->mallocFailed || sqlite3ResolveExprNames(&sNC, whenExpr) ){
        pParse->trigStack = trigStackEntry.pNext;
        sqlite3ExprDelete(db, whenExpr);
        return 1;
      }
      sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, SQLITE_JUMPIFNULL);

  for(p=pTrigger; p; p=p->pNext){
      sqlite3ExprDelete(db, whenExpr);

      codeTriggerProgram(pParse, p->step_list, orconf); 

    if( p->op==op && checkColumnOverlap(p->pColumns,pChanges) ){
      TriggerPrg *pPrg;
      pPrg = getRowTrigger(pParse, p, pTab, orconf);
      if( pPrg ){
        mask |= pPrg->oldmask;
      }
      /* Pop the entry off the trigger stack */
      pParse->trigStack = trigStackEntry.pNext;
      sqlite3AuthContextPop(&sContext);

    }
      sqlite3VdbeResolveLabel(pParse->pVdbe, endTrigger);
    }
  }
  }

  if( piOldColMask ) *piOldColMask |= trigStackEntry.oldColMask;
  if( piNewColMask ) *piNewColMask |= trigStackEntry.newColMask;
  return 0;
  return mask;
}

#endif /* !defined(SQLITE_OMIT_TRIGGER) */
Changes to src/update.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.204 2009/06/27 11:17:35 drh Exp $
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Forward declaration */
static void updateVirtualTable(
  Parse *pParse,       /* The parsing context */
49
50
51
52
53
54
55





56
57

58
59
60
61
62
63
64
65
66
67
68
69





70
71
72
73
74
75
76
47
48
49
50
51
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84







+
+
+
+
+

-
+












+
+
+
+
+







** when the ALTER TABLE is executed and one of the literal values written
** into the sqlite_master table.)
**
** Therefore, the P4 parameter is only required if the default value for
** the column is a literal number, string or null. The sqlite3ValueFromExpr()
** function is capable of transforming these types of expressions into
** sqlite3_value objects.
**
** If parameter iReg is not negative, code an OP_RealAffinity instruction
** on register iReg. This is used when an equivalent integer value is 
** stored in place of an 8-byte floating point value in order to save 
** space.
*/
void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i){
void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
  assert( pTab!=0 );
  if( !pTab->pSelect ){
    sqlite3_value *pValue;
    u8 enc = ENC(sqlite3VdbeDb(v));
    Column *pCol = &pTab->aCol[i];
    VdbeComment((v, "%s.%s", pTab->zName, pCol->zName));
    assert( i<pTab->nCol );
    sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, 
                         pCol->affinity, &pValue);
    if( pValue ){
      sqlite3VdbeChangeP4(v, -1, (const char *)pValue, P4_MEM);
    }
#ifndef SQLITE_OMIT_FLOATING_POINT
    if( iReg>=0 && pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
      sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
    }
#endif
  }
}

/*
** Process an UPDATE statement.
**
**   UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127


128

129
130

131
132
133
134
135
136
137
138
139
140
141
142
143
144

145
146
147
148
149
150
151
152
153
154
155
156
157
158

159
160
161

162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
109
110
111
112
113
114
115
116
117
118
119
120
121









122
123
124
125
126

127
128
129
130
131

132
133
134
135
136
137
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153
154
155
156
157
158
159

160
161
162

163
164
165
166
167
168
169








170
171
172
173
174
175
176







+





-
-
-
-
-
-
-
-
-





-
+
+

+

-
+













-
+













-
+


-
+






-
-
-
-
-
-
-
-







  Expr *pRowidExpr = 0;  /* Expression defining the new record number */
  int openAll = 0;       /* True if all indices need to be opened */
  AuthContext sContext;  /* The authorization context */
  NameContext sNC;       /* The name-context to resolve expressions in */
  int iDb;               /* Database containing the table being updated */
  int j1;                /* Addresses of jump instructions */
  int okOnePass;         /* True for one-pass algorithm without the FIFO */
  int hasFK;             /* True if foreign key processing is required */

#ifndef SQLITE_OMIT_TRIGGER
  int isView;                  /* Trying to update a view */
  Trigger *pTrigger;           /* List of triggers on pTab, if required */
#endif
  int iBeginAfterTrigger = 0;  /* Address of after trigger program */
  int iEndAfterTrigger = 0;    /* Exit of after trigger program */
  int iBeginBeforeTrigger = 0; /* Address of before trigger program */
  int iEndBeforeTrigger = 0;   /* Exit of before trigger program */
  u32 old_col_mask = 0;        /* Mask of OLD.* columns in use */
  u32 new_col_mask = 0;        /* Mask of NEW.* columns in use */

  int newIdx      = -1;  /* index of trigger "new" temp table       */
  int oldIdx      = -1;  /* index of trigger "old" temp table       */

  /* Register Allocations */
  int regRowCount = 0;   /* A count of rows changed */
  int regOldRowid;       /* The old rowid */
  int regNewRowid;       /* The new rowid */
  int regData;           /* New data for the row */
  int regNew;
  int regOld = 0;
  int regRowSet = 0;     /* Rowset of rows to be updated */
  int regRec;            /* Register used for new table record to insert */

  sContext.pParse = 0;
  memset(&sContext, 0, sizeof(sContext));
  db = pParse->db;
  if( pParse->nErr || db->mallocFailed ){
    goto update_cleanup;
  }
  assert( pTabList->nSrc==1 );

  /* Locate the table which we want to update. 
  */
  pTab = sqlite3SrcListLookup(pParse, pTabList);
  if( pTab==0 ) goto update_cleanup;
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);

  /* Figure out if we have any triggers and if the table being
  ** updated is a view
  ** updated is a view.
  */
#ifndef SQLITE_OMIT_TRIGGER
  pTrigger = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges, 0);
  isView = pTab->pSelect!=0;
#else
# define pTrigger 0
# define isView 0
#endif
#ifdef SQLITE_OMIT_VIEW
# undef isView
# define isView 0
#endif

  if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){
  if( sqlite3ViewGetColumnNames(pParse, pTab) ){
    goto update_cleanup;
  }
  if( sqlite3ViewGetColumnNames(pParse, pTab) ){
  if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){
    goto update_cleanup;
  }
  aXRef = sqlite3DbMallocRaw(db, sizeof(int) * pTab->nCol );
  if( aXRef==0 ) goto update_cleanup;
  for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;

  /* If there are FOR EACH ROW triggers, allocate cursors for the
  ** special OLD and NEW tables
  */
  if( pTrigger ){
    newIdx = pParse->nTab++;
    oldIdx = pParse->nTab++;
  }

  /* Allocate a cursors for the main database table and for all indices.
  ** The index cursors might not be used, but if they are used they
  ** need to occur right after the database cursor.  So go ahead and
  ** allocate enough space, just in case.
  */
  pTabList->a[0].iCursor = iCur = pParse->nTab++;
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
227
228
229
230
231
232
233


234
235
236
237
238
239
240
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236







+
+







        goto update_cleanup;
      }else if( rc==SQLITE_IGNORE ){
        aXRef[j] = -1;
      }
    }
#endif
  }

  hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngRowid);

  /* Allocate memory for the array aRegIdx[].  There is one entry in the
  ** array for each index associated with table being updated.  Fill in
  ** the value with a register number for indices that are to be used
  ** and with zero for unused indices.
  */
  for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277

278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295

296
297
298
299
300

301
302
303

304
305

306
307
308

309
310

311
312
313
314


315
316
317
318

319
320
321
322


323
324
325


326
327



328
329
330
331
332
333
334
335
336
250
251
252
253
254
255
256

















257

258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273

274





275



276


277



278


279




280
281




282




283
284



285
286


287
288
289
290
291
292
293
294
295
296
297
298







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
















-
+
-
-
-
-
-
+
-
-
-
+
-
-
+
-
-
-
+
-
-
+
-
-
-
-
+
+
-
-
-
-
+
-
-
-
-
+
+
-
-
-
+
+
-
-
+
+
+









          break;
        }
      }
    }
    aRegIdx[j] = reg;
  }

  /* Allocate a block of register used to store the change record
  ** sent to sqlite3GenerateConstraintChecks().  There are either
  ** one or two registers for holding the rowid.  One rowid register
  ** is used if chngRowid is false and two are used if chngRowid is
  ** true.  Following these are pTab->nCol register holding column
  ** data.
  */
  regOldRowid = regNewRowid = pParse->nMem + 1;
  pParse->nMem += pTab->nCol + 1;
  if( chngRowid ){
    regNewRowid++;
    pParse->nMem++;
  }
  regData = regNewRowid+1;
 

  /* Begin generating code.
  /* Begin generating code. */
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ) goto update_cleanup;
  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
  sqlite3BeginWriteOperation(pParse, 1, iDb);

#ifndef SQLITE_OMIT_VIRTUALTABLE
  /* Virtual tables must be handled separately */
  if( IsVirtual(pTab) ){
    updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef,
                       pWhere);
    pWhere = 0;
    pTabList = 0;
    goto update_cleanup;
  }
#endif

  /* Start the view context
  /* Allocate required registers. */
  */
  if( isView ){
    sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
  }

  regOldRowid = regNewRowid = ++pParse->nMem;
  /* Generate the code for triggers.
  */
  if( pTrigger ){
  if( pTrigger || hasFK ){
    int iGoto;

    regOld = pParse->nMem + 1;
    /* Create pseudo-tables for NEW and OLD
    */
    sqlite3VdbeAddOp3(v, OP_OpenPseudo, oldIdx, 0, pTab->nCol);
    pParse->nMem += pTab->nCol;
    sqlite3VdbeAddOp3(v, OP_OpenPseudo, newIdx, 0, pTab->nCol);

  }
    iGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
    addr = sqlite3VdbeMakeLabel(v);
    iBeginBeforeTrigger = sqlite3VdbeCurrentAddr(v);
    if( sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, 
  if( chngRowid || pTrigger || hasFK ){
    regNewRowid = ++pParse->nMem;
          TRIGGER_BEFORE, pTab, newIdx, oldIdx, onError, addr, 
          &old_col_mask, &new_col_mask) ){
      goto update_cleanup;
    }
  }
    iEndBeforeTrigger = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
    iBeginAfterTrigger = sqlite3VdbeCurrentAddr(v);
    if( sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, 
          TRIGGER_AFTER, pTab, newIdx, oldIdx, onError, addr, 
  regNew = pParse->nMem + 1;
  pParse->nMem += pTab->nCol;
          &old_col_mask, &new_col_mask) ){
      goto update_cleanup;
    }
  regRec = ++pParse->nMem;

    iEndAfterTrigger = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
    sqlite3VdbeJumpHere(v, iGoto);
  /* Start the view context. */
  if( isView ){
    sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
  }

  /* If we are trying to update a view, realize that view into
  ** a ephemeral table.
  */
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
  if( isView ){
    sqlite3MaterializeView(pParse, pTab, pWhere, iCur);
  }
360
361
362
363
364
365
366
367

368
369
370
371
372
373
374
322
323
324
325
326
327
328

329
330
331
332
333
334
335
336







-
+








  /* End the database scan loop.
  */
  sqlite3WhereEnd(pWInfo);

  /* Initialize the count of updated rows
  */
  if( db->flags & SQLITE_CountRows && !pParse->trigStack ){
  if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){
    regRowCount = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
  }

  if( !isView ){
    /* 
    ** Open every index that needs updating.  Note that if any
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420

421
422
423

424
425
426
427
428
429
430
431
432
433
434
435

436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484

485
486
487
488




489
490
491
492
493





494
495
496
497
498
499

























500
501

502
503
504
505


506
507

508
509
510
511





















512
513
514
515

516
517
518






519
520
521
522


523
524

525
526
527
528




529

530
531
532








533
534
535
536
537

538
539
540
541
542
543
544

545
546
547

548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571

572
573
574
575
576
577
578
579
580

581
582
583
584
585
586
587
588
589
590
591
592
593
594









595
596
597
598
599
600
601
355
356
357
358
359
360
361





362
363
364
365
366
367
368
369
370
371






372



373












374

















































375
376



377
378
379
380





381
382
383
384
385
386





387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411


412
413
414


415
416
417

418
419
420


421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441

442


443
444


445
446
447
448
449
450
451
452


453
454


455
456
457
458
459
460
461
462
463

464



465
466
467
468
469
470
471
472
473
474
475
476

477
478
479
480




481



482
483
484
485
486
487
488
489
490
491
492
493
494
495
496




497
498
499
500
501

502
503
504
505
506
507
508
509
510

511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541







-
-
-
-
-










-
-
-
-
-
-
+
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+

-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+

-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+


-
-
+
+

-
+


-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-

-
-
+

-
-
+
+
+
+
+
+


-
-
+
+
-
-
+




+
+
+
+
-
+
-
-
-
+
+
+
+
+
+
+
+




-
+



-
-
-
-
+
-
-
-
+














-
-
-
-





-
+








-
+














+
+
+
+
+
+
+
+
+







        KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
        sqlite3VdbeAddOp4(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, iDb,
                       (char*)pKey, P4_KEYINFO_HANDOFF);
        assert( pParse->nTab>iCur+i+1 );
      }
    }
  }
  
  /* Jump back to this point if a trigger encounters an IGNORE constraint. */
  if( pTrigger ){
    sqlite3VdbeResolveLabel(v, addr);
  }

  /* Top of the update loop */
  if( okOnePass ){
    int a1 = sqlite3VdbeAddOp1(v, OP_NotNull, regOldRowid);
    addr = sqlite3VdbeAddOp0(v, OP_Goto);
    sqlite3VdbeJumpHere(v, a1);
  }else{
    addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, 0, regOldRowid);
  }

  if( pTrigger ){
    int regRowid;
    int regRow;
    int regCols;

    /* Make cursor iCur point to the record that is being updated.
  /* Make cursor iCur point to the record that is being updated. If
    */
    sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid);

  ** this record does not exist for some reason (deleted by a trigger,
    /* Generate the OLD table
    */
    regRowid = sqlite3GetTempReg(pParse);
    regRow = sqlite3GetTempReg(pParse);
    sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regRowid);
    if( !old_col_mask ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, regRow);
    }else{
      sqlite3VdbeAddOp2(v, OP_RowData, iCur, regRow);
    }
    sqlite3VdbeAddOp3(v, OP_Insert, oldIdx, regRow, regRowid);

  ** for example, then jump to the next iteration of the RowSet loop.  */
    /* Generate the NEW table
    */
    if( chngRowid ){
      sqlite3ExprCodeAndCache(pParse, pRowidExpr, regRowid);
      sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid);
    }else{
      sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regRowid);
    }
    regCols = sqlite3GetTempRange(pParse, pTab->nCol);
    for(i=0; i<pTab->nCol; i++){
      if( i==pTab->iPKey ){
        sqlite3VdbeAddOp2(v, OP_Null, 0, regCols+i);
        continue;
      }
      j = aXRef[i];
      if( (i<32 && (new_col_mask&((u32)1<<i))!=0) || new_col_mask==0xffffffff ){
        if( j<0 ){
          sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regCols+i);
          sqlite3ColumnDefault(v, pTab, i);
        }else{
          sqlite3ExprCodeAndCache(pParse, pChanges->a[j].pExpr, regCols+i);
        }
      }else{
        sqlite3VdbeAddOp2(v, OP_Null, 0, regCols+i);
      }
    }
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regCols, pTab->nCol, regRow);
    if( !isView ){
      sqlite3TableAffinityStr(v, pTab);
      sqlite3ExprCacheAffinityChange(pParse, regCols, pTab->nCol);
    }
    sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol);
    /* if( pParse->nErr ) goto update_cleanup; */
    sqlite3VdbeAddOp3(v, OP_Insert, newIdx, regRow, regRowid);
    sqlite3ReleaseTempReg(pParse, regRowid);
    sqlite3ReleaseTempReg(pParse, regRow);

    sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger);
    sqlite3VdbeJumpHere(v, iEndBeforeTrigger);
  }

  if( !isView ){
    /* Loop over every record that needs updating.  We have to load
    ** the old data for each record to be updated because some columns
    ** might not change and we will need to copy the old value.
    ** Also, the old data is needed to delete the old index entries.
    ** So make the cursor point at the old record.
    */
    sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid);
  sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid);

    /* If the record number will change, push the record number as it
    ** will be after the update. (The old record number is currently
    ** on top of the stack.)
  /* If the record number will change, set register regNewRowid to
  ** contain the new value. If the record number is not being modified,
  ** then regNewRowid is the same register as regOldRowid, which is
  ** already populated.  */
    */
    if( chngRowid ){
      sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
      sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid);
    }
  assert( chngRowid || pTrigger || hasFK || regOldRowid==regNewRowid );
  if( chngRowid ){
    sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
    sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid);
  }

    /* Compute new data for this record.  
    */
    for(i=0; i<pTab->nCol; i++){
      if( i==pTab->iPKey ){
        sqlite3VdbeAddOp2(v, OP_Null, 0, regData+i);
  /* If there are triggers on this table, populate an array of registers 
  ** with the required old.* column data.  */
  if( hasFK || pTrigger ){
    u32 oldmask = (hasFK ? sqlite3FkOldmask(pParse, pTab) : 0);
    oldmask |= sqlite3TriggerOldmask(pParse, pTrigger, pChanges, pTab, onError);
    for(i=0; i<pTab->nCol; i++){
      if( aXRef[i]<0 || oldmask==0xffffffff || (oldmask & (1<<i)) ){
        sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regOld+i);
        sqlite3ColumnDefault(v, pTab, i, regOld+i);
      }else{
        sqlite3VdbeAddOp2(v, OP_Null, 0, regOld+i);
      }
    }
    if( chngRowid==0 ){
      sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid);
    }
  }

  /* Populate the array of registers beginning at regNew with the new
  ** row data. This array is used to check constaints, create the new
  ** table and index records, and as the values for any new.* references
  ** made by triggers.  */
  for(i=0; i<pTab->nCol; i++){
    if( i==pTab->iPKey ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
        continue;
      }
    }else{
      j = aXRef[i];
      if( j<0 ){
        sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regData+i);
        sqlite3ColumnDefault(v, pTab, i);
        sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regNew+i);
        sqlite3ColumnDefault(v, pTab, i, regNew+i);
      }else{
        sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regData+i);
        sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i);
      }
    }

    /* Do constraint checks
  }

  /* Fire any BEFORE UPDATE triggers. This happens before constraints are
  ** verified. One could argue that this is wrong.  */
  if( pTrigger ){
    sqlite3VdbeAddOp2(v, OP_Affinity, regNew, pTab->nCol);
    sqlite3TableAffinityStr(v, pTab);
    sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, 
        TRIGGER_BEFORE, pTab, regOldRowid, onError, addr);

    /* The row-trigger may have deleted the row being updated. In this
    ** case, jump to the next row. No updates or AFTER triggers are 
    ** required. This behaviour - what happens when the row being updated
    ** is deleted or renamed by a BEFORE trigger - is left undefined in the
    ** documentation.  */
    sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid);
  }

  if( !isView ){

    /* Do constraint checks. */
    */
    sqlite3GenerateConstraintChecks(pParse, pTab, iCur, regNewRowid,
                                    aRegIdx, chngRowid, 1,
                                    onError, addr, 0);
        aRegIdx, (chngRowid?regOldRowid:0), 1, onError, addr, 0);

    /* Delete the old indices for the current record.
    */
    /* Do FK constraint checks. */
    if( hasFK ){
      sqlite3FkCheck(pParse, pTab, regOldRowid, 0);
    }

    /* Delete the index entries associated with the current record.  */
    j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regOldRowid);
    sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, aRegIdx);

    /* If changing the record number, delete the old record.
  
    /* If changing the record number, delete the old record.  */
    */
    if( chngRowid ){
    if( hasFK || chngRowid ){
      sqlite3VdbeAddOp2(v, OP_Delete, iCur, 0);
    }
    sqlite3VdbeJumpHere(v, j1);

    if( hasFK ){
      sqlite3FkCheck(pParse, pTab, 0, regNewRowid);
    }
  
    /* Create the new index entries and the new record.
    /* Insert the new index entries and the new record. */
    */
    sqlite3CompleteInsertion(pParse, pTab, iCur, regNewRowid, 
                             aRegIdx, 1, -1, 0, 0);
    sqlite3CompleteInsertion(pParse, pTab, iCur, regNewRowid, aRegIdx, 1, 0, 0);

    /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
    ** handle rows (possibly in other tables) that refer via a foreign key
    ** to the row just updated. */ 
    if( hasFK ){
      sqlite3FkActions(pParse, pTab, pChanges, regOldRowid);
    }
  }

  /* Increment the row counter 
  */
  if( db->flags & SQLITE_CountRows && !pParse->trigStack){
  if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab){
    sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
  }

  /* If there are triggers, close all the cursors after each iteration
  ** through the loop.  The fire the after triggers.
  */
  if( pTrigger ){
  sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, 
    sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginAfterTrigger);
    sqlite3VdbeJumpHere(v, iEndAfterTrigger);
  }
      TRIGGER_AFTER, pTab, regOldRowid, onError, addr);

  /* Repeat the above with the next record to be updated, until
  ** all record selected by the WHERE clause have been updated.
  */
  sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
  sqlite3VdbeJumpHere(v, addr);

  /* Close all tables */
  for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
    if( openAll || aRegIdx[i]>0 ){
      sqlite3VdbeAddOp2(v, OP_Close, iCur+i+1, 0);
    }
  }
  sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
  if( pTrigger ){
    sqlite3VdbeAddOp2(v, OP_Close, newIdx, 0);
    sqlite3VdbeAddOp2(v, OP_Close, oldIdx, 0);
  }

  /* Update the sqlite_sequence table by storing the content of the
  ** maximum rowid counter values recorded while inserting into
  ** autoincrement tables.
  */
  if( pParse->nested==0 && pParse->trigStack==0 ){
  if( pParse->nested==0 && pParse->pTriggerTab==0 ){
    sqlite3AutoincrementEnd(pParse);
  }

  /*
  ** Return the number of rows that were changed. If this routine is 
  ** generating code because of a call to sqlite3NestedParse(), do not
  ** invoke the callback function.
  */
  if( db->flags & SQLITE_CountRows && !pParse->trigStack && pParse->nested==0 ){
  if( (db->flags&SQLITE_CountRows) && !pParse->pTriggerTab && !pParse->nested ){
    sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC);
  }

update_cleanup:
  sqlite3AuthContextPop(&sContext);
  sqlite3DbFree(db, aRegIdx);
  sqlite3DbFree(db, aXRef);
  sqlite3SrcListDelete(db, pTabList);
  sqlite3ExprListDelete(db, pChanges);
  sqlite3ExprDelete(db, pWhere);
  return;
}
/* Make sure "isView" and other macros defined above are undefined. Otherwise
** thely may interfere with compilation of other functions in this file
** (or in another file, if this file becomes part of the amalgamation).  */
#ifdef isView
 #undef isView
#endif
#ifdef pTrigger
 #undef pTrigger
#endif

#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Generate code for an UPDATE of a virtual table.
**
** The strategy is that we create an ephemerial table that contains
** for each row to be changed:
627
628
629
630
631
632
633
634

635
636
637
638
639
640

641
642
643
644
645
646
647
648
649
650
651

652
653
654
655
656
657
658
567
568
569
570
571
572
573

574
575
576
577
578
579

580

581
582
583
584
585
586
587
588
589

590
591
592
593
594
595
596
597







-
+





-
+
-









-
+







  Select *pSelect = 0;      /* The SELECT statement */
  Expr *pExpr;              /* Temporary expression */
  int ephemTab;             /* Table holding the result of the SELECT */
  int i;                    /* Loop counter */
  int addr;                 /* Address of top of loop */
  int iReg;                 /* First register in set passed to OP_VUpdate */
  sqlite3 *db = pParse->db; /* Database connection */
  const char *pVtab = (const char*)pTab->pVtab;
  const char *pVTab = (const char*)sqlite3GetVTable(db, pTab);
  SelectDest dest;

  /* Construct the SELECT statement that will find the new values for
  ** all updated rows. 
  */
  pEList = sqlite3ExprListAppend(pParse, 0, 
  pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, "_rowid_"));
                                 sqlite3CreateIdExpr(pParse, "_rowid_"));
  if( pRowid ){
    pEList = sqlite3ExprListAppend(pParse, pEList,
                                   sqlite3ExprDup(db, pRowid, 0));
  }
  assert( pTab->iPKey<0 );
  for(i=0; i<pTab->nCol; i++){
    if( aXRef[i]>=0 ){
      pExpr = sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0);
    }else{
      pExpr = sqlite3CreateIdExpr(pParse, pTab->aCol[i].zName);
      pExpr = sqlite3Expr(db, TK_ID, pTab->aCol[i].zName);
    }
    pEList = sqlite3ExprListAppend(pParse, pEList, pExpr);
  }
  pSelect = sqlite3SelectNew(pParse, pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0);
  
  /* Create the ephemeral table into which the update results will
  ** be stored.
672
673
674
675
676
677
678
679


680
681
682
683
684
685
686
687
688
689
690
691
692
611
612
613
614
615
616
617

618
619
620
621
622
623
624
625
626
627












-
+
+








-
-
-
-
-
  addr = sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0);
  sqlite3VdbeAddOp3(v, OP_Column,  ephemTab, 0, iReg);
  sqlite3VdbeAddOp3(v, OP_Column, ephemTab, (pRowid?1:0), iReg+1);
  for(i=0; i<pTab->nCol; i++){
    sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i+1+(pRowid!=0), iReg+2+i);
  }
  sqlite3VtabMakeWritable(pParse, pTab);
  sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVtab, P4_VTAB);
  sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVTab, P4_VTAB);
  sqlite3MayAbort(pParse);
  sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1);
  sqlite3VdbeJumpHere(v, addr);
  sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);

  /* Cleanup */
  sqlite3SelectDelete(db, pSelect);  
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

/* Make sure "isView" gets undefined in case this file becomes part of
** the amalgamation - so that subsequent files do not see isView as a
** macro. */
#undef isView
Changes to src/utf.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
8
9
10
11
12
13
14


15
16
17
18
19
20
21







-
-







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used to translate between UTF-8, 
** UTF-16, UTF-16BE, and UTF-16LE.
**
** $Id: utf.c,v 1.73 2009/04/01 18:40:32 drh Exp $
**
** Notes on UTF-8:
**
**   Byte-0    Byte-1    Byte-2    Byte-3    Value
**  0xxxxxxx                                 00000000 00000000 0xxxxxxx
**  110yyyyy  10xxxxxx                       00000000 00000yyy yyxxxxxx
**  1110zzzz  10yyyyyy  10xxxxxx             00000000 zzzzyyyy yyxxxxxx
**  11110uuu  10uuzzzz  10yyyyyy  10xxxxxx   000uuuuu zzzzyyyy yyxxxxxx
103
104
105
106
107
108
109
110

111
112
113

114
115
116
117
118
119
120

121
122
123

124
125
126
127
128
129
130
101
102
103
104
105
106
107

108
109
110

111
112
113
114
115
116
117

118
119
120

121
122
123
124
125
126
127
128







-
+


-
+






-
+


-
+







    *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03));              \
    *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0));  \
    *zOut++ = (u8)(0x00DC + ((c>>8)&0x03));                         \
    *zOut++ = (u8)(c&0x00FF);                                       \
  }                                                                 \
}

#define READ_UTF16LE(zIn, c){                                         \
#define READ_UTF16LE(zIn, TERM, c){                                   \
  c = (*zIn++);                                                       \
  c += ((*zIn++)<<8);                                                 \
  if( c>=0xD800 && c<0xE000 ){                                        \
  if( c>=0xD800 && c<0xE000 && TERM ){                                \
    int c2 = (*zIn++);                                                \
    c2 += ((*zIn++)<<8);                                              \
    c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);   \
  }                                                                   \
}

#define READ_UTF16BE(zIn, c){                                         \
#define READ_UTF16BE(zIn, TERM, c){                                   \
  c = ((*zIn++)<<8);                                                  \
  c += (*zIn++);                                                      \
  if( c>=0xD800 && c<0xE000 ){                                        \
  if( c>=0xD800 && c<0xE000 && TERM ){                                \
    int c2 = ((*zIn++)<<8);                                           \
    c2 += (*zIn++);                                                   \
    c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);   \
  }                                                                   \
}

/*
301
302
303
304
305
306
307
308

309
310
311
312
313
314

315
316
317
318
319
320
321
299
300
301
302
303
304
305

306
307
308
309
310
311

312
313
314
315
316
317
318
319







-
+





-
+







    pMem->n = (int)(z - zOut);
    *z++ = 0;
  }else{
    assert( desiredEnc==SQLITE_UTF8 );
    if( pMem->enc==SQLITE_UTF16LE ){
      /* UTF-16 Little-endian -> UTF-8 */
      while( zIn<zTerm ){
        READ_UTF16LE(zIn, c); 
        READ_UTF16LE(zIn, zIn<zTerm, c); 
        WRITE_UTF8(z, c);
      }
    }else{
      /* UTF-16 Big-endian -> UTF-8 */
      while( zIn<zTerm ){
        READ_UTF16BE(zIn, c); 
        READ_UTF16BE(zIn, zIn<zTerm, c); 
        WRITE_UTF8(z, c);
      }
    }
    pMem->n = (int)(z - zOut);
  }
  *z = 0;
  assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len );
451
452
453
454
455
456
457


























458

459
460
461
462
463
464
465

466
467
468
469
470
471
472
473
474
475
476
477

478
479
480
481
482

483
484
485
486
487
488
489
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481

482
483
484
485
486
487
488
489
490
491









492

493
494
495
496
497

498
499
500
501
502
503
504
505







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+







+

-
-
-
-
-
-
-
-
-

-
+




-
+







  }
  assert( (m.flags & MEM_Term)!=0 || db->mallocFailed );
  assert( (m.flags & MEM_Str)!=0 || db->mallocFailed );
  return (m.flags & MEM_Dyn)!=0 ? m.z : sqlite3DbStrDup(db, m.z);
}

/*
** Convert a UTF-8 string to the UTF-16 encoding specified by parameter
** enc. A pointer to the new string is returned, and the value of *pnOut
** is set to the length of the returned string in bytes. The call should
** arrange to call sqlite3DbFree() on the returned pointer when it is
** no longer required.
** 
** If a malloc failure occurs, NULL is returned and the db.mallocFailed
** flag set.
*/
#ifdef SQLITE_ENABLE_STAT2
char *sqlite3Utf8to16(sqlite3 *db, u8 enc, char *z, int n, int *pnOut){
  Mem m;
  memset(&m, 0, sizeof(m));
  m.db = db;
  sqlite3VdbeMemSetStr(&m, z, n, SQLITE_UTF8, SQLITE_STATIC);
  if( sqlite3VdbeMemTranslate(&m, enc) ){
    assert( db->mallocFailed );
    return 0;
  }
  assert( m.z==m.zMalloc );
  *pnOut = m.n;
  return m.z;
}
#endif

/*
** pZ is a UTF-16 encoded unicode string at least nChar characters long.
** zIn is a UTF-16 encoded unicode string at least nChar characters long.
** Return the number of bytes in the first nChar unicode characters
** in pZ.  nChar must be non-negative.
*/
int sqlite3Utf16ByteLen(const void *zIn, int nChar){
  int c;
  unsigned char const *z = zIn;
  int n = 0;
  
  if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){
    /* Using an "if (SQLITE_UTF16NATIVE==SQLITE_UTF16BE)" construct here
    ** and in other parts of this file means that at one branch will
    ** not be covered by coverage testing on any single host. But coverage
    ** will be complete if the tests are run on both a little-endian and 
    ** big-endian host. Because both the UTF16NATIVE and SQLITE_UTF16BE
    ** macros are constant at compile time the compiler can determine
    ** which branch will be followed. It is therefore assumed that no runtime
    ** penalty is paid for this "if" statement.
    */
    while( n<nChar ){
      READ_UTF16BE(z, c);
      READ_UTF16BE(z, 1, c);
      n++;
    }
  }else{
    while( n<nChar ){
      READ_UTF16LE(z, c);
      READ_UTF16LE(z, 1, c);
      n++;
    }
  }
  return (int)(z-(unsigned char const *)zIn);
}

#if defined(SQLITE_TEST)
517
518
519
520
521
522
523
524

525
526
527
528
529
530
531
532
533
534
535
536

537
538
539
540
541
542
533
534
535
536
537
538
539

540
541
542
543
544
545
546
547
548
549
550
551

552
553
554
555
556
557
558







-
+











-
+






    if( i>=0xD800 && i<0xE000 ) continue;
    z = zBuf;
    WRITE_UTF16LE(z, i);
    n = (int)(z-zBuf);
    assert( n>0 && n<=4 );
    z[0] = 0;
    z = zBuf;
    READ_UTF16LE(z, c);
    READ_UTF16LE(z, 1, c);
    assert( c==i );
    assert( (z-zBuf)==n );
  }
  for(i=0; i<0x00110000; i++){
    if( i>=0xD800 && i<0xE000 ) continue;
    z = zBuf;
    WRITE_UTF16BE(z, i);
    n = (int)(z-zBuf);
    assert( n>0 && n<=4 );
    z[0] = 0;
    z = zBuf;
    READ_UTF16BE(z, c);
    READ_UTF16BE(z, 1, c);
    assert( c==i );
    assert( (z-zBuf)==n );
  }
}
#endif /* SQLITE_TEST */
#endif /* SQLITE_OMIT_UTF16 */
Changes to src/util.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
10
11
12
13
14
15
16

17
18
19
20
21
22
23







-







**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.261 2009/06/24 10:26:33 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#ifdef SQLITE_HAVE_ISNAN
# include <math.h>
#endif

221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
220
221
222
223
224
225
226

227
228
229
230
231
232
233
234







-
+







int sqlite3StrICmp(const char *zLeft, const char *zRight){
  register unsigned char *a, *b;
  a = (unsigned char *)zLeft;
  b = (unsigned char *)zRight;
  while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
  return UpperToLower[*a] - UpperToLower[*b];
}
int sqlite3StrNICmp(const char *zLeft, const char *zRight, int N){
int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
  register unsigned char *a, *b;
  a = (unsigned char *)zLeft;
  b = (unsigned char *)zRight;
  while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
  return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
}

269
270
271
272
273
274
275
276

277
278
279
280
281
282
283
284
285
286
287
288
289
290







291
292



293

294
295
296
297
298
299

300

301
302
303
304
305
306
307











308
309
310
311

312
313
314
315
316
317


318
319

320
321
322
323
324





325
326


327
328
329
330
331

332
333
334
335
336
337

338
339

340
341

342
343
344
345
346
347
348
349
350
351
352




























































353
354
355
356
357
358
359
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282
283
284
285
286
287

288
289
290
291
292
293
294
295


296
297
298
299
300
301
302
303
304
305
306
307

308







309
310
311
312
313
314
315
316
317
318
319
320

321

322






323
324


325





326
327
328
329
330


331
332
333



334
335
336
337
338
339
340
341
342
343

344
345
346
347











348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414







-
+












-

+
+
+
+
+
+
+
-
-
+
+
+

+






+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+

-

-
+
-
-
-
-
-
-
+
+
-
-
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+

-
-
-

+






+

-
+


+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    while( sqlite3Isdigit(*z) ){ z += incr; }
    *realnum = 1;
  }
  return *z==0;
}

/*
** The string z[] is an ascii representation of a real number.
** The string z[] is an ASCII representation of a real number.
** Convert this string to a double.
**
** This routine assumes that z[] really is a valid number.  If it
** is not, the result is undefined.
**
** This routine is used instead of the library atof() function because
** the library atof() might want to use "," as the decimal point instead
** of "." depending on how locale is set.  But that would cause problems
** for SQL.  So this routine always uses "." regardless of locale.
*/
int sqlite3AtoF(const char *z, double *pResult){
#ifndef SQLITE_OMIT_FLOATING_POINT
  int sign = 1;
  const char *zBegin = z;
  /* sign * significand * (10 ^ (esign * exponent)) */
  int sign = 1;   /* sign of significand */
  i64 s = 0;      /* significand */
  int d = 0;      /* adjust exponent for shifting decimal point */
  int esign = 1;  /* sign of exponent */
  int e = 0;      /* exponent */
  double result;
  LONGDOUBLE_TYPE v1 = 0.0;
  int nSignificant = 0;
  int nDigits = 0;

  /* skip leading spaces */
  while( sqlite3Isspace(*z) ) z++;
  /* get sign of significand */
  if( *z=='-' ){
    sign = -1;
    z++;
  }else if( *z=='+' ){
    z++;
  }
  /* skip leading zeroes */
  while( z[0]=='0' ){
  while( z[0]=='0' ) z++, nDigits++;
    z++;
  }
  while( sqlite3Isdigit(*z) ){
    v1 = v1*10.0 + (*z - '0');
    z++;
    nSignificant++;
  }

  /* copy max significant digits to significand */
  while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
    s = s*10 + (*z - '0');
    z++, nDigits++;
  }
  /* skip non-significant significand digits
  ** (increase exponent by d to shift decimal left) */
  while( sqlite3Isdigit(*z) ) z++, nDigits++, d++;

  /* if decimal point is present */
  if( *z=='.' ){
    LONGDOUBLE_TYPE divisor = 1.0;
    z++;
    if( nSignificant==0 ){
    /* copy digits from after decimal to significand
      while( z[0]=='0' ){
        divisor *= 10.0;
        z++;
      }
    }
    while( sqlite3Isdigit(*z) ){
    ** (decrease exponent by d to shift decimal right) */
    while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
      if( nSignificant<18 ){
        v1 = v1*10.0 + (*z - '0');
      s = s*10 + (*z - '0');
        divisor *= 10.0;
        nSignificant++;
      }
      z++;
    }
      z++, nDigits++, d--;
    }
    /* skip non-significant digits */
    while( sqlite3Isdigit(*z) ) z++, nDigits++;
  }
    v1 /= divisor;
  }

  /* if exponent is present */
  if( *z=='e' || *z=='E' ){
    int esign = 1;
    int eval = 0;
    LONGDOUBLE_TYPE scale = 1.0;
    z++;
    /* get sign of exponent */
    if( *z=='-' ){
      esign = -1;
      z++;
    }else if( *z=='+' ){
      z++;
    }
    /* copy digits to exponent */
    while( sqlite3Isdigit(*z) ){
      eval = eval*10 + *z - '0';
      e = e*10 + (*z - '0');
      z++;
    }
  }
    while( eval>=64 ){ scale *= 1.0e+64; eval -= 64; }
    while( eval>=16 ){ scale *= 1.0e+16; eval -= 16; }
    while( eval>=4 ){ scale *= 1.0e+4; eval -= 4; }
    while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; }
    if( esign<0 ){
      v1 /= scale;
    }else{
      v1 *= scale;
    }
  }
  *pResult = (double)(sign<0 ? -v1 : v1);

  /* adjust exponent by d, and update sign */
  e = (e*esign) + d;
  if( e<0 ) {
    esign = -1;
    e *= -1;
  } else {
    esign = 1;
  }

  /* if 0 significand */
  if( !s ) {
    /* In the IEEE 754 standard, zero is signed.
    ** Add the sign if we've seen at least one digit */
    result = (sign<0 && nDigits) ? -(double)0 : (double)0;
  } else {
    /* attempt to reduce exponent */
    if( esign>0 ){
      while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10;
    }else{
      while( !(s%10) && e>0 ) e--,s/=10;
    }

    /* adjust the sign of significand */
    s = sign<0 ? -s : s;

    /* if exponent, scale significand as appropriate
    ** and store in result. */
    if( e ){
      double scale = 1.0;
      /* attempt to handle extremely small/large numbers better */
      if( e>307 && e<342 ){
        while( e%308 ) { scale *= 1.0e+1; e -= 1; }
        if( esign<0 ){
          result = s / scale;
          result /= 1.0e+308;
        }else{
          result = s * scale;
          result *= 1.0e+308;
        }
      }else{
        /* 1.0e+22 is the largest power of 10 than can be 
        ** represented exactly. */
        while( e%22 ) { scale *= 1.0e+1; e -= 1; }
        while( e>0 ) { scale *= 1.0e+22; e -= 22; }
        if( esign<0 ){
          result = s / scale;
        }else{
          result = s * scale;
        }
      }
    } else {
      result = (double)s;
    }
  }

  /* store the result */
  *pResult = result;

  /* return number of characters used */
  return (int)(z - zBegin);
#else
  return sqlite3Atoi64(z, pResult);
#endif /* SQLITE_OMIT_FLOATING_POINT */
}

/*
900
901
902
903
904
905
906
907

908
909
910
911
912
913
914
955
956
957
958
959
960
961

962
963
964
965
966
967
968
969







-
+







}



#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC)
/*
** Translate a single byte of Hex into an integer.
** This routinen only works if h really is a valid hexadecimal
** This routine only works if h really is a valid hexadecimal
** character:  0..9a..fA..F
*/
static u8 hexToInt(int h){
  assert( (h>='0' && h<='9') ||  (h>='a' && h<='f') ||  (h>='A' && h<='F') );
#ifdef SQLITE_ASCII
  h += 9*(1&(h>>6));
#endif
Changes to src/vacuum.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
9
10
11
12
13
14
15


16
17
18
19
20
21
22







-
-







**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the VACUUM command.
**
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
** $Id: vacuum.c,v 1.90 2009/06/03 11:25:07 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
/*
** Execute zSql on database db. Return an error code.
93
94
95
96
97
98
99
100



101
102
103
104

105
106
107
108
109
110
111
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112







-
+
+
+




+







  int nRes;

  if( !db->autoCommit ){
    sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
    return SQLITE_ERROR;
  }

  /* Save the current value of the write-schema flag before setting it. */
  /* Save the current value of the database flags so that it can be 
  ** restored before returning. Then set the writable-schema flag, and
  ** disable CHECK and foreign key constraints.  */
  saved_flags = db->flags;
  saved_nChange = db->nChange;
  saved_nTotalChange = db->nTotalChange;
  db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
  db->flags &= ~SQLITE_ForeignKeys;

  pMain = db->aDb[0].pBt;
  isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));

  /* Attach the temporary database as 'vacuum_db'. The synchronous pragma
  ** can be set to 'off' for this file, as it is not recovered if a crash
  ** occurs anyway. The integrity of the database is maintained by a
122
123
124
125
126
127
128






129
130
131
132
133
134
135
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142







+
+
+
+
+
+







  */
  zSql = "ATTACH '' AS vacuum_db;";
  rc = execSql(db, zSql);
  if( rc!=SQLITE_OK ) goto end_of_vacuum;
  pDb = &db->aDb[db->nDb-1];
  assert( strcmp(db->aDb[db->nDb-1].zName,"vacuum_db")==0 );
  pTemp = db->aDb[db->nDb-1].pBt;

  /* The call to execSql() to attach the temp database has left the file
  ** locked (as there was more than one active statement when the transaction
  ** to read the schema was concluded. Unlock it here so that this doesn't
  ** cause problems for the call to BtreeSetPageSize() below.  */
  sqlite3BtreeCommit(pTemp);

  nRes = sqlite3BtreeGetReserve(pMain);

  /* A VACUUM cannot change the pagesize of an encrypted database. */
#ifdef SQLITE_HAS_CODEC
  if( db->nextPagesize ){
    extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
176
177
178
179
180
181
182
183

184
185
186
187
188
189


190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
183
184
185
186
187
188
189

190
191
192
193
194


195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233







-
+




-
-
+
+















-
+













-
+







  if( rc!=SQLITE_OK ) goto end_of_vacuum;
  rc = execExecSql(db, 
      "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21) "
      "  FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'");
  if( rc!=SQLITE_OK ) goto end_of_vacuum;

  /* Loop through the tables in the main database. For each, do
  ** an "INSERT INTO vacuum_db.xxx SELECT * FROM xxx;" to copy
  ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
  ** the contents to the temporary database.
  */
  rc = execExecSql(db, 
      "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
      "|| ' SELECT * FROM ' || quote(name) || ';'"
      "FROM sqlite_master "
      "|| ' SELECT * FROM main.' || quote(name) || ';'"
      "FROM main.sqlite_master "
      "WHERE type = 'table' AND name!='sqlite_sequence' "
      "  AND rootpage>0"

  );
  if( rc!=SQLITE_OK ) goto end_of_vacuum;

  /* Copy over the sequence table
  */
  rc = execExecSql(db, 
      "SELECT 'DELETE FROM vacuum_db.' || quote(name) || ';' "
      "FROM vacuum_db.sqlite_master WHERE name='sqlite_sequence' "
  );
  if( rc!=SQLITE_OK ) goto end_of_vacuum;
  rc = execExecSql(db, 
      "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
      "|| ' SELECT * FROM ' || quote(name) || ';' "
      "|| ' SELECT * FROM main.' || quote(name) || ';' "
      "FROM vacuum_db.sqlite_master WHERE name=='sqlite_sequence';"
  );
  if( rc!=SQLITE_OK ) goto end_of_vacuum;


  /* Copy the triggers, views, and virtual tables from the main database
  ** over to the temporary database.  None of these objects has any
  ** associated storage, so all we have to do is copy their entries
  ** from the SQLITE_MASTER table.
  */
  rc = execSql(db,
      "INSERT INTO vacuum_db.sqlite_master "
      "  SELECT type, name, tbl_name, rootpage, sql"
      "    FROM sqlite_master"
      "    FROM main.sqlite_master"
      "   WHERE type='view' OR type='trigger'"
      "      OR (type='table' AND rootpage=0)"
  );
  if( rc ) goto end_of_vacuum;

  /* At this point, unless the main db was completely empty, there is now a
  ** transaction open on the vacuum database, but not on the main database.
250
251
252
253
254
255
256
257

258
259
260
261
262
263
264
265
257
258
259
260
261
262
263

264

265
266
267
268
269
270
271







-
+
-







    assert( 1==sqlite3BtreeIsInTrans(pTemp) );
    assert( 1==sqlite3BtreeIsInTrans(pMain) );

    /* Copy Btree meta values */
    for(i=0; i<ArraySize(aCopy); i+=2){
      /* GetMeta() and UpdateMeta() cannot fail in this context because
      ** we already have page 1 loaded into cache and marked dirty. */
      rc = sqlite3BtreeGetMeta(pMain, aCopy[i], &meta);
      sqlite3BtreeGetMeta(pMain, aCopy[i], &meta);
      if( NEVER(rc!=SQLITE_OK) ) goto end_of_vacuum;
      rc = sqlite3BtreeUpdateMeta(pTemp, aCopy[i], meta+aCopy[i+1]);
      if( NEVER(rc!=SQLITE_OK) ) goto end_of_vacuum;
    }

    rc = sqlite3BtreeCopyFile(pMain, pTemp);
    if( rc!=SQLITE_OK ) goto end_of_vacuum;
    rc = sqlite3BtreeCommit(pTemp);
Changes to src/vdbe.c.
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
38
39
40
41
42
43
44


45
46
47
48
49
50
51







-
-







** a program instruction by instruction.
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.866 2009/06/26 16:32:13 shane Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes.  The test
94
95
96
97
98
99
100











101
102
103
104
105
106
107
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116







+
+
+
+
+
+
+
+
+
+
+







static void updateMaxBlobsize(Mem *p){
  if( (p->flags & (MEM_Str|MEM_Blob))!=0 && p->n>sqlite3_max_blobsize ){
    sqlite3_max_blobsize = p->n;
  }
}
#endif

/*
** The next global variable is incremented each type the OP_Found opcode
** is executed. This is used to test whether or not the foreign key
** operation implemented using OP_FkIsZero is working. This variable
** has no function other than to help verify the correct operation of the
** library.
*/
#ifdef SQLITE_TEST
int sqlite3_found_count = 0;
#endif

/*
** Test a register to see if it exceeds the current maximum blob size.
** If it does, record the new maximum blob size.
*/
#if defined(SQLITE_TEST) && !defined(SQLITE_OMIT_BUILTIN_TEST)
# define UPDATE_MAX_BLOBSIZE(P)  updateMaxBlobsize(P)
#else
136
137
138
139
140
141
142
143
144
145


146
147
148

149
150
151
152
153
154
155
145
146
147
148
149
150
151



152
153
154


155
156
157
158
159
160
161
162







-
-
-
+
+

-
-
+







** P if required.
*/
#define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0)

/*
** Argument pMem points at a register that will be passed to a
** user-defined function or returned to the user as the result of a query.
** The second argument, 'db_enc' is the text encoding used by the vdbe for
** register variables.  This routine sets the pMem->enc and pMem->type
** variables used by the sqlite3_value_*() routines.
** This routine sets the pMem->type variable used by the sqlite3_value_*() 
** routines.
*/
#define storeTypeInfo(A,B) _storeTypeInfo(A)
static void _storeTypeInfo(Mem *pMem){
void sqlite3VdbeMemStoreType(Mem *pMem){
  int flags = pMem->flags;
  if( flags & MEM_Null ){
    pMem->type = SQLITE_NULL;
  }
  else if( flags & MEM_Int ){
    pMem->type = SQLITE_INTEGER;
  }
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
192
193
194
195
196
197
198

199
200
201
202
203
204
205
206







-
+







** if we run out of memory.
*/
static VdbeCursor *allocateCursor(
  Vdbe *p,              /* The virtual machine */
  int iCur,             /* Index of the new VdbeCursor */
  int nField,           /* Number of fields in the table or index */
  int iDb,              /* When database the cursor belongs to, or -1 */
  int isBtreeCursor     /* True for B-Tree vs. pseudo-table or vtab */
  int isBtreeCursor     /* True for B-Tree.  False for pseudo-table or vtab */
){
  /* Find the memory cell that will be used to store the blob of memory
  ** required for this VdbeCursor structure. It is convenient to use a 
  ** vdbe memory cell to manage the memory allocation required for a
  ** VdbeCursor structure for the following reasons:
  **
  **   * Sometimes cursor numbers are used for a couple of different
312
313
314
315
316
317
318
319

320
321
322
323
324
325
326
319
320
321
322
323
324
325

326
327
328
329
330
331
332
333







-
+







** loss of information and return the revised type of the argument.
**
** This is an EXPERIMENTAL api and is subject to change or removal.
*/
int sqlite3_value_numeric_type(sqlite3_value *pVal){
  Mem *pMem = (Mem*)pVal;
  applyNumericAffinity(pMem);
  storeTypeInfo(pMem, 0);
  sqlite3VdbeMemStoreType(pMem);
  return pMem->type;
}

/*
** Exported version of applyAffinity(). This one works on sqlite3_value*, 
** not the internal Mem* type.
*/
696
697
698
699
700
701
702


703
704
705
706




707
708
709
710
711
712
713
714
703
704
705
706
707
708
709
710
711




712
713
714
715

716
717
718
719
720
721
722







+
+
-
-
-
-
+
+
+
+
-







      pIn1 = &p->aMem[pOp->p1];
      REGISTER_TRACE(pOp->p1, pIn1);
      if( (opProperty & OPFLG_IN2)!=0 ){
        assert( pOp->p2>0 );
        assert( pOp->p2<=p->nMem );
        pIn2 = &p->aMem[pOp->p2];
        REGISTER_TRACE(pOp->p2, pIn2);
        /* As currently implemented, in2 implies out3.  There is no reason
        ** why this has to be, it just worked out that way. */
        if( (opProperty & OPFLG_OUT3)!=0 ){
          assert( pOp->p3>0 );
          assert( pOp->p3<=p->nMem );
          pOut = &p->aMem[pOp->p3];
        assert( (opProperty & OPFLG_OUT3)!=0 );
        assert( pOp->p3>0 );
        assert( pOp->p3<=p->nMem );
        pOut = &p->aMem[pOp->p3];
        }
      }else if( (opProperty & OPFLG_IN3)!=0 ){
        assert( pOp->p3>0 );
        assert( pOp->p3<=p->nMem );
        pIn3 = &p->aMem[pOp->p3];
        REGISTER_TRACE(pOp->p3, pIn3);
      }
    }else if( (opProperty & OPFLG_IN2)!=0 ){
842
843
844
845
846
847
848


















849
850
851

852
853
854
855
856

857
858
859


860
861
862
863
864
865
866
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875

876
877
878
879
880
881

882
883
884
885
886
887
888
889
890
891
892
893
894







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-

+




-
+



+
+







** If P4 is not null then it is an error message string.
**
** There is an implied "Halt 0 0 0" instruction inserted at the very end of
** every program.  So a jump past the last instruction of the program
** is the same as executing Halt.
*/
case OP_Halt: {
  if( pOp->p1==SQLITE_OK && p->pFrame ){
    /* Halt the sub-program. Return control to the parent frame. */
    VdbeFrame *pFrame = p->pFrame;
    p->pFrame = pFrame->pParent;
    p->nFrame--;
    sqlite3VdbeSetChanges(db, p->nChange);
    pc = sqlite3VdbeFrameRestore(pFrame);
    if( pOp->p2==OE_Ignore ){
      /* Instruction pc is the OP_Program that invoked the sub-program 
      ** currently being halted. If the p2 instruction of this OP_Halt
      ** instruction is set to OE_Ignore, then the sub-program is throwing
      ** an IGNORE exception. In this case jump to the address specified
      ** as the p2 of the calling OP_Program.  */
      pc = p->aOp[pc].p2-1;
    }
    break;
  }

  p->rc = pOp->p1;
  p->pc = pc;
  p->errorAction = (u8)pOp->p2;
  p->pc = pc;
  if( pOp->p4.z ){
    sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
  }
  rc = sqlite3VdbeHalt(p);
  assert( rc==SQLITE_BUSY || rc==SQLITE_OK );
  assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
  if( rc==SQLITE_BUSY ){
    p->rc = rc = SQLITE_BUSY;
  }else{
    assert( rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT );
    assert( rc==SQLITE_OK || db->nDeferredCons>0 );
    rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
  }
  goto vdbe_return;
}

/* Opcode: Integer P1 P2 * * *
**
985
986
987
988
989
990
991
992

993
994
995
996
997
998
999
1013
1014
1015
1016
1017
1018
1019

1020
1021
1022
1023
1024
1025
1026
1027







-
+







  Mem *pVar;       /* Value being transferred */

  p1 = pOp->p1 - 1;
  p2 = pOp->p2;
  n = pOp->p3;
  assert( p1>=0 && p1+n<=p->nVar );
  assert( p2>=1 && p2+n-1<=p->nMem );
  assert( pOp->p4.z==0 || pOp->p3==1 );
  assert( pOp->p4.z==0 || pOp->p3==1 || pOp->p3==0 );

  while( n-- > 0 ){
    pVar = &p->aVar[p1++];
    if( sqlite3VdbeMemTooBig(pVar) ){
      goto too_big;
    }
    pOut = &p->aMem[p2++];
1091
1092
1093
1094
1095
1096
1097









1098
1099
1100
1101
1102
1103
1104
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141







+
+
+
+
+
+
+
+
+







*/
case OP_ResultRow: {
  Mem *pMem;
  int i;
  assert( p->nResColumn==pOp->p2 );
  assert( pOp->p1>0 );
  assert( pOp->p1+pOp->p2<=p->nMem+1 );

  /* If this statement has violated immediate foreign key constraints, do
  ** not return the number of rows modified. And do not RELEASE the statement
  ** transaction. It needs to be rolled back.  */
  if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){
    assert( db->flags&SQLITE_CountRows );
    assert( p->usesStmtJournal );
    break;
  }

  /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then 
  ** DML statements invoke this opcode to return the number of rows 
  ** modified to the user. This is the only way that a VM that
  ** opens a statement transaction may invoke this opcode.
  **
  ** In case this is such a statement, close any statement transaction
1123
1124
1125
1126
1127
1128
1129
1130

1131
1132
1133
1134
1135
1136
1137
1160
1161
1162
1163
1164
1165
1166

1167
1168
1169
1170
1171
1172
1173
1174







-
+







  /* Make sure the results of the current row are \000 terminated
  ** and have an assigned type.  The results are de-ephemeralized as
  ** as side effect.
  */
  pMem = p->pResultSet = &p->aMem[pOp->p1];
  for(i=0; i<pOp->p2; i++){
    sqlite3VdbeMemNulTerminate(&pMem[i]);
    storeTypeInfo(&pMem[i], encoding);
    sqlite3VdbeMemStoreType(&pMem[i]);
    REGISTER_TRACE(pOp->p1+i, &pMem[i]);
  }
  if( db->mallocFailed ) goto no_mem;

  /* Return SQLITE_ROW
  */
  p->pc = pc + 1;
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210



1211
1212
1213
1214
1215
1216
1217
1238
1239
1240
1241
1242
1243
1244



1245
1246
1247
1248
1249
1250
1251
1252
1253
1254







-
-
-
+
+
+







** Subtract the value in register P1 from the value in register P2
** and store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: Divide P1 P2 P3 * *
**
** Divide the value in register P1 by the value in register P2
** and store the result in register P3.  If the value in register P2
** is zero, then the result is NULL.
** If either input is NULL, the result is NULL.
** and store the result in register P3 (P3=P2/P1). If the value in 
** register P1 is zero, then the result is NULL. If either input is 
** NULL, the result is NULL.
*/
/* Opcode: Remainder P1 P2 P3 * *
**
** Compute the remainder after integer division of the value in
** register P1 by the value in register P2 and store the result in P3. 
** If the value in register P2 is zero the result is NULL.
** If either operand is NULL, the result is NULL.
1342
1343
1344
1345
1346
1347
1348
1349

1350
1351
1352
1353
1354
1355
1356
1379
1380
1381
1382
1383
1384
1385

1386
1387
1388
1389
1390
1391
1392
1393







-
+







  assert( apVal || n==0 );

  assert( n==0 || (pOp->p2>0 && pOp->p2+n<=p->nMem+1) );
  assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
  pArg = &p->aMem[pOp->p2];
  for(i=0; i<n; i++, pArg++){
    apVal[i] = pArg;
    storeTypeInfo(pArg, encoding);
    sqlite3VdbeMemStoreType(pArg);
    REGISTER_TRACE(pOp->p2, pArg);
  }

  assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC );
  if( pOp->p4type==P4_FUNCDEF ){
    ctx.pFunc = pOp->p4.pFunc;
    ctx.pVdbeFunc = 0;
1655
1656
1657
1658
1659
1660
1661






1662
1663
1664
1665
1666
1667






1668
1669
1670
1671
1672
1673
1674
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723







+
+
+
+
+
+






+
+
+
+
+
+







** store a boolean result (either 0, or 1, or NULL) in register P2.
*/
/* Opcode: Ne P1 P2 P3 P4 P5
**
** This works just like the Lt opcode except that the jump is taken if
** the operands in registers P1 and P3 are not equal.  See the Lt opcode for
** additional information.
**
** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either
** true or false and is never NULL.  If both operands are NULL then the result
** of comparison is false.  If either operand is NULL then the result is true.
** If neither operand is NULL the the result is the same as it would be if
** the SQLITE_NULLEQ flag were omitted from P5.
*/
/* Opcode: Eq P1 P2 P3 P4 P5
**
** This works just like the Lt opcode except that the jump is taken if
** the operands in registers P1 and P3 are equal.
** See the Lt opcode for additional information.
**
** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either
** true or false and is never NULL.  If both operands are NULL then the result
** of comparison is true.  If either operand is NULL then the result is false.
** If neither operand is NULL the the result is the same as it would be if
** the SQLITE_NULLEQ flag were omitted from P5.
*/
/* Opcode: Le P1 P2 P3 P4 P5
**
** This works just like the Lt opcode except that the jump is taken if
** the content of register P3 is less than or equal to the content of
** register P1.  See the Lt opcode for additional information.
*/
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695


1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718































1719
1720
1721
1722
1723





1724
1725
1726
1727
1728
1729
1730
1735
1736
1737
1738
1739
1740
1741



1742
1743
1744






















1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776




1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788







-
-
-
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
+
+
+
+
+







*/
case OP_Eq:               /* same as TK_EQ, jump, in1, in3 */
case OP_Ne:               /* same as TK_NE, jump, in1, in3 */
case OP_Lt:               /* same as TK_LT, jump, in1, in3 */
case OP_Le:               /* same as TK_LE, jump, in1, in3 */
case OP_Gt:               /* same as TK_GT, jump, in1, in3 */
case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
  int flags;
  int res;
  char affinity;
  int res;            /* Result of the comparison of pIn1 against pIn3 */
  char affinity;      /* Affinity to use for comparison */

  flags = pIn1->flags|pIn3->flags;

  if( flags&MEM_Null ){
    /* If either operand is NULL then the result is always NULL.
    ** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
    */
    if( pOp->p5 & SQLITE_STOREP2 ){
      pOut = &p->aMem[pOp->p2];
      MemSetTypeFlag(pOut, MEM_Null);
      REGISTER_TRACE(pOp->p2, pOut);
    }else if( pOp->p5 & SQLITE_JUMPIFNULL ){
      pc = pOp->p2-1;
    }
    break;
  }

  affinity = pOp->p5 & SQLITE_AFF_MASK;
  if( affinity ){
    applyAffinity(pIn1, affinity, encoding);
    applyAffinity(pIn3, affinity, encoding);
    if( db->mallocFailed ) goto no_mem;
  }
  if( (pIn1->flags | pIn3->flags)&MEM_Null ){
    /* One or both operands are NULL */
    if( pOp->p5 & SQLITE_NULLEQ ){
      /* If SQLITE_NULLEQ is set (which will only happen if the operator is
      ** OP_Eq or OP_Ne) then take the jump or not depending on whether
      ** or not both operands are null.
      */
      assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
      res = (pIn1->flags & pIn3->flags & MEM_Null)==0;
    }else{
      /* SQLITE_NULLEQ is clear and at least one operand is NULL,
      ** then the result is always NULL.
      ** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
      */
      if( pOp->p5 & SQLITE_STOREP2 ){
        pOut = &p->aMem[pOp->p2];
        MemSetTypeFlag(pOut, MEM_Null);
        REGISTER_TRACE(pOp->p2, pOut);
      }else if( pOp->p5 & SQLITE_JUMPIFNULL ){
        pc = pOp->p2-1;
      }
      break;
    }
  }else{
    /* Neither operand is NULL.  Do a comparison. */
    affinity = pOp->p5 & SQLITE_AFF_MASK;
    if( affinity ){
      applyAffinity(pIn1, affinity, encoding);
      applyAffinity(pIn3, affinity, encoding);
      if( db->mallocFailed ) goto no_mem;
    }

  assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
  ExpandBlob(pIn1);
  ExpandBlob(pIn3);
  res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
    assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
    ExpandBlob(pIn1);
    ExpandBlob(pIn3);
    res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
  }
  switch( pOp->opcode ){
    case OP_Eq:    res = res==0;     break;
    case OP_Ne:    res = res!=0;     break;
    case OP_Lt:    res = res<0;      break;
    case OP_Le:    res = res<=0;     break;
    case OP_Gt:    res = res>0;      break;
    default:       res = res>=0;     break;
1782
1783
1784
1785
1786
1787
1788
1789
1790








1791



1792
1793
1794
1795
1796
1797
1798
1840
1841
1842
1843
1844
1845
1846

1847
1848
1849
1850
1851
1852
1853
1854
1855

1856
1857
1858
1859
1860
1861
1862
1863
1864
1865







-

+
+
+
+
+
+
+
+
-
+
+
+







  int bRev;          /* True for DESCENDING sort order */

  n = pOp->p3;
  pKeyInfo = pOp->p4.pKeyInfo;
  assert( n>0 );
  assert( pKeyInfo!=0 );
  p1 = pOp->p1;
  assert( p1>0 && p1+n<=p->nMem+1 );
  p2 = pOp->p2;
#if SQLITE_DEBUG
  if( aPermute ){
    int k, mx = 0;
    for(k=0; k<n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
    assert( p1>0 && p1+mx<=p->nMem+1 );
    assert( p2>0 && p2+mx<=p->nMem+1 );
  }else{
    assert( p1>0 && p1+n<=p->nMem+1 );
  assert( p2>0 && p2+n<=p->nMem+1 );
    assert( p2>0 && p2+n<=p->nMem+1 );
  }
#endif /* SQLITE_DEBUG */
  for(i=0; i<n; i++){
    idx = aPermute ? aPermute[i] : i;
    REGISTER_TRACE(p1+idx, &p->aMem[p1+idx]);
    REGISTER_TRACE(p2+idx, &p->aMem[p2+idx]);
    assert( i<pKeyInfo->nField );
    pColl = pKeyInfo->aColl[i];
    bRev = pKeyInfo->aSortOrder[i];
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982

1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994





1995
1996
1997
1998
1999
2000
2001
2020
2021
2022
2023
2024
2025
2026























2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+












+
+
+
+
+







case OP_NotNull: {            /* same as TK_NOTNULL, jump, in1 */
  if( (pIn1->flags & MEM_Null)==0 ){
    pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: SetNumColumns * P2 * * *
**
** This opcode sets the number of columns for the cursor opened by the
** following instruction to P2.
**
** An OP_SetNumColumns is only useful if it occurs immediately before 
** one of the following opcodes:
**
**     OpenRead
**     OpenWrite
**     OpenPseudo
**
** If the OP_Column opcode is to be executed on a cursor, then
** this opcode must be present immediately before the opcode that
** opens the cursor.
*/
#if 0
case OP_SetNumColumns: {
  break;
}
#endif

/* Opcode: Column P1 P2 P3 P4 *
/* Opcode: Column P1 P2 P3 P4 P5
**
** Interpret the data that cursor P1 points to as a structure built using
** the MakeRecord instruction.  (See the MakeRecord opcode for additional
** information about the format of the data.)  Extract the P2-th column
** from this record.  If there are less that (P2+1) 
** values in the record, extract a NULL.
**
** The value extracted is stored in register P3.
**
** If the column contains fewer than P2 fields, then extract a NULL.  Or,
** if the P4 argument is a P4_MEM use the value of the P4 argument as
** the result.
**
** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor,
** then the cache of the cursor is reset prior to extracting the column.
** The first OP_Column against a pseudo-table after the value of the content
** register has changed should have this bit set.
*/
case OP_Column: {
  u32 payloadSize;   /* Number of bytes in the record */
  i64 payloadSize64; /* Number of bytes in the record */
  int p1;            /* P1 value of the opcode */
  int p2;            /* column number to retrieve */
  VdbeCursor *pC;    /* The VDBE cursor */
2011
2012
2013
2014
2015
2016
2017

2018
2019
2020
2021
2022
2023
2024
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075







+







  Mem sMem;          /* For storing the record being decoded */
  u8 *zIdx;          /* Index into header */
  u8 *zEndHdr;       /* Pointer to first byte after the header */
  u32 offset;        /* Offset into the data */
  u64 offset64;      /* 64-bit offset.  64 bits needed to catch overflow */
  int szHdr;         /* Size of the header size field at start of record */
  int avail;         /* Number of bytes of available data */
  Mem *pReg;         /* PseudoTable input register */


  p1 = pOp->p1;
  p2 = pOp->p2;
  pC = 0;
  memset(&sMem, 0, sizeof(sMem));
  assert( p1<p->nCursor );
2051
2052
2053
2054
2055
2056
2057

2058


2059
2060
2061
2062
2063
2064

2065


2066
2067
2068
2069
2070
2071






2072
2073
2074
2075
2076
2077
2078
2102
2103
2104
2105
2106
2107
2108
2109

2110
2111
2112
2113
2114
2115
2116
2117
2118

2119
2120
2121





2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134







+
-
+
+






+
-
+
+

-
-
-
-
-
+
+
+
+
+
+







    if( rc ) goto abort_due_to_error;
    if( pC->nullRow ){
      payloadSize = 0;
    }else if( pC->cacheStatus==p->cacheCtr ){
      payloadSize = pC->payloadSize;
      zRec = (char*)pC->aRow;
    }else if( pC->isIndex ){
      assert( sqlite3BtreeCursorIsValid(pCrsr) );
      sqlite3BtreeKeySize(pCrsr, &payloadSize64);
      rc = sqlite3BtreeKeySize(pCrsr, &payloadSize64);
      assert( rc==SQLITE_OK );   /* True because of CursorMoveto() call above */
      /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the
      ** payload size, so it is impossible for payloadSize64 to be
      ** larger than 32 bits. */
      assert( (payloadSize64 & SQLITE_MAX_U32)==(u64)payloadSize64 );
      payloadSize = (u32)payloadSize64;
    }else{
      assert( sqlite3BtreeCursorIsValid(pCrsr) );
      sqlite3BtreeDataSize(pCrsr, &payloadSize);
      rc = sqlite3BtreeDataSize(pCrsr, &payloadSize);
      assert( rc==SQLITE_OK );   /* DataSize() cannot fail */
    }
  }else if( pC->pseudoTable ){
    /* The record is the sole entry of a pseudo-table */
    payloadSize = pC->nData;
    zRec = pC->pData;
    pC->cacheStatus = CACHE_STALE;
  }else if( pC->pseudoTableReg>0 ){
    pReg = &p->aMem[pC->pseudoTableReg];
    assert( pReg->flags & MEM_Blob );
    payloadSize = pReg->n;
    zRec = pReg->z;
    pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr;
    assert( payloadSize==0 || zRec!=0 );
  }else{
    /* Consider the row to be NULL */
    payloadSize = 0;
  }

  /* If payloadSize is 0, then just store a NULL */
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2496
2497
2498
2499
2500
2501
2502








































2503
2504
2505
2506
2507
2508
2509







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







  }
  pOut->flags = MEM_Int;
  pOut->u.i = nEntry;
  break;
}
#endif

/* Opcode: Statement P1 * * * *
**
** Begin an individual statement transaction which is part of a larger
** transaction.  This is needed so that the statement
** can be rolled back after an error without having to roll back the
** entire transaction.  The statement transaction will automatically
** commit when the VDBE halts.
**
** If the database connection is currently in autocommit mode (that 
** is to say, if it is in between BEGIN and COMMIT)
** and if there are no other active statements on the same database
** connection, then this operation is a no-op.  No statement transaction
** is needed since any error can use the normal ROLLBACK process to
** undo changes.
**
** If a statement transaction is started, then a statement journal file
** will be allocated and initialized.
**
** The statement is begun on the database file with index P1.  The main
** database file has an index of 0 and the file used for temporary tables
** has an index of 1.
*/
case OP_Statement: {
  Btree *pBt;
  if( db->autoCommit==0 || db->activeVdbeCnt>1 ){
    assert( pOp->p1>=0 && pOp->p1<db->nDb );
    assert( db->aDb[pOp->p1].pBt!=0 );
    pBt = db->aDb[pOp->p1].pBt;
    assert( sqlite3BtreeIsInTrans(pBt) );
    assert( (p->btreeMask & (1<<pOp->p1))!=0 );
    if( p->iStatement==0 ){
      assert( db->nStatement>=0 && db->nSavepoint>=0 );
      db->nStatement++; 
      p->iStatement = db->nSavepoint + db->nStatement;
    }
    rc = sqlite3BtreeBeginStmt(pBt, p->iStatement);
  }
  break;
}

/* Opcode: Savepoint P1 * * P4 *
**
** Open, release or rollback the savepoint named by parameter P4, depending
** on the value of P1. To open a new savepoint, P1==0. To release (commit) an
** existing savepoint, P1==1, or to rollback an existing savepoint P1==2.
*/
case OP_Savepoint: {
2536
2537
2538
2539
2540
2541
2542

2543
2544
2545
2546
2547
2548
2549
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566







+







        }else{
          db->nSavepoint++;
        }
    
        /* Link the new savepoint into the database handle's list. */
        pNew->pNext = db->pSavepoint;
        db->pSavepoint = pNew;
        pNew->nDeferredCons = db->nDeferredCons;
      }
    }
  }else{
    iSavepoint = 0;

    /* Find the named savepoint. If there is no such savepoint, then an
    ** an error is returned to the user.  */
2573
2574
2575
2576
2577
2578
2579



2580
2581
2582
2583
2584
2585
2586
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606







+
+
+








      /* Determine whether or not this is a transaction savepoint. If so,
      ** and this is a RELEASE command, then the current transaction 
      ** is committed. 
      */
      int isTransaction = pSavepoint->pNext==0 && db->isTransactionSavepoint;
      if( isTransaction && p1==SAVEPOINT_RELEASE ){
        if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
          goto vdbe_return;
        }
        db->autoCommit = 1;
        if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
          p->pc = pc;
          db->autoCommit = 0;
          p->rc = rc = SQLITE_BUSY;
          goto vdbe_return;
        }
2605
2606
2607
2608
2609
2610
2611
2612




2613
2614
2615
2616
2617
2618
2619


2620
2621
2622
2623
2624
2625
2626
2625
2626
2627
2628
2629
2630
2631

2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651







-
+
+
+
+







+
+







      while( db->pSavepoint!=pSavepoint ){
        pTmp = db->pSavepoint;
        db->pSavepoint = pTmp->pNext;
        sqlite3DbFree(db, pTmp);
        db->nSavepoint--;
      }

      /* If it is a RELEASE, then destroy the savepoint being operated on too */
      /* If it is a RELEASE, then destroy the savepoint being operated on 
      ** too. If it is a ROLLBACK TO, then set the number of deferred 
      ** constraint violations present in the database to the value stored
      ** when the savepoint was created.  */
      if( p1==SAVEPOINT_RELEASE ){
        assert( pSavepoint==db->pSavepoint );
        db->pSavepoint = pSavepoint->pNext;
        sqlite3DbFree(db, pSavepoint);
        if( !isTransaction ){
          db->nSavepoint--;
        }
      }else{
        db->nDeferredCons = pSavepoint->nDeferredCons;
      }
    }
  }

  break;
}

2661
2662
2663
2664
2665
2666
2667


2668
2669
2670
2671
2672
2673
2674
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701







+
+







        "SQL statements in progress");
    rc = SQLITE_BUSY;
  }else if( desiredAutoCommit!=db->autoCommit ){
    if( iRollback ){
      assert( desiredAutoCommit==1 );
      sqlite3RollbackAll(db);
      db->autoCommit = 1;
    }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
      goto vdbe_return;
    }else{
      db->autoCommit = (u8)desiredAutoCommit;
      if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
        p->pc = pc;
        db->autoCommit = (u8)(1-desiredAutoCommit);
        p->rc = rc = SQLITE_BUSY;
        goto vdbe_return;
2707
2708
2709
2710
2711
2712
2713










2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731

2732
2733

















2734
2735
2736
2737
2738
2739
2740
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767

2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794







+
+
+
+
+
+
+
+
+
+

















-
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







** If P2 is non-zero, then a write-transaction is started.  A RESERVED lock is
** obtained on the database file when a write-transaction is started.  No
** other process can start another write transaction while this transaction is
** underway.  Starting a write transaction also creates a rollback journal. A
** write transaction must be started before any changes can be made to the
** database.  If P2 is 2 or greater then an EXCLUSIVE lock is also obtained
** on the file.
**
** If a write-transaction is started and the Vdbe.usesStmtJournal flag is
** true (this flag is set if the Vdbe may modify more than one row and may
** throw an ABORT exception), a statement transaction may also be opened.
** More specifically, a statement transaction is opened iff the database
** connection is currently not in autocommit mode, or if there are other
** active statements. A statement transaction allows the affects of this
** VDBE to be rolled back after an error without having to roll back the
** entire transaction. If no error is encountered, the statement transaction
** will automatically commit when the VDBE halts.
**
** If P2 is zero, then a read-lock is obtained on the database file.
*/
case OP_Transaction: {
  Btree *pBt;

  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  assert( (p->btreeMask & (1<<pOp->p1))!=0 );
  pBt = db->aDb[pOp->p1].pBt;

  if( pBt ){
    rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
    if( rc==SQLITE_BUSY ){
      p->pc = pc;
      p->rc = rc = SQLITE_BUSY;
      goto vdbe_return;
    }
    if( rc!=SQLITE_OK && rc!=SQLITE_READONLY /* && rc!=SQLITE_BUSY */ ){
    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
    }

    if( pOp->p2 && p->usesStmtJournal 
     && (db->autoCommit==0 || db->activeVdbeCnt>1) 
    ){
      assert( sqlite3BtreeIsInTrans(pBt) );
      if( p->iStatement==0 ){
        assert( db->nStatement>=0 && db->nSavepoint>=0 );
        db->nStatement++; 
        p->iStatement = db->nSavepoint + db->nStatement;
      }
      rc = sqlite3BtreeBeginStmt(pBt, p->iStatement);

      /* Store the current value of the database handles deferred constraint
      ** counter. If the statement transaction needs to be rolled back,
      ** the value of this counter needs to be restored too.  */
      p->nStmtDefCons = db->nDeferredCons;
    }
  }
  break;
}

/* Opcode: ReadCookie P1 P2 P3 * *
**
** Read cookie number P3 from database P1 and write it into register P2.
2755
2756
2757
2758
2759
2760
2761
2762

2763
2764
2765
2766
2767
2768
2769
2809
2810
2811
2812
2813
2814
2815

2816
2817
2818
2819
2820
2821
2822
2823







-
+







  iDb = pOp->p1;
  iCookie = pOp->p3;
  assert( pOp->p3<SQLITE_N_BTREE_META );
  assert( iDb>=0 && iDb<db->nDb );
  assert( db->aDb[iDb].pBt!=0 );
  assert( (p->btreeMask & (1<<iDb))!=0 );

  rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
  sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
  pOut->u.i = iMeta;
  MemSetTypeFlag(pOut, MEM_Int);
  break;
}

/* Opcode: SetCookie P1 P2 P3 * *
**
2793
2794
2795
2796
2797
2798
2799

2800
2801
2802
2803
2804
2805
2806
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861







+







    /* Record changes in the file format */
    pDb->pSchema->file_format = (u8)pIn3->u.i;
  }
  if( pOp->p1==1 ){
    /* Invalidate all prepared statements whenever the TEMP database
    ** schema is changed.  Ticket #1644 */
    sqlite3ExpirePreparedStatements(db);
    p->expired = 0;
  }
  break;
}

/* Opcode: VerifyCookie P1 P2 *
**
** Check the value of global database parameter number 0 (the
2820
2821
2822
2823
2824
2825
2826
2827

2828
2829
2830
2831
2832

2833
2834
2835
2836
2837
2838
2839
2875
2876
2877
2878
2879
2880
2881

2882
2883

2884
2885

2886
2887
2888
2889
2890
2891
2892
2893







-
+

-


-
+







case OP_VerifyCookie: {
  int iMeta;
  Btree *pBt;
  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  assert( (p->btreeMask & (1<<pOp->p1))!=0 );
  pBt = db->aDb[pOp->p1].pBt;
  if( pBt ){
    rc = sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
    sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
  }else{
    rc = SQLITE_OK;
    iMeta = 0;
  }
  if( rc==SQLITE_OK && iMeta!=pOp->p2 ){
  if( iMeta!=pOp->p2 ){
    sqlite3DbFree(db, p->zErrMsg);
    p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
    /* If the schema-cookie from the database file matches the cookie 
    ** stored with the in-memory representation of the schema, do
    ** not reload the schema from the database file.
    **
    ** If virtual-tables are in use, this is not just an optimization.
2910
2911
2912
2913
2914
2915
2916
2917





2918
2919
2920
2921
2922
2923
2924
2964
2965
2966
2967
2968
2969
2970

2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982







-
+
+
+
+
+







  KeyInfo *pKeyInfo;
  int p2;
  int iDb;
  int wrFlag;
  Btree *pX;
  VdbeCursor *pCur;
  Db *pDb;
  int flags;

  if( p->expired ){
    rc = SQLITE_ABORT;
    break;
  }

  nField = 0;
  pKeyInfo = 0;
  p2 = pOp->p2;
  iDb = pOp->p3;
  assert( iDb>=0 && iDb<db->nDb );
  assert( (p->btreeMask & (1<<iDb))!=0 );
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968

2969
2970
2971
2972
2973
2974

2975
2976



2977
2978
2979


2980
2981
2982
2983
2984
2985
2986
2987

2988
2989

2990
2991

2992
2993
2994






2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3016
3017
3018
3019
3020
3021
3022




3023






3024


3025
3026
3027



3028
3029








3030


3031


3032



3033
3034
3035
3036
3037
3038









3039
3040
3041
3042
3043
3044
3045







-
-
-
-
+
-
-
-
-
-
-
+
-
-
+
+
+
-
-
-
+
+
-
-
-
-
-
-
-
-
+
-
-
+
-
-
+
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-







  assert( pOp->p1>=0 );
  pCur = allocateCursor(p, pOp->p1, nField, iDb, 1);
  if( pCur==0 ) goto no_mem;
  pCur->nullRow = 1;
  rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor);
  pCur->pKeyInfo = pKeyInfo;

  switch( rc ){
    case SQLITE_OK: {
      flags = sqlite3BtreeFlags(pCur->pCursor);

  /* Since it performs no memory allocation or IO, the only values that
      /* Sanity checking.  Only the lower four bits of the flags byte should
      ** be used.  Bit 3 (mask 0x08) is unpredictable.  The lower 3 bits
      ** (mask 0x07) should be either 5 (intkey+leafdata for tables) or
      ** 2 (zerodata for indices).  If these conditions are not met it can
      ** only mean that we are dealing with a corrupt database file.
      ** Note:  All of the above is checked already in sqlite3BtreeCursor().
  ** sqlite3BtreeCursor() may return are SQLITE_EMPTY and SQLITE_OK. 
      */
      assert( (flags & 0xf0)==0 );
  ** SQLITE_EMPTY is only returned when attempting to open the table
  ** rooted at page 1 of a zero-byte database.  */
  assert( rc==SQLITE_EMPTY || rc==SQLITE_OK );
      assert( (flags & 0x07)==5 || (flags & 0x07)==2 );

      pCur->isTable = (flags & BTREE_INTKEY)!=0 ?1:0;
  if( rc==SQLITE_EMPTY ){
    pCur->pCursor = 0;
      pCur->isIndex = (flags & BTREE_ZERODATA)!=0 ?1:0;
      /* If P4==0 it means we are expected to open a table.  If P4!=0 then
      ** we expect to be opening an index.  If this is not what happened,
      ** then the database is corrupt
      */
      if( (pCur->isTable && pOp->p4type==P4_KEYINFO)
       || (pCur->isIndex && pOp->p4type!=P4_KEYINFO) ){
        rc = SQLITE_CORRUPT_BKPT;
    rc = SQLITE_OK;
        goto abort_due_to_error;
      }
  }
      break;
    }

    case SQLITE_EMPTY: {
      pCur->isTable = pOp->p4type!=P4_KEYINFO;
      pCur->isIndex = !pCur->isTable;
  /* Set the VdbeCursor.isTable and isIndex variables. Previous versions of
  ** SQLite used to check if the root-page flags were sane at this point
  ** and report database corruption if they were not, but this check has
  ** since moved into the btree layer.  */  
  pCur->isTable = pOp->p4type!=P4_KEYINFO;
  pCur->isIndex = !pCur->isTable;
      pCur->pCursor = 0;
      rc = SQLITE_OK;
      break;
    }
    default: {
      assert( rc!=SQLITE_BUSY );  /* Busy conditions detected earlier */
      goto abort_due_to_error;
    }
  }
  break;
}

/* Opcode: OpenEphemeral P1 P2 * P4 *
**
** Open a new cursor P1 to a transient table.
** The cursor is always opened read/write even if 
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075



3076
3077

3078
3079
3080

3081
3082
3083

3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100

3101
3102
3103
3104
3105
3106
3107
3108
3101
3102
3103
3104
3105
3106
3107



3108
3109
3110
3111

3112

3113

3114



3115





3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126

3127

3128
3129
3130
3131
3132
3133
3134







-
-
-
+
+
+

-
+
-

-
+
-
-
-
+
-
-
-
-
-











-
+
-







  pCx->isIndex = !pCx->isTable;
  break;
}

/* Opcode: OpenPseudo P1 P2 P3 * *
**
** Open a new cursor that points to a fake table that contains a single
** row of data.  Any attempt to write a second row of data causes the
** first row to be deleted.  All data is deleted when the cursor is
** closed.
** row of data.  The content of that one row in the content of memory
** register P2.  In other words, cursor P1 becomes an alias for the 
** MEM_Blob content contained in register P2.
**
** A pseudo-table created by this opcode is useful for holding the
** A pseudo-table created by this opcode is used to hold the a single
** NEW or OLD tables in a trigger.  Also used to hold the a single
** row output from the sorter so that the row can be decomposed into
** individual columns using the OP_Column opcode.
** individual columns using the OP_Column opcode.  The OP_Column opcode
**
** When OP_Insert is executed to insert a row in to the pseudo table,
** the pseudo-table cursor may or may not make it's own copy of the
** is the only cursor opcode that works with a pseudo-table.
** original row data. If P2 is 0, then the pseudo-table will copy the
** original row data. Otherwise, a pointer to the original memory cell
** is stored. In this case, the vdbe program must ensure that the 
** memory cell containing the row data is not overwritten until the
** pseudo table is closed (or a new row is inserted into it).
**
** P3 is the number of fields in the records that will be stored by
** the pseudo-table.
*/
case OP_OpenPseudo: {
  VdbeCursor *pCx;

  assert( pOp->p1>=0 );
  pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0);
  if( pCx==0 ) goto no_mem;
  pCx->nullRow = 1;
  pCx->pseudoTable = 1;
  pCx->pseudoTableReg = pOp->p2;
  pCx->ephemPseudoTable = (u8)pOp->p2;
  pCx->isTable = 1;
  pCx->isIndex = 0;
  break;
}

/* Opcode: Close P1 * * * *
**
3179
3180
3181
3182
3183
3184
3185

3186
3187
3188
3189
3190
3191
3192
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219







+







  int nField;
  i64 iKey;      /* The rowid we are to seek to */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( pOp->p2!=0 );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->pseudoTableReg==0 );
  if( pC->pCursor!=0 ){
    oc = pOp->opcode;
    pC->nullRow = 0;
    if( pC->isTable ){
      /* The input value in P3 might be of any type: integer, real, string,
      ** blob, or NULL.  But it needs to be an integer before we can do
      ** the seek, so covert it. */
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3319
3320
3321
3322
3323
3324
3325

3326
3327
3328
3329
3330
3331
3332







-







      pc = pOp->p2 - 1;
    }
  }else{
    /* This happens when attempting to open the sqlite3_master table
    ** for read access returns SQLITE_EMPTY. In this case always
    ** take the jump (since there are no records in the table).
    */
    assert( pC->pseudoTable==0 );
    pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: Seek P1 P2 * * *
**
3361
3362
3363
3364
3365
3366
3367




3368
3369
3370
3371
3372
3373
3374
3375
3376

3377
3378
3379
3380
3381
3382
3383
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414







+
+
+
+









+







case OP_NotFound:       /* jump, in3 */
case OP_Found: {        /* jump, in3 */
  int alreadyExists;
  VdbeCursor *pC;
  int res;
  UnpackedRecord *pIdxKey;
  char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];

#ifdef SQLITE_TEST
  sqlite3_found_count++;
#endif

  alreadyExists = 0;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  if( ALWAYS(pC->pCursor!=0) ){

    assert( pC->isTable==0 );
    assert( pIn3->flags & MEM_Blob );
    ExpandBlob(pIn3);
    pIdxKey = sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z,
                                      aTempRec, sizeof(aTempRec));
    if( pIdxKey==0 ){
      goto no_mem;
    }
    if( pOp->opcode==OP_Found ){
      pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
3502
3503
3504
3505
3506
3507
3508

3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559


3560
3561
3562
3563
3564
3565
3566







+



















-
-







  u64 iKey;

  assert( pIn3->flags & MEM_Int );
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->isTable );
  assert( pC->pseudoTableReg==0 );
  pCrsr = pC->pCursor;
  if( pCrsr!=0 ){
    res = 0;
    iKey = pIn3->u.i;
    rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
    pC->lastRowid = pIn3->u.i;
    pC->rowidIsValid = res==0 ?1:0;
    pC->nullRow = 0;
    pC->cacheStatus = CACHE_STALE;
    pC->deferredMoveto = 0;
    if( res!=0 ){
      pc = pOp->p2 - 1;
      assert( pC->rowidIsValid==0 );
    }
    pC->seekResult = res;
  }else{
    /* This happens when an attempt to open a read cursor on the 
    ** sqlite_master table returns SQLITE_EMPTY.
    */
    assert( !pC->pseudoTable );
    assert( pC->isTable );
    pc = pOp->p2 - 1;
    assert( pC->rowidIsValid==0 );
    pC->seekResult = 0;
  }
  break;
}

3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564





3565
3566
3567
3568
3569
3570
3571
3572

3573
3574
3575
3576
3577
3578
3579
3583
3584
3585
3586
3587
3588
3589





3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610







-
-
-
-
-
+
+
+
+
+








+







/* Opcode: NewRowid P1 P2 P3 * *
**
** Get a new integer record number (a.k.a "rowid") used as the key to a table.
** The record number is not previously used as a key in the database
** table that cursor P1 points to.  The new record number is written
** written to register P2.
**
** If P3>0 then P3 is a register that holds the largest previously
** generated record number.  No new record numbers are allowed to be less
** than this value.  When this value reaches its maximum, a SQLITE_FULL
** error is generated.  The P3 register is updated with the generated
** record number.  This P3 mechanism is used to help implement the
** If P3>0 then P3 is a register in the root frame of this VDBE that holds 
** the largest previously generated record number. No new record numbers are
** allowed to be less than this value. When this value reaches its maximum, 
** a SQLITE_FULL error is generated. The P3 register is updated with the '
** generated record number. This P3 mechanism is used to help implement the
** AUTOINCREMENT feature.
*/
case OP_NewRowid: {           /* out2-prerelease */
  i64 v;                 /* The new rowid */
  VdbeCursor *pC;        /* Cursor of table to get the new rowid */
  int res;               /* Result of an sqlite3BtreeLast() */
  int cnt;               /* Counter to limit the number of searches */
  Mem *pMem;             /* Register holding largest rowid for AUTOINCREMENT */
  VdbeFrame *pFrame;     /* Root frame of VDBE */

  v = 0;
  res = 0;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  if( NEVER(pC->pCursor==0) ){
3611
3612
3613
3614
3615
3616
3617

3618


3619
3620
3621
3622
3623
3624
3625
3626
3627
3628

3629
3630
3631













3632
3633
3634
3635
3636
3637
3638
3642
3643
3644
3645
3646
3647
3648
3649

3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662



3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682







+
-
+
+










+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+







        rc = sqlite3BtreeLast(pC->pCursor, &res);
        if( rc!=SQLITE_OK ){
          goto abort_due_to_error;
        }
        if( res ){
          v = 1;
        }else{
          assert( sqlite3BtreeCursorIsValid(pC->pCursor) );
          sqlite3BtreeKeySize(pC->pCursor, &v);
          rc = sqlite3BtreeKeySize(pC->pCursor, &v);
          assert( rc==SQLITE_OK );   /* Cannot fail following BtreeLast() */
          if( v==MAX_ROWID ){
            pC->useRandomRowid = 1;
          }else{
            v++;
          }
        }
      }

#ifndef SQLITE_OMIT_AUTOINCREMENT
      if( pOp->p3 ){
        /* Assert that P3 is a valid memory cell. */
        assert( pOp->p3>0 && pOp->p3<=p->nMem ); /* P3 is a valid memory cell */
        pMem = &p->aMem[pOp->p3];
	REGISTER_TRACE(pOp->p3, pMem);
        assert( pOp->p3>0 );
        if( p->pFrame ){
          for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
          /* Assert that P3 is a valid memory cell. */
          assert( pOp->p3<=pFrame->nMem );
          pMem = &pFrame->aMem[pOp->p3];
        }else{
          /* Assert that P3 is a valid memory cell. */
          assert( pOp->p3<=p->nMem );
          pMem = &p->aMem[pOp->p3];
        }

        REGISTER_TRACE(pOp->p3, pMem);
        sqlite3VdbeMemIntegerify(pMem);
        assert( (pMem->flags & MEM_Int)!=0 );  /* mem(P3) holds an integer */
        if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){
          rc = SQLITE_FULL;
          goto abort_due_to_error;
        }
        if( v<pMem->u.i+1 ){
3673
3674
3675
3676
3677
3678
3679
3680

3681
3682

3683
3684
3685
3686
3687













3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701






3702
3703
3704
3705
3706
3707
3708
3709
3710
3711










3712
3713
3714
3715
3716
3717
3718
3719


3720
3721




3722
3723
3724







3725
3726

3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765











3766
3767
3768
3769
3770
3771
3772
3773
3774
3717
3718
3719
3720
3721
3722
3723

3724
3725

3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764










3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776

3777
3778
3779


3780
3781
3782
3783
3784
3785
3786
3787



3788
3789
3790
3791
3792
3793
3794
3795

3796
3797
3798
3799
3800
3801
3802

































3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813


3814
3815
3816
3817
3818
3819
3820







-
+

-
+





+
+
+
+
+
+
+
+
+
+
+
+
+














+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+


-



-
-
+
+


+
+
+
+
-
-
-
+
+
+
+
+
+
+

-
+






-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-







  break;
}

/* Opcode: Insert P1 P2 P3 P4 P5
**
** Write an entry into the table of cursor P1.  A new entry is
** created if it doesn't already exist or the data for an existing
** entry is overwritten.  The data is the value stored register
** entry is overwritten.  The data is the value MEM_Blob stored in register
** number P2. The key is stored in register P3. The key must
** be an integer.
** be a MEM_Int.
**
** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is
** incremented (otherwise not).  If the OPFLAG_LASTROWID flag of P5 is set,
** then rowid is stored for subsequent return by the
** sqlite3_last_insert_rowid() function (otherwise it is unmodified).
**
** If the OPFLAG_USESEEKRESULT flag of P5 is set and if the result of
** the last seek operation (OP_NotExists) was a success, then this
** operation will not attempt to find the appropriate row before doing
** the insert but will instead overwrite the row that the cursor is
** currently pointing to.  Presumably, the prior OP_NotExists opcode
** has already positioned the cursor correctly.  This is an optimization
** that boosts performance by avoiding redundant seeks.
**
** If the OPFLAG_ISUPDATE flag is set, then this opcode is part of an
** UPDATE operation.  Otherwise (if the flag is clear) then this opcode
** is part of an INSERT operation.  The difference is only important to
** the update hook.
**
** Parameter P4 may point to a string containing the table-name, or
** may be NULL. If it is not NULL, then the update-hook 
** (sqlite3.xUpdateCallback) is invoked following a successful insert.
**
** (WARNING/TODO: If P1 is a pseudo-cursor and P2 is dynamically
** allocated, then ownership of P2 is transferred to the pseudo-cursor
** and register P2 becomes ephemeral.  If the cursor is changed, the
** value of register P2 will then change.  Make sure this does not
** cause any problems.)
**
** This instruction only works on tables.  The equivalent instruction
** for indices is OP_IdxInsert.
*/
/* Opcode: InsertInt P1 P2 P3 P4 P5
**
** This works exactly like OP_Insert except that the key is the
** integer value P3, not the value of the integer stored in register P3.
*/
case OP_Insert: 
case OP_Insert: {
  Mem *pData;
  Mem *pKey;
  i64 iKey;   /* The integer ROWID or key for the record to be inserted */
  VdbeCursor *pC;
  int nZero;
  int seekResult;
  const char *zDb;
  const char *zTbl;
  int op;
case OP_InsertInt: {
  Mem *pData;       /* MEM cell holding data for the record to be inserted */
  Mem *pKey;        /* MEM cell holding key  for the record */
  i64 iKey;         /* The integer ROWID or key for the record to be inserted */
  VdbeCursor *pC;   /* Cursor to table into which insert is written */
  int nZero;        /* Number of zero-bytes to append */
  int seekResult;   /* Result of prior seek or 0 if no USESEEKRESULT flag */
  const char *zDb;  /* database name - used by the update hook */
  const char *zTbl; /* Table name - used by the opdate hook */
  int op;           /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */

  pData = &p->aMem[pOp->p2];
  pKey = &p->aMem[pOp->p3];
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->pCursor!=0 || pC->pseudoTable );
  assert( pKey->flags & MEM_Int );
  assert( pC->pCursor!=0 );
  assert( pC->pseudoTableReg==0 );
  assert( pC->isTable );
  REGISTER_TRACE(pOp->p2, pData);

  if( pOp->opcode==OP_Insert ){
    pKey = &p->aMem[pOp->p3];
    assert( pKey->flags & MEM_Int );
  REGISTER_TRACE(pOp->p3, pKey);

  iKey = pKey->u.i;
    REGISTER_TRACE(pOp->p3, pKey);
    iKey = pKey->u.i;
  }else{
    assert( pOp->opcode==OP_InsertInt );
    iKey = pOp->p3;
  }

  if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
  if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = pKey->u.i;
  if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = iKey;
  if( pData->flags & MEM_Null ){
    pData->z = 0;
    pData->n = 0;
  }else{
    assert( pData->flags & (MEM_Blob|MEM_Str) );
  }
  if( pC->pseudoTable ){
    if( !pC->ephemPseudoTable ){
      sqlite3DbFree(db, pC->pData);
    }
    pC->iKey = iKey;
    pC->nData = pData->n;
    if( pC->ephemPseudoTable || pData->z==pData->zMalloc ){
      pC->pData = pData->z;
      if( !pC->ephemPseudoTable ){
        pData->flags &= ~MEM_Dyn;
        pData->flags |= MEM_Ephem;
        pData->zMalloc = 0;
      }
    }else{
      pC->pData = sqlite3Malloc( pC->nData+2 );
      if( !pC->pData ) goto no_mem;
      memcpy(pC->pData, pData->z, pC->nData);
      pC->pData[pC->nData] = 0;
      pC->pData[pC->nData+1] = 0;
    }
    pC->nullRow = 0;
  }else{
    seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0);
    if( pData->flags & MEM_Zero ){
      nZero = pData->u.nZero;
    }else{
      nZero = 0;
    }
    sqlite3BtreeSetCachedRowid(pC->pCursor, 0);
    rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
                            pData->z, pData->n, nZero,
                            pOp->p5 & OPFLAG_APPEND, seekResult
    );
  seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0);
  if( pData->flags & MEM_Zero ){
    nZero = pData->u.nZero;
  }else{
    nZero = 0;
  }
  sqlite3BtreeSetCachedRowid(pC->pCursor, 0);
  rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
                          pData->z, pData->n, nZero,
                          pOp->p5 & OPFLAG_APPEND, seekResult
  );
  }
  
  pC->rowidIsValid = 0;
  pC->deferredMoveto = 0;
  pC->cacheStatus = CACHE_STALE;

  /* Invoke the update-hook if required. */
  if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
    zDb = db->aDb[pC->iDb].zName;
3841
3842
3843
3844
3845
3846
3847
3848
3849

3850
3851
3852
3853
3854




3855
3856
3857
3858

3859
3860
3861
3862
3863
3864
3865
3866
3887
3888
3889
3890
3891
3892
3893


3894
3895




3896
3897
3898
3899
3900
3901


3902

3903
3904
3905
3906
3907
3908
3909







-
-
+

-
-
-
-
+
+
+
+


-
-
+
-







    const char *zTbl = pOp->p4.z;
    db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, iKey);
    assert( pC->iDb>=0 );
  }
  if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
  break;
}

/* Opcode: ResetCount P1 * *
/* Opcode: ResetCount * * * * *
**
** This opcode resets the VMs internal change counter to 0. If P1 is true,
** then the value of the change counter is copied to the database handle
** change counter (returned by subsequent calls to sqlite3_changes())
** before it is reset. This is used by trigger programs.
** The value of the change counter is copied to the database handle
** change counter (returned by subsequent calls to sqlite3_changes()).
** Then the VMs internal change counter resets to 0.
** This is used by trigger programs.
*/
case OP_ResetCount: {
  if( pOp->p1 ){
    sqlite3VdbeSetChanges(db, p->nChange);
  sqlite3VdbeSetChanges(db, p->nChange);
  }
  p->nChange = 0;
  break;
}

/* Opcode: RowData P1 P2 * * *
**
** Write into register P2 the complete row data for cursor P1.
3893
3894
3895
3896
3897
3898
3899
3900

3901
3902

3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915


3916
3917
3918
3919
3920
3921


3922
3923
3924
3925
3926
3927
3928
3936
3937
3938
3939
3940
3941
3942

3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958

3959
3960
3961
3962
3963
3964
3965

3966
3967
3968
3969
3970
3971
3972
3973
3974







-
+


+












-
+
+





-
+
+







  /* Note that RowKey and RowData are really exactly the same instruction */
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC->isTable || pOp->opcode==OP_RowKey );
  assert( pC->isIndex || pOp->opcode==OP_RowData );
  assert( pC!=0 );
  assert( pC->nullRow==0 );
  assert( pC->pseudoTable==0 );
  assert( pC->pseudoTableReg==0 );
  assert( pC->pCursor!=0 );
  pCrsr = pC->pCursor;
  assert( sqlite3BtreeCursorIsValid(pCrsr) );

  /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
  ** OP_Rewind/Op_Next with no intervening instructions that might invalidate
  ** the cursor.  Hence the following sqlite3VdbeCursorMoveto() call is always
  ** a no-op and can never fail.  But we leave it in place as a safety.
  */
  assert( pC->deferredMoveto==0 );
  rc = sqlite3VdbeCursorMoveto(pC);
  if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;

  if( pC->isIndex ){
    assert( !pC->isTable );
    sqlite3BtreeKeySize(pCrsr, &n64);
    rc = sqlite3BtreeKeySize(pCrsr, &n64);
    assert( rc==SQLITE_OK );    /* True because of CursorMoveto() call above */
    if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
      goto too_big;
    }
    n = (u32)n64;
  }else{
    sqlite3BtreeDataSize(pCrsr, &n);
    rc = sqlite3BtreeDataSize(pCrsr, &n);
    assert( rc==SQLITE_OK );    /* DataSize() cannot fail */
    if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
      goto too_big;
    }
  }
  if( sqlite3VdbeMemGrow(pOut, n, 0) ){
    goto no_mem;
  }
3952
3953
3954
3955
3956
3957
3958

3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978

3979
3980
3981
3982
3983
3984
3985


3986
3987
3988
3989
3990
3991
3992
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010


4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029


4030
4031
4032
4033
4034
4035
4036
4037
4038







+





-
-













+





-
-
+
+







  i64 v;
  sqlite3_vtab *pVtab;
  const sqlite3_module *pModule;

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->pseudoTableReg==0 );
  if( pC->nullRow ){
    /* Do nothing so that reg[P2] remains NULL */
    break;
  }else if( pC->deferredMoveto ){
    v = pC->movetoTarget;
  }else if( pC->pseudoTable ){
    v = pC->iKey;
#ifndef SQLITE_OMIT_VIRTUALTABLE
  }else if( pC->pVtabCursor ){
    pVtab = pC->pVtabCursor->pVtab;
    pModule = pVtab->pModule;
    assert( pModule->xRowid );
    if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
    rc = pModule->xRowid(pC->pVtabCursor, &v);
    sqlite3DbFree(db, p->zErrMsg);
    p->zErrMsg = pVtab->zErrMsg;
    pVtab->zErrMsg = 0;
    if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
#endif /* SQLITE_OMIT_VIRTUALTABLE */
  }else{
    assert( pC->pCursor!=0 );
    rc = sqlite3VdbeCursorMoveto(pC);
    if( rc ) goto abort_due_to_error;
    if( pC->rowidIsValid ){
      v = pC->lastRowid;
    }else{
      assert( pC->pCursor!=0 );
      sqlite3BtreeKeySize(pC->pCursor, &v);
      rc = sqlite3BtreeKeySize(pC->pCursor, &v);
      assert( rc==SQLITE_OK );  /* Always so because of CursorMoveto() above */
    }
  }
  pOut->u.i = v;
  MemSetTypeFlag(pOut, MEM_Int);
  break;
}

4741
4742
4743
4744
4745
4746
4747

4748

4749
4750
4751
4752










4753
4754
4755


4756







4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773









































































4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784














4785
4786






















4787
4788






































4789
4790
4791


4792
4793


4794
4795
4796
4797
4798









4799
4800
4801
4802
4803
4804
4805
4787
4788
4789
4790
4791
4792
4793
4794

4795
4796



4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807


4808
4809

4810
4811
4812
4813
4814
4815
4816
4817
















4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890











4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973


4974
4975
4976
4977
4978
4979

4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995







+
-
+

-
-
-
+
+
+
+
+
+
+
+
+
+

-
-
+
+
-
+
+
+
+
+
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



+
+
-
-
+
+




-
+
+
+
+
+
+
+
+
+







    sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
  }
  break;
}


#ifndef SQLITE_OMIT_TRIGGER

/* Opcode: ContextPush * * * 
/* Opcode: Program P1 P2 P3 P4 *
**
** Save the current Vdbe context such that it can be restored by a ContextPop
** opcode. The context stores the last insert row id, the last statement change
** count, and the current statement change count.
** Execute the trigger program passed as P4 (type P4_SUBPROGRAM). 
**
** P1 contains the address of the memory cell that contains the first memory 
** cell in an array of values used as arguments to the sub-program. P2 
** contains the address to jump to if the sub-program throws an IGNORE 
** exception using the RAISE() function. Register P3 contains the address 
** of a memory cell in this (the parent) VM that is used to allocate the 
** memory required by the sub-vdbe at runtime.
**
** P4 is a pointer to the VM containing the trigger program.
*/
case OP_ContextPush: {
  int i;
case OP_Program: {        /* jump */
  int nMem;               /* Number of memory registers for sub-program */
  Context *pContext;
  int nByte;              /* Bytes of runtime space required for sub-program */
  Mem *pRt;               /* Register to allocate runtime space */
  Mem *pMem;              /* Used to iterate through memory cells */
  Mem *pEnd;              /* Last memory cell in new array */
  VdbeFrame *pFrame;      /* New vdbe frame to execute in */
  SubProgram *pProgram;   /* Sub-program to execute */
  void *t;                /* Token identifying trigger */

  i = p->contextStackTop++;
  assert( i>=0 );
  /* FIX ME: This should be allocated as part of the vdbe at compile-time */
  if( i>=p->contextStackDepth ){
    p->contextStackDepth = i+1;
    p->contextStack = sqlite3DbReallocOrFree(db, p->contextStack,
                                          sizeof(Context)*(i+1));
    if( p->contextStack==0 ) goto no_mem;
  }
  pContext = &p->contextStack[i];
  pContext->lastRowid = db->lastRowid;
  pContext->nChange = p->nChange;
  break;
}

/* Opcode: ContextPop * * * 
  pProgram = pOp->p4.pProgram;
  pRt = &p->aMem[pOp->p3];
  assert( pProgram->nOp>0 );
  
  /* If the p5 flag is clear, then recursive invocation of triggers is 
  ** disabled for backwards compatibility (p5 is set if this sub-program
  ** is really a trigger, not a foreign key action, and the flag set
  ** and cleared by the "PRAGMA recursive_triggers" command is clear).
  ** 
  ** It is recursive invocation of triggers, at the SQL level, that is 
  ** disabled. In some cases a single trigger may generate more than one 
  ** SubProgram (if the trigger may be executed with more than one different 
  ** ON CONFLICT algorithm). SubProgram structures associated with a
  ** single trigger all have the same value for the SubProgram.token 
  ** variable.  */
  if( pOp->p5 ){
    t = pProgram->token;
    for(pFrame=p->pFrame; pFrame && pFrame->token!=t; pFrame=pFrame->pParent);
    if( pFrame ) break;
  }

  if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){
    rc = SQLITE_ERROR;
    sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion");
    break;
  }

  /* Register pRt is used to store the memory required to save the state
  ** of the current program, and the memory required at runtime to execute
  ** the trigger program. If this trigger has been fired before, then pRt 
  ** is already allocated. Otherwise, it must be initialized.  */
  if( (pRt->flags&MEM_Frame)==0 ){
    /* SubProgram.nMem is set to the number of memory cells used by the 
    ** program stored in SubProgram.aOp. As well as these, one memory
    ** cell is required for each cursor used by the program. Set local
    ** variable nMem (and later, VdbeFrame.nChildMem) to this value.
    */
    nMem = pProgram->nMem + pProgram->nCsr;
    nByte = ROUND8(sizeof(VdbeFrame))
              + nMem * sizeof(Mem)
              + pProgram->nCsr * sizeof(VdbeCursor *);
    pFrame = sqlite3DbMallocZero(db, nByte);
    if( !pFrame ){
      goto no_mem;
    }
    sqlite3VdbeMemRelease(pRt);
    pRt->flags = MEM_Frame;
    pRt->u.pFrame = pFrame;

    pFrame->v = p;
    pFrame->nChildMem = nMem;
    pFrame->nChildCsr = pProgram->nCsr;
    pFrame->pc = pc;
    pFrame->aMem = p->aMem;
    pFrame->nMem = p->nMem;
    pFrame->apCsr = p->apCsr;
    pFrame->nCursor = p->nCursor;
    pFrame->aOp = p->aOp;
    pFrame->nOp = p->nOp;
    pFrame->token = pProgram->token;

    pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem];
    for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){
      pMem->flags = MEM_Null;
      pMem->db = db;
    }
  }else{
    pFrame = pRt->u.pFrame;
    assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem );
    assert( pProgram->nCsr==pFrame->nChildCsr );
    assert( pc==pFrame->pc );
  }

**
** Restore the Vdbe context to the state it was in when contextPush was last
** executed. The context stores the last insert row id, the last statement
** change count, and the current statement change count.
*/
case OP_ContextPop: {
  Context *pContext;
  pContext = &p->contextStack[--p->contextStackTop];
  assert( p->contextStackTop>=0 );
  db->lastRowid = pContext->lastRowid;
  p->nChange = pContext->nChange;
  p->nFrame++;
  pFrame->pParent = p->pFrame;
  pFrame->lastRowid = db->lastRowid;
  pFrame->nChange = p->nChange;
  p->nChange = 0;
  p->pFrame = pFrame;
  p->aMem = &VdbeFrameMem(pFrame)[-1];
  p->nMem = pFrame->nChildMem;
  p->nCursor = (u16)pFrame->nChildCsr;
  p->apCsr = (VdbeCursor **)&p->aMem[p->nMem+1];
  p->aOp = pProgram->aOp;
  p->nOp = pProgram->nOp;
  pc = -1;

  break;
}

/* Opcode: Param P1 P2 * * *
**
** This opcode is only ever present in sub-programs called via the 
** OP_Program instruction. Copy a value currently stored in a memory 
** cell of the calling (parent) frame to cell P2 in the current frames 
** address space. This is used by trigger programs to access the new.* 
** and old.* values.
**
** The address of the cell in the parent frame is determined by adding
** the value of the P1 argument to the value of the P1 argument to the
** calling OP_Program instruction.
*/
case OP_Param: {           /* out2-prerelease */
  VdbeFrame *pFrame;
  Mem *pIn;
  pFrame = p->pFrame;
  pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1];   
  sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem);
  break;
}

#endif /* #ifndef SQLITE_OMIT_TRIGGER */

#ifndef SQLITE_OMIT_FOREIGN_KEY
/* Opcode: FkCounter P1 P2 * * *
**
** Increment a "constraint counter" by P2 (P2 may be negative or positive).
** If P1 is non-zero, the database constraint counter is incremented 
** (deferred foreign key constraints). Otherwise, if P1 is zero, the 
** statement counter is incremented (immediate foreign key constraints).
*/
case OP_FkCounter: {
  if( pOp->p1 ){
    db->nDeferredCons += pOp->p2;
  }else{
    p->nFkConstraint += pOp->p2;
  }
  break;
}

/* Opcode: FkIfZero P1 P2 * * *
**
** This opcode tests if a foreign key constraint-counter is currently zero.
** If so, jump to instruction P2. Otherwise, fall through to the next 
** instruction.
**
** If P1 is non-zero, then the jump is taken if the database constraint-counter
** is zero (the one that counts deferred constraint violations). If P1 is
** zero, the jump is taken if the statement constraint-counter is zero
** (immediate foreign key constraint violations).
*/
case OP_FkIfZero: {         /* jump */
  if( pOp->p1 ){
    if( db->nDeferredCons==0 ) pc = pOp->p2-1;
  }else{
    if( p->nFkConstraint==0 ) pc = pOp->p2-1;
  }
  break;
}
#endif /* #ifndef SQLITE_OMIT_FOREIGN_KEY */

#ifndef SQLITE_OMIT_AUTOINCREMENT
/* Opcode: MemMax P1 P2 * * *
**
** P1 is a register in the root frame of this VM (the root frame is
** different from the current frame if this instruction is being executed
** Set the value of register P1 to the maximum of its current value
** and the value in register P2.
** within a sub-program). Set the value of register P1 to the maximum of 
** its current value and the value in register P2.
**
** This instruction throws an error if the memory cell is not initially
** an integer.
*/
case OP_MemMax: {        /* in1, in2 */
case OP_MemMax: {        /* in2 */
  Mem *pIn1;
  VdbeFrame *pFrame;
  if( p->pFrame ){
    for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
    pIn1 = &pFrame->aMem[pOp->p1];
  }else{
    pIn1 = &p->aMem[pOp->p1];
  }
  sqlite3VdbeMemIntegerify(pIn1);
  sqlite3VdbeMemIntegerify(pIn2);
  if( pIn1->u.i<pIn2->u.i){
    pIn1->u.i = pIn2->u.i;
  }
  break;
}
4871
4872
4873
4874
4875
4876
4877
4878

4879
4880
4881
4882
4883
4884
4885
5061
5062
5063
5064
5065
5066
5067

5068
5069
5070
5071
5072
5073
5074
5075







-
+







  n = pOp->p5;
  assert( n>=0 );
  pRec = &p->aMem[pOp->p2];
  apVal = p->apArg;
  assert( apVal || n==0 );
  for(i=0; i<n; i++, pRec++){
    apVal[i] = pRec;
    storeTypeInfo(pRec, encoding);
    sqlite3VdbeMemStoreType(pRec);
  }
  ctx.pFunc = pOp->p4.pFunc;
  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  ctx.pMem = pMem = &p->aMem[pOp->p3];
  pMem->n++;
  ctx.s.flags = MEM_Null;
  ctx.s.z = 0;
4990
4991
4992
4993
4994
4995
4996
4997

4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010



5011
5012
5013
5014
5015
5016
5017
5018








5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038




5039
5040
5041


5042
5043
5044
5045
5046
5047
5048
5180
5181
5182
5183
5184
5185
5186

5187
5188
5189
5190
5191
5192
5193
5194
5195
5196




5197
5198
5199








5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223




5224
5225
5226
5227
5228


5229
5230
5231
5232
5233
5234
5235
5236
5237







-
+









-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
















-
-
-
-
+
+
+
+

-
-
+
+








#ifndef SQLITE_OMIT_SHARED_CACHE
/* Opcode: TableLock P1 P2 P3 P4 *
**
** Obtain a lock on a particular table. This instruction is only used when
** the shared-cache feature is enabled. 
**
** If P1 is  the index of the database in sqlite3.aDb[] of the database
** P1 is the index of the database in sqlite3.aDb[] of the database
** on which the lock is acquired.  A readlock is obtained if P3==0 or
** a write lock if P3==1.
**
** P2 contains the root-page of the table to lock.
**
** P4 contains a pointer to the name of the table being locked. This is only
** used to generate an error message if the lock cannot be obtained.
*/
case OP_TableLock: {
  int p1;
  u8 isWriteLock;

  p1 = pOp->p1; 
  u8 isWriteLock = (u8)pOp->p3;
  if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){
    int p1 = pOp->p1; 
  isWriteLock = (u8)pOp->p3;
  assert( p1>=0 && p1<db->nDb );
  assert( (p->btreeMask & (1<<p1))!=0 );
  assert( isWriteLock==0 || isWriteLock==1 );
  rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
  if( (rc&0xFF)==SQLITE_LOCKED ){
    const char *z = pOp->p4.z;
    sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z);
    assert( p1>=0 && p1<db->nDb );
    assert( (p->btreeMask & (1<<p1))!=0 );
    assert( isWriteLock==0 || isWriteLock==1 );
    rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
    if( (rc&0xFF)==SQLITE_LOCKED ){
      const char *z = pOp->p4.z;
      sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z);
    }
  }
  break;
}
#endif /* SQLITE_OMIT_SHARED_CACHE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VBegin * * * P4 *
**
** P4 may be a pointer to an sqlite3_vtab structure. If so, call the 
** xBegin method for that table.
**
** Also, whether or not P4 is set, check that this is not being called from
** within a callback to a virtual table xSync() method. If it is, the error
** code will be set to SQLITE_LOCKED.
*/
case OP_VBegin: {
  sqlite3_vtab *pVtab;
  pVtab = pOp->p4.pVtab;
  rc = sqlite3VtabBegin(db, pVtab);
  if( pVtab ){
  VTable *pVTab;
  pVTab = pOp->p4.pVtab;
  rc = sqlite3VtabBegin(db, pVTab);
  if( pVTab ){
    sqlite3DbFree(db, p->zErrMsg);
    p->zErrMsg = pVtab->zErrMsg;
    pVtab->zErrMsg = 0;
    p->zErrMsg = pVTab->pVtab->zErrMsg;
    pVTab->pVtab->zErrMsg = 0;
  }
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VCreate P1 * * P4 *
5081
5082
5083
5084
5085
5086
5087
5088

5089
5090
5091
5092
5093
5094
5095
5270
5271
5272
5273
5274
5275
5276

5277
5278
5279
5280
5281
5282
5283
5284







-
+







  VdbeCursor *pCur;
  sqlite3_vtab_cursor *pVtabCursor;
  sqlite3_vtab *pVtab;
  sqlite3_module *pModule;

  pCur = 0;
  pVtabCursor = 0;
  pVtab = pOp->p4.pVtab;
  pVtab = pOp->p4.pVtab->pVtab;
  pModule = (sqlite3_module *)pVtab->pModule;
  assert(pVtab && pModule);
  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
  rc = pModule->xOpen(pVtab, &pVtabCursor);
  sqlite3DbFree(db, p->zErrMsg);
  p->zErrMsg = pVtab->zErrMsg;
  pVtab->zErrMsg = 0;
5160
5161
5162
5163
5164
5165
5166
5167

5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5349
5350
5351
5352
5353
5354
5355

5356
5357
5358
5359

5360
5361
5362
5363
5364
5365

5366
5367
5368
5369
5370
5371
5372







-
+



-






-








  /* Invoke the xFilter method */
  {
    res = 0;
    apArg = p->apArg;
    for(i = 0; i<nArg; i++){
      apArg[i] = &pArgc[i+1];
      storeTypeInfo(apArg[i], 0);
      sqlite3VdbeMemStoreType(apArg[i]);
    }

    if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
    sqlite3VtabLock(pVtab);
    p->inVtabMethod = 1;
    rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
    p->inVtabMethod = 0;
    sqlite3DbFree(db, p->zErrMsg);
    p->zErrMsg = pVtab->zErrMsg;
    pVtab->zErrMsg = 0;
    sqlite3VtabUnlock(db, pVtab);
    if( rc==SQLITE_OK ){
      res = pModule->xEof(pVtabCursor);
    }
    if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;

    if( res ){
      pc = pOp->p2 - 1;
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5466
5467
5468
5469
5470
5471
5472

5473
5474
5475
5476
5477
5478

5479
5480
5481
5482
5483
5484
5485







-






-







  /* Invoke the xNext() method of the module. There is no way for the
  ** underlying implementation to return an error if one occurs during
  ** xNext(). Instead, if an error occurs, true is returned (indicating that 
  ** data is available) and the error code returned when xColumn or
  ** some other method is next invoked on the save virtual table cursor.
  */
  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
  sqlite3VtabLock(pVtab);
  p->inVtabMethod = 1;
  rc = pModule->xNext(pCur->pVtabCursor);
  p->inVtabMethod = 0;
  sqlite3DbFree(db, p->zErrMsg);
  p->zErrMsg = pVtab->zErrMsg;
  pVtab->zErrMsg = 0;
  sqlite3VtabUnlock(db, pVtab);
  if( rc==SQLITE_OK ){
    res = pModule->xEof(pCur->pVtabCursor);
  }
  if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;

  if( !res ){
    /* If there is data, jump to P2 */
5311
5312
5313
5314
5315
5316
5317
5318

5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5496
5497
5498
5499
5500
5501
5502

5503
5504
5505
5506
5507
5508

5509
5510
5511
5512

5513
5514
5515
5516
5517
5518
5519







-
+





-




-







** This opcode invokes the corresponding xRename method. The value
** in register P1 is passed as the zName argument to the xRename method.
*/
case OP_VRename: {
  sqlite3_vtab *pVtab;
  Mem *pName;

  pVtab = pOp->p4.pVtab;
  pVtab = pOp->p4.pVtab->pVtab;
  pName = &p->aMem[pOp->p1];
  assert( pVtab->pModule->xRename );
  REGISTER_TRACE(pOp->p1, pName);
  assert( pName->flags & MEM_Str );
  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
  sqlite3VtabLock(pVtab);
  rc = pVtab->pModule->xRename(pVtab, pName->z);
  sqlite3DbFree(db, p->zErrMsg);
  p->zErrMsg = pVtab->zErrMsg;
  pVtab->zErrMsg = 0;
  sqlite3VtabUnlock(db, pVtab);
  if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;

  break;
}
#endif

#ifndef SQLITE_OMIT_VIRTUALTABLE
5362
5363
5364
5365
5366
5367
5368
5369

5370
5371
5372
5373
5374
5375
5376
5377

5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5545
5546
5547
5548
5549
5550
5551

5552
5553
5554
5555
5556
5557
5558
5559

5560
5561
5562
5563
5564

5565
5566
5567
5568

5569
5570
5571
5572
5573
5574
5575







-
+







-
+




-




-







  sqlite3_module *pModule;
  int nArg;
  int i;
  sqlite_int64 rowid;
  Mem **apArg;
  Mem *pX;

  pVtab = pOp->p4.pVtab;
  pVtab = pOp->p4.pVtab->pVtab;
  pModule = (sqlite3_module *)pVtab->pModule;
  nArg = pOp->p2;
  assert( pOp->p4type==P4_VTAB );
  if( ALWAYS(pModule->xUpdate) ){
    apArg = p->apArg;
    pX = &p->aMem[pOp->p3];
    for(i=0; i<nArg; i++){
      storeTypeInfo(pX, 0);
      sqlite3VdbeMemStoreType(pX);
      apArg[i] = pX;
      pX++;
    }
    if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
    sqlite3VtabLock(pVtab);
    rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
    sqlite3DbFree(db, p->zErrMsg);
    p->zErrMsg = pVtab->zErrMsg;
    pVtab->zErrMsg = 0;
    sqlite3VtabUnlock(db, pVtab);
    if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
    if( rc==SQLITE_OK && pOp->p1 ){
      assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
      db->lastRowid = rowid;
    }
    p->nChange++;
  }
Changes to src/vdbe.h.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60
61

62
63

64
65
66
67
68
69
70
71
72
73
74













75
76
77
78
79
80
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
10
11
12
13
14
15
16


17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125







-
-


















+














-
+









-
+


+











+
+
+
+
+
+
+
+
+
+
+
+
+













-
+
















+







**
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.141 2009/04/10 00:56:29 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
** in the source file sqliteVdbe.c are allowed to see the insides
** of this structure.
*/
typedef struct Vdbe Vdbe;

/*
** The names of the following types declared in vdbeInt.h are required
** for the VdbeOp definition.
*/
typedef struct VdbeFunc VdbeFunc;
typedef struct Mem Mem;
typedef struct SubProgram SubProgram;

/*
** A single instruction of the virtual machine has an opcode
** and as many as three operands.  The instruction is recorded
** as an instance of the following structure:
*/
struct VdbeOp {
  u8 opcode;          /* What operation to perform */
  signed char p4type; /* One of the P4_xxx constants for p4 */
  u8 opflags;         /* Not currently used */
  u8 p5;              /* Fifth parameter is an unsigned character */
  int p1;             /* First operand */
  int p2;             /* Second parameter (often the jump destination) */
  int p3;             /* The third parameter */
  union {             /* forth parameter */
  union {             /* fourth parameter */
    int i;                 /* Integer value if p4type==P4_INT32 */
    void *p;               /* Generic pointer */
    char *z;               /* Pointer to data for string (char array) types */
    i64 *pI64;             /* Used when p4type is P4_INT64 */
    double *pReal;         /* Used when p4type is P4_REAL */
    FuncDef *pFunc;        /* Used when p4type is P4_FUNCDEF */
    VdbeFunc *pVdbeFunc;   /* Used when p4type is P4_VDBEFUNC */
    CollSeq *pColl;        /* Used when p4type is P4_COLLSEQ */
    Mem *pMem;             /* Used when p4type is P4_MEM */
    sqlite3_vtab *pVtab;   /* Used when p4type is P4_VTAB */
    VTable *pVtab;         /* Used when p4type is P4_VTAB */
    KeyInfo *pKeyInfo;     /* Used when p4type is P4_KEYINFO */
    int *ai;               /* Used when p4type is P4_INTARRAY */
    SubProgram *pProgram;  /* Used when p4type is P4_SUBPROGRAM */
  } p4;
#ifdef SQLITE_DEBUG
  char *zComment;          /* Comment to improve readability */
#endif
#ifdef VDBE_PROFILE
  int cnt;                 /* Number of times this instruction was executed */
  u64 cycles;              /* Total time spent executing this instruction */
#endif
};
typedef struct VdbeOp VdbeOp;


/*
** A sub-routine used to implement a trigger program.
*/
struct SubProgram {
  VdbeOp *aOp;                  /* Array of opcodes for sub-program */
  int nOp;                      /* Elements in aOp[] */
  int nMem;                     /* Number of memory cells required */
  int nCsr;                     /* Number of cursors required */
  int nRef;                     /* Number of pointers to this structure */
  void *token;                  /* id that may be used to recursive triggers */
};

/*
** A smaller version of VdbeOp used for the VdbeAddOpList() function because
** it takes up less space.
*/
struct VdbeOpList {
  u8 opcode;          /* What operation to perform */
  signed char p1;     /* First operand */
  signed char p2;     /* Second parameter (often the jump destination) */
  signed char p3;     /* Third parameter */
};
typedef struct VdbeOpList VdbeOpList;

/*
** Allowed values of VdbeOp.p3type
** Allowed values of VdbeOp.p4type
*/
#define P4_NOTUSED    0   /* The P4 parameter is not used */
#define P4_DYNAMIC  (-1)  /* Pointer to a string obtained from sqliteMalloc() */
#define P4_STATIC   (-2)  /* Pointer to a static string */
#define P4_COLLSEQ  (-4)  /* P4 is a pointer to a CollSeq structure */
#define P4_FUNCDEF  (-5)  /* P4 is a pointer to a FuncDef structure */
#define P4_KEYINFO  (-6)  /* P4 is a pointer to a KeyInfo structure */
#define P4_VDBEFUNC (-7)  /* P4 is a pointer to a VdbeFunc structure */
#define P4_MEM      (-8)  /* P4 is a pointer to a Mem*    structure */
#define P4_TRANSIENT (-9) /* P4 is a pointer to a transient string */
#define P4_VTAB     (-10) /* P4 is a pointer to an sqlite3_vtab structure */
#define P4_MPRINTF  (-11) /* P4 is a string obtained from sqlite3_mprintf() */
#define P4_REAL     (-12) /* P4 is a 64-bit floating point value */
#define P4_INT64    (-13) /* P4 is a 64-bit signed integer */
#define P4_INT32    (-14) /* P4 is a 32-bit signed integer */
#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
#define P4_SUBPROGRAM  (-18) /* P4 is a pointer to a SubProgram structure */

/* When adding a P4 argument using P4_KEYINFO, a copy of the KeyInfo structure
** is made.  That copy is freed when the Vdbe is finalized.  But if the
** argument is P4_KEYINFO_HANDOFF, the passed in pointer is used.  It still
** gets freed when the Vdbe is finalized so it still should be obtained
** from a single sqliteMalloc().  But no copy is made and the calling
** function should *not* try to free the KeyInfo.
164
165
166
167
168
169
170
171

172
173
174
175

176
177
178
179
180
181
182
183
184
185




186
187
188
189
190
191
192
193
194
195
196
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205



206
207
208
209
210
211
212







-
+




+










+
+
+
+

-
-
-







void sqlite3VdbeJumpHere(Vdbe*, int addr);
void sqlite3VdbeChangeToNoop(Vdbe*, int addr, int N);
void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
void sqlite3VdbeUsesBtree(Vdbe*, int);
VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
int sqlite3VdbeMakeLabel(Vdbe*);
void sqlite3VdbeDelete(Vdbe*);
void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int);
void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int,int,int);
int sqlite3VdbeFinalize(Vdbe*);
void sqlite3VdbeResolveLabel(Vdbe*, int);
int sqlite3VdbeCurrentAddr(Vdbe*);
#ifdef SQLITE_DEBUG
  int sqlite3VdbeAssertMayAbort(Vdbe *, int);
  void sqlite3VdbeTrace(Vdbe*,FILE*);
#endif
void sqlite3VdbeResetStepResult(Vdbe*);
int sqlite3VdbeReset(Vdbe*);
void sqlite3VdbeSetNumCols(Vdbe*,int);
int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*));
void sqlite3VdbeCountChanges(Vdbe*);
sqlite3 *sqlite3VdbeDb(Vdbe*);
void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int);
void sqlite3VdbeSwap(Vdbe*,Vdbe*);
VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
void sqlite3VdbeProgramDelete(sqlite3 *, SubProgram *, int);
sqlite3_value *sqlite3VdbeGetValue(Vdbe*, int, u8);
void sqlite3VdbeSetVarmask(Vdbe*, int);

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
int sqlite3VdbeReleaseMemory(int);
#endif
UnpackedRecord *sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,char*,int);
void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord*);
int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);


#ifndef NDEBUG
  void sqlite3VdbeComment(Vdbe*, const char*, ...);
Changes to src/vdbeInt.h.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
10
11
12
13
14
15
16


17
18
19
20
21
22
23







-
-







**
*************************************************************************
** This is the header file for information that is private to the
** VDBE.  This information used to all be at the top of the single
** source code file "vdbe.c".  When that file became too big (over
** 6000 lines long) it was split up into several smaller files and
** this header information was factored out.
**
** $Id: vdbeInt.h,v 1.174 2009/06/23 14:15:04 drh Exp $
*/
#ifndef _VDBEINT_H_
#define _VDBEINT_H_

/*
** SQL is translated into a sequence of instructions to be
** executed by a virtual machine.  Each instruction is an instance
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
75
76
77
78
79
80





81
82
83
84

85
86
87
88
89
90
91

































92
93
94
95
96
97
98
50
51
52
53
54
55
56


57
58
59
60
61


62

63
64
65
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129







-
-





-
-
+
-











-
+
+
+
+
+



-
+







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







  int iDb;              /* Index of cursor database in db->aDb[] (or -1) */
  i64 lastRowid;        /* Last rowid from a Next or NextIdx operation */
  Bool zeroed;          /* True if zeroed out and ready for reuse */
  Bool rowidIsValid;    /* True if lastRowid is valid */
  Bool atFirst;         /* True if pointing to first entry */
  Bool useRandomRowid;  /* Generate new record numbers semi-randomly */
  Bool nullRow;         /* True if pointing to a row with no data */
  Bool pseudoTable;     /* This is a NEW or OLD pseudo-tables of a trigger */
  Bool ephemPseudoTable;
  Bool deferredMoveto;  /* A call to sqlite3BtreeMoveto() is needed */
  Bool isTable;         /* True if a table requiring integer keys */
  Bool isIndex;         /* True if an index containing keys only - no data */
  i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
  Btree *pBt;           /* Separate file holding temporary table */
  int nData;            /* Number of bytes in pData */
  char *pData;          /* Data for a NEW or OLD pseudo-table */
  int pseudoTableReg;   /* Register holding pseudotable content. */
  i64 iKey;             /* Key for the NEW or OLD pseudo-table row */
  KeyInfo *pKeyInfo;    /* Info about index keys needed by index cursors */
  int nField;           /* Number of fields in the header */
  i64 seqCount;         /* Sequence counter */
  sqlite3_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
  const sqlite3_module *pModule;     /* Module for cursor pVtabCursor */

  /* Result of last sqlite3BtreeMoveto() done by an OP_NotExists or 
  ** OP_IsUnique opcode on this cursor. */
  int seekResult;

  /* Cached information about the header for the data record that the
  ** cursor is currently pointing to.  Only valid if cacheValid is true.
  ** cursor is currently pointing to.  Only valid if cacheStatus matches
  ** Vdbe.cacheCtr.  Vdbe.cacheCtr will never take on the value of
  ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that
  ** the cache is out of date.
  **
  ** aRow might point to (ephemeral) data for the current row, or it might
  ** be NULL.
  */
  int cacheStatus;      /* Cache is valid if this matches Vdbe.cacheCtr */
  u32 cacheStatus;      /* Cache is valid if this matches Vdbe.cacheCtr */
  int payloadSize;      /* Total number of bytes in the record */
  u32 *aType;           /* Type values for all entries in the record */
  u32 *aOffset;         /* Cached offsets to the start of each columns data */
  u8 *aRow;             /* Data for the current row, if all on one page */
};
typedef struct VdbeCursor VdbeCursor;

/*
** When a sub-program is executed (OP_Program), a structure of this type
** is allocated to store the current value of the program counter, as
** well as the current memory cell array and various other frame specific
** values stored in the Vdbe struct. When the sub-program is finished, 
** these values are copied back to the Vdbe from the VdbeFrame structure,
** restoring the state of the VM to as it was before the sub-program
** began executing.
**
** Frames are stored in a linked list headed at Vdbe.pParent. Vdbe.pParent
** is the parent of the current frame, or zero if the current frame
** is the main Vdbe program.
*/
typedef struct VdbeFrame VdbeFrame;
struct VdbeFrame {
  Vdbe *v;                /* VM this frame belongs to */
  int pc;                 /* Program Counter */
  Op *aOp;                /* Program instructions */
  int nOp;                /* Size of aOp array */
  Mem *aMem;              /* Array of memory cells */
  int nMem;               /* Number of entries in aMem */
  VdbeCursor **apCsr;     /* Element of Vdbe cursors */
  u16 nCursor;            /* Number of entries in apCsr */
  void *token;            /* Copy of SubProgram.token */
  int nChildMem;          /* Number of memory cells for child frame */
  int nChildCsr;          /* Number of cursors for child frame */
  i64 lastRowid;          /* Last insert rowid (sqlite3.lastRowid) */
  int nChange;            /* Statement changes (Vdbe.nChanges)     */
  VdbeFrame *pParent;     /* Parent of this frame */
};

#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])

/*
** A value for VdbeCursor.cacheValid that means the cache is always invalid.
*/
#define CACHE_STALE 0

/*
** Internally, the vdbe manipulates nearly all SQL values as Mem
107
108
109
110
111
112
113

114
115
116
117
118
119
120
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152







+







*/
struct Mem {
  union {
    i64 i;              /* Integer value. */
    int nZero;          /* Used when bit MEM_Zero is set in flags */
    FuncDef *pDef;      /* Used only when flags==MEM_Agg */
    RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
    VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */
  } u;
  double r;           /* Real value */
  sqlite3 *db;        /* The associated database connection */
  char *z;            /* String or BLOB value */
  int n;              /* Number of characters in string value, excluding '\0' */
  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
  u8  type;           /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
140
141
142
143
144
145
146

147
148
149
150
151
152
153
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186







+







*/
#define MEM_Null      0x0001   /* Value is NULL */
#define MEM_Str       0x0002   /* Value is a string */
#define MEM_Int       0x0004   /* Value is an integer */
#define MEM_Real      0x0008   /* Value is a real number */
#define MEM_Blob      0x0010   /* Value is a BLOB */
#define MEM_RowSet    0x0020   /* Value is a RowSet object */
#define MEM_Frame     0x0040   /* Value is a VdbeFrame object */
#define MEM_TypeMask  0x00ff   /* Mask of type bits */

/* Whenever Mem contains a valid string or blob representation, one of
** the following flags must be set to determine the memory management
** policy for Mem.z.  The MEM_Term flag tells us whether or not the
** string is \000 or \u0000 terminated
*/
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
252
253
254
255
256
257
258















259
260
261
262
263
264
265







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







*/
typedef struct Set Set;
struct Set {
  Hash hash;             /* A set is just a hash table */
  HashElem *prev;        /* Previously accessed hash elemen */
};

/*
** A Context stores the last insert rowid, the last statement change count,
** and the current statement change count (i.e. changes since last statement).
** The current keylist is also stored in the context.
** Elements of Context structure type make up the ContextStack, which is
** updated by the ContextPush and ContextPop opcodes (used by triggers).
** The context is pushed before executing a trigger a popped when the
** trigger finishes.
*/
typedef struct Context Context;
struct Context {
  i64 lastRowid;    /* Last insert rowid (sqlite3.lastRowid) */
  int nChange;      /* Statement changes (Vdbe.nChanges)     */
};

/*
** An instance of the virtual machine.  This structure contains the complete
** state of the virtual machine.
**
** The "sqlite3_stmt" structure pointer that is returned by sqlite3_compile()
** is really a pointer to an instance of this structure.
**
266
267
268
269
270
271
272
273

274
275
276
277
278
279

280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300


301
302
303
304



305
306
307
308
309
310
311
284
285
286
287
288
289
290

291
292
293
294
295
296

297



298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331







-
+





-
+
-
-
-


















+
+




+
+
+







  Mem *aColName;          /* Column names to return */
  Mem *pResultSet;        /* Pointer to an array of results */
  u16 nResColumn;         /* Number of columns in one row of the result set */
  u16 nCursor;            /* Number of slots in apCsr[] */
  VdbeCursor **apCsr;     /* One element of this array for each open cursor */
  u8 errorAction;         /* Recovery action to do in case of an error */
  u8 okVar;               /* True if azVar[] has been initialized */
  u16 nVar;               /* Number of entries in aVar[] */
  ynVar nVar;             /* Number of entries in aVar[] */
  Mem *aVar;              /* Values for the OP_Variable opcode. */
  char **azVar;           /* Name of variables */
  u32 magic;              /* Magic number for sanity checking */
  int nMem;               /* Number of memory locations currently allocated */
  Mem *aMem;              /* The memory locations */
  int cacheCtr;           /* VdbeCursor row cache generation counter */
  u32 cacheCtr;           /* VdbeCursor row cache generation counter */
  int contextStackTop;    /* Index of top element in the context stack */
  int contextStackDepth;  /* The size of the "context" stack */
  Context *contextStack;  /* Stack used by opcodes ContextPush & ContextPop*/
  int pc;                 /* The program counter */
  int rc;                 /* Value to return */
  char *zErrMsg;          /* Error message written here */
  u8 explain;             /* True if EXPLAIN present on SQL command */
  u8 changeCntOn;         /* True to update the change-counter */
  u8 expired;             /* True if the VM needs to be recompiled */
  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
  u8 inVtabMethod;        /* See comments above */
  u8 usesStmtJournal;     /* True if uses a statement journal */
  u8 readOnly;            /* True for read-only statements */
  u8 isPrepareV2;         /* True if prepared with prepare_v2() */
  int nChange;            /* Number of db changes made since last reset */
  int btreeMask;          /* Bitmask of db->aDb[] entries referenced */
  i64 startTime;          /* Time when query started - used for profiling */
  BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */
  int aCounter[2];        /* Counters used by sqlite3_stmt_status() */
  char *zSql;             /* Text of the SQL statement that generated this */
  void *pFree;            /* Free this when deleting the vdbe */
  i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
  i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
  int iStatement;         /* Statement number (or 0 if has not opened stmt) */
#ifdef SQLITE_DEBUG
  FILE *trace;            /* Write an execution trace here, if not NULL */
#endif
  VdbeFrame *pFrame;      /* Parent frame */
  int nFrame;             /* Number of frames in pFrame list */
  u32 expmask;            /* Binding to these vars invalidates VM */
};

/*
** The following are allowed values for Vdbe.magic
*/
#define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
#define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */
358
359
360
361
362
363
364



365
366





367
368
369
370
371
372
373
378
379
380
381
382
383
384
385
386
387


388
389
390
391
392
393
394
395
396
397
398
399







+
+
+
-
-
+
+
+
+
+







void sqlite3VdbeMemRelease(Mem *p);
void sqlite3VdbeMemReleaseExternal(Mem *p);
int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
const char *sqlite3OpcodeName(int);
int sqlite3VdbeOpcodeHasProperty(int, int);
int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
int sqlite3VdbeCloseStatement(Vdbe *, int);
void sqlite3VdbeFrameDelete(VdbeFrame*);
int sqlite3VdbeFrameRestore(VdbeFrame *);
void sqlite3VdbeMemStoreType(Mem *pMem);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
int sqlite3VdbeReleaseBuffers(Vdbe *p);

#ifndef SQLITE_OMIT_FOREIGN_KEY
int sqlite3VdbeCheckFk(Vdbe *, int);
#else
# define sqlite3VdbeCheckFk(p,i) 0
#endif

#ifndef SQLITE_OMIT_SHARED_CACHE
void sqlite3VdbeMutexArrayEnter(Vdbe *p);
#else
# define sqlite3VdbeMutexArrayEnter(p)
#endif
Changes to src/vdbeapi.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
8
9
10
11
12
13
14


15
16
17
18
19
20
21







-
-







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code use to implement APIs that are part of the
** VDBE.
**
** $Id: vdbeapi.c,v 1.167 2009/06/25 01:47:12 drh Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

#ifndef SQLITE_OMIT_DEPRECATED
/*
** Return TRUE (non-zero) of the statement supplied as an argument needs
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84







-
+







  int rc;
  if( pStmt==0 ){
    rc = SQLITE_OK;
  }else{
    Vdbe *v = (Vdbe*)pStmt;
    sqlite3_mutex_enter(v->db->mutex);
    rc = sqlite3VdbeReset(v);
    sqlite3VdbeMakeReady(v, -1, 0, 0, 0);
    sqlite3VdbeMakeReady(v, -1, 0, 0, 0, 0, 0);
    assert( (rc & (v->db->errMask))==rc );
    rc = sqlite3ApiExit(v->db, rc);
    sqlite3_mutex_leave(v->db->mutex);
  }
  return rc;
}

94
95
96
97
98
99
100



101
102
103
104
105
106
107
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108







+
+
+







#if SQLITE_THREADSAFE
  sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex;
#endif
  sqlite3_mutex_enter(mutex);
  for(i=0; i<p->nVar; i++){
    sqlite3VdbeMemRelease(&p->aVar[i]);
    p->aVar[i].flags = MEM_Null;
  }
  if( p->isPrepareV2 && p->expmask ){
    p->expired = 1;
  }
  sqlite3_mutex_leave(mutex);
  return rc;
}


/**************************** sqlite3_value_  *******************************
300
301
302
303
304
305
306
307

308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324


325
326
327
328
329
330
331
301
302
303
304
305
306
307

308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334







-
+

















+
+







  /* Assert that malloc() has not failed */
  db = p->db;
  if( db->mallocFailed ){
    return SQLITE_NOMEM;
  }

  if( p->pc<=0 && p->expired ){
    if( ALWAYS(p->rc==SQLITE_OK) ){
    if( ALWAYS(p->rc==SQLITE_OK || p->rc==SQLITE_SCHEMA) ){
      p->rc = SQLITE_SCHEMA;
    }
    rc = SQLITE_ERROR;
    goto end_of_step;
  }
  if( sqlite3SafetyOn(db) ){
    p->rc = SQLITE_MISUSE;
    return SQLITE_MISUSE;
  }
  if( p->pc<0 ){
    /* If there are no other statements currently running, then
    ** reset the interrupt flag.  This prevents a call to sqlite3_interrupt
    ** from interrupting a statement that has not yet started.
    */
    if( db->activeVdbeCnt==0 ){
      db->u1.isInterrupted = 0;
    }

    assert( db->writeVdbeCnt>0 || db->autoCommit==0 || db->nDeferredCons==0 );

#ifndef SQLITE_OMIT_TRACE
    if( db->xProfile && !db->init.busy ){
      double rNow;
      sqlite3OsCurrentTime(db->pVfs, &rNow);
      p->startTime = (u64)((rNow - (int)rNow)*3600.0*24.0*1000000000.0);
    }
908
909
910
911
912
913
914









915
916
917
918
919
920
921
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933







+
+
+
+
+
+
+
+
+







    return SQLITE_RANGE;
  }
  i--;
  pVar = &p->aVar[i];
  sqlite3VdbeMemRelease(pVar);
  pVar->flags = MEM_Null;
  sqlite3Error(p->db, SQLITE_OK, 0);

  /* If the bit corresponding to this variable in Vdbe.expmask is set, then 
  ** binding a new value to this variable invalidates the current query plan.
  */
  if( p->isPrepareV2 &&
     ((i<32 && p->expmask & ((u32)1 << i)) || p->expmask==0xffffffff)
  ){
    p->expired = 1;
  }
  return SQLITE_OK;
}

/*
** Bind a text or BLOB value.
*/
static int bindText(
1157
1158
1159
1160
1161
1162
1163






1164
1165
1166
1167
1168
1169
1170
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188







+
+
+
+
+
+







** SQLITE_OK is returned.
*/
int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
  Vdbe *pFrom = (Vdbe*)pFromStmt;
  Vdbe *pTo = (Vdbe*)pToStmt;
  if( pFrom->nVar!=pTo->nVar ){
    return SQLITE_ERROR;
  }
  if( pTo->isPrepareV2 && pTo->expmask ){
    pTo->expired = 1;
  }
  if( pFrom->isPrepareV2 && pFrom->expmask ){
    pFrom->expired = 1;
  }
  return sqlite3TransferBindings(pFromStmt, pToStmt);
}
#endif

/*
** Return the sqlite3* database handle to which the prepared statement given
Changes to src/vdbeaux.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
9
10
11
12
13
14
15


16
17
18
19
20
21
22







-
-







**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used for creating, destroying, and populating
** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.)  Prior
** to version 2.8.7, all this code was combined into the vdbe.c source file.
** But that file was getting too big so this subroutines were split out.
**
** $Id: vdbeaux.c,v 1.467 2009/06/26 16:32:13 shane Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"



/*
49
50
51
52
53
54
55

56
57
58
59
60
61
62

63
64
65
66
67
68
69
47
48
49
50
51
52
53
54
55
56
57
58
59
60

61
62
63
64
65
66
67
68







+






-
+







  return p;
}

/*
** Remember the SQL string for a prepared statement.
*/
void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
  assert( isPrepareV2==1 || isPrepareV2==0 );
  if( p==0 ) return;
#ifdef SQLITE_OMIT_TRACE
  if( !isPrepareV2 ) return;
#endif
  assert( p->zSql==0 );
  p->zSql = sqlite3DbStrNDup(p->db, z, n);
  p->isPrepareV2 = isPrepareV2 ? 1 : 0;
  p->isPrepareV2 = (u8)isPrepareV2;
}

/*
** Return the SQL associated with a prepared statement
*/
const char *sqlite3_sql(sqlite3_stmt *pStmt){
  Vdbe *p = (Vdbe *)pStmt;
236
237
238
239
240
241
242

























































































































243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269

270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
























341
342
343
344
345
346
347
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372













373
374
375

376
377
378


379

380
381
382
383
384
385
386
387
388










389
390
391


392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409














410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+










-
-
-
-
-
-
-
-
-
-
-
-
-



-
+


-
-

-









-
-
-
-
-
-
-
-
-
-



-
-


















-
-
-
-
-
-
-
-
-
-
-
-
-
-









+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







  assert( p->magic==VDBE_MAGIC_INIT );
  assert( j>=0 && j<p->nLabel );
  if( p->aLabel ){
    p->aLabel[j] = p->nOp;
  }
}

#ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */

/*
** The following type and function are used to iterate through all opcodes
** in a Vdbe main program and each of the sub-programs (triggers) it may 
** invoke directly or indirectly. It should be used as follows:
**
**   Op *pOp;
**   VdbeOpIter sIter;
**
**   memset(&sIter, 0, sizeof(sIter));
**   sIter.v = v;                            // v is of type Vdbe* 
**   while( (pOp = opIterNext(&sIter)) ){
**     // Do something with pOp
**   }
**   sqlite3DbFree(v->db, sIter.apSub);
** 
*/
typedef struct VdbeOpIter VdbeOpIter;
struct VdbeOpIter {
  Vdbe *v;                   /* Vdbe to iterate through the opcodes of */
  SubProgram **apSub;        /* Array of subprograms */
  int nSub;                  /* Number of entries in apSub */
  int iAddr;                 /* Address of next instruction to return */
  int iSub;                  /* 0 = main program, 1 = first sub-program etc. */
};
static Op *opIterNext(VdbeOpIter *p){
  Vdbe *v = p->v;
  Op *pRet = 0;
  Op *aOp;
  int nOp;

  if( p->iSub<=p->nSub ){

    if( p->iSub==0 ){
      aOp = v->aOp;
      nOp = v->nOp;
    }else{
      aOp = p->apSub[p->iSub-1]->aOp;
      nOp = p->apSub[p->iSub-1]->nOp;
    }
    assert( p->iAddr<nOp );

    pRet = &aOp[p->iAddr];
    p->iAddr++;
    if( p->iAddr==nOp ){
      p->iSub++;
      p->iAddr = 0;
    }
  
    if( pRet->p4type==P4_SUBPROGRAM ){
      int nByte = (p->nSub+1)*sizeof(SubProgram*);
      int j;
      for(j=0; j<p->nSub; j++){
        if( p->apSub[j]==pRet->p4.pProgram ) break;
      }
      if( j==p->nSub ){
        p->apSub = sqlite3DbReallocOrFree(v->db, p->apSub, nByte);
        if( !p->apSub ){
          pRet = 0;
        }else{
          p->apSub[p->nSub++] = pRet->p4.pProgram;
        }
      }
    }
  }

  return pRet;
}

/*
** Check if the program stored in the VM associated with pParse may
** throw an ABORT exception (causing the statement, but not entire transaction
** to be rolled back). This condition is true if the main program or any
** sub-programs contains any of the following:
**
**   *  OP_Halt with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
**   *  OP_HaltIfNull with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
**   *  OP_Destroy
**   *  OP_VUpdate
**   *  OP_VRename
**   *  OP_FkCounter with P2==0 (immediate foreign key constraint)
**
** Then check that the value of Parse.mayAbort is true if an
** ABORT may be thrown, or false otherwise. Return true if it does
** match, or false otherwise. This function is intended to be used as
** part of an assert statement in the compiler. Similar to:
**
**   assert( sqlite3VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) );
*/
int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
  int hasAbort = 0;
  Op *pOp;
  VdbeOpIter sIter;
  memset(&sIter, 0, sizeof(sIter));
  sIter.v = v;

  while( (pOp = opIterNext(&sIter))!=0 ){
    int opcode = pOp->opcode;
    if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename 
#ifndef SQLITE_OMIT_FOREIGN_KEY
     || (opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1) 
#endif
     || ((opcode==OP_Halt || opcode==OP_HaltIfNull) 
      && (pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
    ){
      hasAbort = 1;
      break;
    }
  }
  sqlite3DbFree(v->db, sIter.apSub);

  /* Return true if hasAbort==mayAbort. Or if a malloc failure occured.
  ** If malloc failed, then the while() loop above may not have iterated
  ** through all opcodes and hasAbort may be set incorrectly. Return
  ** true for this case to prevent the assert() in the callers frame
  ** from failing.  */
  return ( v->db->mallocFailed || hasAbort==mayAbort );
}
#endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */

/*
** Loop through the program looking for P2 values that are negative
** on jump instructions.  Each such value is a label.  Resolve the
** label by setting the P2 value to its correct non-zero value.
**
** This routine is called once after all opcodes have been inserted.
**
** Variable *pMaxFuncArgs is set to the maximum value of any P2 argument 
** to an OP_Function, OP_AggStep or OP_VFilter opcode. This is used by 
** sqlite3VdbeMakeReady() to size the Vdbe.apArg[] array.
**
** This routine also does the following optimization:  It scans for
** instructions that might cause a statement rollback.  Such instructions
** are:
**
**   *  OP_Halt with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
**   *  OP_Destroy
**   *  OP_VUpdate
**   *  OP_VRename
**
** If no such instruction is found, then every Statement instruction 
** is changed to a Noop.  In this way, we avoid creating the statement 
** journal file unnecessarily.
*/
static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
  int i;
  int nMaxArgs = 0;
  int nMaxArgs = *pMaxFuncArgs;
  Op *pOp;
  int *aLabel = p->aLabel;
  int doesStatementRollback = 0;
  int hasStatementBegin = 0;
  p->readOnly = 1;
  p->usesStmtJournal = 0;
  for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
    u8 opcode = pOp->opcode;

    if( opcode==OP_Function || opcode==OP_AggStep ){
      if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
#ifndef SQLITE_OMIT_VIRTUALTABLE
    }else if( opcode==OP_VUpdate ){
      if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
#endif
    }
    if( opcode==OP_Halt ){
      if( pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort ){
        doesStatementRollback = 1;
      }
    }else if( opcode==OP_Statement ){
      hasStatementBegin = 1;
      p->usesStmtJournal = 1;
    }else if( opcode==OP_Destroy ){
      doesStatementRollback = 1;
    }else if( opcode==OP_Transaction && pOp->p2!=0 ){
      p->readOnly = 0;
#ifndef SQLITE_OMIT_VIRTUALTABLE
    }else if( opcode==OP_VUpdate || opcode==OP_VRename ){
      doesStatementRollback = 1;
    }else if( opcode==OP_VFilter ){
      int n;
      assert( p->nOp - i >= 3 );
      assert( pOp[-1].opcode==OP_Integer );
      n = pOp[-1].p1;
      if( n>nMaxArgs ) nMaxArgs = n;
#endif
    }

    if( sqlite3VdbeOpcodeHasProperty(opcode, OPFLG_JUMP) && pOp->p2<0 ){
      assert( -1-pOp->p2<p->nLabel );
      pOp->p2 = aLabel[-1-pOp->p2];
    }
  }
  sqlite3DbFree(p->db, p->aLabel);
  p->aLabel = 0;

  *pMaxFuncArgs = nMaxArgs;

  /* If we never rollback a statement transaction, then statement
  ** transactions are not needed.  So change every OP_Statement
  ** opcode into an OP_Noop.  This avoid a call to sqlite3OsOpenExclusive()
  ** which can be expensive on some platforms.
  */
  if( hasStatementBegin && !doesStatementRollback ){
    p->usesStmtJournal = 0;
    for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
      if( pOp->opcode==OP_Statement ){
        pOp->opcode = OP_Noop;
      }
    }
  }
}

/*
** Return the address of the next instruction to be inserted.
*/
int sqlite3VdbeCurrentAddr(Vdbe *p){
  assert( p->magic==VDBE_MAGIC_INIT );
  return p->nOp;
}

/*
** This function returns a pointer to the array of opcodes associated with
** the Vdbe passed as the first argument. It is the callers responsibility
** to arrange for the returned array to be eventually freed using the 
** vdbeFreeOpArray() function.
**
** Before returning, *pnOp is set to the number of entries in the returned
** array. Also, *pnMaxArg is set to the larger of its current value and 
** the number of entries in the Vdbe.apArg[] array required to execute the 
** returned program.
*/
VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){
  VdbeOp *aOp = p->aOp;
  assert( aOp && !p->db->mallocFailed );

  /* Check that sqlite3VdbeUsesBtree() was not called on this VM */
  assert( p->aMutex.nMutex==0 );

  resolveP2Values(p, pnMaxArg);
  *pnOp = p->nOp;
  p->aOp = 0;
  return aOp;
}

/*
** Add a whole list of operations to the operation stack.  Return the
** address of the first operation added.
*/
int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
  int addr;
474
475
476
477
478
479
480























































481
482
483
484
485
486
487
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







        freeEphemeralFunction(db, (FuncDef*)p4);
        break;
      }
      case P4_MEM: {
        sqlite3ValueFree((sqlite3_value*)p4);
        break;
      }
      case P4_VTAB : {
        sqlite3VtabUnlock((VTable *)p4);
        break;
      }
      case P4_SUBPROGRAM : {
        sqlite3VdbeProgramDelete(db, (SubProgram *)p4, 1);
        break;
      }
    }
  }
}

/*
** Free the space allocated for aOp and any p4 values allocated for the
** opcodes contained within. If aOp is not NULL it is assumed to contain 
** nOp entries. 
*/
static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){
  if( aOp ){
    Op *pOp;
    for(pOp=aOp; pOp<&aOp[nOp]; pOp++){
      freeP4(db, pOp->p4type, pOp->p4.p);
#ifdef SQLITE_DEBUG
      sqlite3DbFree(db, pOp->zComment);
#endif     
    }
  }
  sqlite3DbFree(db, aOp);
}

/*
** Decrement the ref-count on the SubProgram structure passed as the
** second argument. If the ref-count reaches zero, free the structure.
**
** The array of VDBE opcodes stored as SubProgram.aOp is freed if
** either the ref-count reaches zero or parameter freeop is non-zero.
**
** Since the array of opcodes pointed to by SubProgram.aOp may directly
** or indirectly contain a reference to the SubProgram structure itself.
** By passing a non-zero freeop parameter, the caller may ensure that all
** SubProgram structures and their aOp arrays are freed, even when there
** are such circular references.
*/
void sqlite3VdbeProgramDelete(sqlite3 *db, SubProgram *p, int freeop){
  if( p ){
    assert( p->nRef>0 );
    if( freeop || p->nRef==1 ){
      Op *aOp = p->aOp;
      p->aOp = 0;
      vdbeFreeOpArray(db, aOp, p->nOp);
      p->nOp = 0;
    }
    p->nRef--;
    if( p->nRef==0 ){
      sqlite3DbFree(db, p);
    }
  }
}


/*
** Change N opcodes starting at addr to No-ops.
527
528
529
530
531
532
533
534

535
536
537
538
539
540
541
684
685
686
687
688
689
690

691
692
693
694
695
696
697
698







-
+







void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
  Op *pOp;
  sqlite3 *db;
  assert( p!=0 );
  db = p->db;
  assert( p->magic==VDBE_MAGIC_INIT );
  if( p->aOp==0 || db->mallocFailed ){
    if (n != P4_KEYINFO) {
    if ( n!=P4_KEYINFO && n!=P4_VTAB ) {
      freeP4(db, n, (void*)*(char**)&zP4);
    }
    return;
  }
  assert( p->nOp>0 );
  assert( addr<p->nOp );
  if( addr<0 ){
572
573
574
575
576
577
578





579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597

598
599
600
601
602
603
604
605
606
607
608
609

610
611
612
613
614
615
616
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780







+
+
+
+
+



















+












+







    }else{
      p->db->mallocFailed = 1;
      pOp->p4type = P4_NOTUSED;
    }
  }else if( n==P4_KEYINFO_HANDOFF ){
    pOp->p4.p = (void*)zP4;
    pOp->p4type = P4_KEYINFO;
  }else if( n==P4_VTAB ){
    pOp->p4.p = (void*)zP4;
    pOp->p4type = P4_VTAB;
    sqlite3VtabLock((VTable *)zP4);
    assert( ((VTable *)zP4)->db==p->db );
  }else if( n<0 ){
    pOp->p4.p = (void*)zP4;
    pOp->p4type = (signed char)n;
  }else{
    if( n==0 ) n = sqlite3Strlen30(zP4);
    pOp->p4.z = sqlite3DbStrNDup(p->db, zP4, n);
    pOp->p4type = P4_DYNAMIC;
  }
}

#ifndef NDEBUG
/*
** Change the comment on the the most recently coded instruction.  Or
** insert a No-op and add the comment to that new instruction.  This
** makes the code easier to read during debugging.  None of this happens
** in a production build.
*/
void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
  va_list ap;
  if( !p ) return;
  assert( p->nOp>0 || p->aOp==0 );
  assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
  if( p->nOp ){
    char **pz = &p->aOp[p->nOp-1].zComment;
    va_start(ap, zFormat);
    sqlite3DbFree(p->db, *pz);
    *pz = sqlite3VMPrintf(p->db, zFormat, ap);
    va_end(ap);
  }
}
void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){
  va_list ap;
  if( !p ) return;
  sqlite3VdbeAddOp0(p, OP_Noop);
  assert( p->nOp>0 || p->aOp==0 );
  assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
  if( p->nOp ){
    char **pz = &p->aOp[p->nOp-1].zComment;
    va_start(ap, zFormat);
    sqlite3DbFree(p->db, *pz);
722
723
724
725
726
727
728



729
730
731
732
733
734

735
736
737
738
739
740
741




742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900

901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928

929
930
931
932
933
934
935







+
+
+





-
+







+
+
+
+
















-







      assert( (pMem->flags & MEM_Null)==0 );
      if( pMem->flags & MEM_Str ){
        zP4 = pMem->z;
      }else if( pMem->flags & MEM_Int ){
        sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i);
      }else if( pMem->flags & MEM_Real ){
        sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->r);
      }else{
        assert( pMem->flags & MEM_Blob );
        zP4 = "(blob)";
      }
      break;
    }
#ifndef SQLITE_OMIT_VIRTUALTABLE
    case P4_VTAB: {
      sqlite3_vtab *pVtab = pOp->p4.pVtab;
      sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
      sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule);
      break;
    }
#endif
    case P4_INTARRAY: {
      sqlite3_snprintf(nTemp, zTemp, "intarray");
      break;
    }
    case P4_SUBPROGRAM: {
      sqlite3_snprintf(nTemp, zTemp, "program");
      break;
    }
    default: {
      zP4 = pOp->p4.z;
      if( zP4==0 ){
        zP4 = zTemp;
        zTemp[0] = 0;
      }
    }
  }
  assert( zP4!=0 );
  return zP4;
}
#endif

/*
** Declare to the Vdbe that the BTree object at db->aDb[i] is used.
**
*/
void sqlite3VdbeUsesBtree(Vdbe *p, int i){
  int mask;
  assert( i>=0 && i<p->db->nDb && i<sizeof(u32)*8 );
  assert( i<(int)sizeof(p->btreeMask)*8 );
  mask = ((u32)1)<<i;
  if( (p->btreeMask & mask)==0 ){
810
811
812
813
814
815
816
817

818
819
820
821
822
823
824
825
826
827
828
829
830
831
832






833
834
835
836
837
838



839
840
841
842
843
844


845
846


847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865




866
867
868
869
870
871
872

873
874
875
876
877
878
879
880

881
882
883
884
885
886
887














888
889
890
891
892


893
894
895
896
897
898
899
900


901









902
903
904
905
906
907
908
909
910
911
912
913
914














915
916
917
918
919
920
921
980
981
982
983
984
985
986

987
988
989
990
991
992
993
994
995
996
997
998
999



1000
1001
1002
1003
1004
1005






1006
1007
1008






1009
1010


1011
1012
1013

1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040

1041
1042
1043
1044
1045
1046
1047
1048

1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073


1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085

1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128







-
+












-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
+
+
-
-
+
+

-

















+
+
+
+






-
+







-
+







+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
-
+
+








+
+
-
+
+
+
+
+
+
+
+
+













+
+
+
+
+
+
+
+
+
+
+
+
+
+







      ** callgrind, this causes a certain test case to hit the CPU 4.7 
      ** percent less (x86 linux, gcc version 4.1.2, -O6) than if 
      ** sqlite3MemRelease() were called from here. With -O2, this jumps
      ** to 6.6 percent. The test case is inserting 1000 rows into a table 
      ** with no indexes using a single prepared INSERT statement, bind() 
      ** and reset(). Inserts are grouped into a transaction.
      */
      if( p->flags&(MEM_Agg|MEM_Dyn) ){
      if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
        sqlite3VdbeMemRelease(p);
      }else if( p->zMalloc ){
        sqlite3DbFree(db, p->zMalloc);
        p->zMalloc = 0;
      }

      p->flags = MEM_Null;
    }
    db->mallocFailed = malloc_failed;
  }
}

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
int sqlite3VdbeReleaseBuffers(Vdbe *p){
  int ii;
/*
** Delete a VdbeFrame object and its contents. VdbeFrame objects are
** allocated by the OP_Program opcode in sqlite3VdbeExec().
*/
void sqlite3VdbeFrameDelete(VdbeFrame *p){
  int i;
  int nFree = 0;
  assert( sqlite3_mutex_held(p->db->mutex) );
  for(ii=1; ii<=p->nMem; ii++){
    Mem *pMem = &p->aMem[ii];
    if( pMem->flags & MEM_RowSet ){
      sqlite3RowSetClear(pMem->u.pRowSet);
  Mem *aMem = VdbeFrameMem(p);
  VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem];
  for(i=0; i<p->nChildCsr; i++){
    }
    if( pMem->z && pMem->flags&MEM_Dyn ){
      assert( !pMem->xDel );
      nFree += sqlite3DbMallocSize(pMem->db, pMem->z);
      sqlite3VdbeMemRelease(pMem);
    }
    sqlite3VdbeFreeCursor(p->v, apCsr[i]);
  }
  }
  return nFree;
  releaseMemArray(aMem, p->nChildMem);
  sqlite3DbFree(p->v->db, p);
}
#endif

#ifndef SQLITE_OMIT_EXPLAIN
/*
** Give a listing of the program in the virtual machine.
**
** The interface is the same as sqlite3VdbeExec().  But instead of
** running the code, it invokes the callback once for each instruction.
** This feature is used to implement "EXPLAIN".
**
** When p->explain==1, each instruction is listed.  When
** p->explain==2, only OP_Explain instructions are listed and these
** are shown in a different format.  p->explain==2 is used to implement
** EXPLAIN QUERY PLAN.
*/
int sqlite3VdbeList(
  Vdbe *p                   /* The VDBE */
){
  int nRow;                            /* Total number of rows to return */
  int nSub = 0;                        /* Number of sub-vdbes seen so far */
  SubProgram **apSub = 0;              /* Array of sub-vdbes */
  Mem *pSub = 0;
  sqlite3 *db = p->db;
  int i;
  int rc = SQLITE_OK;
  Mem *pMem = p->pResultSet = &p->aMem[1];

  assert( p->explain );
  if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;
  assert( p->magic==VDBE_MAGIC_RUN );
  assert( db->magic==SQLITE_MAGIC_BUSY );
  assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );

  /* Even though this opcode does not use dynamic strings for
  ** the result, result columns may become dynamic if the user calls
  ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
  */
  releaseMemArray(pMem, p->nMem);
  releaseMemArray(pMem, 8);

  if( p->rc==SQLITE_NOMEM ){
    /* This happens if a malloc() inside a call to sqlite3_column_text() or
    ** sqlite3_column_text16() failed.  */
    db->mallocFailed = 1;
    return SQLITE_ERROR;
  }

  /* Figure out total number of rows that will be returned by this 
  ** EXPLAIN program.  */
  nRow = p->nOp;
  if( p->explain==1 ){
    pSub = &p->aMem[9];
    if( pSub->flags&MEM_Blob ){
      nSub = pSub->n/sizeof(Vdbe*);
      apSub = (SubProgram **)pSub->z;
    }
    for(i=0; i<nSub; i++){
      nRow += apSub[i]->nOp;
    }
  }

  do{
    i = p->pc++;
  }while( i<p->nOp && p->explain==2 && p->aOp[i].opcode!=OP_Explain );
  if( i>=p->nOp ){
  }while( i<nRow && p->explain==2 && p->aOp[i].opcode!=OP_Explain );
  if( i>=nRow ){
    p->rc = SQLITE_OK;
    rc = SQLITE_DONE;
  }else if( db->u1.isInterrupted ){
    p->rc = SQLITE_INTERRUPT;
    rc = SQLITE_ERROR;
    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(p->rc));
  }else{
    char *z;
    Op *pOp;
    if( i<p->nOp ){
    Op *pOp = &p->aOp[i];
      pOp = &p->aOp[i];
    }else{
      int j;
      i -= p->nOp;
      for(j=0; i>=apSub[j]->nOp; j++){
        i -= apSub[j]->nOp;
      }
      pOp = &apSub[j]->aOp[i];
    }
    if( p->explain==1 ){
      pMem->flags = MEM_Int;
      pMem->type = SQLITE_INTEGER;
      pMem->u.i = i;                                /* Program counter */
      pMem++;
  
      pMem->flags = MEM_Static|MEM_Str|MEM_Term;
      pMem->z = (char*)sqlite3OpcodeName(pOp->opcode);  /* Opcode */
      assert( pMem->z!=0 );
      pMem->n = sqlite3Strlen30(pMem->z);
      pMem->type = SQLITE_TEXT;
      pMem->enc = SQLITE_UTF8;
      pMem++;

      if( pOp->p4type==P4_SUBPROGRAM ){
        int nByte = (nSub+1)*sizeof(SubProgram*);
        int j;
        for(j=0; j<nSub; j++){
          if( apSub[j]==pOp->p4.pProgram ) break;
        }
        if( j==nSub && SQLITE_OK==sqlite3VdbeMemGrow(pSub, nByte, 1) ){
          apSub = (SubProgram **)pSub->z;
          apSub[nSub++] = pOp->p4.pProgram;
          pSub->flags |= MEM_Blob;
          pSub->n = nSub*sizeof(SubProgram*);
        }
      }
    }

    pMem->flags = MEM_Int;
    pMem->u.i = pOp->p1;                          /* P1 */
    pMem->type = SQLITE_INTEGER;
    pMem++;

1051
1052
1053
1054
1055
1056
1057
1058

1059
1060
1061
1062
1063
1064
1065
1258
1259
1260
1261
1262
1263
1264

1265
1266
1267
1268
1269
1270
1271
1272







-
+







  u8 **ppFrom,         /* IN/OUT: Allocate from *ppFrom */
  u8 *pEnd,            /* Pointer to 1 byte past the end of *ppFrom buffer */
  int *pnByte          /* If allocation cannot be made, increment *pnByte */
){
  assert( EIGHT_BYTE_ALIGNMENT(*ppFrom) );
  if( (*(void**)pp)==0 ){
    nByte = ROUND8(nByte);
    if( (pEnd - *ppFrom)>=nByte ){
    if( &(*ppFrom)[nByte] <= pEnd ){
      *(void**)pp = (void *)*ppFrom;
      *ppFrom += nByte;
    }else{
      *pnByte += nByte;
    }
  }
}
1082
1083
1084
1085
1086
1087
1088

1089


1090
1091
1092
1093
1094
1095
1096
1289
1290
1291
1292
1293
1294
1295
1296

1297
1298
1299
1300
1301
1302
1303
1304
1305







+
-
+
+







** is passed -1 and nMem, nCursor and isExplain are all passed zero.
*/
void sqlite3VdbeMakeReady(
  Vdbe *p,                       /* The VDBE */
  int nVar,                      /* Number of '?' see in the SQL statement */
  int nMem,                      /* Number of memory cells to allocate */
  int nCursor,                   /* Number of cursors to allocate */
  int nArg,                      /* Maximum number of args in SubPrograms */
  int isExplain                  /* True if the EXPLAIN keywords is present */
  int isExplain,                 /* True if the EXPLAIN keywords is present */
  int usesStmtJournal            /* True to set Vdbe.usesStmtJournal */
){
  int n;
  sqlite3 *db = p->db;

  assert( p!=0 );
  assert( p->magic==VDBE_MAGIC_INIT );

1113
1114
1115
1116
1117
1118
1119
1120

1121
1122
1123
1124
1125

1126
1127
1128

1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144

1145
1146
1147
1148
1149
1150
1151
1152

1153
1154
1155
1156
1157
1158
1159
1322
1323
1324
1325
1326
1327
1328

1329
1330
1331
1332

1333
1334
1335
1336
1337
1338
1339
1340

1341
1342

1343
1344
1345
1346
1347
1348
1349
1350
1351

1352
1353
1354
1355
1356
1357
1358
1359

1360
1361
1362
1363
1364
1365
1366
1367







-
+



-

+



+


-


-









-
+







-
+







  nMem += nCursor;

  /* Allocate space for memory registers, SQL variables, VDBE cursors and 
  ** an array to marshal SQL function arguments in. This is only done the
  ** first time this function is called for a given VDBE, not when it is
  ** being called from sqlite3_reset() to reset the virtual machine.
  */
  if( nVar>=0 && !db->mallocFailed ){
  if( nVar>=0 && ALWAYS(db->mallocFailed==0) ){
    u8 *zCsr = (u8 *)&p->aOp[p->nOp];
    u8 *zEnd = (u8 *)&p->aOp[p->nOpAlloc];
    int nByte;
    int nArg;       /* Maximum number of args passed to a user function. */
    resolveP2Values(p, &nArg);
    p->usesStmtJournal = (u8)usesStmtJournal;
    if( isExplain && nMem<10 ){
      nMem = 10;
    }
    memset(zCsr, 0, zEnd-zCsr);
    zCsr += (zCsr - (u8*)0)&7;
    assert( EIGHT_BYTE_ALIGNMENT(zCsr) );
    if( zEnd<zCsr ) zEnd = zCsr;

    do {
      memset(zCsr, 0, zEnd-zCsr);
      nByte = 0;
      allocSpace((char*)&p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte);
      allocSpace((char*)&p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte);
      allocSpace((char*)&p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte);
      allocSpace((char*)&p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte);
      allocSpace((char*)&p->apCsr, 
                 nCursor*sizeof(VdbeCursor*), &zCsr, zEnd, &nByte
      );
      if( nByte ){
        p->pFree = sqlite3DbMallocRaw(db, nByte);
        p->pFree = sqlite3DbMallocZero(db, nByte);
      }
      zCsr = p->pFree;
      zEnd = &zCsr[nByte];
    }while( nByte && !db->mallocFailed );

    p->nCursor = (u16)nCursor;
    if( p->aVar ){
      p->nVar = (u16)nVar;
      p->nVar = (ynVar)nVar;
      for(n=0; n<nVar; n++){
        p->aVar[n].flags = MEM_Null;
        p->aVar[n].db = db;
      }
    }
    if( p->aMem ){
      p->aMem--;                      /* aMem[] goes from 1..nMem */
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223




















1224
1225
1226






1227
1228
1229
1230
1231
1232
1233
1234
1235
1236





















1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255

1256
1257
1258
1259







1260
1261

1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1420
1421
1422
1423
1424
1425
1426





1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447


1448
1449
1450
1451
1452
1453
1454









1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486

1487






1488




1489
1490
1491
1492
1493
1494
1495


1496



1497
1498
1499
1500
1501
1502
1503







-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
+
+
+
+
+
+

-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+











-

-
-
-
-
-
-
+
-
-
-
-
+
+
+
+
+
+
+
-
-
+
-
-
-







    p->inVtabMethod = 1;
    (void)sqlite3SafetyOff(p->db);
    pModule->xClose(pVtabCursor);
    (void)sqlite3SafetyOn(p->db);
    p->inVtabMethod = 0;
  }
#endif
  if( !pCx->ephemPseudoTable ){
    sqlite3DbFree(p->db, pCx->pData);
  }
}

}

/*
** Copy the values stored in the VdbeFrame structure to its Vdbe. This
** is used, for example, when a trigger sub-program is halted to restore
** control to the main program.
*/
int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
  Vdbe *v = pFrame->v;
  v->aOp = pFrame->aOp;
  v->nOp = pFrame->nOp;
  v->aMem = pFrame->aMem;
  v->nMem = pFrame->nMem;
  v->apCsr = pFrame->apCsr;
  v->nCursor = pFrame->nCursor;
  v->db->lastRowid = pFrame->lastRowid;
  v->nChange = pFrame->nChange;
  return pFrame->pc;
}

/*
** Close all cursors except for VTab cursors that are currently
** in use.
** Close all cursors.
**
** Also release any dynamic memory held by the VM in the Vdbe.aMem memory 
** cell array. This is necessary as the memory cell array may contain
** pointers to VdbeFrame objects, which may in turn contain pointers to
** open cursors.
*/
static void closeAllCursorsExceptActiveVtabs(Vdbe *p){
  int i;
  if( p->apCsr==0 ) return;
  for(i=0; i<p->nCursor; i++){
    VdbeCursor *pC = p->apCsr[i];
    if( pC && (!p->inVtabMethod || !pC->pVtabCursor) ){
      sqlite3VdbeFreeCursor(p, pC);
      p->apCsr[i] = 0;
    }
static void closeAllCursors(Vdbe *p){
  if( p->pFrame ){
    VdbeFrame *pFrame = p->pFrame;
    for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
    sqlite3VdbeFrameRestore(pFrame);
  }
  p->pFrame = 0;
  p->nFrame = 0;

  if( p->apCsr ){
    int i;
    for(i=0; i<p->nCursor; i++){
      VdbeCursor *pC = p->apCsr[i];
      if( pC ){
        sqlite3VdbeFreeCursor(p, pC);
        p->apCsr[i] = 0;
      }
    }
  }
  if( p->aMem ){
    releaseMemArray(&p->aMem[1], p->nMem);
  }
}

/*
** Clean up the VM after execution.
**
** This routine will automatically close any cursors, lists, and/or
** sorters that were left open.  It also deletes the values of
** variables in the aVar[] array.
*/
static void Cleanup(Vdbe *p){
  int i;
  sqlite3 *db = p->db;
  Mem *pMem;
  closeAllCursorsExceptActiveVtabs(p);
  for(pMem=&p->aMem[1], i=1; i<=p->nMem; i++, pMem++){
    if( pMem->flags & MEM_RowSet ){
      sqlite3RowSetClear(pMem->u.pRowSet);
    }

    MemSetTypeFlag(pMem, MEM_Null);
  }
  releaseMemArray(&p->aMem[1], p->nMem);
  if( p->contextStack ){
#ifdef SQLITE_DEBUG
  /* Execute assert() statements to ensure that the Vdbe.apCsr[] and 
  ** Vdbe.aMem[] arrays have already been cleaned up.  */
  int i;
  for(i=0; i<p->nCursor; i++) assert( p->apCsr==0 || p->apCsr[i]==0 );
  for(i=1; i<=p->nMem; i++) assert( p->aMem==0 || p->aMem[i].flags==MEM_Null );
#endif
    sqlite3DbFree(db, p->contextStack);
  }

  p->contextStack = 0;
  p->contextStackDepth = 0;
  p->contextStackTop = 0;
  sqlite3DbFree(db, p->zErrMsg);
  p->zErrMsg = 0;
  p->pResultSet = 0;
}

/*
** Set the number of result columns that will be returned by this SQL
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1597
1598
1599
1600
1601
1602
1603


1604
1605
1606

1607
1608
1609
1610
1611
1612
1613







-
-



-







      needXcommit = 1;
      if( i!=1 ) nTrans++;
    }
  }

  /* If there are any write-transactions at all, invoke the commit hook */
  if( needXcommit && db->xCommitCallback ){
    assert( (db->flags & SQLITE_CommitBusy)==0 );
    db->flags |= SQLITE_CommitBusy;
    (void)sqlite3SafetyOff(db);
    rc = db->xCommitCallback(db->pCommitArg);
    (void)sqlite3SafetyOn(db);
    db->flags &= ~SQLITE_CommitBusy;
    if( rc ){
      return SQLITE_CONSTRAINT;
    }
  }

  /* The simple case - no more than one database file (not counting the
  ** TEMP database) has a transaction active.   There is no need for the
1613
1614
1615
1616
1617
1618
1619






1620

1621
1622
1623
1624
1625
1626
1627
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854

1855
1856
1857
1858
1859
1860
1861
1862







+
+
+
+
+
+
-
+







**
** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned. 
** Otherwise SQLITE_OK.
*/
int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
  sqlite3 *const db = p->db;
  int rc = SQLITE_OK;

  /* If p->iStatement is greater than zero, then this Vdbe opened a 
  ** statement transaction that should be closed here. The only exception
  ** is that an IO error may have occured, causing an emergency rollback.
  ** In this case (db->nStatement==0), and there is nothing to do.
  */
  if( p->iStatement && db->nStatement ){
  if( db->nStatement && p->iStatement ){
    int i;
    const int iSavepoint = p->iStatement-1;

    assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE);
    assert( db->nStatement>0 );
    assert( p->iStatement==(db->nStatement+db->nSavepoint) );

1638
1639
1640
1641
1642
1643
1644







1645
1646
1647
1648
1649
1650
1651
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893







+
+
+
+
+
+
+







        if( rc==SQLITE_OK ){
          rc = rc2;
        }
      }
    }
    db->nStatement--;
    p->iStatement = 0;

    /* If the statement transaction is being rolled back, also restore the 
    ** database handles deferred constraint counter to the value it had when 
    ** the statement transaction was opened.  */
    if( eOp==SAVEPOINT_ROLLBACK ){
      db->nDeferredCons = p->nStmtDefCons;
    }
  }
  return rc;
}

/*
** If SQLite is compiled to support shared-cache mode and to be threadsafe,
** this routine obtains the mutex associated with each BtShared structure
1669
1670
1671
1672
1673
1674
1675























1676
1677
1678
1679
1680
1681
1682
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







  sqlite3BtreeMutexArrayEnter(&p->aMutex);
#else
  sqlite3BtreeEnterAll(p->db);
#endif
}
#endif

/*
** This function is called when a transaction opened by the database 
** handle associated with the VM passed as an argument is about to be 
** committed. If there are outstanding deferred foreign key constraint
** violations, return SQLITE_ERROR. Otherwise, SQLITE_OK.
**
** If there are outstanding FK violations and this function returns 
** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT and write
** an error message to it. Then return SQLITE_ERROR.
*/
#ifndef SQLITE_OMIT_FOREIGN_KEY
int sqlite3VdbeCheckFk(Vdbe *p, int deferred){
  sqlite3 *db = p->db;
  if( (deferred && db->nDeferredCons>0) || (!deferred && p->nFkConstraint>0) ){
    p->rc = SQLITE_CONSTRAINT;
    p->errorAction = OE_Abort;
    sqlite3SetString(&p->zErrMsg, db, "foreign key constraint failed");
    return SQLITE_ERROR;
  }
  return SQLITE_OK;
}
#endif

/*
** This routine is called the when a VDBE tries to halt.  If the VDBE
** has made changes and is in autocommit mode, then commit those
** changes.  If a rollback is needed, then do the rollback.
**
** This routine is the only way to move the state of a VM from
** SQLITE_MAGIC_RUN to SQLITE_MAGIC_HALT.  It is harmless to
1705
1706
1707
1708
1709
1710
1711
1712

1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728

1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739

1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752





1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765




1766
1767
1768




1769
1770
1771
1772
1773
1774
1775
1776
1777

1778
1779
1780
1781
1782
1783
1784
1970
1971
1972
1973
1974
1975
1976

1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001




2002

2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029

2030
2031
2032
2033
2034
2035



2036
2037
2038
2039

2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055







-
+
















+







-
-
-
-
+
-












+
+
+
+
+










-


+
+
+
+
-
-
-
+
+
+
+
-








+







  ** state.  We need to rollback the statement transaction, if there is
  ** one, or the complete transaction if there is no statement transaction.
  */

  if( p->db->mallocFailed ){
    p->rc = SQLITE_NOMEM;
  }
  closeAllCursorsExceptActiveVtabs(p);
  closeAllCursors(p);
  if( p->magic!=VDBE_MAGIC_RUN ){
    return SQLITE_OK;
  }
  checkActiveVdbeCnt(db);

  /* No commit or rollback needed if the program never started */
  if( p->pc>=0 ){
    int mrc;   /* Primary error code from p->rc */
    int eStatementOp = 0;
    int isSpecialError;            /* Set to true if a 'special' error */

    /* Lock all btrees used by the statement */
    sqlite3VdbeMutexArrayEnter(p);

    /* Check for one of the special errors */
    mrc = p->rc & 0xff;
    assert( p->rc!=SQLITE_IOERR_BLOCKED );  /* This error no longer exists */
    isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR
                     || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL;
    if( isSpecialError ){
      /* If the query was read-only, we need do no rollback at all. Otherwise,
      ** proceed with the special handling.
      */
      if( !p->readOnly || mrc!=SQLITE_INTERRUPT ){
        if( p->rc==SQLITE_IOERR_BLOCKED && p->usesStmtJournal ){
          eStatementOp = SAVEPOINT_ROLLBACK;
          p->rc = SQLITE_BUSY;
        }else if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL)
        if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL) && p->usesStmtJournal ){
                   && p->usesStmtJournal ){
          eStatementOp = SAVEPOINT_ROLLBACK;
        }else{
          /* We are forced to roll back the active transaction. Before doing
          ** so, abort any other statements this handle currently has active.
          */
          invalidateCursorsOnModifiedBtrees(db);
          sqlite3RollbackAll(db);
          sqlite3CloseSavepoints(db);
          db->autoCommit = 1;
        }
      }
    }

    /* Check for immediate foreign key violations. */
    if( p->rc==SQLITE_OK ){
      sqlite3VdbeCheckFk(p, 0);
    }
  
    /* If the auto-commit flag is set and this is the only active writer 
    ** VM, then we do either a commit or rollback of the current transaction. 
    **
    ** Note: This block also runs if one of the special errors handled 
    ** above has occurred. 
    */
    if( !sqlite3VtabInSync(db) 
     && db->autoCommit 
     && db->writeVdbeCnt==(p->readOnly==0) 
     && (db->flags & SQLITE_CommitBusy)==0
    ){
      if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
        if( sqlite3VdbeCheckFk(p, 1) ){
          sqlite3BtreeMutexArrayLeave(&p->aMutex);
          return SQLITE_ERROR;
        }
        /* The auto-commit flag is true, and the vdbe program was 
        ** successful or hit an 'OR FAIL' constraint. This means a commit 
        ** is required.
        /* The auto-commit flag is true, the vdbe program was successful 
        ** or hit an 'OR FAIL' constraint and there are no deferred foreign
        ** key constraints to hold up the transaction. This means a commit 
        ** is required.  */
        */
        rc = vdbeCommit(db, p);
        if( rc==SQLITE_BUSY ){
          sqlite3BtreeMutexArrayLeave(&p->aMutex);
          return SQLITE_BUSY;
        }else if( rc!=SQLITE_OK ){
          p->rc = rc;
          sqlite3RollbackAll(db);
        }else{
          db->nDeferredCons = 0;
          sqlite3CommitInternalChanges(db);
        }
      }else{
        sqlite3RollbackAll(db);
      }
      db->nStatement = 0;
    }else if( eStatementOp==0 ){
1808
1809
1810
1811
1812
1813
1814
1815

1816
1817
1818
1819
1820
1821
1822
2079
2080
2081
2082
2083
2084
2085

2086
2087
2088
2089
2090
2091
2092
2093







-
+







        p->zErrMsg = 0;
      }
    }
  
    /* If this was an INSERT, UPDATE or DELETE and no statement transaction
    ** has been rolled back, update the database connection change-counter. 
    */
    if( p->changeCntOn && p->pc>=0 ){
    if( p->changeCntOn ){
      if( eStatementOp!=SAVEPOINT_ROLLBACK ){
        sqlite3VdbeSetChanges(db, p->nChange);
      }else{
        sqlite3VdbeSetChanges(db, 0);
      }
      p->nChange = 0;
    }
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
2226
2227
2228
2229
2230
2231
2232


2233
2234
2235
2236
2237
2238
2239







-
-







** the result code.  Write any error message text into *pzErrMsg.
*/
int sqlite3VdbeFinalize(Vdbe *p){
  int rc = SQLITE_OK;
  if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){
    rc = sqlite3VdbeReset(p);
    assert( (rc & p->db->errMask)==rc );
  }else if( p->magic!=VDBE_MAGIC_INIT ){
    return SQLITE_MISUSE;
  }
  sqlite3VdbeDelete(p);
  return rc;
}

/*
** Call the destructor for each auxdata entry in pVdbeFunc for which
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995

1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017


2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2254
2255
2256
2257
2258
2259
2260

2261
2262

2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273









2274

2275
2276
2277
2278
2279
2280

2281
2282
2283
2284
2285
2286
2287







-


-
+










-
-
-
-
-
-
-
-
-

-

+
+



-







  }
}

/*
** Delete an entire VDBE.
*/
void sqlite3VdbeDelete(Vdbe *p){
  int i;
  sqlite3 *db;

  if( p==0 ) return;
  if( NEVER(p==0) ) return;
  db = p->db;
  if( p->pPrev ){
    p->pPrev->pNext = p->pNext;
  }else{
    assert( db->pVdbe==p );
    db->pVdbe = p->pNext;
  }
  if( p->pNext ){
    p->pNext->pPrev = p->pPrev;
  }
  if( p->aOp ){
    Op *pOp = p->aOp;
    for(i=0; i<p->nOp; i++, pOp++){
      freeP4(db, pOp->p4type, pOp->p4.p);
#ifdef SQLITE_DEBUG
      sqlite3DbFree(db, pOp->zComment);
#endif     
    }
  }
  releaseMemArray(p->aVar, p->nVar);
  sqlite3DbFree(db, p->aLabel);
  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
  vdbeFreeOpArray(db, p->aOp, p->nOp);
  sqlite3DbFree(db, p->aLabel);
  sqlite3DbFree(db, p->aColName);
  sqlite3DbFree(db, p->zSql);
  p->magic = VDBE_MAGIC_DEAD;
  sqlite3DbFree(db, p->aOp);
  sqlite3DbFree(db, p->pFree);
  sqlite3DbFree(db, p);
}

/*
** Make sure the cursor p is ready to read or write the row to which it
** was last positioned.  Return an error code if an OOM fault or I/O error
2052
2053
2054
2055
2056
2057
2058
2059

2060
2061
2062
2063
2064
2065
2066
2311
2312
2313
2314
2315
2316
2317

2318
2319
2320
2321
2322
2323
2324
2325







-
+







      if( rc ) return rc;
    }
#ifdef SQLITE_TEST
    sqlite3_search_count++;
#endif
    p->deferredMoveto = 0;
    p->cacheStatus = CACHE_STALE;
  }else if( p->pCursor ){
  }else if( ALWAYS(p->pCursor) ){
    int hasMoved;
    int rc = sqlite3BtreeCursorHasMoved(p->pCursor, &hasMoved);
    if( rc ) return rc;
    if( hasMoved ){
      p->cacheStatus = CACHE_STALE;
      p->nullRow = 1;
    }
2425
2426
2427
2428
2429
2430
2431
2432

2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2684
2685
2686
2687
2688
2689
2690

2691
2692
2693
2694

2695
2696
2697
2698
2699
2700
2701







-
+



-







  p->pKeyInfo = pKeyInfo;
  p->nField = pKeyInfo->nField + 1;
  p->aMem = pMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
  assert( EIGHT_BYTE_ALIGNMENT(pMem) );
  idx = getVarint32(aKey, szHdr);
  d = szHdr;
  u = 0;
  while( idx<szHdr && u<p->nField ){
  while( idx<szHdr && u<p->nField && d<=nKey ){
    u32 serial_type;

    idx += getVarint32(&aKey[idx], serial_type);
    if( d>=nKey && sqlite3VdbeSerialTypeLen(serial_type)>0 ) break;
    pMem->enc = pKeyInfo->enc;
    pMem->db = pKeyInfo->db;
    pMem->flags = 0;
    pMem->zMalloc = 0;
    d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
    pMem++;
    u++;
2453
2454
2455
2456
2457
2458
2459
2460
2461






2462
2463
2464
2465
2466
2467
2468
2469
2711
2712
2713
2714
2715
2716
2717


2718
2719
2720
2721
2722
2723

2724
2725
2726
2727
2728
2729
2730







-
-
+
+
+
+
+
+
-







void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){
  int i;
  Mem *pMem;

  assert( p!=0 );
  assert( p->flags & UNPACKED_NEED_DESTROY );
  for(i=0, pMem=p->aMem; i<p->nField; i++, pMem++){
    if( pMem->zMalloc ){
      sqlite3VdbeMemRelease(pMem);
    /* The unpacked record is always constructed by the
    ** sqlite3VdbeUnpackRecord() function above, which makes all
    ** strings and blobs static.  And none of the elements are
    ** ever transformed, so there is never anything to delete.
    */
    if( NEVER(pMem->zMalloc) ) sqlite3VdbeMemRelease(pMem);
    }
  }
  if( p->flags & UNPACKED_NEED_FREE ){
    sqlite3DbFree(p->pKeyInfo->db, p);
  }
}

/*
2535
2536
2537
2538
2539
2540
2541


2542

2543
2544
2545
2546
2547
2548
2549
2796
2797
2798
2799
2800
2801
2802
2803
2804

2805
2806
2807
2808
2809
2810
2811
2812







+
+
-
+







    rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
                           i<nField ? pKeyInfo->aColl[i] : 0);
    if( rc!=0 ){
      break;
    }
    i++;
  }

  /* No memory allocation is ever used on mem1. */
  if( mem1.zMalloc ) sqlite3VdbeMemRelease(&mem1);
  if( NEVER(mem1.zMalloc) ) sqlite3VdbeMemRelease(&mem1);

  /* If the PREFIX_SEARCH flag is set and all fields except the final
  ** rowid field were equal, then clear the PREFIX_SEARCH flag and set 
  ** pPKey2->rowid to the value of the rowid field in (pKey1, nKey1).
  ** This is used by the OP_IsUnique opcode.
  */
  if( (pPKey2->flags & UNPACKED_PREFIX_SEARCH) && i==(pPKey2->nField-1) ){
2589
2590
2591
2592
2593
2594
2595


2596
2597
2598
2599
2600
2601





2602
2603
2604
2605

2606
2607
2608
2609
2610
2611
2612
2613
2614
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864


2865
2866
2867
2868
2869
2870
2871
2872

2873


2874
2875
2876
2877
2878
2879
2880







+
+




-
-
+
+
+
+
+



-
+
-
-







int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
  i64 nCellKey = 0;
  int rc;
  u32 szHdr;        /* Size of the header */
  u32 typeRowid;    /* Serial type of the rowid */
  u32 lenRowid;     /* Size of the rowid */
  Mem m, v;

  UNUSED_PARAMETER(db);

  /* Get the size of the index entry.  Only indices entries of less
  ** than 2GiB are support - anything large must be database corruption.
  ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so
  ** this code can safely assume that nCellKey is 32-bits  */
  sqlite3BtreeKeySize(pCur, &nCellKey);
  ** this code can safely assume that nCellKey is 32-bits  
  */
  assert( sqlite3BtreeCursorIsValid(pCur) );
  rc = sqlite3BtreeKeySize(pCur, &nCellKey);
  assert( rc==SQLITE_OK );     /* pCur is always valid so KeySize cannot fail */
  assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey );

  /* Read in the complete content of the index entry */
  m.flags = 0;
  memset(&m, 0, sizeof(m));
  m.db = db;
  m.zMalloc = 0;
  rc = sqlite3VdbeMemFromBtree(pCur, 0, (int)nCellKey, 1, &m);
  if( rc ){
    return rc;
  }

  /* The index entry must begin with a header size */
  (void)getVarint32((u8*)m.z, szHdr);
2629
2630
2631
2632
2633
2634
2635
2636
2637


2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657


2658
2659

2660
2661

2662
2663
2664
2665
2666
2667
2668
2669
2670
2671

2672
2673
2674
2675
2676
2677
2678

2679




2680
2681
2682

2683
2684

2685
2686
2687
2688
2689
2690
2691
2692
2693
2895
2896
2897
2898
2899
2900
2901


2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921


2922
2923
2924

2925
2926

2927
2928
2929
2930



2931
2932
2933

2934
2935
2936
2937
2938
2939
2940
2941
2942

2943
2944
2945
2946
2947
2948

2949
2950

2951


2952
2953
2954
2955
2956
2957
2958







-
-
+
+


















-
-
+
+

-
+

-
+



-
-
-



-
+







+
-
+
+
+
+


-
+

-
+
-
-







  testcase( typeRowid==6 );
  testcase( typeRowid==8 );
  testcase( typeRowid==9 );
  if( unlikely(typeRowid<1 || typeRowid>9 || typeRowid==7) ){
    goto idx_rowid_corruption;
  }
  lenRowid = sqlite3VdbeSerialTypeLen(typeRowid);
  testcase( m.n-lenRowid==szHdr );
  if( unlikely(m.n-lenRowid<szHdr) ){
  testcase( (u32)m.n==szHdr+lenRowid );
  if( unlikely((u32)m.n<szHdr+lenRowid) ){
    goto idx_rowid_corruption;
  }

  /* Fetch the integer off the end of the index record */
  sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v);
  *rowid = v.u.i;
  sqlite3VdbeMemRelease(&m);
  return SQLITE_OK;

  /* Jump here if database corruption is detected after m has been
  ** allocated.  Free the m object and return SQLITE_CORRUPT. */
idx_rowid_corruption:
  testcase( m.zMalloc!=0 );
  sqlite3VdbeMemRelease(&m);
  return SQLITE_CORRUPT_BKPT;
}

/*
** Compare the key of the index entry that cursor pC is point to against
** the key string in pKey (of length nKey).  Write into *pRes a number
** Compare the key of the index entry that cursor pC is pointing to against
** the key string in pUnpacked.  Write into *pRes a number
** that is negative, zero, or positive if pC is less than, equal to,
** or greater than pKey.  Return SQLITE_OK on success.
** or greater than pUnpacked.  Return SQLITE_OK on success.
**
** pKey is either created without a rowid or is truncated so that it
** pUnpacked is either created without a rowid or is truncated so that it
** omits the rowid at the end.  The rowid at the end of the index entry
** is ignored as well.  Hence, this routine only compares the prefixes 
** of the keys prior to the final rowid, not the entire key.
**
** pUnpacked may be an unpacked version of pKey,nKey.  If pUnpacked is
** supplied it is used in place of pKey,nKey.
*/
int sqlite3VdbeIdxKeyCompare(
  VdbeCursor *pC,             /* The cursor to compare against */
  UnpackedRecord *pUnpacked,  /* Unpacked version of pKey and nKey */
  UnpackedRecord *pUnpacked,  /* Unpacked version of key to compare against */
  int *res                    /* Write the comparison result here */
){
  i64 nCellKey = 0;
  int rc;
  BtCursor *pCur = pC->pCursor;
  Mem m;

  assert( sqlite3BtreeCursorIsValid(pCur) );
  sqlite3BtreeKeySize(pCur, &nCellKey);
  rc = sqlite3BtreeKeySize(pCur, &nCellKey);
  assert( rc==SQLITE_OK );    /* pCur is always valid so KeySize cannot fail */
  /* nCellKey will always be between 0 and 0xffffffff because of the say
  ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
  if( nCellKey<=0 || nCellKey>0x7fffffff ){
    *res = 0;
    return SQLITE_OK;
    return SQLITE_CORRUPT;
  }
  m.db = 0;
  memset(&m, 0, sizeof(m));
  m.flags = 0;
  m.zMalloc = 0;
  rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (int)nCellKey, 1, &m);
  if( rc ){
    return rc;
  }
  assert( pUnpacked->flags & UNPACKED_IGNORE_ROWID );
  *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked);
  sqlite3VdbeMemRelease(&m);
2731
2732
2733
2734
2735
2736
2737







































2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

/*
** Return the database associated with the Vdbe.
*/
sqlite3 *sqlite3VdbeDb(Vdbe *v){
  return v->db;
}

/*
** Return a pointer to an sqlite3_value structure containing the value bound
** parameter iVar of VM v. Except, if the value is an SQL NULL, return 
** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_*
** constants) to the value before returning it.
**
** The returned value must be freed by the caller using sqlite3ValueFree().
*/
sqlite3_value *sqlite3VdbeGetValue(Vdbe *v, int iVar, u8 aff){
  assert( iVar>0 );
  if( v ){
    Mem *pMem = &v->aVar[iVar-1];
    if( 0==(pMem->flags & MEM_Null) ){
      sqlite3_value *pRet = sqlite3ValueNew(v->db);
      if( pRet ){
        sqlite3VdbeMemCopy((Mem *)pRet, pMem);
        sqlite3ValueApplyAffinity(pRet, aff, SQLITE_UTF8);
        sqlite3VdbeMemStoreType((Mem *)pRet);
      }
      return pRet;
    }
  }
  return 0;
}

/*
** Configure SQL variable iVar so that binding a new value to it signals
** to sqlite3_reoptimize() that re-preparing the statement may result
** in a better query plan.
*/
void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
  assert( iVar>0 );
  if( iVar>32 ){
    v->expmask = 0xffffffff;
  }else{
    v->expmask |= ((u32)1 << (iVar-1));
  }
}
Changes to src/vdbeblob.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2007 May 1
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code used to implement incremental BLOB I/O.
**
** $Id: vdbeblob.c,v 1.33 2009/06/01 19:53:31 drh Exp $
*/

#include "sqliteInt.h"
#include "vdbeInt.h"

#ifndef SQLITE_OMIT_INCRBLOB

62
63
64
65
66
67
68

69
70

71
72
73
74


75
76
77
78
79
80
81






82
83
84
85
86
87
88
60
61
62
63
64
65
66
67
68

69




70
71
72






73
74
75
76
77
78
79
80
81
82
83
84
85







+

-
+
-
-
-
-
+
+

-
-
-
-
-
-
+
+
+
+
+
+







  ** The sqlite3_blob_close() function finalizes the vdbe program,
  ** which closes the b-tree cursor and (possibly) commits the 
  ** transaction.
  */
  static const VdbeOpList openBlob[] = {
    {OP_Transaction, 0, 0, 0},     /* 0: Start a transaction */
    {OP_VerifyCookie, 0, 0, 0},    /* 1: Check the schema cookie */
    {OP_TableLock, 0, 0, 0},       /* 2: Acquire a read or write lock */

    /* One of the following two instructions is replaced by an
    /* One of the following two instructions is replaced by an OP_Noop. */
    ** OP_Noop before exection.
    */
    {OP_OpenRead, 0, 0, 0},        /* 2: Open cursor 0 for reading */
    {OP_OpenWrite, 0, 0, 0},       /* 3: Open cursor 0 for read/write */
    {OP_OpenRead, 0, 0, 0},        /* 3: Open cursor 0 for reading */
    {OP_OpenWrite, 0, 0, 0},       /* 4: Open cursor 0 for read/write */

    {OP_Variable, 1, 1, 1},        /* 4: Push the rowid to the stack */
    {OP_NotExists, 0, 8, 1},       /* 5: Seek the cursor */
    {OP_Column, 0, 0, 1},          /* 6  */
    {OP_ResultRow, 1, 0, 0},       /* 7  */
    {OP_Close, 0, 0, 0},           /* 8  */
    {OP_Halt, 0, 0, 0},            /* 9 */
    {OP_Variable, 1, 1, 1},        /* 5: Push the rowid to the stack */
    {OP_NotExists, 0, 9, 1},       /* 6: Seek the cursor */
    {OP_Column, 0, 0, 1},          /* 7  */
    {OP_ResultRow, 1, 0, 0},       /* 8  */
    {OP_Close, 0, 0, 0},           /* 9  */
    {OP_Halt, 0, 0, 0},            /* 10 */
  };

  Vdbe *v = 0;
  int rc = SQLITE_OK;
  char *zErr = 0;
  Table *pTab;
  Parse *pParse;
141
142
143
144
145
146
147

148
149


150
151

152

















153
154
155
156
157
158
159

160
161
162
163
164
165
166








167
168
169
170
171
172

173
174
175
176

177
178
179
180
181
182
183
184






185
186

187
188
189
190
191



192
193
194
195
196
197
198
199
200
201


202
203

204
205
206
207
208
209
210
138
139
140
141
142
143
144
145


146
147

148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171



172




173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209

210





211
212
213
214
215
216
217
218
219
220
221


222
223
224

225
226
227
228
229
230
231
232







+
-
-
+
+
-

+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




-
-
-
+
-
-
-
-



+
+
+
+
+
+
+
+






+



-
+








+
+
+
+
+
+

-
+
-
-
-
-
-
+
+
+








-
-
+
+

-
+







      rc = SQLITE_ERROR;
      (void)sqlite3SafetyOff(db);
      sqlite3BtreeLeaveAll(db);
      goto blob_open_out;
    }

    /* If the value is being opened for writing, check that the
    ** column is not indexed, and that it is not part of a foreign key. 
    ** column is not indexed. It is against the rules to open an
    ** indexed column for writing.
    ** It is against the rules to open a column to which either of these
    ** descriptions applies for writing.  */
    */
    if( flags ){
      const char *zFault = 0;
      Index *pIdx;
#ifndef SQLITE_OMIT_FOREIGN_KEY
      if( db->flags&SQLITE_ForeignKeys ){
        /* Check that the column is not part of an FK child key definition. It
        ** is not necessary to check if it is part of a parent key, as parent
        ** key columns must be indexed. The check below will pick up this 
        ** case.  */
        FKey *pFKey;
        for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
          int j;
          for(j=0; j<pFKey->nCol; j++){
            if( pFKey->aCol[j].iFrom==iCol ){
              zFault = "foreign key";
            }
          }
        }
      }
#endif
      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
        int j;
        for(j=0; j<pIdx->nColumn; j++){
          if( pIdx->aiColumn[j]==iCol ){
            sqlite3DbFree(db, zErr);
            zErr = sqlite3MPrintf(db,
                             "cannot open indexed column for writing");
            zFault = "indexed";
            rc = SQLITE_ERROR;
            (void)sqlite3SafetyOff(db);
            sqlite3BtreeLeaveAll(db);
            goto blob_open_out;
          }
        }
      }
      if( zFault ){
        sqlite3DbFree(db, zErr);
        zErr = sqlite3MPrintf(db, "cannot open %s column for writing", zFault);
        rc = SQLITE_ERROR;
        (void)sqlite3SafetyOff(db);
        sqlite3BtreeLeaveAll(db);
        goto blob_open_out;
      }
    }

    v = sqlite3VdbeCreate(db);
    if( v ){
      int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
      sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob);
      flags = !!flags;                 /* flags = (flags ? 1 : 0); */

      /* Configure the OP_Transaction */
      sqlite3VdbeChangeP1(v, 0, iDb);
      sqlite3VdbeChangeP2(v, 0, (flags ? 1 : 0));
      sqlite3VdbeChangeP2(v, 0, flags);

      /* Configure the OP_VerifyCookie */
      sqlite3VdbeChangeP1(v, 1, iDb);
      sqlite3VdbeChangeP2(v, 1, pTab->pSchema->schema_cookie);

      /* Make sure a mutex is held on the table to be accessed */
      sqlite3VdbeUsesBtree(v, iDb); 

      /* Configure the OP_TableLock instruction */
      sqlite3VdbeChangeP1(v, 2, iDb);
      sqlite3VdbeChangeP2(v, 2, pTab->tnum);
      sqlite3VdbeChangeP3(v, 2, flags);
      sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT);

      /* Remove either the OP_OpenWrite or OpenRead. Set the P2 
      ** parameter of the other to pTab->tnum. 
      ** parameter of the other to pTab->tnum.  */
      */
      flags = !!flags;
      sqlite3VdbeChangeToNoop(v, 3 - flags, 1);
      sqlite3VdbeChangeP2(v, 2 + flags, pTab->tnum);
      sqlite3VdbeChangeP3(v, 2 + flags, iDb);
      sqlite3VdbeChangeToNoop(v, 4 - flags, 1);
      sqlite3VdbeChangeP2(v, 3 + flags, pTab->tnum);
      sqlite3VdbeChangeP3(v, 3 + flags, iDb);

      /* Configure the number of columns. Configure the cursor to
      ** think that the table has one more column than it really
      ** does. An OP_Column to retrieve this imaginary column will
      ** always return an SQL NULL. This is useful because it means
      ** we can invoke OP_Column to fill in the vdbe cursors type 
      ** and offset cache without causing any IO.
      */
      sqlite3VdbeChangeP4(v, 2+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32);
      sqlite3VdbeChangeP2(v, 6, pTab->nCol);
      sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32);
      sqlite3VdbeChangeP2(v, 7, pTab->nCol);
      if( !db->mallocFailed ){
        sqlite3VdbeMakeReady(v, 1, 1, 1, 0);
        sqlite3VdbeMakeReady(v, 1, 1, 1, 0, 0, 0);
      }
    }
   
    sqlite3BtreeLeaveAll(db);
    rc = sqlite3SafetyOff(db);
    if( NEVER(rc!=SQLITE_OK) || db->mallocFailed ){
      goto blob_open_out;
Changes to src/vdbemem.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
10
11
12
13
14
15
16


17
18
19
20
21
22
23







-
-







**
*************************************************************************
**
** This file contains code use to manipulate "Mem" structure.  A "Mem"
** stores a single value in the VDBE.  Mem is an opaque structure visible
** only within the VDBE.  Interface routines refer to a Mem using the
** name sqlite_value
**
** $Id: vdbemem.c,v 1.150 2009/06/25 01:47:12 drh Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

/*
** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*)
** P if required.
266
267
268
269
270
271
272




273

274
275
276
277
278
279
280
281
282
283


284
285
286
287
288
289
290
264
265
266
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294







+
+
+
+
-
+










+
+







/*
** If the memory cell contains a string value that must be freed by
** invoking an external callback, free it now. Calling this function
** does not free any Mem.zMalloc buffer.
*/
void sqlite3VdbeMemReleaseExternal(Mem *p){
  assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) );
  testcase( p->flags & MEM_Agg );
  testcase( p->flags & MEM_Dyn );
  testcase( p->flags & MEM_RowSet );
  testcase( p->flags & MEM_Frame );
  if( p->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet) ){
  if( p->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame) ){
    if( p->flags&MEM_Agg ){
      sqlite3VdbeMemFinalize(p, p->u.pDef);
      assert( (p->flags & MEM_Agg)==0 );
      sqlite3VdbeMemRelease(p);
    }else if( p->flags&MEM_Dyn && p->xDel ){
      assert( (p->flags&MEM_RowSet)==0 );
      p->xDel((void *)p->z);
      p->xDel = 0;
    }else if( p->flags&MEM_RowSet ){
      sqlite3RowSetClear(p->u.pRowSet);
    }else if( p->flags&MEM_Frame ){
      sqlite3VdbeMemSetNull(p);
    }
  }
}

/*
** Release any memory held by the Mem. This may leave the Mem in an
** inconsistent state, for example with (Mem.z==0) and
414
415
416
417
418
419
420
421
422
423





424
425


426
427
428
429
430
431
432
418
419
420
421
422
423
424



425
426
427
428
429
430

431
432
433
434
435
436
437
438
439







-
-
-
+
+
+
+
+

-
+
+








  /* Only mark the value as an integer if
  **
  **    (1) the round-trip conversion real->int->real is a no-op, and
  **    (2) The integer is neither the largest nor the smallest
  **        possible integer (ticket #3922)
  **
  ** The second term in the following conditional enforces the second
  ** condition under the assumption that additional overflow causes
  ** values to wrap around.
  ** The second and third terms in the following conditional enforces
  ** the second condition under the assumption that addition overflow causes
  ** values to wrap around.  On x86 hardware, the third term is always
  ** true and could be omitted.  But we leave it in because other
  ** architectures might behave differently.
  */
  if( pMem->r==(double)pMem->u.i && (pMem->u.i-1) < (pMem->u.i+1) ){
  if( pMem->r==(double)pMem->u.i && pMem->u.i>SMALLEST_INT64
      && ALWAYS(pMem->u.i<LARGEST_INT64) ){
    pMem->flags |= MEM_Int;
  }
}

/*
** Convert pMem to type integer.  Invalidate any prior representations.
*/
475
476
477
478
479
480
481



482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500








501
502
503
504
505
506
507
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525







+
+
+



















+
+
+
+
+
+
+
+







  return SQLITE_OK;
}

/*
** Delete any previous value and set the value stored in *pMem to NULL.
*/
void sqlite3VdbeMemSetNull(Mem *pMem){
  if( pMem->flags & MEM_Frame ){
    sqlite3VdbeFrameDelete(pMem->u.pFrame);
  }
  if( pMem->flags & MEM_RowSet ){
    sqlite3RowSetClear(pMem->u.pRowSet);
  }
  MemSetTypeFlag(pMem, MEM_Null);
  pMem->type = SQLITE_NULL;
}

/*
** Delete any previous value and set the value to be a BLOB of length
** n containing all zeros.
*/
void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
  sqlite3VdbeMemRelease(pMem);
  pMem->flags = MEM_Blob|MEM_Zero;
  pMem->type = SQLITE_BLOB;
  pMem->n = 0;
  if( n<0 ) n = 0;
  pMem->u.nZero = n;
  pMem->enc = SQLITE_UTF8;

#ifdef SQLITE_OMIT_INCRBLOB
  sqlite3VdbeMemGrow(pMem, n, 0);
  if( pMem->z ){
    pMem->n = n;
    memset(pMem->z, 0, n);
  }
#endif
}

/*
** Delete any previous value and set the value stored in *pMem to val,
** manifest type INTEGER.
*/
void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
862
863
864
865
866
867
868


869
870
871
872
873
874
875
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895







+
+







  int amt,          /* Number of bytes to return. */
  int key,          /* If true, retrieve from the btree key, not data. */
  Mem *pMem         /* OUT: Return data in this Mem structure. */
){
  char *zData;        /* Data from the btree layer */
  int available = 0;  /* Number of bytes available on the local btree page */
  int rc = SQLITE_OK; /* Return code */

  assert( sqlite3BtreeCursorIsValid(pCur) );

  /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() 
  ** that both the BtShared and database handle mutexes are held. */
  assert( (pMem->flags & MEM_RowSet)==0 );
  if( key ){
    zData = (char *)sqlite3BtreeKeyFetch(pCur, &available);
  }else{
982
983
984
985
986
987
988



989
990
991
992
993
994
995
996
997
998

999
1000
1001
1002
1003
1004
1005
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029







+
+
+










+







  sqlite3_value *pVal = 0;

  if( !pExpr ){
    *ppVal = 0;
    return SQLITE_OK;
  }
  op = pExpr->op;
  if( op==TK_REGISTER ){
    op = pExpr->op2;  /* This only happens with SQLITE_ENABLE_STAT2 */
  }

  if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
    pVal = sqlite3ValueNew(db);
    if( pVal==0 ) goto no_mem;
    if( ExprHasProperty(pExpr, EP_IntValue) ){
      sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue);
    }else{
      zVal = sqlite3DbStrDup(db, pExpr->u.zToken);
      if( zVal==0 ) goto no_mem;
      sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
      if( op==TK_FLOAT ) pVal->type = SQLITE_FLOAT;
    }
    if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
      sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
    }else{
      sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
    }
    if( enc!=SQLITE_UTF8 ){
1023
1024
1025
1026
1027
1028
1029



1030
1031
1032
1033
1034
1035
1036
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063







+
+
+







    nVal = sqlite3Strlen30(zVal)-1;
    assert( zVal[nVal]=='\'' );
    sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2,
                         0, SQLITE_DYNAMIC);
  }
#endif

  if( pVal ){
    sqlite3VdbeMemStoreType(pVal);
  }
  *ppVal = pVal;
  return SQLITE_OK;

no_mem:
  db->mallocFailed = 1;
  sqlite3DbFree(db, zVal);
  sqlite3ValueFree(pVal);
Changes to src/vtab.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

31
32
33
34
35
36
37
1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35












-
-















-
+







/*
** 2006 June 10
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to help implement virtual tables.
**
** $Id: vtab.c,v 1.91 2009/06/15 16:27:08 shane Exp $
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
#include "sqliteInt.h"

/*
** The actual function that does the work of creating a new module.
** This function implements the sqlite3_create_module() and
** sqlite3_create_module_v2() interfaces.
*/
static int createModule(
  sqlite3 *db,                    /* Database in which module is registered */
  const char *zName,              /* Name assigned to this module */
  const sqlite3_module *pModule,  /* The definition of the module */
  void *pAux,                     /* Context pointer for xCreate/xConnect */
  void (*xDestroy)(void *)        /* Module destructor function */
) {
){
  int rc, nName;
  Module *pMod;

  sqlite3_mutex_enter(db->mutex);
  nName = sqlite3Strlen30(zName);
  pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1);
  if( pMod ){
89
90
91
92
93
94
95
96
97















98
99
100
101
102


103
104
105
106



107
108

109
110

111


112



113
114
115
116
117
118





119
120
121
122



















































































123
124
125
126
127
128
129









130
131
132
133
134
135

136
137
138
139
140
141
142
143

144
145

146
147
148
149
150
151
152
87
88
89
90
91
92
93


94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111


112
113
114



115
116
117


118


119
120
121
122

123
124
125
126





127
128
129
130
131
132



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233




234




235
236
237

238
239

240
241
242
243
244
245
246
247







-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
-
+
+

-
-
-
+
+
+
-
-
+
-
-
+

+
+
-
+
+
+

-
-
-
-
-
+
+
+
+
+

-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







+
+
+
+
+
+
+
+
+


-
-
-
-
+
-
-
-
-



-
+

-
+







** Lock the virtual table so that it cannot be disconnected.
** Locks nest.  Every lock should have a corresponding unlock.
** If an unlock is omitted, resources leaks will occur.  
**
** If a disconnect is attempted while a virtual table is locked,
** the disconnect is deferred until all locks have been removed.
*/
void sqlite3VtabLock(sqlite3_vtab *pVtab){
  pVtab->nRef++;
void sqlite3VtabLock(VTable *pVTab){
  pVTab->nRef++;
}


/*
** pTab is a pointer to a Table structure representing a virtual-table.
** Return a pointer to the VTable object used by connection db to access 
** this virtual-table, if one has been created, or NULL otherwise.
*/
VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){
  VTable *pVtab;
  assert( IsVirtual(pTab) );
  for(pVtab=pTab->pVTable; pVtab && pVtab->db!=db; pVtab=pVtab->pNext);
  return pVtab;
}

/*
** Unlock a virtual table.  When the last lock is removed,
** disconnect the virtual table.
** Decrement the ref-count on a virtual table object. When the ref-count
** reaches zero, call the xDisconnect() method to delete the object.
*/
void sqlite3VtabUnlock(sqlite3 *db, sqlite3_vtab *pVtab){
#ifndef SQLITE_DEBUG
  UNUSED_PARAMETER(db);
void sqlite3VtabUnlock(VTable *pVTab){
  sqlite3 *db = pVTab->db;

#endif
  assert( pVtab->nRef>0 );
  assert( db );
  pVtab->nRef--;
  assert(db);
  assert( pVTab->nRef>0 );
  assert( sqlite3SafetyCheckOk(db) );

  pVTab->nRef--;
  if( pVtab->nRef==0 ){
  if( pVTab->nRef==0 ){
    sqlite3_vtab *p = pVTab->pVtab;
    if( p ){
#ifdef SQLITE_DEBUG
    if( db->magic==SQLITE_MAGIC_BUSY ){
      (void)sqlite3SafetyOff(db);
      pVtab->pModule->xDisconnect(pVtab);
      (void)sqlite3SafetyOn(db);
    } else 
      if( pVTab->db->magic==SQLITE_MAGIC_BUSY ){
        (void)sqlite3SafetyOff(db);
        p->pModule->xDisconnect(p);
        (void)sqlite3SafetyOn(db);
      } else
#endif
    {
      pVtab->pModule->xDisconnect(pVtab);
    }
      {
        p->pModule->xDisconnect(p);
      }
    }
    sqlite3DbFree(db, pVTab);
  }
}

/*
** Table p is a virtual table. This function moves all elements in the
** p->pVTable list to the sqlite3.pDisconnect lists of their associated
** database connections to be disconnected at the next opportunity. 
** Except, if argument db is not NULL, then the entry associated with
** connection db is left in the p->pVTable list.
*/
static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){
  VTable *pRet = 0;
  VTable *pVTable = p->pVTable;
  p->pVTable = 0;

  /* Assert that the mutex (if any) associated with the BtShared database 
  ** that contains table p is held by the caller. See header comments 
  ** above function sqlite3VtabUnlockList() for an explanation of why
  ** this makes it safe to access the sqlite3.pDisconnect list of any
  ** database connection that may have an entry in the p->pVTable list.  */
  assert( db==0 ||
    sqlite3BtreeHoldsMutex(db->aDb[sqlite3SchemaToIndex(db, p->pSchema)].pBt) 
  );

  while( pVTable ){
    sqlite3 *db2 = pVTable->db;
    VTable *pNext = pVTable->pNext;
    assert( db2 );
    if( db2==db ){
      pRet = pVTable;
      p->pVTable = pRet;
      pRet->pNext = 0;
    }else{
      pVTable->pNext = db2->pDisconnect;
      db2->pDisconnect = pVTable;
    }
    pVTable = pNext;
  }

  assert( !db || pRet );
  return pRet;
}


/*
** Disconnect all the virtual table objects in the sqlite3.pDisconnect list.
**
** This function may only be called when the mutexes associated with all
** shared b-tree databases opened using connection db are held by the 
** caller. This is done to protect the sqlite3.pDisconnect list. The
** sqlite3.pDisconnect list is accessed only as follows:
**
**   1) By this function. In this case, all BtShared mutexes and the mutex
**      associated with the database handle itself must be held.
**
**   2) By function vtabDisconnectAll(), when it adds a VTable entry to
**      the sqlite3.pDisconnect list. In this case either the BtShared mutex
**      associated with the database the virtual table is stored in is held
**      or, if the virtual table is stored in a non-sharable database, then
**      the database handle mutex is held.
**
** As a result, a sqlite3.pDisconnect cannot be accessed simultaneously 
** by multiple threads. It is thread-safe.
*/
void sqlite3VtabUnlockList(sqlite3 *db){
  VTable *p = db->pDisconnect;
  db->pDisconnect = 0;

  assert( sqlite3BtreeHoldsAllMutexes(db) );
  assert( sqlite3_mutex_held(db->mutex) );

  if( p ){
    sqlite3ExpirePreparedStatements(db);
    do {
      VTable *pNext = p->pNext;
      sqlite3VtabUnlock(p);
      p = pNext;
    }while( p );
  }
}

/*
** Clear any and all virtual-table information from the Table record.
** This routine is called, for example, just before deleting the Table
** record.
**
** Since it is a virtual-table, the Table structure contains a pointer
** to the head of a linked list of VTable structures. Each VTable 
** structure is associated with a single sqlite3* user of the schema.
** The reference count of the VTable structure associated with database 
** connection db is decremented immediately (which may lead to the 
** structure being xDisconnected and free). Any other VTable structures
** in the list are moved to the sqlite3.pDisconnect list of the associated 
** database connection.
*/
void sqlite3VtabClear(Table *p){
  sqlite3_vtab *pVtab = p->pVtab;
  Schema *pSchema = p->pSchema;
  sqlite3 *db = pSchema ? pSchema->db : 0;
  if( pVtab ){
  vtabDisconnectAll(0, p);
    assert( p->pMod && p->pMod->pModule );
    sqlite3VtabUnlock(db, pVtab);
    p->pVtab = 0;
  }
  if( p->azModuleArg ){
    int i;
    for(i=0; i<p->nModuleArg; i++){
      sqlite3DbFree(db, p->azModuleArg[i]);
      sqlite3DbFree(p->dbMem, p->azModuleArg[i]);
    }
    sqlite3DbFree(db, p->azModuleArg);
    sqlite3DbFree(p->dbMem, p->azModuleArg);
  }
}

/*
** Add a new module argument to pTable->azModuleArg[].
** The string is not copied - the pointer is stored.  The
** string will be freed automatically when the table is
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
278
279
280
281
282
283
284





285
286
287
288
289
290
291







-
-
-
-
-







  Token *pName2,        /* Name of new table or NULL */
  Token *pModuleName    /* Name of the module for the virtual table */
){
  int iDb;              /* The database the table is being created in */
  Table *pTable;        /* The new virtual table */
  sqlite3 *db;          /* Database connection */

  if( pParse->db->flags & SQLITE_SharedCache ){
    sqlite3ErrorMsg(pParse, "Cannot use virtual tables in shared-cache mode");
    return;
  }

  sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0);
  pTable = pParse->pNewTable;
  if( pTable==0 ) return;
  assert( 0==pTable->pIndex );

  db = pParse->db;
  iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
236
237
238
239
240
241
242
243
244


245
246
247

248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
326
327
328
329
330
331
332


333
334


335
336
337
338





339




340
341
342
343
344
345
346







-
-
+
+
-
-

+


-
-
-
-
-

-
-
-
-







}

/*
** The parser calls this routine after the CREATE VIRTUAL TABLE statement
** has been completely parsed.
*/
void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
  Table *pTab;        /* The table being constructed */
  sqlite3 *db;        /* The database connection */
  Table *pTab = pParse->pNewTable;  /* The table being constructed */
  sqlite3 *db = pParse->db;         /* The database connection */
  char *zModule;      /* The module name of the table: USING modulename */
  Module *pMod = 0;

  if( pTab==0 ) return;
  addArgumentToVtab(pParse);
  pParse->sArg.z = 0;

  /* Lookup the module name. */
  pTab = pParse->pNewTable;
  if( pTab==0 ) return;
  db = pParse->db;
  if( pTab->nModuleArg<1 ) return;
  zModule = pTab->azModuleArg[0];
  pMod = (Module*)sqlite3HashFind(&db->aModule, zModule,
                                  sqlite3Strlen30(zModule));
  pTab->pMod = pMod;
  
  /* If the CREATE VIRTUAL TABLE statement is being entered for the
  ** first time (in other words if the virtual table is actually being
  ** created now instead of just being read out of sqlite_master) then
  ** do additional initialization work and store the statement text
  ** in the sqlite_master table.
  */
303
304
305
306
307
308
309
310
311
312




313
314
315
316
317
318
319
383
384
385
386
387
388
389



390
391
392
393
394
395
396
397
398
399
400







-
-
-
+
+
+
+







    zWhere = sqlite3MPrintf(db, "name='%q'", pTab->zName);
    sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 1, 0, zWhere, P4_DYNAMIC);
    sqlite3VdbeAddOp4(v, OP_VCreate, iDb, 0, 0, 
                         pTab->zName, sqlite3Strlen30(pTab->zName) + 1);
  }

  /* If we are rereading the sqlite_master table create the in-memory
  ** record of the table. If the module has already been registered,
  ** also call the xConnect method here.
  */
  ** record of the table. The xConnect() method is not called until
  ** the first time the virtual table is used in an SQL statement. This
  ** allows a schema that contains virtual tables to be loaded before
  ** the required virtual table implementations are registered.  */
  else {
    Table *pOld;
    Schema *pSchema = pTab->pSchema;
    const char *zName = pTab->zName;
    int nName = sqlite3Strlen30(zName);
    pOld = sqlite3HashInsert(&pSchema->tblHash, zName, nName, pTab);
    if( pOld ){
359
360
361
362
363
364
365

366
367
368
369
370
371
372
373
374
375
376
377








378
379
380
381


382

383
384
385


386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401






402
403
404
405
406






407
408
409
410
411
412
413
414
415
416
417









418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449


































450
451
452
453
454
455
456
457
458
459
460


461
462

463
464
465

466
467
468

469



470
471
472
473
474

475
476
477
478
479
480
481
482
483
484
485
486
487
488

489
490

491
492
493
494
495

496
497
498
499
500
501
502
503
504
505
506
507


508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523

524
525
526
527
528





529
530
531
532
533
534
535

536
537
538
539
540
541
542
543
544


545
546
547
548
549
550
551
440
441
442
443
444
445
446
447
448


449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467

468
469
470

471



472
473
474







475
476
477
478
479
480
481
482
483
484
485
486
487
488





489
490
491
492
493
494











495
496
497
498
499
500
501
502
503
































504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551

552
553
554

555
556
557
558
559

560
561
562
563
564
565
566

567
568

569
570
571
572
573
574
575
576
577
578
579

580
581

582
583
584
585
586

587
588
589
590
591
592
593
594
595
596
597


598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614

615
616
617



618
619
620
621
622
623
624
625
626
627
628

629
630
631
632
633
634
635
636


637
638
639
640
641
642
643
644
645







+

-
-









+
+
+
+
+
+
+
+


-

+
+
-
+
-
-
-
+
+

-
-
-
-
-
-
-








+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+











+
+

-
+


-
+



+
-
+
+
+




-
+

-











-
+

-
+




-
+










-
-
+
+















-
+


-
-
-
+
+
+
+
+






-
+







-
-
+
+







static int vtabCallConstructor(
  sqlite3 *db, 
  Table *pTab,
  Module *pMod,
  int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
  char **pzErr
){
  VTable *pVTable;
  int rc;
  int rc2;
  sqlite3_vtab *pVtab = 0;
  const char *const*azArg = (const char *const*)pTab->azModuleArg;
  int nArg = pTab->nModuleArg;
  char *zErr = 0;
  char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);

  if( !zModuleName ){
    return SQLITE_NOMEM;
  }

  pVTable = sqlite3DbMallocZero(db, sizeof(VTable));
  if( !pVTable ){
    sqlite3DbFree(db, zModuleName);
    return SQLITE_NOMEM;
  }
  pVTable->db = db;
  pVTable->pMod = pMod;

  assert( !db->pVTab );
  assert( xConstruct );

  db->pVTab = pTab;

  /* Invoke the virtual table constructor */
  rc = sqlite3SafetyOff(db);
  (void)sqlite3SafetyOff(db);
  assert( rc==SQLITE_OK );
  rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVtab, &zErr);
  rc2 = sqlite3SafetyOn(db);
  rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
  (void)sqlite3SafetyOn(db);
  if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
  /* Justification of ALWAYS():  A correct vtab constructor must allocate
  ** the sqlite3_vtab object if successful. */
  if( rc==SQLITE_OK && ALWAYS(pVtab) ){
    pVtab->pModule = pMod->pModule;
    pVtab->nRef = 1;
    pTab->pVtab = pVtab;
  }

  if( SQLITE_OK!=rc ){
    if( zErr==0 ){
      *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName);
    }else {
      *pzErr = sqlite3MPrintf(db, "%s", zErr);
      sqlite3DbFree(db, zErr);
    }
    sqlite3DbFree(db, pVTable);
  }else if( ALWAYS(pVTable->pVtab) ){
    /* Justification of ALWAYS():  A correct vtab constructor must allocate
    ** the sqlite3_vtab object if successful.  */
    pVTable->pVtab->pModule = pMod->pModule;
    pVTable->nRef = 1;
  }else if( db->pVTab ){
    const char *zFormat = "vtable constructor did not declare schema: %s";
    *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
    rc = SQLITE_ERROR;
  } 
    if( db->pVTab ){
      const char *zFormat = "vtable constructor did not declare schema: %s";
      *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
      sqlite3VtabUnlock(pVTable);
      rc = SQLITE_ERROR;
    }else{
  if( rc==SQLITE_OK ){
    rc = rc2;
  }
  db->pVTab = 0;
  sqlite3DbFree(db, zModuleName);

  /* If everything went according to plan, loop through the columns
  ** of the table to see if any of them contain the token "hidden".
  ** If so, set the Column.isHidden flag and remove the token from
  ** the type string.
  */
      int iCol;
      /* If everything went according to plan, link the new VTable structure
      ** into the linked list headed by pTab->pVTable. Then loop through the 
      ** columns of the table to see if any of them contain the token "hidden".
      ** If so, set the Column.isHidden flag and remove the token from
      ** the type string.  */
      pVTable->pNext = pTab->pVTable;
      pTab->pVTable = pVTable;

  if( rc==SQLITE_OK ){
    int iCol;
    for(iCol=0; iCol<pTab->nCol; iCol++){
      char *zType = pTab->aCol[iCol].zType;
      int nType;
      int i = 0;
      if( !zType ) continue;
      nType = sqlite3Strlen30(zType);
      if( sqlite3StrNICmp("hidden", zType, 6) || (zType[6] && zType[6]!=' ') ){
        for(i=0; i<nType; i++){
          if( (0==sqlite3StrNICmp(" hidden", &zType[i], 7))
           && (zType[i+7]=='\0' || zType[i+7]==' ')
          ){
            i++;
            break;
          }
        }
      }
      if( i<nType ){
        int j;
        int nDel = 6 + (zType[i+6] ? 1 : 0);
        for(j=i; (j+nDel)<=nType; j++){
          zType[j] = zType[j+nDel];
        }
        if( zType[i]=='\0' && i>0 ){
          assert(zType[i-1]==' ');
          zType[i-1] = '\0';
        }
        pTab->aCol[iCol].isHidden = 1;
      }
    }
  }
      for(iCol=0; iCol<pTab->nCol; iCol++){
        char *zType = pTab->aCol[iCol].zType;
        int nType;
        int i = 0;
        if( !zType ) continue;
        nType = sqlite3Strlen30(zType);
        if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){
          for(i=0; i<nType; i++){
            if( (0==sqlite3StrNICmp(" hidden", &zType[i], 7))
             && (zType[i+7]=='\0' || zType[i+7]==' ')
            ){
              i++;
              break;
            }
          }
        }
        if( i<nType ){
          int j;
          int nDel = 6 + (zType[i+6] ? 1 : 0);
          for(j=i; (j+nDel)<=nType; j++){
            zType[j] = zType[j+nDel];
          }
          if( zType[i]=='\0' && i>0 ){
            assert(zType[i-1]==' ');
            zType[i-1] = '\0';
          }
          pTab->aCol[iCol].isHidden = 1;
        }
      }
    }
  }

  sqlite3DbFree(db, zModuleName);
  db->pVTab = 0;
  return rc;
}

/*
** This function is invoked by the parser to call the xConnect() method
** of the virtual table pTab. If an error occurs, an error code is returned 
** and an error left in pParse.
**
** This call is a no-op if table pTab is not a virtual table.
*/
int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
  sqlite3 *db = pParse->db;
  const char *zMod;
  Module *pMod;
  int rc = SQLITE_OK;
  int rc;

  assert( pTab );
  if( (pTab->tabFlags & TF_Virtual)==0 || pTab->pVtab ){
  if( (pTab->tabFlags & TF_Virtual)==0 || sqlite3GetVTable(db, pTab) ){
    return SQLITE_OK;
  }

  /* Locate the required virtual table module */
  pMod = pTab->pMod;
  zMod = pTab->azModuleArg[0];
  pMod = (Module*)sqlite3HashFind(&db->aModule, zMod, sqlite3Strlen30(zMod));

  if( !pMod ){
    const char *zModule = pTab->azModuleArg[0];
    sqlite3ErrorMsg(pParse, "no such module: %s", zModule);
    rc = SQLITE_ERROR;
  } else {
  }else{
    char *zErr = 0;
    sqlite3 *db = pParse->db;
    rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr);
    if( rc!=SQLITE_OK ){
      sqlite3ErrorMsg(pParse, "%s", zErr);
    }
    sqlite3DbFree(db, zErr);
  }

  return rc;
}

/*
** Add the virtual table pVtab to the array sqlite3.aVTrans[].
** Add the virtual table pVTab to the array sqlite3.aVTrans[].
*/
static int addToVTrans(sqlite3 *db, sqlite3_vtab *pVtab){
static int addToVTrans(sqlite3 *db, VTable *pVTab){
  const int ARRAY_INCR = 5;

  /* Grow the sqlite3.aVTrans array if required */
  if( (db->nVTrans%ARRAY_INCR)==0 ){
    sqlite3_vtab **aVTrans;
    VTable **aVTrans;
    int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR);
    aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes);
    if( !aVTrans ){
      return SQLITE_NOMEM;
    }
    memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR);
    db->aVTrans = aVTrans;
  }

  /* Add pVtab to the end of sqlite3.aVTrans */
  db->aVTrans[db->nVTrans++] = pVtab;
  sqlite3VtabLock(pVtab);
  db->aVTrans[db->nVTrans++] = pVTab;
  sqlite3VtabLock(pVTab);
  return SQLITE_OK;
}

/*
** This function is invoked by the vdbe to call the xCreate method
** of the virtual table named zTab in database iDb. 
**
** If an error occurs, *pzErr is set to point an an English language
** description of the error and an SQLITE_XXX error code is returned.
** In this case the caller must call sqlite3DbFree(db, ) on *pzErr.
*/
int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
  int rc = SQLITE_OK;
  Table *pTab;
  Module *pMod;
  const char *zModule;
  const char *zMod;

  pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
  assert(pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVtab);
  pMod = pTab->pMod;
  zModule = pTab->azModuleArg[0];
  assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable );

  /* Locate the required virtual table module */
  zMod = pTab->azModuleArg[0];
  pMod = (Module*)sqlite3HashFind(&db->aModule, zMod, sqlite3Strlen30(zMod));

  /* If the module has been registered and includes a Create method, 
  ** invoke it now. If the module has not been registered, return an 
  ** error. Otherwise, do nothing.
  */
  if( !pMod ){
    *pzErr = sqlite3MPrintf(db, "no such module: %s", zModule);
    *pzErr = sqlite3MPrintf(db, "no such module: %s", zMod);
    rc = SQLITE_ERROR;
  }else{
    rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr);
  }

  /* Justification of ALWAYS():  The xConstructor method is required to
  ** create a valid sqlite3_vtab if it returns SQLITE_OK. */
  if( rc==SQLITE_OK && ALWAYS(pTab->pVtab) ){
      rc = addToVTrans(db, pTab->pVtab);
  if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){
      rc = addToVTrans(db, sqlite3GetVTable(db, pTab));
  }

  return rc;
}

/*
** This function is used to set the schema of a virtual table.  It is only
562
563
564
565
566
567
568
569

570
571
572
573
574
575
576
577
578
579
580
581
582
583

584
585
586
587





588
589
590
591
592
593
594
656
657
658
659
660
661
662

663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678




679
680
681
682
683
684
685
686
687
688
689
690







-
+














+
-
-
-
-
+
+
+
+
+







  sqlite3_mutex_enter(db->mutex);
  pTab = db->pVTab;
  if( !pTab ){
    sqlite3Error(db, SQLITE_MISUSE, 0);
    sqlite3_mutex_leave(db->mutex);
    return SQLITE_MISUSE;
  }
  assert((pTab->tabFlags & TF_Virtual)!=0 && pTab->nCol==0 && pTab->aCol==0);
  assert( (pTab->tabFlags & TF_Virtual)!=0 );

  pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
  if( pParse==0 ){
    rc = SQLITE_NOMEM;
  }else{
    pParse->declareVtab = 1;
    pParse->db = db;
  
    if( 
        SQLITE_OK == sqlite3RunParser(pParse, zCreateTable, &zErr) && 
        pParse->pNewTable && 
        !pParse->pNewTable->pSelect && 
        (pParse->pNewTable->tabFlags & TF_Virtual)==0
    ){
      if( !pTab->aCol ){
      pTab->aCol = pParse->pNewTable->aCol;
      pTab->nCol = pParse->pNewTable->nCol;
      pParse->pNewTable->nCol = 0;
      pParse->pNewTable->aCol = 0;
        pTab->aCol = pParse->pNewTable->aCol;
        pTab->nCol = pParse->pNewTable->nCol;
        pParse->pNewTable->nCol = 0;
        pParse->pNewTable->aCol = 0;
      }
      db->pVTab = 0;
    } else {
      sqlite3Error(db, SQLITE_ERROR, zErr);
      sqlite3DbFree(db, zErr);
      rc = SQLITE_ERROR;
    }
    pParse->declareVtab = 0;
614
615
616
617
618
619
620
621
622



623
624
625

626


627
628
629
630

631
632
633
634
635



636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655




656
657
658
659
660




661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680

681
682
683
684
685
686
687
688


689
690
691
692
693
694
695
696
710
711
712
713
714
715
716


717
718
719
720
721

722
723
724
725
726



727





728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748


749
750
751
752





753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775

776
777
778
779
780

781


782
783

784
785
786
787
788
789
790







-
-
+
+
+


-
+

+
+

-
-
-
+
-
-
-
-
-
+
+
+


















-
-
+
+
+
+
-
-
-
-
-
+
+
+
+



















-
+




-

-
-
+
+
-







** This call is a no-op if zTab is not a virtual table.
*/
int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
  int rc = SQLITE_OK;
  Table *pTab;

  pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
  if( ALWAYS(pTab!=0 && pTab->pVtab!=0) ){
    int (*xDestroy)(sqlite3_vtab *pVTab) = pTab->pMod->pModule->xDestroy;
  if( ALWAYS(pTab!=0 && pTab->pVTable!=0) ){
    VTable *p = vtabDisconnectAll(db, pTab);

    rc = sqlite3SafetyOff(db);
    assert( rc==SQLITE_OK );
    rc = xDestroy(pTab->pVtab);
    rc = p->pMod->pModule->xDestroy(p->pVtab);
    (void)sqlite3SafetyOn(db);

    /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
    if( rc==SQLITE_OK ){
      int i;
      for(i=0; i<db->nVTrans; i++){
        if( db->aVTrans[i]==pTab->pVtab ){
      assert( pTab->pVTable==p && p->pNext==0 );
          db->aVTrans[i] = db->aVTrans[--db->nVTrans];
          break;
        }
      }
      pTab->pVtab = 0;
      p->pVtab = 0;
      pTab->pVTable = 0;
      sqlite3VtabUnlock(p);
    }
  }

  return rc;
}

/*
** This function invokes either the xRollback or xCommit method
** of each of the virtual tables in the sqlite3.aVTrans array. The method
** called is identified by the second argument, "offset", which is
** the offset of the method to call in the sqlite3_module structure.
**
** The array is cleared after invoking the callbacks. 
*/
static void callFinaliser(sqlite3 *db, int offset){
  int i;
  if( db->aVTrans ){
    for(i=0; i<db->nVTrans; i++){
      sqlite3_vtab *pVtab = db->aVTrans[i];
      int (*x)(sqlite3_vtab *);
      VTable *pVTab = db->aVTrans[i];
      sqlite3_vtab *p = pVTab->pVtab;
      if( p ){
        int (*x)(sqlite3_vtab *);

      assert( pVtab!=0 );
      x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset);
      if( x ) x(pVtab);
      sqlite3VtabUnlock(db, pVtab);
        x = *(int (**)(sqlite3_vtab *))((char *)p->pModule + offset);
        if( x ) x(p);
      }
      sqlite3VtabUnlock(pVTab);
    }
    sqlite3DbFree(db, db->aVTrans);
    db->nVTrans = 0;
    db->aVTrans = 0;
  }
}

/*
** Invoke the xSync method of all virtual tables in the sqlite3.aVTrans
** array. Return the error code for the first error that occurs, or
** SQLITE_OK if all xSync operations are successful.
**
** Set *pzErrmsg to point to a buffer that should be released using 
** sqlite3DbFree() containing an error message, if one is available.
*/
int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
  int i;
  int rc = SQLITE_OK;
  int rcsafety;
  sqlite3_vtab **aVTrans = db->aVTrans;
  VTable **aVTrans = db->aVTrans;

  rc = sqlite3SafetyOff(db);
  db->aVTrans = 0;
  for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
    sqlite3_vtab *pVtab = aVTrans[i];
    int (*x)(sqlite3_vtab *);
    assert( pVtab!=0 );
    x = pVtab->pModule->xSync;
    sqlite3_vtab *pVtab = aVTrans[i]->pVtab;
    if( pVtab && (x = pVtab->pModule->xSync)!=0 ){
    if( x ){
      rc = x(pVtab);
      sqlite3DbFree(db, *pzErrmsg);
      *pzErrmsg = pVtab->zErrMsg;
      pVtab->zErrMsg = 0;
    }
  }
  db->aVTrans = aVTrans;
724
725
726
727
728
729
730
731

732
733
734
735
736
737
738
739
740
741
742
743

744
745
746

747
748
749
750
751
752
753
754

755
756
757
758
759
760

761
762

763
764
765
766
767
768
769
818
819
820
821
822
823
824

825
826
827
828
829
830
831
832
833
834
835
836

837
838
839

840
841
842
843
844
845
846
847

848
849
850
851
852
853

854
855

856
857
858
859
860
861
862
863







-
+











-
+


-
+







-
+





-
+

-
+







** If the virtual table pVtab supports the transaction interface
** (xBegin/xRollback/xCommit and optionally xSync) and a transaction is
** not currently open, invoke the xBegin method now.
**
** If the xBegin call is successful, place the sqlite3_vtab pointer
** in the sqlite3.aVTrans array.
*/
int sqlite3VtabBegin(sqlite3 *db, sqlite3_vtab *pVtab){
int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){
  int rc = SQLITE_OK;
  const sqlite3_module *pModule;

  /* Special case: If db->aVTrans is NULL and db->nVTrans is greater
  ** than zero, then this function is being called from within a
  ** virtual module xSync() callback. It is illegal to write to 
  ** virtual module tables in this case, so return SQLITE_LOCKED.
  */
  if( sqlite3VtabInSync(db) ){
    return SQLITE_LOCKED;
  }
  if( !pVtab ){
  if( !pVTab ){
    return SQLITE_OK;
  } 
  pModule = pVtab->pModule;
  pModule = pVTab->pVtab->pModule;

  if( pModule->xBegin ){
    int i;


    /* If pVtab is already in the aVTrans array, return early */
    for(i=0; i<db->nVTrans; i++){
      if( db->aVTrans[i]==pVtab ){
      if( db->aVTrans[i]==pVTab ){
        return SQLITE_OK;
      }
    }

    /* Invoke the xBegin method */
    rc = pModule->xBegin(pVtab);
    rc = pModule->xBegin(pVTab->pVtab);
    if( rc==SQLITE_OK ){
      rc = addToVTrans(db, pVtab);
      rc = addToVTrans(db, pVTab);
    }
  }
  return rc;
}

/*
** The first parameter (pDef) is a function implementation.  The
797
798
799
800
801
802
803
804

805
806
807
808
809
810
811
891
892
893
894
895
896
897

898
899
900
901
902
903
904
905







-
+








  /* Check to see the left operand is a column in a virtual table */
  if( NEVER(pExpr==0) ) return pDef;
  if( pExpr->op!=TK_COLUMN ) return pDef;
  pTab = pExpr->pTab;
  if( NEVER(pTab==0) ) return pDef;
  if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef;
  pVtab = pTab->pVtab;
  pVtab = sqlite3GetVTable(db, pTab)->pVtab;
  assert( pVtab!=0 );
  assert( pVtab->pModule!=0 );
  pMod = (sqlite3_module *)pVtab->pModule;
  if( pMod->xFindFunction==0 ) return pDef;
 
  /* Call the xFindFunction method on the virtual table implementation
  ** to see if the implementation wants to overload this function 
821
822
823
824
825
826
827
828

829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847

848
849
850
851
852
853


854
855
856


857
858
859


860
861

862
863
864
865
915
916
917
918
919
920
921

922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946


947
948
949


950
951
952


953
954
955

956
957
958
959
960







-
+



















+




-
-
+
+

-
-
+
+

-
-
+
+

-
+




  if( rc==0 ){
    return pDef;
  }

  /* Create a new ephemeral function definition for the overloaded
  ** function */
  pNew = sqlite3DbMallocZero(db, sizeof(*pNew)
                             + sqlite3Strlen30(pDef->zName) );
                             + sqlite3Strlen30(pDef->zName) + 1);
  if( pNew==0 ){
    return pDef;
  }
  *pNew = *pDef;
  pNew->zName = (char *)&pNew[1];
  memcpy(pNew->zName, pDef->zName, sqlite3Strlen30(pDef->zName)+1);
  pNew->xFunc = xFunc;
  pNew->pUserData = pArg;
  pNew->flags |= SQLITE_FUNC_EPHEM;
  return pNew;
}

/*
** Make sure virtual table pTab is contained in the pParse->apVirtualLock[]
** array so that an OP_VBegin will get generated for it.  Add pTab to the
** array if it is missing.  If pTab is already in the array, this routine
** is a no-op.
*/
void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
  Parse *pToplevel = sqlite3ParseToplevel(pParse);
  int i, n;
  Table **apVtabLock;

  assert( IsVirtual(pTab) );
  for(i=0; i<pParse->nVtabLock; i++){
    if( pTab==pParse->apVtabLock[i] ) return;
  for(i=0; i<pToplevel->nVtabLock; i++){
    if( pTab==pToplevel->apVtabLock[i] ) return;
  }
  n = (pParse->nVtabLock+1)*sizeof(pParse->apVtabLock[0]);
  apVtabLock = sqlite3_realloc(pParse->apVtabLock, n);
  n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]);
  apVtabLock = sqlite3_realloc(pToplevel->apVtabLock, n);
  if( apVtabLock ){
    pParse->apVtabLock = apVtabLock;
    pParse->apVtabLock[pParse->nVtabLock++] = pTab;
    pToplevel->apVtabLock = apVtabLock;
    pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
  }else{
    pParse->db->mallocFailed = 1;
    pToplevel->db->mallocFailed = 1;
  }
}

#endif /* SQLITE_OMIT_VIRTUALTABLE */
Changes to src/walker.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20













-
-







/*
** 2008 August 16
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for walking the parser tree for
** an SQL statement.
**
** $Id: walker.c,v 1.7 2009/06/15 23:15:59 drh Exp $
*/
#include "sqliteInt.h"
#include <stdlib.h>
#include <string.h>


/*
Changes to src/where.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
11
12
13
14
15
16
17


18
19
20
21
22
23
24







-
-







*************************************************************************
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  This module is responsible for
** generating the code that loops through a table looking for applicable
** rows.  Indices are selected and used to speed the search when doing
** so is applicable.  Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
** $Id: where.c,v 1.408 2009/06/16 14:15:22 shane Exp $
*/
#include "sqliteInt.h"

/*
** Trace output macros
*/
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
191
192
193
194
195
196
197

198
199
200
201
202
203
204
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203







+







** A WhereCost object records a lookup strategy and the estimated
** cost of pursuing that strategy.
*/
struct WhereCost {
  WherePlan plan;    /* The lookup strategy */
  double rCost;      /* Overall cost of pursuing this search strategy */
  double nRow;       /* Estimated number of output rows */
  Bitmask used;      /* Bitmask of cursors used by this plan */
};

/*
** Bitmasks for the operators that indices are able to exploit.  An
** OR-ed combination of these values can be used when searching for
** terms in the where clause.
*/
620
621
622
623
624
625
626
627

628
629
630
631

632
633
634
635
636
637
638


639
640
641
642
643
644
645
646
647
648
649
650
651
652



653
654

655
656

657
658
659







660
661
662
663
664


















665
666
667
668
669

670


671
672



















673
674


675

676
677
678
679
680
681
682
619
620
621
622
623
624
625

626
627
628
629

630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647




648

649
650
651
652
653
654
655

656

657
658
659
660
661
662
663
664
665
666
667



668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694


695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717

718
719
720
721
722
723
724
725







-
+



-
+







+
+








-
-
-
-

-
+
+
+


+

-
+
-


+
+
+
+
+
+
+


-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+





+

+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
+
-
+







**
** In order for the operator to be optimizible, the RHS must be a string
** literal that does not begin with a wildcard.  
*/
static int isLikeOrGlob(
  Parse *pParse,    /* Parsing and code generating context */
  Expr *pExpr,      /* Test this expression */
  int *pnPattern,   /* Number of non-wildcard prefix characters */
  Expr **ppPrefix,  /* Pointer to TK_STRING expression with pattern prefix */
  int *pisComplete, /* True if the only wildcard is % in the last character */
  int *pnoCase      /* True if uppercase is equivalent to lowercase */
){
  const char *z;             /* String on RHS of LIKE operator */
  const char *z = 0;         /* String on RHS of LIKE operator */
  Expr *pRight, *pLeft;      /* Right and left size of LIKE operator */
  ExprList *pList;           /* List of operands to the LIKE operator */
  int c;                     /* One character in z[] */
  int cnt;                   /* Number of non-wildcard prefix characters */
  char wc[3];                /* Wildcard characters */
  CollSeq *pColl;            /* Collating sequence for LHS */
  sqlite3 *db = pParse->db;  /* Database connection */
  sqlite3_value *pVal = 0;
  int op;                    /* Opcode of pRight */

  if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, wc) ){
    return 0;
  }
#ifdef SQLITE_EBCDIC
  if( *pnoCase ) return 0;
#endif
  pList = pExpr->x.pList;
  pRight = pList->a[0].pExpr;
  if( pRight->op!=TK_STRING ){
    return 0;
  }
  pLeft = pList->a[1].pExpr;
  if( pLeft->op!=TK_COLUMN ){
  if( pLeft->op!=TK_COLUMN || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT ){
    /* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must
    ** be the name of an indexed column with TEXT affinity. */
    return 0;
  }
  assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */
  pColl = sqlite3ExprCollSeq(pParse, pLeft);
  assert( pColl!=0 || pLeft->iColumn==-1 );
  assert( pColl!=0 );  /* Every non-IPK column has a collating sequence */
  if( pColl==0 ) return 0;
  if( (pColl->type!=SQLITE_COLL_BINARY || *pnoCase) &&
      (pColl->type!=SQLITE_COLL_NOCASE || !*pnoCase) ){
    /* IMP: R-09003-32046 For the GLOB operator, the column must use the
    ** default BINARY collating sequence.
    ** IMP: R-41408-28306 For the LIKE operator, if case_sensitive_like mode
    ** is enabled then the column must use the default BINARY collating
    ** sequence, or if case_sensitive_like mode is disabled then the column
    ** must use the built-in NOCASE collating sequence.
    */
    return 0;
  }
  if( sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT ) return 0;
  z = pRight->u.zToken;
  if( ALWAYS(z) ){

  pRight = pList->a[0].pExpr;
  op = pRight->op;
  if( op==TK_REGISTER ){
    op = pRight->op2;
  }
  if( op==TK_VARIABLE ){
    Vdbe *pReprepare = pParse->pReprepare;
    pVal = sqlite3VdbeGetValue(pReprepare, pRight->iColumn, SQLITE_AFF_NONE);
    if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
      z = (char *)sqlite3_value_text(pVal);
    }
    sqlite3VdbeSetVarmask(pParse->pVdbe, pRight->iColumn);
    assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
  }else if( op==TK_STRING ){
    z = pRight->u.zToken;
  }
  if( z ){
    cnt = 0;
    while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
      cnt++;
    }
    if( cnt!=0 && c!=0 && 255!=(u8)z[cnt-1] ){
      Expr *pPrefix;
      *pisComplete = z[cnt]==wc[0] && z[cnt+1]==0;
      pPrefix = sqlite3Expr(db, TK_STRING, z);
      if( pPrefix ) pPrefix->u.zToken[cnt] = 0;
      *pnPattern = cnt;
      return 1;
      *ppPrefix = pPrefix;
      if( op==TK_VARIABLE ){
        Vdbe *v = pParse->pVdbe;
        sqlite3VdbeSetVarmask(v, pRight->iColumn);
        if( *pisComplete && pRight->u.zToken[1] ){
          /* If the rhs of the LIKE expression is a variable, and the current
          ** value of the variable means there is no need to invoke the LIKE
          ** function, then no OP_Variable will be added to the program.
          ** This causes problems for the sqlite3_bind_parameter_name()
          ** API. To workaround them, add a dummy OP_Variable here.
          */ 
          int r1 = sqlite3GetTempReg(pParse);
          sqlite3ExprCodeTarget(pParse, pRight, r1);
          sqlite3VdbeChangeP3(v, sqlite3VdbeCurrentAddr(v)-1, 0);
          sqlite3ReleaseTempReg(pParse, r1);
        }
      }
    }else{
      z = 0;
    }
  }

  sqlite3ValueFree(pVal);
  return 0;
  return (z!=0);
}
#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */


#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Check to see if the given expression is of the form
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059




1060
1061
1062
1063
1064
1065
1066
1092
1093
1094
1095
1096
1097
1098




1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109







-
-
-
-
+
+
+
+







  int idxTerm               /* Index of the term to be analyzed */
){
  WhereTerm *pTerm;                /* The term to be analyzed */
  WhereMaskSet *pMaskSet;          /* Set of table index masks */
  Expr *pExpr;                     /* The expression to be analyzed */
  Bitmask prereqLeft;              /* Prerequesites of the pExpr->pLeft */
  Bitmask prereqAll;               /* Prerequesites of pExpr */
  Bitmask extraRight = 0;
  int nPattern;
  int isComplete;
  int noCase;
  Bitmask extraRight = 0;          /* */
  Expr *pStr1 = 0;                 /* RHS of LIKE/GLOB operator */
  int isComplete = 0;              /* RHS of LIKE/GLOB ends with wildcard */
  int noCase = 0;                  /* LIKE/GLOB distinguishes case */
  int op;                          /* Top-level operator.  pExpr->op */
  Parse *pParse = pWC->pParse;     /* Parsing context */
  sqlite3 *db = pParse->db;        /* Database connection */

  if( db->mallocFailed ){
    return;
  }
1172
1173
1174
1175
1176
1177
1178

1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198









1199
1200
1201
1202
1203
1204
1205
1206
1207

1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236






1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247



1248
1249
1250

1251
1252
1253
1254
1255
1256
1257
1258







+














-
-
-
-
-
-
+
+
+
+
+
+
+
+
+


-
-
-



-
+







#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
  /* Analyze a term that is composed of two or more subterms connected by
  ** an OR operator.
  */
  else if( pExpr->op==TK_OR ){
    assert( pWC->op==TK_AND );
    exprAnalyzeOrTerm(pSrc, pWC, idxTerm);
    pTerm = &pWC->a[idxTerm];
  }
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */

#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION
  /* Add constraints to reduce the search space on a LIKE or GLOB
  ** operator.
  **
  ** A like pattern of the form "x LIKE 'abc%'" is changed into constraints
  **
  **          x>='abc' AND x<'abd' AND x LIKE 'abc%'
  **
  ** The last character of the prefix "abc" is incremented to form the
  ** termination condition "abd".
  */
  if( isLikeOrGlob(pParse, pExpr, &nPattern, &isComplete, &noCase)
         && pWC->op==TK_AND ){
    Expr *pLeft, *pRight;
    Expr *pStr1, *pStr2;
    Expr *pNewExpr1, *pNewExpr2;
    int idxNew1, idxNew2;
  if( pWC->op==TK_AND 
   && isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase)
  ){
    Expr *pLeft;       /* LHS of LIKE/GLOB operator */
    Expr *pStr2;       /* Copy of pStr1 - RHS of LIKE/GLOB operator */
    Expr *pNewExpr1;
    Expr *pNewExpr2;
    int idxNew1;
    int idxNew2;

    pLeft = pExpr->x.pList->a[1].pExpr;
    pRight = pExpr->x.pList->a[0].pExpr;
    pStr1 = sqlite3Expr(db, TK_STRING, pRight->u.zToken);
    if( pStr1 ) pStr1->u.zToken[nPattern] = 0;
    pStr2 = sqlite3ExprDup(db, pStr1, 0);
    if( !db->mallocFailed ){
      u8 c, *pC;       /* Last character before the first wildcard */
      pC = (u8*)&pStr2->u.zToken[nPattern-1];
      pC = (u8*)&pStr2->u.zToken[sqlite3Strlen30(pStr2->u.zToken)-1];
      c = *pC;
      if( noCase ){
        /* The point is to increment the last character before the first
        ** wildcard.  But if we increment '@', that will push it into the
        ** alphabetic range where case conversions will mess up the 
        ** inequality.  To avoid this, make sure to also run the full
        ** LIKE on all candidate expressions by clearing the isComplete flag
1333
1334
1335
1336
1337
1338
1339





1340
1341
1342
1343
1344
1345
1346
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395







+
+
+
+
+







  struct ExprList_item *pTerm;    /* A term of the ORDER BY clause */
  sqlite3 *db = pParse->db;

  assert( pOrderBy!=0 );
  nTerm = pOrderBy->nExpr;
  assert( nTerm>0 );

  /* Argument pIdx must either point to a 'real' named index structure, 
  ** or an index structure allocated on the stack by bestBtreeIndex() to
  ** represent the rowid index that is part of every table.  */
  assert( pIdx->zName || (pIdx->nColumn==1 && pIdx->aiColumn[0]==-1) );

  /* Match terms of the ORDER BY clause against columns of
  ** the index.
  **
  ** Note that indices have pIdx->nColumn regular columns plus
  ** one additional column containing the rowid.  The rowid column
  ** of the index is also allowed to match against the ORDER BY
  ** clause.
1359
1360
1361
1362
1363
1364
1365
1366

1367
1368
1369
1370
1371
1372
1373
1408
1409
1410
1411
1412
1413
1414

1415
1416
1417
1418
1419
1420
1421
1422







-
+







      ** left-most table of the FROM clause */
      break;
    }
    pColl = sqlite3ExprCollSeq(pParse, pExpr);
    if( !pColl ){
      pColl = db->pDfltColl;
    }
    if( i<pIdx->nColumn ){
    if( pIdx->zName && i<pIdx->nColumn ){
      iColumn = pIdx->aiColumn[i];
      if( iColumn==pIdx->pTable->iPKey ){
        iColumn = -1;
      }
      iSortOrder = pIdx->aSortOrder[i];
      zColl = pIdx->azColl[i];
    }else{
1388
1389
1390
1391
1392
1393
1394
1395

1396
1397
1398
1399
1400
1401
1402
1437
1438
1439
1440
1441
1442
1443

1444
1445
1446
1447
1448
1449
1450
1451







-
+







      }else{
        /* If an index column fails to match and is not constrained by ==
        ** then the index cannot satisfy the ORDER BY constraint.
        */
        return 0;
      }
    }
    assert( pIdx->aSortOrder!=0 );
    assert( pIdx->aSortOrder!=0 || iColumn==-1 );
    assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 );
    assert( iSortOrder==0 || iSortOrder==1 );
    termSortOrder = iSortOrder ^ pTerm->sortOrder;
    if( i>nEqCol ){
      if( termSortOrder!=sortOrder ){
        /* Indices can only be used if all ORDER BY terms past the
        ** equality constraints are all either DESC or ASC. */
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1477
1478
1479
1480
1481
1482
1483
























1484
1485
1486
1487
1488
1489
1490







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







      && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){
    /* All terms of this index match some prefix of the ORDER BY clause
    ** and the index is UNIQUE and no terms on the tail of the ORDER BY
    ** clause reference other tables in a join.  If this is all true then
    ** the order by clause is superfluous. */
    return 1;
  }
  return 0;
}

/*
** Check table to see if the ORDER BY clause in pOrderBy can be satisfied
** by sorting in order of ROWID.  Return true if so and set *pbRev to be
** true for reverse ROWID and false for forward ROWID order.
*/
static int sortableByRowid(
  int base,               /* Cursor number for table to be sorted */
  ExprList *pOrderBy,     /* The ORDER BY clause */
  WhereMaskSet *pMaskSet, /* Mapping from table cursors to bitmaps */
  int *pbRev              /* Set to 1 if ORDER BY is DESC */
){
  Expr *p;

  assert( pOrderBy!=0 );
  assert( pOrderBy->nExpr>0 );
  p = pOrderBy->a[0].pExpr;
  if( p->op==TK_COLUMN && p->iTable==base && p->iColumn==-1
    && !referencesOtherTables(pOrderBy, pMaskSet, 1, base) ){
    *pbRev = pOrderBy->a[0].sortOrder;
    return 1;
  }
  return 0;
}

/*
** Prepare a crude estimate of the logarithm of the input value.
** The results need not be exact.  This is only used for estimating
** the total cost of performing operations with O(logN) or O(NlogN)
1555
1556
1557
1558
1559
1560
1561

1562
1563
1564
1565
1566
1567
1568
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594







+







    ){
      WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
      WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];
      WhereTerm *pOrTerm;
      int flags = WHERE_MULTI_OR;
      double rTotal = 0;
      double nRow = 0;
      Bitmask used = 0;

      for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
        WhereCost sTermCost;
        WHERETRACE(("... Multi-index OR testing for term %d of %d....\n", 
          (pOrTerm - pOrWC->a), (pTerm - pWC->a)
        ));
        if( pOrTerm->eOperator==WO_AND ){
1577
1578
1579
1580
1581
1582
1583

1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600

1601
1602
1603
1604
1605
1606
1607
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635







+

















+







          tempWC.nTerm = 1;
          bestIndex(pParse, &tempWC, pSrc, notReady, 0, &sTermCost);
        }else{
          continue;
        }
        rTotal += sTermCost.rCost;
        nRow += sTermCost.nRow;
        used |= sTermCost.used;
        if( rTotal>=pCost->rCost ) break;
      }

      /* If there is an ORDER BY clause, increase the scan cost to account 
      ** for the cost of the sort. */
      if( pOrderBy!=0 ){
        rTotal += nRow*estLog(nRow);
        WHERETRACE(("... sorting increases OR cost to %.9g\n", rTotal));
      }

      /* If the cost of scanning using this OR term for optimization is
      ** less than the current cost stored in pCost, replace the contents
      ** of pCost. */
      WHERETRACE(("... multi-index OR cost=%.9g nrow=%.9g\n", rTotal, nRow));
      if( rTotal<pCost->rCost ){
        pCost->rCost = rTotal;
        pCost->nRow = nRow;
        pCost->used = used;
        pCost->plan.wsFlags = flags;
        pCost->plan.u.pTerm = pTerm;
      }
    }
  }
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
}
1722
1723
1724
1725
1726
1727
1728
1729

1730
1731
1732
1733
1734
1735
1736
1750
1751
1752
1753
1754
1755
1756

1757
1758
1759
1760
1761
1762
1763
1764







-
+







** part of the sqlite3_index_info structure is left populated.
**
** Whether or not an error is returned, it is the responsibility of the
** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates
** that this is required.
*/
static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
  sqlite3_vtab *pVtab = pTab->pVtab;
  sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab;
  int i;
  int rc;

  (void)sqlite3SafetyOff(pParse->db);
  WHERETRACE(("xBestIndex for %s\n", pTab->zName));
  TRACE_IDX_INPUTS(p);
  rc = pVtab->pModule->xBestIndex(pVtab, p);
1819
1820
1821
1822
1823
1824
1825
1826

1827
1828
1829
1830
1831
1832
1833
1847
1848
1849
1850
1851
1852
1853

1854
1855
1856
1857
1858
1859
1860
1861







-
+







  */

  /* The module name must be defined. Also, by this point there must
  ** be a pointer to an sqlite3_vtab structure. Otherwise
  ** sqlite3ViewGetColumnNames() would have picked up the error. 
  */
  assert( pTab->azModuleArg && pTab->azModuleArg[0] );
  assert( pTab->pVtab );
  assert( sqlite3GetVTable(pParse->db, pTab) );

  /* Set the aConstraint[].usable fields and initialize all 
  ** output variables to zero.
  **
  ** aConstraint[].usable is true for constraints where the right-hand
  ** side contains only references to tables to the left of the current
  ** table.  In other words, if the constraint is of the form:
1846
1847
1848
1849
1850
1851
1852
1853

1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872







1873
1874
1875
1876
1877
1878
1879
1874
1875
1876
1877
1878
1879
1880

1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914







-
+



















+
+
+
+
+
+
+







  ** each time.
  */
  pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
  pUsage = pIdxInfo->aConstraintUsage;
  for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
    j = pIdxCons->iTermOffset;
    pTerm = &pWC->a[j];
    pIdxCons->usable =  (pTerm->prereqRight & notReady)==0 ?1:0;
    pIdxCons->usable = (pTerm->prereqRight&notReady) ? 0 : 1;
  }
  memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
  if( pIdxInfo->needToFreeIdxStr ){
    sqlite3_free(pIdxInfo->idxStr);
  }
  pIdxInfo->idxStr = 0;
  pIdxInfo->idxNum = 0;
  pIdxInfo->needToFreeIdxStr = 0;
  pIdxInfo->orderByConsumed = 0;
  /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */
  pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2);
  nOrderBy = pIdxInfo->nOrderBy;
  if( !pOrderBy ){
    pIdxInfo->nOrderBy = 0;
  }

  if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
    return;
  }

  pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
  for(i=0; i<pIdxInfo->nConstraint; i++){
    if( pUsage[i].argvIndex>0 ){
      pCost->used |= pWC->a[pIdxCons[i].iTermOffset].prereqRight;
    }
  }

  /* The cost is not allowed to be larger than SQLITE_BIG_DBL (the
  ** inital value of lowestCost in this loop. If it is, then the
  ** (cost<lowestCost) test below will never be true.
  ** 
  ** Use "(double)2" instead of "2.0" in case OMIT_FLOATING_POINT 
  ** is defined.
1892
1893
1894
1895
1896
1897
1898





















































































































































































































































1899
1900
1901
1902
1903
1904
1905
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








  /* Try to find a more efficient access pattern by using multiple indexes
  ** to optimize an OR expression within the WHERE clause. 
  */
  bestOrClauseIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost);
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

/*
** Argument pIdx is a pointer to an index structure that has an array of
** SQLITE_INDEX_SAMPLES evenly spaced samples of the first indexed column
** stored in Index.aSample. The domain of values stored in said column
** may be thought of as divided into (SQLITE_INDEX_SAMPLES+1) regions.
** Region 0 contains all values smaller than the first sample value. Region
** 1 contains values larger than or equal to the value of the first sample,
** but smaller than the value of the second. And so on.
**
** If successful, this function determines which of the regions value 
** pVal lies in, sets *piRegion to the region index (a value between 0
** and SQLITE_INDEX_SAMPLES+1, inclusive) and returns SQLITE_OK.
** Or, if an OOM occurs while converting text values between encodings,
** SQLITE_NOMEM is returned and *piRegion is undefined.
*/
#ifdef SQLITE_ENABLE_STAT2
static int whereRangeRegion(
  Parse *pParse,              /* Database connection */
  Index *pIdx,                /* Index to consider domain of */
  sqlite3_value *pVal,        /* Value to consider */
  int *piRegion               /* OUT: Region of domain in which value lies */
){
  if( ALWAYS(pVal) ){
    IndexSample *aSample = pIdx->aSample;
    int i = 0;
    int eType = sqlite3_value_type(pVal);

    if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
      double r = sqlite3_value_double(pVal);
      for(i=0; i<SQLITE_INDEX_SAMPLES; i++){
        if( aSample[i].eType==SQLITE_NULL ) continue;
        if( aSample[i].eType>=SQLITE_TEXT || aSample[i].u.r>r ) break;
      }
    }else{ 
      sqlite3 *db = pParse->db;
      CollSeq *pColl;
      const u8 *z;
      int n;

      /* pVal comes from sqlite3ValueFromExpr() so the type cannot be NULL */
      assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );

      if( eType==SQLITE_BLOB ){
        z = (const u8 *)sqlite3_value_blob(pVal);
        pColl = db->pDfltColl;
        assert( pColl->enc==SQLITE_UTF8 );
      }else{
        pColl = sqlite3GetCollSeq(db, SQLITE_UTF8, 0, *pIdx->azColl);
        if( pColl==0 ){
          sqlite3ErrorMsg(pParse, "no such collation sequence: %s",
                          *pIdx->azColl);
          return SQLITE_ERROR;
        }
        z = (const u8 *)sqlite3ValueText(pVal, pColl->enc);
        if( !z ){
          return SQLITE_NOMEM;
        }
        assert( z && pColl && pColl->xCmp );
      }
      n = sqlite3ValueBytes(pVal, pColl->enc);

      for(i=0; i<SQLITE_INDEX_SAMPLES; i++){
        int r;
        int eSampletype = aSample[i].eType;
        if( eSampletype==SQLITE_NULL || eSampletype<eType ) continue;
        if( (eSampletype!=eType) ) break;
#ifndef SQLITE_OMIT_UTF16
        if( pColl->enc!=SQLITE_UTF8 ){
          int nSample;
          char *zSample = sqlite3Utf8to16(
              db, pColl->enc, aSample[i].u.z, aSample[i].nByte, &nSample
          );
          if( !zSample ){
            assert( db->mallocFailed );
            return SQLITE_NOMEM;
          }
          r = pColl->xCmp(pColl->pUser, nSample, zSample, n, z);
          sqlite3DbFree(db, zSample);
        }else
#endif
        {
          r = pColl->xCmp(pColl->pUser, aSample[i].nByte, aSample[i].u.z, n, z);
        }
        if( r>0 ) break;
      }
    }

    assert( i>=0 && i<=SQLITE_INDEX_SAMPLES );
    *piRegion = i;
  }
  return SQLITE_OK;
}
#endif   /* #ifdef SQLITE_ENABLE_STAT2 */

/*
** If expression pExpr represents a literal value, set *pp to point to
** an sqlite3_value structure containing the same value, with affinity
** aff applied to it, before returning. It is the responsibility of the 
** caller to eventually release this structure by passing it to 
** sqlite3ValueFree().
**
** If the current parse is a recompile (sqlite3Reprepare()) and pExpr
** is an SQL variable that currently has a non-NULL value bound to it,
** create an sqlite3_value structure containing this value, again with
** affinity aff applied to it, instead.
**
** If neither of the above apply, set *pp to NULL.
**
** If an error occurs, return an error code. Otherwise, SQLITE_OK.
*/
#ifdef SQLITE_ENABLE_STAT2
static int valueFromExpr(
  Parse *pParse, 
  Expr *pExpr, 
  u8 aff, 
  sqlite3_value **pp
){
  /* The evalConstExpr() function will have already converted any TK_VARIABLE
  ** expression involved in an comparison into a TK_REGISTER. */
  assert( pExpr->op!=TK_VARIABLE );
  if( pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE ){
    int iVar = pExpr->iColumn;
    sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
    *pp = sqlite3VdbeGetValue(pParse->pReprepare, iVar, aff);
    return SQLITE_OK;
  }
  return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp);
}
#endif

/*
** This function is used to estimate the number of rows that will be visited
** by scanning an index for a range of values. The range may have an upper
** bound, a lower bound, or both. The WHERE clause terms that set the upper
** and lower bounds are represented by pLower and pUpper respectively. For
** example, assuming that index p is on t1(a):
**
**   ... FROM t1 WHERE a > ? AND a < ? ...
**                    |_____|   |_____|
**                       |         |
**                     pLower    pUpper
**
** If either of the upper or lower bound is not present, then NULL is passed in
** place of the corresponding WhereTerm.
**
** The nEq parameter is passed the index of the index column subject to the
** range constraint. Or, equivalently, the number of equality constraints
** optimized by the proposed index scan. For example, assuming index p is
** on t1(a, b), and the SQL query is:
**
**   ... FROM t1 WHERE a = ? AND b > ? AND b < ? ...
**
** then nEq should be passed the value 1 (as the range restricted column,
** b, is the second left-most column of the index). Or, if the query is:
**
**   ... FROM t1 WHERE a > ? AND a < ? ...
**
** then nEq should be passed 0.
**
** The returned value is an integer between 1 and 100, inclusive. A return
** value of 1 indicates that the proposed range scan is expected to visit
** approximately 1/100th (1%) of the rows selected by the nEq equality
** constraints (if any). A return value of 100 indicates that it is expected
** that the range scan will visit every row (100%) selected by the equality
** constraints.
**
** In the absence of sqlite_stat2 ANALYZE data, each range inequality
** reduces the search space by 2/3rds.  Hence a single constraint (x>?)
** results in a return of 33 and a range constraint (x>? AND x<?) results
** in a return of 11.
*/
static int whereRangeScanEst(
  Parse *pParse,       /* Parsing & code generating context */
  Index *p,            /* The index containing the range-compared column; "x" */
  int nEq,             /* index into p->aCol[] of the range-compared column */
  WhereTerm *pLower,   /* Lower bound on the range. ex: "x>123" Might be NULL */
  WhereTerm *pUpper,   /* Upper bound on the range. ex: "x<455" Might be NULL */
  int *piEst           /* OUT: Return value */
){
  int rc = SQLITE_OK;

#ifdef SQLITE_ENABLE_STAT2

  if( nEq==0 && p->aSample ){
    sqlite3_value *pLowerVal = 0;
    sqlite3_value *pUpperVal = 0;
    int iEst;
    int iLower = 0;
    int iUpper = SQLITE_INDEX_SAMPLES;
    u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity;

    if( pLower ){
      Expr *pExpr = pLower->pExpr->pRight;
      rc = valueFromExpr(pParse, pExpr, aff, &pLowerVal);
    }
    if( rc==SQLITE_OK && pUpper ){
      Expr *pExpr = pUpper->pExpr->pRight;
      rc = valueFromExpr(pParse, pExpr, aff, &pUpperVal);
    }

    if( rc!=SQLITE_OK || (pLowerVal==0 && pUpperVal==0) ){
      sqlite3ValueFree(pLowerVal);
      sqlite3ValueFree(pUpperVal);
      goto range_est_fallback;
    }else if( pLowerVal==0 ){
      rc = whereRangeRegion(pParse, p, pUpperVal, &iUpper);
      if( pLower ) iLower = iUpper/2;
    }else if( pUpperVal==0 ){
      rc = whereRangeRegion(pParse, p, pLowerVal, &iLower);
      if( pUpper ) iUpper = (iLower + SQLITE_INDEX_SAMPLES + 1)/2;
    }else{
      rc = whereRangeRegion(pParse, p, pUpperVal, &iUpper);
      if( rc==SQLITE_OK ){
        rc = whereRangeRegion(pParse, p, pLowerVal, &iLower);
      }
    }

    iEst = iUpper - iLower;
    testcase( iEst==SQLITE_INDEX_SAMPLES );
    assert( iEst<=SQLITE_INDEX_SAMPLES );
    if( iEst<1 ){
      iEst = 1;
    }

    sqlite3ValueFree(pLowerVal);
    sqlite3ValueFree(pUpperVal);
    *piEst = (iEst * 100)/SQLITE_INDEX_SAMPLES;
    return rc;
  }
range_est_fallback:
#else
  UNUSED_PARAMETER(pParse);
  UNUSED_PARAMETER(p);
  UNUSED_PARAMETER(nEq);
#endif
  assert( pLower || pUpper );
  if( pLower && pUpper ){
    *piEst = 11;
  }else{
    *piEst = 33;
  }
  return rc;
}


/*
** Find the query plan for accessing a particular table.  Write the
** best query plan and its cost into the WhereCost object supplied as the
** last parameter.
**
** The lowest cost plan wins.  The cost is an estimate of the amount of
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943




1944
1945
1946



1947
1948
1949
1950
1951
1952


1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069


2070
2071

2072
2073
2074
2075
2076

2077
2078


















2079
2080
2081
2082
2083
2084
2085
2086




























2087
2088
2089
2090






2091
2092


















































2093

2094
2095
2096
2097











2098
2099

2100
2101
2102
2103
2104
2105


2106
2107

2108
2109
2110
2111

2112
2113

2114
2115

2116
2117
2118
2119
2120










2121
2122
2123







2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140



2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155

2156
2157
2158
2159
2160

2161
2162
2163
2164
2165

2166
2167

2168
2169
2170

2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183


2184
2185




2186
2187
2188
2189


2190
2191
2192
2193
2194
2195







































2196

2197
2198
2199









2200
2201


2202
2203

2204
2205

2206

2207
2208
2209

2210

















2211
2212
2213

2214
2215
2216
2217
2218
2219












2220
2221
2222
2223
2224
2225
2226
2209
2210
2211
2212
2213
2214
2215

2216
2217





2218
2219
2220
2221



2222
2223
2224






2225
2226






2227












2228
2229

























































































2230
2231
2232
2233
2234


2235
2236
2237

2238
2239
2240


2241
2242


2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260








2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288




2289
2290
2291
2292
2293
2294


2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346




2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358

2359
2360
2361
2362
2363


2364
2365
2366

2367
2368
2369
2370
2371
2372
2373

2374


2375





2376
2377
2378
2379
2380
2381
2382
2383
2384
2385



2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398


2399








2400
2401
2402















2403


2404
2405

2406
2407




2408


2409

2410

2411

2412






2413
2414



2415
2416


2417
2418
2419
2420
2421
2422


2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469

2470



2471
2472
2473
2474
2475
2476
2477
2478
2479
2480

2481
2482
2483

2484
2485
2486
2487

2488
2489


2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510

2511






2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530







-


-
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-





-
-
+
+

-
+


-
-

+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+

-
+




-
-
+
+

-
+




+

-
+
-
-
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+






-
-

-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-


-
+

-
-
-
-
+
-
-
+
-

-
+
-

-
-
-
-
-
-


-
-
-
+
+
-
-
+
+
+
+


-
-
+
+






+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
+
+
+
+
+
+
+
+
+

-
+
+

-
+


+
-
+

-
-
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+







  Parse *pParse,              /* The parsing context */
  WhereClause *pWC,           /* The WHERE clause */
  struct SrcList_item *pSrc,  /* The FROM clause term to search */
  Bitmask notReady,           /* Mask of cursors that are not available */
  ExprList *pOrderBy,         /* The ORDER BY clause */
  WhereCost *pCost            /* Lowest cost query plan */
){
  WhereTerm *pTerm;           /* A single term of the WHERE clause */
  int iCur = pSrc->iCursor;   /* The cursor of the table to be accessed */
  Index *pProbe;              /* An index we are evaluating */
  int rev;                    /* True to scan in reverse order */
  int wsFlags;                /* Flags associated with pProbe */
  int nEq;                    /* Number of == or IN constraints */
  int eqTermMask;             /* Mask of valid equality operators */
  double cost;                /* Cost of using pProbe */
  Index *pIdx;                /* Copy of pProbe, or zero for IPK index */
  int eqTermMask;             /* Current mask of valid equality operators */
  int idxEqTermMask;          /* Index mask of valid equality operators */
  Index sPk;                  /* A fake index object for the primary key */
  double nRow;                /* Estimated number of rows in result set */
  int i;                      /* Loop counter */

  unsigned int aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */
  int aiColumnPk = -1;        /* The aColumn[] value for the sPk index */
  int wsFlagMask;             /* Allowed flags in pCost->plan.wsFlag */
  WHERETRACE(("bestIndex: tbl=%s notReady=%llx\n", pSrc->pTab->zName,notReady));
  pProbe = pSrc->pTab->pIndex;
  if( pSrc->notIndexed ){
    pProbe = 0;
  }


  /* Initialize the cost to a worst-case value */
  /* If the table has no indices and there are no terms in the where
  ** clause that refer to the ROWID, then we will never be able to do
  ** anything other than a full table scan on this table.  We might as
  ** well put it first in the join order.  That way, perhaps it can be
  ** referenced by other tables in the join.
  */
  memset(pCost, 0, sizeof(*pCost));
  if( pProbe==0 &&
     findTerm(pWC, iCur, -1, 0, WO_EQ|WO_IN|WO_LT|WO_LE|WO_GT|WO_GE,0)==0 &&
     (pOrderBy==0 || !sortableByRowid(iCur, pOrderBy, pWC->pMaskSet, &rev)) ){
     if( pParse->db->flags & SQLITE_ReverseOrder ){
      /* For application testing, randomly reverse the output order for
      ** SELECT statements that omit the ORDER BY clause.  This will help
      ** to find cases where
      */
      pCost->plan.wsFlags |= WHERE_REVERSE;
    }
    return;
  }
  pCost->rCost = SQLITE_BIG_DBL;

  /* Check for a rowid=EXPR or rowid IN (...) constraints. If there was
  ** an INDEXED BY clause attached to this table, skip this step.
  */
  if( !pSrc->pIndex ){
    pTerm = findTerm(pWC, iCur, -1, notReady, WO_EQ|WO_IN, 0);
    if( pTerm ){
      Expr *pExpr;
      pCost->plan.wsFlags = WHERE_ROWID_EQ;
      if( pTerm->eOperator & WO_EQ ){
        /* Rowid== is always the best pick.  Look no further.  Because only
        ** a single row is generated, output is always in sorted order */
        pCost->plan.wsFlags = WHERE_ROWID_EQ | WHERE_UNIQUE;
        pCost->plan.nEq = 1;
        WHERETRACE(("... best is rowid\n"));
        pCost->rCost = 0;
        pCost->nRow = 1;
        return;
      }else if( !ExprHasProperty((pExpr = pTerm->pExpr), EP_xIsSelect) 
             && pExpr->x.pList 
      ){
        /* Rowid IN (LIST): cost is NlogN where N is the number of list
        ** elements.  */
        pCost->rCost = pCost->nRow = pExpr->x.pList->nExpr;
        pCost->rCost *= estLog(pCost->rCost);
      }else{
        /* Rowid IN (SELECT): cost is NlogN where N is the number of rows
        ** in the result of the inner select.  We have no way to estimate
        ** that value so make a wild guess. */
        pCost->nRow = 100;
        pCost->rCost = 200;
      }
      WHERETRACE(("... rowid IN cost: %.9g\n", pCost->rCost));
    }
  
    /* Estimate the cost of a table scan.  If we do not know how many
    ** entries are in the table, use 1 million as a guess.
    */
    cost = pProbe ? pProbe->aiRowEst[0] : 1000000;
    WHERETRACE(("... table scan base cost: %.9g\n", cost));
    wsFlags = WHERE_ROWID_RANGE;
  
    /* Check for constraints on a range of rowids in a table scan.
    */
    pTerm = findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE|WO_GT|WO_GE, 0);
    if( pTerm ){
      if( findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE, 0) ){
        wsFlags |= WHERE_TOP_LIMIT;
        cost /= 3;  /* Guess that rowid<EXPR eliminates two-thirds of rows */
      }
      if( findTerm(pWC, iCur, -1, notReady, WO_GT|WO_GE, 0) ){
        wsFlags |= WHERE_BTM_LIMIT;
        cost /= 3;  /* Guess that rowid>EXPR eliminates two-thirds of rows */
      }
      WHERETRACE(("... rowid range reduces cost to %.9g\n", cost));
    }else{
      wsFlags = 0;
    }
    nRow = cost;
  
    /* If the table scan does not satisfy the ORDER BY clause, increase
    ** the cost by NlogN to cover the expense of sorting. */
    if( pOrderBy ){
      if( sortableByRowid(iCur, pOrderBy, pWC->pMaskSet, &rev) ){
        wsFlags |= WHERE_ORDERBY|WHERE_ROWID_RANGE;
        if( rev ){
          wsFlags |= WHERE_REVERSE;
        }
      }else{
        cost += cost*estLog(cost);
        WHERETRACE(("... sorting increases cost to %.9g\n", cost));
      }
    }else if( pParse->db->flags & SQLITE_ReverseOrder ){
      /* For application testing, randomly reverse the output order for
      ** SELECT statements that omit the ORDER BY clause.  This will help
      ** to find cases where
      */
      wsFlags |= WHERE_REVERSE;
    }

    /* Remember this case if it is the best so far */
    if( cost<pCost->rCost ){
      pCost->rCost = cost;
      pCost->nRow = nRow;
      pCost->plan.wsFlags = wsFlags;
    }
  }

  bestOrClauseIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost);

  /* If the pSrc table is the right table of a LEFT JOIN then we may not
  ** use an index to satisfy IS NULL constraints on that table.  This is
  ** because columns might end up being NULL if the table does not match -
  ** a circumstance which the index cannot help us discover.  Ticket #2177.
  */
  if( (pSrc->jointype & JT_LEFT)!=0 ){
    eqTermMask = WO_EQ|WO_IN;
  if( pSrc->jointype & JT_LEFT ){
    idxEqTermMask = WO_EQ|WO_IN;
  }else{
    eqTermMask = WO_EQ|WO_IN|WO_ISNULL;
    idxEqTermMask = WO_EQ|WO_IN|WO_ISNULL;
  }

  /* Look at each index.
  */
  if( pSrc->pIndex ){
    /* An INDEXED BY clause specifies a particular index to use */
    pProbe = pSrc->pIndex;
  }
    pIdx = pProbe = pSrc->pIndex;
    wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE);
    eqTermMask = idxEqTermMask;
  }else{
    /* There is no INDEXED BY clause.  Create a fake Index object to
    ** represent the primary key */
    Index *pFirst;                /* Any other index on the table */
    memset(&sPk, 0, sizeof(Index));
    sPk.nColumn = 1;
    sPk.aiColumn = &aiColumnPk;
    sPk.aiRowEst = aiRowEstPk;
    aiRowEstPk[1] = 1;
    sPk.onError = OE_Replace;
    sPk.pTable = pSrc->pTab;
    pFirst = pSrc->pTab->pIndex;
    if( pSrc->notIndexed==0 ){
      sPk.pNext = pFirst;
    }
  for(; pProbe; pProbe=(pSrc->pIndex ? 0 : pProbe->pNext)){
    double inMultiplier = 1;  /* Number of equality look-ups needed */
    int inMultIsEst = 0;      /* True if inMultiplier is an estimate */

    WHERETRACE(("... index %s:\n", pProbe->zName));

    /* Count the number of columns in the index that are satisfied
    ** by x=EXPR or x IS NULL constraints or x IN (...) constraints.
    /* The aiRowEstPk[0] is an estimate of the total number of rows in the
    ** table.  Get this information from the ANALYZE information if it is
    ** available.  If not available, assume the table 1 million rows in size.
    */
    if( pFirst ){
      assert( pFirst->aiRowEst!=0 ); /* Allocated together with pFirst */
      aiRowEstPk[0] = pFirst->aiRowEst[0];
    }else{
      aiRowEstPk[0] = 1000000;
    }
    pProbe = &sPk;
    wsFlagMask = ~(
        WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE
    );
    eqTermMask = WO_EQ|WO_IN;
    pIdx = 0;
  }

  /* Loop over all indices looking for the best one to use
  */
  for(; pProbe; pIdx=pProbe=pProbe->pNext){
    const unsigned int * const aiRowEst = pProbe->aiRowEst;
    double cost;                /* Cost of using pProbe */
    double nRow;                /* Estimated number of rows in result set */
    int rev;                    /* True to scan in reverse order */
    int wsFlags = 0;
    Bitmask used = 0;

    ** For a term of the form x=EXPR or x IS NULL we only have to do 
    ** a single binary search.  But for x IN (...) we have to do a
    ** number of binary searched
    ** equal to the number of entries on the RHS of the IN operator.
    /* The following variables are populated based on the properties of
    ** scan being evaluated. They are then used to determine the expected
    ** cost and number of rows returned.
    **
    **  nEq: 
    **    Number of equality terms that can be implemented using the index.
    ** The inMultipler variable with try to estimate the number of
    ** binary searches needed.
    **
    **  nInMul:  
    **    The "in-multiplier". This is an estimate of how many seek operations 
    **    SQLite must perform on the index in question. For example, if the 
    **    WHERE clause is:
    **
    **      WHERE a IN (1, 2, 3) AND b IN (4, 5, 6)
    **
    **    SQLite must perform 9 lookups on an index on (a, b), so nInMul is 
    **    set to 9. Given the same schema and either of the following WHERE 
    **    clauses:
    **
    **      WHERE a =  1
    **      WHERE a >= 2
    **
    **    nInMul is set to 1.
    **
    **    If there exists a WHERE term of the form "x IN (SELECT ...)", then 
    **    the sub-select is assumed to return 25 rows for the purposes of 
    **    determining nInMul.
    **
    **  bInEst:  
    **    Set to true if there was at least one "x IN (SELECT ...)" term used 
    **    in determining the value of nInMul.
    **
    **  nBound:
    **    An estimate on the amount of the table that must be searched.  A
    **    value of 100 means the entire table is searched.  Range constraints
    **    might reduce this to a value less than 100 to indicate that only
    **    a fraction of the table needs searching.  In the absence of
    **    sqlite_stat2 ANALYZE data, a single inequality reduces the search
    **    space to 1/3rd its original size.  So an x>? constraint reduces
    **    nBound to 33.  Two constraints (x>? AND x<?) reduce nBound to 11.
    **
    **  bSort:   
    **    Boolean. True if there is an ORDER BY clause that will require an 
    **    external sort (i.e. scanning the index being evaluated will not 
    **    correctly order records).
    **
    **  bLookup: 
    **    Boolean. True if for each index entry visited a lookup on the 
    **    corresponding table b-tree is required. This is always false 
    **    for the rowid index. For other indexes, it is true unless all the 
    **    columns of the table used by the SELECT statement are present in 
    **    the index (such an index is sometimes described as a covering index).
    **    For example, given the index on (a, b), the second of the following 
    **    two queries requires table b-tree lookups, but the first does not.
    **
    **             SELECT a, b    FROM tbl WHERE a = 1;
    **             SELECT a, b, c FROM tbl WHERE a = 1;
    */
    int nEq;
    wsFlags = 0;
    for(i=0; i<pProbe->nColumn; i++){
      int j = pProbe->aiColumn[i];
      pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pProbe);
    int bInEst = 0;
    int nInMul = 1;
    int nBound = 100;
    int bSort = 0;
    int bLookup = 0;

    /* Determine the values of nEq and nInMul */
    for(nEq=0; nEq<pProbe->nColumn; nEq++){
      WhereTerm *pTerm;           /* A single term of the WHERE clause */
      int j = pProbe->aiColumn[nEq];
      pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pIdx);
      if( pTerm==0 ) break;
      wsFlags |= WHERE_COLUMN_EQ;
      wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ);
      if( pTerm->eOperator & WO_IN ){
        Expr *pExpr = pTerm->pExpr;
        wsFlags |= WHERE_COLUMN_IN;
        if( ExprHasProperty(pExpr, EP_xIsSelect) ){
          inMultiplier *= 25;
          inMultIsEst = 1;
          nInMul *= 25;
          bInEst = 1;
        }else if( pExpr->x.pList ){
          inMultiplier *= pExpr->x.pList->nExpr + 1;
          nInMul *= pExpr->x.pList->nExpr + 1;
        }
      }else if( pTerm->eOperator & WO_ISNULL ){
        wsFlags |= WHERE_COLUMN_NULL;
      }
      used |= pTerm->prereqRight;
    }
    nRow = pProbe->aiRowEst[i] * inMultiplier;

    /* If inMultiplier is an estimate and that estimate results in an
    ** nRow it that is more than half number of rows in the table,
    /* Determine the value of nBound. */
    ** then reduce inMultipler */
    if( inMultIsEst && nRow*2 > pProbe->aiRowEst[0] ){
      nRow = pProbe->aiRowEst[0]/2;
      inMultiplier = nRow/pProbe->aiRowEst[i];
    }
    if( nEq<pProbe->nColumn ){
      int j = pProbe->aiColumn[nEq];
      if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){
        WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx);
        WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx);
        whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &nBound);
        if( pTop ){
          wsFlags |= WHERE_TOP_LIMIT;
          used |= pTop->prereqRight;
        }
    cost = nRow + inMultiplier*estLog(pProbe->aiRowEst[0]);
    nEq = i;
    if( pProbe->onError!=OE_None && nEq==pProbe->nColumn ){
        if( pBtm ){
          wsFlags |= WHERE_BTM_LIMIT;
          used |= pBtm->prereqRight;
        }
        wsFlags |= (WHERE_COLUMN_RANGE|WHERE_ROWID_RANGE);
      }
    }else if( pProbe->onError!=OE_None ){
      testcase( wsFlags & WHERE_COLUMN_IN );
      testcase( wsFlags & WHERE_COLUMN_NULL );
      if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){
        wsFlags |= WHERE_UNIQUE;
      }
    }
    WHERETRACE(("...... nEq=%d inMult=%.9g nRow=%.9g cost=%.9g\n",
                nEq, inMultiplier, nRow, cost));

    /* Look for range constraints.  Assume that each range constraint
    ** makes the search space 1/3rd smaller.
    */
    if( nEq<pProbe->nColumn ){
      int j = pProbe->aiColumn[nEq];
      pTerm = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pProbe);
      if( pTerm ){
        wsFlags |= WHERE_COLUMN_RANGE;
    /* If there is an ORDER BY clause and the index being considered will
    ** naturally scan rows in the required order, set the appropriate flags
    ** in wsFlags. Otherwise, if there is an ORDER BY clause but the index
        if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pProbe) ){
          wsFlags |= WHERE_TOP_LIMIT;
          cost /= 3;
          nRow /= 3;
        }
        if( findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pProbe) ){
          wsFlags |= WHERE_BTM_LIMIT;
          cost /= 3;
          nRow /= 3;
        }
        WHERETRACE(("...... range reduces nRow to %.9g and cost to %.9g\n",
                    nRow, cost));
      }
    }

    ** will scan rows in a different order, set the bSort variable.  */
    /* Add the additional cost of sorting if that is a factor.
    */
    if( pOrderBy ){
      if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0
       && isSortingIndex(pParse,pWC->pMaskSet,pProbe,iCur,pOrderBy,nEq,&rev)
        && isSortingIndex(pParse,pWC->pMaskSet,pProbe,iCur,pOrderBy,nEq,&rev)
      ){
        if( wsFlags==0 ){
          wsFlags = WHERE_COLUMN_RANGE;
        }
        wsFlags |= WHERE_ORDERBY;
        wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY;
        if( rev ){
          wsFlags |= WHERE_REVERSE;
        wsFlags |= (rev ? WHERE_REVERSE : 0);
        }
      }else{
        cost += cost*estLog(cost);
        bSort = 1;
        WHERETRACE(("...... orderby increases cost to %.9g\n", cost));
      }
    }else if( wsFlags!=0 && (pParse->db->flags & SQLITE_ReverseOrder)!=0 ){
      /* For application testing, randomly reverse the output order for
      ** SELECT statements that omit the ORDER BY clause.  This will help
      ** to find cases where
      */
      wsFlags |= WHERE_REVERSE;
    }

    /* Check to see if we can get away with using just the index without
    ** ever reading the table.  If that is the case, then halve the
    ** cost of this index.
    /* If currently calculating the cost of using an index (not the IPK
    ** index), determine if all required column data may be obtained without 
    */
    if( wsFlags && pSrc->colUsed < (((Bitmask)1)<<(BMS-1)) ){
    ** seeking to entries in the main table (i.e. if the index is a covering
    ** index for this query). If it is, set the WHERE_IDX_ONLY flag in
    ** wsFlags. Otherwise, set the bLookup variable to true.  */
    if( pIdx && wsFlags ){
      Bitmask m = pSrc->colUsed;
      int j;
      for(j=0; j<pProbe->nColumn; j++){
        int x = pProbe->aiColumn[j];
      for(j=0; j<pIdx->nColumn; j++){
        int x = pIdx->aiColumn[j];
        if( x<BMS-1 ){
          m &= ~(((Bitmask)1)<<x);
        }
      }
      if( m==0 ){
        wsFlags |= WHERE_IDX_ONLY;
      }else{
        bLookup = 1;
      }
    }

    /**** Begin adding up the cost of using this index (Needs improvements)
    **
    ** Estimate the number of rows of output.  For an IN operator,
    ** do not let the estimate exceed half the rows in the table.
    */
    nRow = (double)(aiRowEst[nEq] * nInMul);
    if( bInEst && nRow*2>aiRowEst[0] ){
      nRow = aiRowEst[0]/2;
      nInMul = (int)(nRow / aiRowEst[nEq]);
    }

    /* Assume constant cost to access a row and logarithmic cost to
    ** do a binary search.  Hence, the initial cost is the number of output
    ** rows plus log2(table-size) times the number of binary searches.
    */
    cost = nRow + nInMul*estLog(aiRowEst[0]);

    /* Adjust the number of rows and the cost downward to reflect rows
    ** that are excluded by range constraints.
    */
    nRow = (nRow * (double)nBound) / (double)100;
    cost = (cost * (double)nBound) / (double)100;

    /* Add in the estimated cost of sorting the result
    */
    if( bSort ){
      cost += cost*estLog(cost);
    }

    /* If all information can be taken directly from the index, we avoid
    ** doing table lookups.  This reduces the cost by half.  (Not really -
    ** this needs to be fixed.)
    */
    if( pIdx && bLookup==0 ){
        cost /= 2;
      cost /= (double)2;
        WHERETRACE(("...... idx-only reduces cost to %.9g\n", cost));
      }
    }
    }
    /**** Cost of using this index has now been computed ****/

    WHERETRACE((
      "tbl=%s idx=%s nEq=%d nInMul=%d nBound=%d bSort=%d bLookup=%d"
      " wsFlags=%d   (nRow=%.2f cost=%.2f)\n",
      pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"), 
      nEq, nInMul, nBound, bSort, bLookup, wsFlags, nRow, cost
    ));

    /* If this index has achieved the lowest cost so far, then use it.
    /* If this index is the best we have seen so far, then record this
    ** index and its cost in the pCost structure.
    */
    if( wsFlags!=0 && cost < pCost->rCost ){
    if( (!pIdx || wsFlags) && cost<pCost->rCost ){
      pCost->rCost = cost;
      pCost->nRow = nRow;
      pCost->used = used;
      pCost->plan.wsFlags = wsFlags;
      pCost->plan.wsFlags = (wsFlags&wsFlagMask);
      pCost->plan.nEq = nEq;
      assert( pCost->plan.wsFlags & WHERE_INDEXED );
      pCost->plan.u.pIdx = pProbe;
      pCost->plan.u.pIdx = pIdx;
    }

    /* If there was an INDEXED BY clause, then only that one index is
    ** considered. */
    if( pSrc->pIndex ) break;

    /* Reset masks for the next index in the loop */
    wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE);
    eqTermMask = idxEqTermMask;
  }

  /* If there is no ORDER BY clause and the SQLITE_ReverseOrder flag
  ** is set, then reverse the order that the index will be scanned
  ** in. This is used for application testing, to help find cases
  ** where application behaviour depends on the (undefined) order that
  ** SQLite outputs rows in in the absence of an ORDER BY clause.  */
  if( !pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){
    pCost->plan.wsFlags |= WHERE_REVERSE;
  }

  /* Report the best result
  assert( pOrderBy || (pCost->plan.wsFlags&WHERE_ORDERBY)==0 );
  */
  pCost->plan.wsFlags |= eqTermMask;
  WHERETRACE(("best index is %s, cost=%.9g, nrow=%.9g, wsFlags=%x, nEq=%d\n",
        (pCost->plan.wsFlags & WHERE_INDEXED)!=0 ?
             pCost->plan.u.pIdx->zName : "(none)", pCost->nRow,
        pCost->rCost, pCost->plan.wsFlags, pCost->plan.nEq));
  assert( pCost->plan.u.pIdx==0 || (pCost->plan.wsFlags&WHERE_ROWID_EQ)==0 );
  assert( pSrc->pIndex==0 
       || pCost->plan.u.pIdx==0 
       || pCost->plan.u.pIdx==pSrc->pIndex 
  );

  WHERETRACE(("best index is: %s\n", 
    (pCost->plan.u.pIdx ? pCost->plan.u.pIdx->zName : "ipk")
  ));
  
  bestOrClauseIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost);
  pCost->plan.wsFlags |= eqTermMask;
}

/*
** Find the query plan for accessing table pSrc->pTab. Write the
** best query plan and its cost into the WhereCost object supplied 
** as the last parameter. This function may calculate the cost of
** both real and virtual table scans.
2283
2284
2285
2286
2287
2288
2289
2290
2291






2292
2293

2294
2295
2296
2297
2298
2299





2300
2301
2302
2303
2304
2305
2306
2307
2587
2588
2589
2590
2591
2592
2593


2594
2595
2596
2597
2598
2599
2600

2601






2602
2603
2604
2605
2606

2607
2608
2609
2610
2611
2612
2613







-
-
+
+
+
+
+
+

-
+
-
-
-
-
-
-
+
+
+
+
+
-







        disableTerm(pLevel, pOther);
      }
    }
  }
}

/*
** Apply the affinities associated with the first n columns of index
** pIdx to the values in the n registers starting at base.
** Code an OP_Affinity opcode to apply the column affinity string zAff
** to the n registers starting at base. 
**
** Buffer zAff was allocated using sqlite3DbMalloc(). It is the 
** responsibility of this function to arrange for it to be eventually
** freed using sqlite3DbFree().
*/
static void codeApplyAffinity(Parse *pParse, int base, int n, Index *pIdx){
static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){
  if( n>0 ){
    Vdbe *v = pParse->pVdbe;
    assert( v!=0 );
    sqlite3VdbeAddOp2(v, OP_Affinity, base, n);
    sqlite3IndexAffinityStr(v, pIdx);
    sqlite3ExprCacheAffinityChange(pParse, base, n);
  Vdbe *v = pParse->pVdbe;
  assert( v!=0 );
  sqlite3VdbeAddOp2(v, OP_Affinity, base, n);
  sqlite3VdbeChangeP4(v, -1, zAff, P4_DYNAMIC);
  sqlite3ExprCacheAffinityChange(pParse, base, n);
  }
}


/*
** Generate code for a single equality term of the WHERE clause.  An equality
** term can be either X=expr or X IN (...).   pTerm is the term to be 
** coded.
2384
2385
2386
2387
2388
2389
2390















2391
2392
2393
2394
2395
2396
2397


2398
2399
2400
2401
2402
2403
2404
2405
2406

2407
2408
2409
2410
2411
2412
2413
2414
2415
2416





2417
2418
2419
2420
2421
2422
2423
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717

2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






-
+
+









+










+
+
+
+
+







**
** This routine always allocates at least one memory cell and returns
** the index of that memory cell. The code that
** calls this routine will use that memory cell to store the termination
** key value of the loop.  If one or more IN operators appear, then
** this routine allocates an additional nEq memory cells for internal
** use.
**
** Before returning, *pzAff is set to point to a buffer containing a
** copy of the column affinity string of the index allocated using
** sqlite3DbMalloc(). Except, entries in the copy of the string associated
** with equality constraints that use NONE affinity are set to
** SQLITE_AFF_NONE. This is to deal with SQL such as the following:
**
**   CREATE TABLE t1(a TEXT PRIMARY KEY, b);
**   SELECT ... FROM t1 AS t2, t1 WHERE t1.a = t2.b;
**
** In the example above, the index on t1(a) has TEXT affinity. But since
** the right hand side of the equality constraint (t2.b) has NONE affinity,
** no conversion should be attempted before using a t2.b value as part of
** a key to search the index. Hence the first byte in the returned affinity
** string in this example would be set to SQLITE_AFF_NONE.
*/
static int codeAllEqualityTerms(
  Parse *pParse,        /* Parsing context */
  WhereLevel *pLevel,   /* Which nested loop of the FROM we are coding */
  WhereClause *pWC,     /* The WHERE clause */
  Bitmask notReady,     /* Which parts of FROM have not yet been coded */
  int nExtraReg         /* Number of extra registers to allocate */
  int nExtraReg,        /* Number of extra registers to allocate */
  char **pzAff          /* OUT: Set to point to affinity string */
){
  int nEq = pLevel->plan.nEq;   /* The number of == or IN constraints to code */
  Vdbe *v = pParse->pVdbe;      /* The vm under construction */
  Index *pIdx;                  /* The index being used for this loop */
  int iCur = pLevel->iTabCur;   /* The cursor of the table */
  WhereTerm *pTerm;             /* A single constraint term */
  int j;                        /* Loop counter */
  int regBase;                  /* Base register */
  int nReg;                     /* Number of registers to allocate */
  char *zAff;                   /* Affinity string to return */

  /* This module is only called on query plans that use an index. */
  assert( pLevel->plan.wsFlags & WHERE_INDEXED );
  pIdx = pLevel->plan.u.pIdx;

  /* Figure out how many memory cells we will need then allocate them.
  */
  regBase = pParse->nMem + 1;
  nReg = pLevel->plan.nEq + nExtraReg;
  pParse->nMem += nReg;

  zAff = sqlite3DbStrDup(pParse->db, sqlite3IndexAffinityStr(v, pIdx));
  if( !zAff ){
    pParse->db->mallocFailed = 1;
  }

  /* Evaluate the equality constraints
  */
  assert( pIdx->nColumn>=nEq );
  for(j=0; j<nEq; j++){
    int r1;
    int k = pIdx->aiColumn[j];
2433
2434
2435
2436
2437
2438
2439




2440
2441




2442
2443
2444
2445
2446
2447
2448
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771


2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782







+
+
+
+
-
-
+
+
+
+







        sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j);
      }
    }
    testcase( pTerm->eOperator & WO_ISNULL );
    testcase( pTerm->eOperator & WO_IN );
    if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
      sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
      if( zAff 
       && sqlite3CompareAffinity(pTerm->pExpr->pRight, zAff[j])==SQLITE_AFF_NONE
      ){
        zAff[j] = SQLITE_AFF_NONE;
    }
  }
      }
    }
  }
  *pzAff = zAff;
  return regBase;
}

/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
** implementation described by pWInfo.
*/
2690
2691
2692
2693
2694
2695
2696

2697
2698
2699
2700
2701
2702
2703
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038







+







    int endEq;                   /* True if range end uses ==, >= or <= */
    int start_constraints;       /* Start of range is constrained */
    int nConstraint;             /* Number of constraint terms */
    Index *pIdx;         /* The index we will be using */
    int iIdxCur;         /* The VDBE cursor for the index */
    int nExtraReg = 0;   /* Number of extra registers needed */
    int op;              /* Instruction opcode */
    char *zAff;

    pIdx = pLevel->plan.u.pIdx;
    iIdxCur = pLevel->iIdxCur;
    k = pIdx->aiColumn[nEq];     /* Column for inequality constraints */

    /* If this loop satisfies a sort order (pOrderBy) request that 
    ** was passed to this function to implement a "SELECT min(x) ..." 
2729
2730
2731
2732
2733
2734
2735
2736



2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758

2759

2760








2761
2762
2763
2764
2765
2766
2767
2768

2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784

2785
2786

2787









2788

2789
2790
2791
2792
2793
2794
2795
3064
3065
3066
3067
3068
3069
3070

3071
3072
3073
3074

3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095

3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112

3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131

3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142

3143
3144
3145
3146
3147
3148
3149
3150







-
+
+
+

-




















+
-
+

+
+
+
+
+
+
+
+







-
+
















+

-
+

+
+
+
+
+
+
+
+
+
-
+







      nExtraReg = 1;
    }

    /* Generate code to evaluate all constraint terms using == or IN
    ** and store the values of those terms in an array of registers
    ** starting at regBase.
    */
    regBase = codeAllEqualityTerms(pParse, pLevel, pWC, notReady, nExtraReg);
    regBase = codeAllEqualityTerms(
        pParse, pLevel, pWC, notReady, nExtraReg, &zAff
    );
    addrNxt = pLevel->addrNxt;


    /* If we are doing a reverse order scan on an ascending index, or
    ** a forward order scan on a descending index, interchange the 
    ** start and end terms (pRangeStart and pRangeEnd).
    */
    if( bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC) ){
      SWAP(WhereTerm *, pRangeEnd, pRangeStart);
    }

    testcase( pRangeStart && pRangeStart->eOperator & WO_LE );
    testcase( pRangeStart && pRangeStart->eOperator & WO_GE );
    testcase( pRangeEnd && pRangeEnd->eOperator & WO_LE );
    testcase( pRangeEnd && pRangeEnd->eOperator & WO_GE );
    startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE);
    endEq =   !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE);
    start_constraints = pRangeStart || nEq>0;

    /* Seek the index cursor to the start of the range. */
    nConstraint = nEq;
    if( pRangeStart ){
      Expr *pRight = pRangeStart->pExpr->pRight;
      sqlite3ExprCode(pParse, pRangeStart->pExpr->pRight, regBase+nEq);
      sqlite3ExprCode(pParse, pRight, regBase+nEq);
      sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
      if( zAff 
       && sqlite3CompareAffinity(pRight, zAff[nConstraint])==SQLITE_AFF_NONE
      ){
        /* Since the comparison is to be performed with no conversions applied
        ** to the operands, set the affinity to apply to pRight to 
        ** SQLITE_AFF_NONE.  */
        zAff[nConstraint] = SQLITE_AFF_NONE;
      }
      nConstraint++;
    }else if( isMinQuery ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
      nConstraint++;
      startEq = 0;
      start_constraints = 1;
    }
    codeApplyAffinity(pParse, regBase, nConstraint, pIdx);
    codeApplyAffinity(pParse, regBase, nConstraint, zAff);
    op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
    assert( op!=0 );
    testcase( op==OP_Rewind );
    testcase( op==OP_Last );
    testcase( op==OP_SeekGt );
    testcase( op==OP_SeekGe );
    testcase( op==OP_SeekLe );
    testcase( op==OP_SeekLt );
    sqlite3VdbeAddOp4(v, op, iIdxCur, addrNxt, regBase, 
                      SQLITE_INT_TO_PTR(nConstraint), P4_INT32);

    /* Load the value for the inequality constraint at the end of the
    ** range (if any).
    */
    nConstraint = nEq;
    if( pRangeEnd ){
      Expr *pRight = pRangeEnd->pExpr->pRight;
      sqlite3ExprCacheRemove(pParse, regBase+nEq);
      sqlite3ExprCode(pParse, pRangeEnd->pExpr->pRight, regBase+nEq);
      sqlite3ExprCode(pParse, pRight, regBase+nEq);
      sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
      zAff = sqlite3DbStrDup(pParse->db, zAff);
      if( zAff 
       && sqlite3CompareAffinity(pRight, zAff[nConstraint])==SQLITE_AFF_NONE
      ){
        /* Since the comparison is to be performed with no conversions applied
        ** to the operands, set the affinity to apply to pRight to 
        ** SQLITE_AFF_NONE.  */
        zAff[nConstraint] = SQLITE_AFF_NONE;
      }
      codeApplyAffinity(pParse, regBase, nEq+1, pIdx);
      codeApplyAffinity(pParse, regBase, nEq+1, zAff);
      nConstraint++;
    }

    /* Top of the loop body */
    pLevel->p2 = sqlite3VdbeCurrentAddr(v);

    /* Check if the index cursor is past the end of the range. */
3266
3267
3268
3269
3270
3271
3272
3273

3274
3275

3276
3277
3278




































3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293















3294
3295
3296
3297
3298




3299
3300
3301
3302
3303







3304
3305
3306
3307
3308
3309
3310








3311
3312
3313
3314
3315
3316
3317
3621
3622
3623
3624
3625
3626
3627

3628
3629

3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669















3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685




3686
3687
3688
3689
3690




3691
3692
3693
3694
3695
3696
3697







3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712







-
+

-
+



+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
+
+
+
+

-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+







  pLevel = pWInfo->a;
  andFlags = ~0;
  WHERETRACE(("*** Optimizer Start ***\n"));
  for(i=iFrom=0, pLevel=pWInfo->a; i<pTabList->nSrc; i++, pLevel++){
    WhereCost bestPlan;         /* Most efficient plan seen so far */
    Index *pIdx;                /* Index for FROM table at pTabItem */
    int j;                      /* For looping over FROM tables */
    int bestJ = 0;              /* The value of j */
    int bestJ = -1;             /* The value of j */
    Bitmask m;                  /* Bitmask value for j or bestJ */
    int once = 0;               /* True when first table is seen */
    int isOptimal;              /* Iterator for optimal/non-optimal search */

    memset(&bestPlan, 0, sizeof(bestPlan));
    bestPlan.rCost = SQLITE_BIG_DBL;

    /* Loop through the remaining entries in the FROM clause to find the
    ** next nested loop. The FROM clause entries may be iterated through
    ** either once or twice. 
    **
    ** The first iteration, which is always performed, searches for the
    ** FROM clause entry that permits the lowest-cost, "optimal" scan. In
    ** this context an optimal scan is one that uses the same strategy
    ** for the given FROM clause entry as would be selected if the entry
    ** were used as the innermost nested loop.  In other words, a table
    ** is chosen such that the cost of running that table cannot be reduced
    ** by waiting for other tables to run first.
    **
    ** The second iteration is only performed if no optimal scan strategies
    ** were found by the first. This iteration is used to search for the
    ** lowest cost scan overall.
    **
    ** Previous versions of SQLite performed only the second iteration -
    ** the next outermost loop was always that with the lowest overall
    ** cost. However, this meant that SQLite could select the wrong plan
    ** for scripts such as the following:
    **   
    **   CREATE TABLE t1(a, b); 
    **   CREATE TABLE t2(c, d);
    **   SELECT * FROM t2, t1 WHERE t2.rowid = t1.a;
    **
    ** The best strategy is to iterate through table t1 first. However it
    ** is not possible to determine this with a simple greedy algorithm.
    ** However, since the cost of a linear scan through table t2 is the same 
    ** as the cost of a linear scan through table t1, a simple greedy 
    ** algorithm may choose to use t2 for the outer loop, which is a much
    ** costlier approach.
    */
    for(isOptimal=1; isOptimal>=0 && bestJ<0; isOptimal--){
      Bitmask mask = (isOptimal ? 0 : notReady);
      assert( (pTabList->nSrc-iFrom)>1 || isOptimal );
    for(j=iFrom, pTabItem=&pTabList->a[j]; j<pTabList->nSrc; j++, pTabItem++){
      int doNotReorder;    /* True if this table should not be reordered */
      WhereCost sCost;     /* Cost information from best[Virtual]Index() */
      ExprList *pOrderBy;  /* ORDER BY clause for index to optimize */

      doNotReorder =  (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0;
      if( once && doNotReorder ) break;
      m = getMask(pMaskSet, pTabItem->iCursor);
      if( (m & notReady)==0 ){
        if( j==iFrom ) iFrom++;
        continue;
      }
      pOrderBy = ((i==0 && ppOrderBy )?*ppOrderBy:0);

      assert( pTabItem->pTab );
      for(j=iFrom, pTabItem=&pTabList->a[j]; j<pTabList->nSrc; j++, pTabItem++){
        int doNotReorder;    /* True if this table should not be reordered */
        WhereCost sCost;     /* Cost information from best[Virtual]Index() */
        ExprList *pOrderBy;  /* ORDER BY clause for index to optimize */
  
        doNotReorder =  (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0;
        if( j!=iFrom && doNotReorder ) break;
        m = getMask(pMaskSet, pTabItem->iCursor);
        if( (m & notReady)==0 ){
          if( j==iFrom ) iFrom++;
          continue;
        }
        pOrderBy = ((i==0 && ppOrderBy )?*ppOrderBy:0);
  
        assert( pTabItem->pTab );
#ifndef SQLITE_OMIT_VIRTUALTABLE
      if( IsVirtual(pTabItem->pTab) ){
        sqlite3_index_info **pp = &pWInfo->a[j].pIdxInfo;
        bestVirtualIndex(pParse, pWC, pTabItem, notReady, pOrderBy, &sCost, pp);
      }else 
        if( IsVirtual(pTabItem->pTab) ){
          sqlite3_index_info **pp = &pWInfo->a[j].pIdxInfo;
          bestVirtualIndex(pParse, pWC, pTabItem, mask, pOrderBy, &sCost, pp);
        }else 
#endif
      {
        bestBtreeIndex(pParse, pWC, pTabItem, notReady, pOrderBy, &sCost);
      }
      if( once==0 || sCost.rCost<bestPlan.rCost ){
        {
          bestBtreeIndex(pParse, pWC, pTabItem, mask, pOrderBy, &sCost);
        }
        assert( isOptimal || (sCost.used&notReady)==0 );

        if( (sCost.used&notReady)==0
         && (j==iFrom || sCost.rCost<bestPlan.rCost) 
        once = 1;
        bestPlan = sCost;
        bestJ = j;
      }
      if( doNotReorder ) break;
    }
    assert( once );
        ){
          bestPlan = sCost;
          bestJ = j;
        }
        if( doNotReorder ) break;
      }
    }
    assert( bestJ>=0 );
    assert( notReady & getMask(pMaskSet, pTabList->a[bestJ].iCursor) );
    WHERETRACE(("*** Optimizer selects table %d for loop %d\n", bestJ,
           pLevel-pWInfo->a));
    if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 ){
      *ppOrderBy = 0;
    }
    andFlags &= bestPlan.plan.wsFlags;
3400
3401
3402
3403
3404
3405
3406
3407

3408
3409
3410

3411
3412

3413
3414
3415
3416
3417
3418
3419
3420
3795
3796
3797
3798
3799
3800
3801

3802
3803
3804
3805
3806
3807

3808

3809
3810
3811
3812
3813
3814
3815







-
+



+

-
+
-







        zMsg = sqlite3MAppendf(db, zMsg, "%s ORDER BY", zMsg);
      }
      sqlite3VdbeAddOp4(v, OP_Explain, i, pLevel->iFrom, 0, zMsg, P4_DYNAMIC);
    }
#endif /* SQLITE_OMIT_EXPLAIN */
    pTabItem = &pTabList->a[pLevel->iFrom];
    pTab = pTabItem->pTab;
    iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
    iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
    if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ) continue;
#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
      const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
      int iCur = pTabItem->iCursor;
      sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0,
      sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
                        (const char*)pTab->pVtab, P4_VTAB);
    }else
#endif
    if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
         && (wctrlFlags & WHERE_OMIT_OPEN)==0 ){
      int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
      sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
      if( !pWInfo->okOnePass && pTab->nCol<BMS ){
Added test/analyze2.test.

























































































































































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 August 06
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file implements regression tests for SQLite library. This file 
# implements tests for the extra functionality provided by the ANALYZE 
# command when the library is compiled with SQLITE_ENABLE_STAT2 defined.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !stat2 {
  finish_test
  return
}

#--------------------------------------------------------------------
# Test organization:
#
# analyze2-1.*: Tests to verify that ANALYZE creates and populates the
#               sqlite_stat2 table as expected.
#
# analyze2-2.*: Test that when a table has two indexes on it and either
#               index may be used for the scan, the index suggested by
#               the contents of sqlite_stat2 table is prefered.
# 
# analyze2-3.*: Similar to the previous block of tests, but using tables
#               that contain a mixture of NULL, numeric, text and blob
#               values.
#
# analyze2-4.*: Check that when an indexed column uses a collation other
#               than BINARY, the collation is taken into account when
#               using the contents of sqlite_stat2 to estimate the cost
#               of a range scan.
#
# analyze2-5.*: Check that collation sequences are used as described above
#               even when the only available version of the collation 
#               function require UTF-16 encoded arguments.
#
# analyze2-6.*: Check that the library behaves correctly when one of the
#               sqlite_stat2 or sqlite_stat1 tables are missing.
#
# analyze2-7.*: Check that in a shared-schema situation, nothing goes
#               wrong if sqlite_stat2 data is read by one connection,
#               and freed by another.
# 

proc eqp {sql {db db}} {
  uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db
}

do_test analyze2-1.1 {
  execsql { CREATE TABLE t1(x PRIMARY KEY) }
  for {set i 0} {$i < 1000} {incr i} {
    execsql { INSERT INTO t1 VALUES($i) }
  }
  execsql { 
    ANALYZE;
    SELECT * FROM sqlite_stat2;
  }
} [list t1 sqlite_autoindex_t1_1 0 50  \
        t1 sqlite_autoindex_t1_1 1 149 \
        t1 sqlite_autoindex_t1_1 2 249 \
        t1 sqlite_autoindex_t1_1 3 349 \
        t1 sqlite_autoindex_t1_1 4 449 \
        t1 sqlite_autoindex_t1_1 5 549 \
        t1 sqlite_autoindex_t1_1 6 649 \
        t1 sqlite_autoindex_t1_1 7 749 \
        t1 sqlite_autoindex_t1_1 8 849 \
        t1 sqlite_autoindex_t1_1 9 949 \
]

do_test analyze2-1.2 {
  execsql {
    DELETE FROM t1 WHERe x>9;
    ANALYZE;
    SELECT tbl, idx, group_concat(sample, ' ') FROM sqlite_stat2;
  }
} {t1 sqlite_autoindex_t1_1 {0 1 2 3 4 5 6 7 8 9}}
do_test analyze2-1.3 {
  execsql {
    DELETE FROM t1 WHERE x>8;
    ANALYZE;
    SELECT * FROM sqlite_stat2;
  }
} {}
do_test analyze2-1.4 {
  execsql {
    DELETE FROM t1;
    ANALYZE;
    SELECT * FROM sqlite_stat2;
  }
} {}

do_test analyze2-2.1 {
  execsql { 
    BEGIN;
    DROP TABLE t1;
    CREATE TABLE t1(x, y);
    CREATE INDEX t1_x ON t1(x);
    CREATE INDEX t1_y ON t1(y);
  }
  for {set i 0} {$i < 1000} {incr i} {
    execsql { INSERT INTO t1 VALUES($i, $i) }
  }
  execsql COMMIT
  execsql ANALYZE
} {}
do_test analyze2-2.2 {
  eqp "SELECT * FROM t1 WHERE x>500 AND y>700"
} {0 0 {TABLE t1 WITH INDEX t1_y}}
do_test analyze2-2.3 {
  eqp "SELECT * FROM t1 WHERE x>700 AND y>500"
} {0 0 {TABLE t1 WITH INDEX t1_x}}
do_test analyze2-2.3 {
  eqp "SELECT * FROM t1 WHERE y>700 AND x>500"
} {0 0 {TABLE t1 WITH INDEX t1_y}}
do_test analyze2-2.4 {
  eqp "SELECT * FROM t1 WHERE y>500 AND x>700"
} {0 0 {TABLE t1 WITH INDEX t1_x}}
do_test analyze2-2.5 {
  eqp "SELECT * FROM t1 WHERE x BETWEEN 100 AND 200 AND y BETWEEN 400 AND 700"
} {0 0 {TABLE t1 WITH INDEX t1_x}}
do_test analyze2-2.6 {
  eqp "SELECT * FROM t1 WHERE x BETWEEN 100 AND 500 AND y BETWEEN 400 AND 700"
} {0 0 {TABLE t1 WITH INDEX t1_y}}
do_test analyze2-2.7 {
  eqp "SELECT * FROM t1 WHERE x BETWEEN -400 AND -300 AND y BETWEEN 100 AND 300"
} {0 0 {TABLE t1 WITH INDEX t1_x}}
do_test analyze2-2.8 {
  eqp "SELECT * FROM t1 WHERE x BETWEEN 100 AND 300 AND y BETWEEN -400 AND -300"
} {0 0 {TABLE t1 WITH INDEX t1_y}}
do_test analyze2-2.9 {
  eqp "SELECT * FROM t1 WHERE x BETWEEN 500 AND 100 AND y BETWEEN 100 AND 300"
} {0 0 {TABLE t1 WITH INDEX t1_x}}
do_test analyze2-2.10 {
  eqp "SELECT * FROM t1 WHERE x BETWEEN 100 AND 300 AND y BETWEEN 500 AND 100"
} {0 0 {TABLE t1 WITH INDEX t1_y}}

do_test analyze2-3.1 {
  set alphabet [list a b c d e f g h i j]
  execsql BEGIN
  for {set i 0} {$i < 1000} {incr i} {
    set str    [lindex $alphabet [expr ($i/100)%10]] 
    append str [lindex $alphabet [expr ($i/ 10)%10]]
    append str [lindex $alphabet [expr ($i/  1)%10]]
    execsql { INSERT INTO t1 VALUES($str, $str) }
  }
  execsql COMMIT
  execsql ANALYZE
  execsql { 
    SELECT tbl,idx,group_concat(sample,' ') 
    FROM sqlite_stat2 
    WHERE idx = 't1_x' 
    GROUP BY tbl,idx
  }
} {t1 t1_x {100 299 499 699 899 ajj cjj ejj gjj ijj}}
do_test analyze2-3.2 {
  execsql { 
    SELECT tbl,idx,group_concat(sample,' ') 
    FROM sqlite_stat2 
    WHERE idx = 't1_y' 
    GROUP BY tbl,idx
  }
} {t1 t1_y {100 299 499 699 899 ajj cjj ejj gjj ijj}}

do_test analyze2-3.3 {
  eqp "SELECT * FROM t1 WHERE x BETWEEN 100 AND 500 AND y BETWEEN 'a' AND 'b'"
} {0 0 {TABLE t1 WITH INDEX t1_y}}
do_test analyze2-3.4 {
  eqp "SELECT * FROM t1 WHERE x BETWEEN 100 AND 400 AND y BETWEEN 'a' AND 'h'"
} {0 0 {TABLE t1 WITH INDEX t1_x}}
do_test analyze2-3.5 {
  eqp "SELECT * FROM t1 WHERE x<'a' AND y>'h'"
} {0 0 {TABLE t1 WITH INDEX t1_y}}
do_test analyze2-3.6 {
  eqp "SELECT * FROM t1 WHERE x<444 AND y>'h'"
} {0 0 {TABLE t1 WITH INDEX t1_y}}
do_test analyze2-3.7 {
  eqp "SELECT * FROM t1 WHERE x<221 AND y>'g'"
} {0 0 {TABLE t1 WITH INDEX t1_x}}

do_test analyze2-4.1 {
  execsql { CREATE TABLE t3(a COLLATE nocase, b) }
  execsql { CREATE INDEX t3a ON t3(a) }
  execsql { CREATE INDEX t3b ON t3(b) }
  set alphabet [list A b C d E f G h I j]
  execsql BEGIN
  for {set i 0} {$i < 1000} {incr i} {
    set str    [lindex $alphabet [expr ($i/100)%10]] 
    append str [lindex $alphabet [expr ($i/ 10)%10]]
    append str [lindex $alphabet [expr ($i/  1)%10]]
    execsql { INSERT INTO t3 VALUES($str, $str) }
  }
  execsql COMMIT
  execsql ANALYZE
} {}
do_test analyze2-4.2 {
  execsql { 
    SELECT tbl,idx,group_concat(sample,' ') 
    FROM sqlite_stat2 
    WHERE idx = 't3a' 
    GROUP BY tbl,idx
  }
} {t3 t3a {AfA bEj CEj dEj EEj fEj GEj hEj IEj jEj}}
do_test analyze2-4.3 {
  execsql { 
    SELECT tbl,idx,group_concat(sample,' ') 
    FROM sqlite_stat2 
    WHERE idx = 't3b' 
    GROUP BY tbl,idx
  }
} {t3 t3b {AbA CIj EIj GIj IIj bIj dIj fIj hIj jIj}}

do_test analyze2-4.4 {
  eqp "SELECT * FROM t3 WHERE a > 'A' AND a < 'C' AND b > 'A' AND b < 'C'"
} {0 0 {TABLE t3 WITH INDEX t3b}}
do_test analyze2-4.5 {
  eqp "SELECT * FROM t3 WHERE a > 'A' AND a < 'c' AND b > 'A' AND b < 'c'"
} {0 0 {TABLE t3 WITH INDEX t3a}}

ifcapable utf16 {
  proc test_collate {enc lhs rhs} {
    # puts $enc
    return [string compare $lhs $rhs]
  }
  do_test analyze2-5.1 {
    add_test_collate db 0 0 1
    execsql { CREATE TABLE t4(x COLLATE test_collate) }
    execsql { CREATE INDEX t4x ON t4(x) }
    set alphabet [list a b c d e f g h i j]
    execsql BEGIN
    for {set i 0} {$i < 1000} {incr i} {
      set str    [lindex $alphabet [expr ($i/100)%10]] 
      append str [lindex $alphabet [expr ($i/ 10)%10]]
      append str [lindex $alphabet [expr ($i/  1)%10]]
      execsql { INSERT INTO t4 VALUES($str) }
    }
    execsql COMMIT
    execsql ANALYZE
  } {}
  do_test analyze2-5.2 {
    execsql { 
      SELECT tbl,idx,group_concat(sample,' ') 
      FROM sqlite_stat2 
      WHERE tbl = 't4' 
      GROUP BY tbl,idx
    }
  } {t4 t4x {afa bej cej dej eej fej gej hej iej jej}}
  do_test analyze2-5.3 {
    eqp "SELECT * FROM t4 WHERE x>'ccc'"
  } {0 0 {TABLE t4 WITH INDEX t4x}}
  do_test analyze2-5.4 {
    eqp "SELECT * FROM t4 AS t41, t4 AS t42 WHERE t41.x>'ccc' AND t42.x>'ggg'"
  } {0 1 {TABLE t4 AS t42 WITH INDEX t4x} 1 0 {TABLE t4 AS t41 WITH INDEX t4x}}
  do_test analyze2-5.5 {
    eqp "SELECT * FROM t4 AS t41, t4 AS t42 WHERE t41.x>'ddd' AND t42.x>'ccc'"
  } {0 0 {TABLE t4 AS t41 WITH INDEX t4x} 1 1 {TABLE t4 AS t42 WITH INDEX t4x}}
}

#--------------------------------------------------------------------
# These tests, analyze2-6.*, verify that the library behaves correctly
# when one of the sqlite_stat1 and sqlite_stat2 tables is missing.
#
# If the sqlite_stat1 table is not present, then the sqlite_stat2
# table is not read. However, if it is the sqlite_stat2 table that
# is missing, the data in the sqlite_stat1 table is still used.
#
# Tests analyze2-6.1.* test the libary when the sqlite_stat2 table
# is missing. Tests analyze2-6.2.* test the library when sqlite_stat1
# is not present.
#
do_test analyze2-6.0 {
  execsql {
    DROP TABLE IF EXISTS t4;
    CREATE TABLE t5(a, b); CREATE INDEX t5i ON t5(a, b);
    CREATE TABLE t6(a, b); CREATE INDEX t6i ON t6(a, b);
  }
  for {set ii 0} {$ii < 20} {incr ii} {
    execsql {
      INSERT INTO t5 VALUES($ii, $ii);
      INSERT INTO t6 VALUES($ii/10, $ii/10);
    }
  }
  execsql { 
    CREATE TABLE master AS 
    SELECT * FROM sqlite_master WHERE name LIKE 'sqlite_stat%' 
  }
} {}

do_test analyze2-6.1.1 {
  eqp {SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND 
       t5.a = 1 AND
       t6.a = 1 AND t6.b = 1
  }
} {0 1 {TABLE t6 WITH INDEX t6i} 1 0 {TABLE t5 USING PRIMARY KEY}}
do_test analyze2-6.1.2 {
  db cache flush
  execsql ANALYZE
  eqp {SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND 
       t5.a = 1 AND
       t6.a = 1 AND t6.b = 1
  }
} {0 0 {TABLE t5 WITH INDEX t5i} 1 1 {TABLE t6 USING PRIMARY KEY}}
do_test analyze2-6.1.3 {
  sqlite3 db test.db
  eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND 
       t5.a = 1 AND
       t6.a = 1 AND t6.b = 1
  }
} {0 0 {TABLE t5 WITH INDEX t5i} 1 1 {TABLE t6 USING PRIMARY KEY}}
do_test analyze2-6.1.4 {
  execsql { 
    PRAGMA writable_schema = 1;
    DELETE FROM sqlite_master WHERE tbl_name = 'sqlite_stat2';
  }
  sqlite3 db test.db
  eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND 
       t5.a = 1 AND
       t6.a = 1 AND t6.b = 1
  }
} {0 0 {TABLE t5 WITH INDEX t5i} 1 1 {TABLE t6 USING PRIMARY KEY}}
do_test analyze2-6.1.5 {
  execsql { 
    PRAGMA writable_schema = 1;
    DELETE FROM sqlite_master WHERE tbl_name = 'sqlite_stat1';
  }
  sqlite3 db test.db
  eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND 
       t5.a = 1 AND
       t6.a = 1 AND t6.b = 1
  }
} {0 1 {TABLE t6 WITH INDEX t6i} 1 0 {TABLE t5 USING PRIMARY KEY}}
do_test analyze2-6.1.6 {
  execsql { 
    PRAGMA writable_schema = 1;
    INSERT INTO sqlite_master SELECT * FROM master;
  }
  sqlite3 db test.db
  eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND 
       t5.a = 1 AND
       t6.a = 1 AND t6.b = 1
  }
} {0 0 {TABLE t5 WITH INDEX t5i} 1 1 {TABLE t6 USING PRIMARY KEY}}

do_test analyze2-6.2.1 {
  execsql { 
    DELETE FROM sqlite_stat1;
    DELETE FROM sqlite_stat2;
  }
  sqlite3 db test.db
  eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND 
        t5.a>1 AND t5.a<15 AND
        t6.a>1
  }
} {0 0 {TABLE t5 WITH INDEX t5i} 1 1 {TABLE t6 USING PRIMARY KEY}}
do_test analyze2-6.2.2 {
  db cache flush
  execsql ANALYZE
  eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND 
        t5.a>1 AND t5.a<15 AND
        t6.a>1
  }
} {0 1 {TABLE t6 WITH INDEX t6i} 1 0 {TABLE t5 USING PRIMARY KEY}}
do_test analyze2-6.2.3 {
  sqlite3 db test.db
  eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND 
        t5.a>1 AND t5.a<15 AND
        t6.a>1
  }
} {0 1 {TABLE t6 WITH INDEX t6i} 1 0 {TABLE t5 USING PRIMARY KEY}}
do_test analyze2-6.2.4 {
  execsql { 
    PRAGMA writable_schema = 1;
    DELETE FROM sqlite_master WHERE tbl_name = 'sqlite_stat1';
  }
  sqlite3 db test.db
  eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND 
        t5.a>1 AND t5.a<15 AND
        t6.a>1
  }
} {0 0 {TABLE t5 WITH INDEX t5i} 1 1 {TABLE t6 USING PRIMARY KEY}}
do_test analyze2-6.2.5 {
  execsql { 
    PRAGMA writable_schema = 1;
    DELETE FROM sqlite_master WHERE tbl_name = 'sqlite_stat2';
  }
  sqlite3 db test.db
  eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND 
        t5.a>1 AND t5.a<15 AND
        t6.a>1
  }
} {0 0 {TABLE t5 WITH INDEX t5i} 1 1 {TABLE t6 USING PRIMARY KEY}}
do_test analyze2-6.2.6 {
  execsql { 
    PRAGMA writable_schema = 1;
    INSERT INTO sqlite_master SELECT * FROM master;
  }
  sqlite3 db test.db
  execsql ANALYZE
  eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND 
        t5.a>1 AND t5.a<15 AND
        t6.a>1
  }
} {0 1 {TABLE t6 WITH INDEX t6i} 1 0 {TABLE t5 USING PRIMARY KEY}}

#--------------------------------------------------------------------
# These tests, analyze2-7.*, test that the sqlite_stat2 functionality
# works in shared-cache mode. Note that these tests reuse the database
# created for the analyze2-6.* tests.
#
ifcapable shared_cache {
  db close
  set ::enable_shared_cache [sqlite3_enable_shared_cache 1]

  proc incr_schema_cookie {zDb} {
    foreach iOffset {24 40} {
      set cookie [hexio_get_int [hexio_read $zDb $iOffset 4]]
      incr cookie
      hexio_write $zDb $iOffset [hexio_render_int32 $cookie]
    }
  }

  do_test analyze2-7.1 {
    sqlite3 db1 test.db
    sqlite3 db2 test.db
    db1 cache size 0
    db2 cache size 0
    execsql { SELECT count(*) FROM t5 } db1
  } {20}
  do_test analyze2-7.2 {
    incr_schema_cookie test.db
    execsql { SELECT count(*) FROM t5 } db2
  } {20}
  do_test analyze2-7.3 {
    incr_schema_cookie test.db
    execsql { SELECT count(*) FROM t5 } db1
  } {20}
  do_test analyze2-7.4 {
    incr_schema_cookie test.db
    execsql { SELECT count(*) FROM t5 } db2
  } {20}

  do_test analyze2-7.5 {
    eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND 
          t5.a>1 AND t5.a<15 AND
          t6.a>1
    } db1
  } {0 1 {TABLE t6 WITH INDEX t6i} 1 0 {TABLE t5 USING PRIMARY KEY}}
  do_test analyze2-7.6 {
    incr_schema_cookie test.db
    execsql { SELECT * FROM sqlite_master } db2
    eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND 
          t5.a>1 AND t5.a<15 AND
          t6.a>1
    } db2
  } {0 1 {TABLE t6 WITH INDEX t6i} 1 0 {TABLE t5 USING PRIMARY KEY}}
  do_test analyze2-7.7 {
    incr_schema_cookie test.db
    execsql { SELECT * FROM sqlite_master } db1
    eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND 
          t5.a>1 AND t5.a<15 AND
          t6.a>1
    } db1
  } {0 1 {TABLE t6 WITH INDEX t6i} 1 0 {TABLE t5 USING PRIMARY KEY}}

  do_test analyze2-7.8 {
    execsql { DELETE FROM sqlite_stat2 } db2
    execsql { SELECT * FROM sqlite_master } db1
    eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND 
          t5.a>1 AND t5.a<15 AND
          t6.a>1
    } db1
  } {0 1 {TABLE t6 WITH INDEX t6i} 1 0 {TABLE t5 USING PRIMARY KEY}}
  do_test analyze2-7.9 {
    execsql { SELECT * FROM sqlite_master } db2
    eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND 
          t5.a>1 AND t5.a<15 AND
          t6.a>1
    } db2
  } {0 1 {TABLE t6 WITH INDEX t6i} 1 0 {TABLE t5 USING PRIMARY KEY}}

  do_test analyze2-7.10 {
    incr_schema_cookie test.db
    execsql { SELECT * FROM sqlite_master } db1
    eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND 
          t5.a>1 AND t5.a<15 AND
          t6.a>1
    } db1
  } {0 0 {TABLE t5 WITH INDEX t5i} 1 1 {TABLE t6 USING PRIMARY KEY}}

  db1 close
  db2 close
  sqlite3_enable_shared_cache $::enable_shared_cache
}

finish_test
Added test/analyze3.test.

























































































































































































































































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 August 06
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file implements regression tests for SQLite library. This file 
# implements tests for range and LIKE constraints that use bound variables
# instead of literal constant arguments.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !stat2 {
  finish_test
  return
}

#----------------------------------------------------------------------
# Test Organization:
#
# analyze3-1.*: Test that the values of bound parameters are considered 
#               in the same way as constants when planning queries that
#               use range constraints.
#
# analyze3-2.*: Test that the values of bound parameters are considered 
#               in the same way as constants when planning queries that
#               use LIKE expressions in the WHERE clause.
#
# analyze3-3.*: Test that binding to a variable does not invalidate the 
#               query plan when there is no way in which replanning the
#               query may produce a superior outcome.
#
# analyze3-4.*: Test that SQL or authorization callback errors occuring
#               within sqlite3Reprepare() are handled correctly.
#
# analyze3-5.*: Check that the query plans of applicable statements are
#               invalidated if the values of SQL parameter are modified
#               using the clear_bindings() or transfer_bindings() APIs.
#

proc getvar {varname} { uplevel #0 set $varname }
db function var getvar

proc eqp {sql {db db}} {
  uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db
}

proc sf_execsql {sql {db db}} {
  set ::sqlite_search_count 0
  set r [uplevel [list execsql $sql $db]]

  concat $::sqlite_search_count [$db status step] $r
}

#-------------------------------------------------------------------------
#
# analyze3-1.1.1: 
#   Create a table with two columns. Populate the first column (affinity 
#   INTEGER) with integer values from 100 to 1100. Create an index on this 
#   column. ANALYZE the table.
#
# analyze3-1.1.2 - 3.1.3
#   Show that there are two possible plans for querying the table with
#   a range constraint on the indexed column - "full table scan" or "use 
#   the index". When the range is specified using literal values, SQLite
#   is able to pick the best plan based on the samples in sqlite_stat2.
#
# analyze3-1.1.4 - 3.1.9
#   Show that using SQL variables produces the same results as using
#   literal values to constrain the range scan.
#
#   These tests also check that the compiler code considers column 
#   affinities when estimating the number of rows scanned by the "use 
#   index strategy".
#
do_test analyze3-1.1.1 {
  execsql {
    BEGIN;
    CREATE TABLE t1(x INTEGER, y);
    CREATE INDEX i1 ON t1(x);
  }
  for {set i 0} {$i < 1000} {incr i} {
    execsql { INSERT INTO t1 VALUES($i+100, $i) }
  }
  execsql {
    COMMIT;
    ANALYZE;
  }
} {}

do_test analyze3-1.1.2 {
  eqp { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 }
} {0 0 {TABLE t1 WITH INDEX i1}}
do_test analyze3-1.1.3 {
  eqp { SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 }
} {0 0 {TABLE t1}}

do_test analyze3-1.1.4 {
  sf_execsql { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 }
} {199 0 14850}
do_test analyze3-1.1.5 {
  set l [string range "200" 0 end]
  set u [string range "300" 0 end]
  sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
} {199 0 14850}
do_test analyze3-1.1.6 {
  set l [expr int(200)]
  set u [expr int(300)]
  sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
} {199 0 14850}
do_test analyze3-1.1.7 {
  sf_execsql { SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 }
} {999 999 499500}
do_test analyze3-1.1.8 {
  set l [string range "0" 0 end]
  set u [string range "1100" 0 end]
  sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
} {999 999 499500}
do_test analyze3-1.1.9 {
  set l [expr int(0)]
  set u [expr int(1100)]
  sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
} {999 999 499500}


# The following tests are similar to the block above. The difference is
# that the indexed column has TEXT affinity in this case. In the tests
# above the affinity is INTEGER.
#
do_test analyze3-1.2.1 {
  execsql {
    BEGIN;
      CREATE TABLE t2(x TEXT, y);
      INSERT INTO t2 SELECT * FROM t1;
      CREATE INDEX i2 ON t2(x);
    COMMIT;
    ANALYZE;
  }
} {}
do_test analyze3-1.2.2 {
  eqp { SELECT sum(y) FROM t2 WHERE x>1 AND x<2 }
} {0 0 {TABLE t2 WITH INDEX i2}}
do_test analyze3-1.2.3 {
  eqp { SELECT sum(y) FROM t2 WHERE x>0 AND x<99 }
} {0 0 {TABLE t2}}
do_test analyze3-1.2.4 {
  sf_execsql { SELECT sum(y) FROM t2 WHERE x>12 AND x<20 }
} {161 0 4760}
do_test analyze3-1.2.5 {
  set l [string range "12" 0 end]
  set u [string range "20" 0 end]
  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
} {161 0 text text 4760}
do_test analyze3-1.2.6 {
  set l [expr int(12)]
  set u [expr int(20)]
  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
} {161 0 integer integer 4760}
do_test analyze3-1.2.7 {
  sf_execsql { SELECT sum(y) FROM t2 WHERE x>0 AND x<99 }
} {999 999 490555}
do_test analyze3-1.2.8 {
  set l [string range "0" 0 end]
  set u [string range "99" 0 end]
  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
} {999 999 text text 490555}
do_test analyze3-1.2.9 {
  set l [expr int(0)]
  set u [expr int(99)]
  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
} {999 999 integer integer 490555}

# Same tests a third time. This time, column x has INTEGER affinity and
# is not the leftmost column of the table. This triggered a bug causing
# SQLite to use sub-optimal query plans in 3.6.18 and earlier.
#
do_test analyze3-1.3.1 {
  execsql {
    BEGIN;
      CREATE TABLE t3(y TEXT, x INTEGER);
      INSERT INTO t3 SELECT y, x FROM t1;
      CREATE INDEX i3 ON t3(x);
    COMMIT;
    ANALYZE;
  }
} {}
do_test analyze3-1.3.2 {
  eqp { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 }
} {0 0 {TABLE t3 WITH INDEX i3}}
do_test analyze3-1.3.3 {
  eqp { SELECT sum(y) FROM t3 WHERE x>0 AND x<1100 }
} {0 0 {TABLE t3}}

do_test analyze3-1.3.4 {
  sf_execsql { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 }
} {199 0 14850}
do_test analyze3-1.3.5 {
  set l [string range "200" 0 end]
  set u [string range "300" 0 end]
  sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
} {199 0 14850}
do_test analyze3-1.3.6 {
  set l [expr int(200)]
  set u [expr int(300)]
  sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
} {199 0 14850}
do_test analyze3-1.3.7 {
  sf_execsql { SELECT sum(y) FROM t3 WHERE x>0 AND x<1100 }
} {999 999 499500}
do_test analyze3-1.3.8 {
  set l [string range "0" 0 end]
  set u [string range "1100" 0 end]
  sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
} {999 999 499500}
do_test analyze3-1.3.9 {
  set l [expr int(0)]
  set u [expr int(1100)]
  sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
} {999 999 499500}

#-------------------------------------------------------------------------
# Test that the values of bound SQL variables may be used for the LIKE
# optimization.
#
drop_all_tables
do_test analyze3-2.1 {
  execsql {
    PRAGMA case_sensitive_like=off;
    BEGIN;
    CREATE TABLE t1(a, b TEXT COLLATE nocase);
    CREATE INDEX i1 ON t1(b);
  }
  for {set i 0} {$i < 1000} {incr i} {
    set t ""
    append t [lindex {a b c d e f g h i j} [expr $i/100]]
    append t [lindex {a b c d e f g h i j} [expr ($i/10)%10]]
    append t [lindex {a b c d e f g h i j} [expr ($i%10)]]
    execsql { INSERT INTO t1 VALUES($i, $t) }
  }
  execsql COMMIT
} {}
do_test analyze3-2.2 {
  eqp { SELECT count(a) FROM t1 WHERE b LIKE 'a%' }
} {0 0 {TABLE t1 WITH INDEX i1}}
do_test analyze3-2.3 {
  eqp { SELECT count(a) FROM t1 WHERE b LIKE '%a' }
} {0 0 {TABLE t1}}

do_test analyze3-2.4 {
  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE 'a%' }
} {101 0 100}
do_test analyze3-2.5 {
  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE '%a' }
} {999 999 100}

do_test analyze3-2.4 {
  set like "a%"
  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
} {101 0 100}
do_test analyze3-2.5 {
  set like "%a"
  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
} {999 999 100}


#-------------------------------------------------------------------------
# This block of tests checks that statements are correctly marked as
# expired when the values bound to any parameters that may affect the 
# query plan are modified.
#
drop_all_tables
db auth auth
proc auth {args} {
  set ::auth 1
  return SQLITE_OK
}

do_test analyze3-3.1 {
  execsql {
    BEGIN;
    CREATE TABLE t1(a, b, c);
    CREATE INDEX i1 ON t1(b);
  }
  for {set i 0} {$i < 100} {incr i} {
    execsql { INSERT INTO t1 VALUES($i, $i, $i) }
  }
  execsql COMMIT
  execsql ANALYZE
} {}

do_test analyze3-3.2.1 {
  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE b>?" -1 dummy]
  sqlite3_expired $S
} {0}
do_test analyze3-3.2.2 {
  sqlite3_bind_text $S 1 "abc" 3
  sqlite3_expired $S
} {1}
do_test analyze3-3.2.4 {
  sqlite3_finalize $S
} {SQLITE_OK}

do_test analyze3-3.2.5 {
  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE b=?" -1 dummy]
  sqlite3_expired $S
} {0}
do_test analyze3-3.2.6 {
  sqlite3_bind_text $S 1 "abc" 3
  sqlite3_expired $S
} {0}
do_test analyze3-3.2.7 {
  sqlite3_finalize $S
} {SQLITE_OK}

do_test analyze3-3.4.1 {
  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
  sqlite3_expired $S
} {0}
do_test analyze3-3.4.2 {
  sqlite3_bind_text $S 1 "abc" 3
  sqlite3_expired $S
} {0}
do_test analyze3-3.4.3 {
  sqlite3_bind_text $S 2 "def" 3
  sqlite3_expired $S
} {1}
do_test analyze3-3.4.4 {
  sqlite3_bind_text $S 2 "ghi" 3
  sqlite3_expired $S
} {1}
do_test analyze3-3.4.5 {
  sqlite3_expired $S
} {1}
do_test analyze3-3.4.6 {
  sqlite3_finalize $S
} {SQLITE_OK}

do_test analyze3-3.5.1 {
  set S [sqlite3_prepare_v2 db {
    SELECT * FROM t1 WHERE a IN (
      ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10,
      ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20,
      ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31
    ) AND b>?32;
  } -1 dummy]
  sqlite3_expired $S
} {0}
do_test analyze3-3.5.2 {
  sqlite3_bind_text $S 31 "abc" 3
  sqlite3_expired $S
} {0}
do_test analyze3-3.5.3 {
  sqlite3_bind_text $S 32 "def" 3
  sqlite3_expired $S
} {1}
do_test analyze3-3.5.5 {
  sqlite3_finalize $S
} {SQLITE_OK}

do_test analyze3-3.6.1 {
  set S [sqlite3_prepare_v2 db {
    SELECT * FROM t1 WHERE a IN (
      ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10,
      ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20,
      ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32
    ) AND b>?33;
  } -1 dummy]
  sqlite3_expired $S
} {0}
do_test analyze3-3.6.2 {
  sqlite3_bind_text $S 32 "abc" 3
  sqlite3_expired $S
} {1}
do_test analyze3-3.6.3 {
  sqlite3_bind_text $S 33 "def" 3
  sqlite3_expired $S
} {1}
do_test analyze3-3.6.5 {
  sqlite3_finalize $S
} {SQLITE_OK}

do_test analyze3-3.7.1 {
breakpoint
  set S [sqlite3_prepare_v2 db {
    SELECT * FROM t1 WHERE a IN (
      ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?33,
      ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20,
      ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32
    ) AND b>?10;
  } -1 dummy]
  sqlite3_expired $S
} {0}
do_test analyze3-3.7.2 {
  sqlite3_bind_text $S 32 "abc" 3
  sqlite3_expired $S
} {0}
do_test analyze3-3.7.3 {
  sqlite3_bind_text $S 33 "def" 3
  sqlite3_expired $S
} {0}
do_test analyze3-3.7.4 {
  sqlite3_bind_text $S 10 "def" 3
  sqlite3_expired $S
} {1}
do_test analyze3-3.7.6 {
  sqlite3_finalize $S
} {SQLITE_OK}

do_test analyze3-3.8.1 {
  execsql {
    CREATE TABLE t4(x, y TEXT COLLATE NOCASE);
    CREATE INDEX i4 ON t4(y);
  }
} {}
do_test analyze3-3.8.2 {
  set S [sqlite3_prepare_v2 db {
    SELECT * FROM t4 WHERE x != ? AND y LIKE ?
  } -1 dummy]
  sqlite3_expired $S
} {0}
do_test analyze3-3.8.3 {
  sqlite3_bind_text $S 1 "abc" 3
  sqlite3_expired $S
} {0}
do_test analyze3-3.8.4 {
  sqlite3_bind_text $S 2 "def" 3
  sqlite3_expired $S
} {1}
do_test analyze3-3.8.7 {
  sqlite3_bind_text $S 2 "ghi%" 4
  sqlite3_expired $S
} {1}
do_test analyze3-3.8.8 {
  sqlite3_expired $S
} {1}
do_test analyze3-3.8.9 {
  sqlite3_bind_text $S 2 "ghi%def" 7
  sqlite3_expired $S
} {1}
do_test analyze3-3.8.10 {
  sqlite3_expired $S
} {1}
do_test analyze3-3.8.11 {
  sqlite3_bind_text $S 2 "%ab" 3
  sqlite3_expired $S
} {1}
do_test analyze3-3.8.12 {
  sqlite3_expired $S
} {1}
do_test analyze3-3.8.12 {
  sqlite3_bind_text $S 2 "%de" 3
  sqlite3_expired $S
} {1}
do_test analyze3-3.8.13 {
  sqlite3_expired $S
} {1}
do_test analyze3-3.8.14 {
  sqlite3_finalize $S
} {SQLITE_OK}

#-------------------------------------------------------------------------
# These tests check that errors encountered while repreparing an SQL
# statement within sqlite3Reprepare() are handled correctly.
#

# Check a schema error.
#
do_test analyze3-4.1.1 {
  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
  sqlite3_step $S
} {SQLITE_DONE}
do_test analyze3-4.1.2 {
  sqlite3_reset $S
  sqlite3_bind_text $S 2 "abc" 3
  execsql { DROP TABLE t1 }
  sqlite3_step $S
} {SQLITE_SCHEMA}
do_test analyze3-4.1.3 {
  sqlite3_finalize $S
} {SQLITE_SCHEMA}

# Check an authorization error.
#
do_test analyze3-4.2.1 {
  execsql {
    BEGIN;
    CREATE TABLE t1(a, b, c);
    CREATE INDEX i1 ON t1(b);
  }
  for {set i 0} {$i < 100} {incr i} {
    execsql { INSERT INTO t1 VALUES($i, $i, $i) }
  }
  execsql COMMIT
  execsql ANALYZE
  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
  sqlite3_step $S
} {SQLITE_DONE}
db auth auth
proc auth {args} {
  if {[lindex $args 0] == "SQLITE_READ"} {return SQLITE_DENY}
  return SQLITE_OK
}
do_test analyze3-4.2.2 {
  sqlite3_reset $S
  sqlite3_bind_text $S 2 "abc" 3
  sqlite3_step $S
} {SQLITE_SCHEMA}
do_test analyze3-4.2.4 {
  sqlite3_finalize $S
} {SQLITE_SCHEMA}

# Check the effect of an authorization error that occurs in a re-prepare
# performed by sqlite3_step() is the same as one that occurs within
# sqlite3Reprepare().
#
do_test analyze3-4.3.1 {
  db auth {}
  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE a=? AND b>?" -1 dummy]
  execsql { CREATE TABLE t2(d, e, f) }
  db auth auth
  sqlite3_step $S
} {SQLITE_SCHEMA}
do_test analyze3-4.3.2 {
  sqlite3_finalize $S
} {SQLITE_SCHEMA}
db auth {}

#-------------------------------------------------------------------------
# Test that modifying bound variables using the clear_bindings() or
# transfer_bindings() APIs works.
#
#   analyze3-5.1.*: sqlite3_clear_bindings()
#   analyze3-5.2.*: sqlite3_transfer_bindings()
#
do_test analyze3-5.1.1 {
  drop_all_tables
  execsql {
    CREATE TABLE t1(x TEXT COLLATE NOCASE);
    CREATE INDEX i1 ON t1(x);
    INSERT INTO t1 VALUES('aaa');
    INSERT INTO t1 VALUES('abb');
    INSERT INTO t1 VALUES('acc');
    INSERT INTO t1 VALUES('baa');
    INSERT INTO t1 VALUES('bbb');
    INSERT INTO t1 VALUES('bcc');
  }

  set S [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x LIKE ?" -1 dummy]
  sqlite3_bind_text $S 1 "a%" 2
  set R [list]
  while { "SQLITE_ROW" == [sqlite3_step $S] } {
    lappend R [sqlite3_column_text $S 0]
  }
  concat [sqlite3_reset $S] $R
} {SQLITE_OK aaa abb acc}
do_test analyze3-5.1.2 {
  sqlite3_clear_bindings $S
  set R [list]
  while { "SQLITE_ROW" == [sqlite3_step $S] } {
    lappend R [sqlite3_column_text $S 0]
  }
  concat [sqlite3_reset $S] $R
} {SQLITE_OK}
do_test analyze3-5.1.3 {
  sqlite3_finalize $S
} {SQLITE_OK}

do_test analyze3-5.1.1 {
  set S1 [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x LIKE ?" -1 dummy]
  sqlite3_bind_text $S1 1 "b%" 2
  set R [list]
  while { "SQLITE_ROW" == [sqlite3_step $S1] } {
    lappend R [sqlite3_column_text $S1 0]
  }
  concat [sqlite3_reset $S1] $R
} {SQLITE_OK baa bbb bcc}

do_test analyze3-5.1.2 {
  set S2 [sqlite3_prepare_v2 db "SELECT * FROM t1 WHERE x = ?" -1 dummy]
  sqlite3_bind_text $S2 1 "a%" 2
  sqlite3_transfer_bindings $S2 $S1
  set R [list]
  while { "SQLITE_ROW" == [sqlite3_step $S1] } {
    lappend R [sqlite3_column_text $S1 0]
  }
  concat [sqlite3_reset $S1] $R
} {SQLITE_OK aaa abb acc}
do_test analyze3-5.1.3 {
  sqlite3_finalize $S2
  sqlite3_finalize $S1
} {SQLITE_OK}

finish_test

Added test/async5.test.





































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 July 19
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file tests that asynchronous IO is compatible with multi-file
# transactions.
#
# $Id: async5.test,v 1.1 2009/07/18 11:52:04 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

if {[info commands sqlite3async_initialize] eq ""} {
  # The async logic is not built into this system
  finish_test
  return
}

db close
file delete -force test2.db
sqlite3async_initialize "" 1
sqlite3async_control halt never
sqlite3 db test.db

do_test async5-1.1 {
  execsql {
    ATTACH 'test2.db' AS next;
    CREATE TABLE main.t1(a, b);
    CREATE TABLE next.t2(a, b);
    BEGIN;
      INSERT INTO t1 VALUES(1, 2);
      INSERT INTO t2 VALUES(3, 4);
    COMMIT;
  }
} {}
do_test async5-1.2 {
  execsql { SELECT * FROM t1 }
} {1 2}
do_test async5-1.3 {
  execsql { SELECT * FROM t2 }
} {3 4}
do_test async5-1.4 {
  execsql {
    BEGIN;
      INSERT INTO t1 VALUES('a', 'b');
      INSERT INTO t2 VALUES('c', 'd');
    COMMIT;
  }
} {}
do_test async5-1.5 {
  execsql { SELECT * FROM t1 }
} {1 2 a b}
do_test async5-1.6 {
  execsql { SELECT * FROM t2 }
} {3 4 c d}

db close

sqlite3async_control halt idle
sqlite3async_start
sqlite3async_wait
sqlite3async_control halt never
sqlite3async_shutdown
set sqlite3async_trace 0
finish_test

Changes to test/attach3.test.
18
19
20
21
22
23
24





25
26
27
28
29
30
31
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36







+
+
+
+
+







set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !attach {
  finish_test
  return
}

# The tests in this file were written before SQLite supported recursive
# trigger invocation, and some tests depend on that to pass. So disable
# recursive triggers for this file.
catchsql { pragma recursive_triggers = off } 

# Create tables t1 and t2 in the main database
execsql {
  CREATE TABLE t1(a, b);
  CREATE TABLE t2(c, d);
}

313
314
315
316
317
318
319

320
321
322
323
324
325
326
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332







+







do_test attach3-12.9 {
  execsql {
    ATTACH DATABASE '' AS NULL
  }
  db_list
} {main temp {}}
do_test attach3-12.10 {
breakpoint
  execsql {
    DETACH ?
  }
  db_list
} {main temp}
do_test attach3-12.11 {
  catchsql {
Changes to test/auth.test.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the sqlite3_set_authorizer() API
# and related functionality.
#
# $Id: auth.test,v 1.45 2009/05/04 01:58:31 drh Exp $
# $Id: auth.test,v 1.46 2009/07/02 18:40:35 danielk1977 Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# disable this test if the SQLITE_OMIT_AUTHORIZATION macro is
# defined during compilation.
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258



2259

2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282


2283
2284
2285
2286
2287
2288
2289
2244
2245
2246
2247
2248
2249
2250



2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276


2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290







-
-
-





+
+
+

+
















-
-





+
+







  set authargs {}
  execsql {
    UPDATE v1 SET x=1 WHERE x=117
  }
  set authargs
} [list \
  SQLITE_UPDATE v1     x  main {} \
  SQLITE_INSERT v1chng {} main r2 \
  SQLITE_READ   v1     x  main r2 \
  SQLITE_READ   v1     x  main r2 \
  SQLITE_SELECT {}     {} {}   v1 \
  SQLITE_READ   t2     a  main v1 \
  SQLITE_READ   t2     b  main v1 \
  SQLITE_SELECT {}     {} {}   {} \
  SQLITE_READ   v1     x  main v1 \
  SQLITE_INSERT v1chng {} main r2 \
  SQLITE_READ   v1     x  main r2 \
  SQLITE_READ   v1     x  main r2 \
]

do_test auth-4.4 {
  execsql {
    CREATE TRIGGER r3 INSTEAD OF DELETE ON v1 BEGIN
      INSERT INTO v1chng VALUES(OLD.x,NULL);
    END;
    SELECT * FROM v1;
  }
} {115 117}
do_test auth-4.5 {
  set authargs {}
  execsql {
    DELETE FROM v1 WHERE x=117
  }
  set authargs
} [list \
  SQLITE_DELETE v1     {} main {} \
  SQLITE_INSERT v1chng {} main r3 \
  SQLITE_READ   v1     x  main r3 \
  SQLITE_SELECT {}     {} {}   v1 \
  SQLITE_READ   t2     a  main v1 \
  SQLITE_READ   t2     b  main v1 \
  SQLITE_SELECT {}     {} {}   {} \
  SQLITE_READ   v1     x  main v1 \
  SQLITE_INSERT v1chng {} main r3 \
  SQLITE_READ   v1     x  main r3 \
]

} ;# ifcapable view && trigger

# Ticket #1338:  Make sure authentication works in the presence of an AS
# clause.
#
2304
2305
2306
2307
2308
2309
2310





2311
2312
2313
2314
2315
2316
2317
2318
2319





























2320
2321
2322
2323
2324
2325
2326
2327
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324

2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361







+
+
+
+
+








-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








      DROP TABLE tx;
    }
    ifcapable view {
      execsql {
        DROP TABLE v1chng;
      }
    }
  }
  ifcapable stat2 {
    set stat2 "sqlite_stat2 "
  } else {
    set stat2 ""
  }
  do_test auth-5.2 {
    execsql {
      SELECT name FROM (
        SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master)
      WHERE type='table'
      ORDER BY name
    }
  } {sqlite_stat1 t1 t2 t3 t4}
  } "sqlite_stat1 ${stat2}t1 t2 t3 t4"
}

# Ticket #3944
#
ifcapable trigger {
  do_test auth-5.3.1 {
    execsql {
      CREATE TABLE t5 ( x );
      CREATE TRIGGER t5_tr1 AFTER INSERT ON t5 BEGIN 
        UPDATE t5 SET x = 1 WHERE NEW.x = 0;
      END;
    }
  } {}
  set ::authargs [list]
  proc auth {args} {
    eval lappend ::authargs $args
    return SQLITE_OK
  }
  do_test auth-5.3.2 {
    execsql { INSERT INTO t5 (x) values(0) }
    set ::authargs
  } [list SQLITE_INSERT t5 {} main {}    \
          SQLITE_UPDATE t5 x main t5_tr1 \
          SQLITE_READ t5 x main t5_tr1   \
    ]
  do_test auth-5.3.2 {
    execsql { SELECT * FROM t5 }
  } {1}
}


rename proc {}
rename proc_real proc


finish_test
Changes to test/autoinc.test.
21
22
23
24
25
26
27


28
29
30
31
32
33
34
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36







+
+







# skip all tests in this file.
#
ifcapable {!autoinc} {
  finish_test
  return
}

sqlite3_db_config_lookaside db 0 0 0

# The database is initially empty.
#
do_test autoinc-1.1 {
  execsql {
    SELECT name FROM sqlite_master WHERE type='table';
  }
} {}
552
553
554
555
556
557
558



559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581























582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635















































































636
637
554
555
556
557
558
559
560
561
562
563























564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587





















































588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668







+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


    CREATE TABLE t3(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
    INSERT INTO t3 SELECT * FROM t2 WHERE y>1;

    SELECT * FROM sqlite_sequence WHERE name='t3';
  }
} {t3 0}

ifcapable trigger {
  catchsql { pragma recursive_triggers = off } 
  
# Ticket #3928.  Make sure that triggers to not make extra slots in
# the SQLITE_SEQUENCE table.
#
do_test autoinc-3928.1 {
  db eval {
    CREATE TABLE t3928(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
    CREATE TRIGGER t3928r1 BEFORE INSERT ON t3928 BEGIN
      INSERT INTO t3928(b) VALUES('before1');
      INSERT INTO t3928(b) VALUES('before2');
    END;
    CREATE TRIGGER t3928r2 AFTER INSERT ON t3928 BEGIN
      INSERT INTO t3928(b) VALUES('after1');
      INSERT INTO t3928(b) VALUES('after2');
    END;
    INSERT INTO t3928(b) VALUES('test');
    SELECT * FROM t3928 ORDER BY a;
  }
} {1 before1 2 after1 3 after2 4 before2 5 after1 6 after2 7 test 8 before1 9 before2 10 after1 11 before1 12 before2 13 after2}
do_test autoinc-3928.2 {
  db eval {
    SELECT * FROM sqlite_sequence WHERE name='t3928'
  }
} {t3928 13}
  # Ticket #3928.  Make sure that triggers to not make extra slots in
  # the SQLITE_SEQUENCE table.
  #
  do_test autoinc-3928.1 {
    db eval {
      CREATE TABLE t3928(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
      CREATE TRIGGER t3928r1 BEFORE INSERT ON t3928 BEGIN
        INSERT INTO t3928(b) VALUES('before1');
        INSERT INTO t3928(b) VALUES('before2');
      END;
      CREATE TRIGGER t3928r2 AFTER INSERT ON t3928 BEGIN
        INSERT INTO t3928(b) VALUES('after1');
        INSERT INTO t3928(b) VALUES('after2');
      END;
      INSERT INTO t3928(b) VALUES('test');
      SELECT * FROM t3928 ORDER BY a;
    }
  } {1 before1 2 after1 3 after2 4 before2 5 after1 6 after2 7 test 8 before1 9 before2 10 after1 11 before1 12 before2 13 after2}
  do_test autoinc-3928.2 {
    db eval {
      SELECT * FROM sqlite_sequence WHERE name='t3928'
    }
  } {t3928 13}

do_test autoinc-3928.3 {
  db eval {
    DROP TRIGGER t3928r1;
    DROP TRIGGER t3928r2;
    CREATE TRIGGER t3928r3 BEFORE UPDATE ON t3928 
      WHEN typeof(new.b)=='integer' BEGIN
         INSERT INTO t3928(b) VALUES('before-int-' || new.b);
    END;
    CREATE TRIGGER t3928r4 AFTER UPDATE ON t3928 
      WHEN typeof(new.b)=='integer' BEGIN
         INSERT INTO t3928(b) VALUES('after-int-' || new.b);
    END;
    DELETE FROM t3928 WHERE a!=1;
    UPDATE t3928 SET b=456 WHERE a=1;
    SELECT * FROM t3928 ORDER BY a;
  }
} {1 456 14 before-int-456 15 after-int-456}
do_test autoinc-3928.4 {
  db eval {
    SELECT * FROM sqlite_sequence WHERE name='t3928'
  }
} {t3928 15}

do_test autoinc-3928.5 {
  db eval {
    CREATE TABLE t3928b(x);
    INSERT INTO t3928b VALUES(100);
    INSERT INTO t3928b VALUES(200);
    INSERT INTO t3928b VALUES(300);
    DELETE FROM t3928;
    CREATE TABLE t3928c(y INTEGER PRIMARY KEY AUTOINCREMENT, z);
    CREATE TRIGGER t3928br1 BEFORE DELETE ON t3928b BEGIN
      INSERT INTO t3928(b) VALUES('before-del-'||old.x);
      INSERT INTO t3928c(z) VALUES('before-del-'||old.x);
    END;
    CREATE TRIGGER t3928br2 AFTER DELETE ON t3928b BEGIN
      INSERT INTO t3928(b) VALUES('after-del-'||old.x);
      INSERT INTO t3928c(z) VALUES('after-del-'||old.x);
    END;
    DELETE FROM t3928b;
    SELECT * FROM t3928 ORDER BY a;
  }
} {16 before-del-100 17 after-del-100 18 before-del-200 19 after-del-200 20 before-del-300 21 after-del-300}
do_test autoinc-3928.6 {
  db eval {
    SELECT * FROM t3928c ORDER BY y;
  }
} {1 before-del-100 2 after-del-100 3 before-del-200 4 after-del-200 5 before-del-300 6 after-del-300}
do_test autoinc-3928.7 {
  db eval {
    SELECT * FROM sqlite_sequence WHERE name LIKE 't3928%' ORDER BY name;
  }
} {t3928 21 t3928c 6}
  do_test autoinc-3928.3 {
    db eval {
      DROP TRIGGER t3928r1;
      DROP TRIGGER t3928r2;
      CREATE TRIGGER t3928r3 BEFORE UPDATE ON t3928 
        WHEN typeof(new.b)=='integer' BEGIN
           INSERT INTO t3928(b) VALUES('before-int-' || new.b);
      END;
      CREATE TRIGGER t3928r4 AFTER UPDATE ON t3928 
        WHEN typeof(new.b)=='integer' BEGIN
           INSERT INTO t3928(b) VALUES('after-int-' || new.b);
      END;
      DELETE FROM t3928 WHERE a!=1;
      UPDATE t3928 SET b=456 WHERE a=1;
      SELECT * FROM t3928 ORDER BY a;
    }
  } {1 456 14 before-int-456 15 after-int-456}
  do_test autoinc-3928.4 {
    db eval {
      SELECT * FROM sqlite_sequence WHERE name='t3928'
    }
  } {t3928 15}
  
  do_test autoinc-3928.5 {
    db eval {
      CREATE TABLE t3928b(x);
      INSERT INTO t3928b VALUES(100);
      INSERT INTO t3928b VALUES(200);
      INSERT INTO t3928b VALUES(300);
      DELETE FROM t3928;
      CREATE TABLE t3928c(y INTEGER PRIMARY KEY AUTOINCREMENT, z);
      CREATE TRIGGER t3928br1 BEFORE DELETE ON t3928b BEGIN
        INSERT INTO t3928(b) VALUES('before-del-'||old.x);
        INSERT INTO t3928c(z) VALUES('before-del-'||old.x);
      END;
      CREATE TRIGGER t3928br2 AFTER DELETE ON t3928b BEGIN
        INSERT INTO t3928(b) VALUES('after-del-'||old.x);
        INSERT INTO t3928c(z) VALUES('after-del-'||old.x);
      END;
      DELETE FROM t3928b;
      SELECT * FROM t3928 ORDER BY a;
    }
  } {16 before-del-100 17 after-del-100 18 before-del-200 19 after-del-200 20 before-del-300 21 after-del-300}
  do_test autoinc-3928.6 {
    db eval {
      SELECT * FROM t3928c ORDER BY y;
    }
  } {1 before-del-100 2 after-del-100 3 before-del-200 4 after-del-200 5 before-del-300 6 after-del-300}
  do_test autoinc-3928.7 {
    db eval {
      SELECT * FROM sqlite_sequence WHERE name LIKE 't3928%' ORDER BY name;
    }
  } {t3928 21 t3928c 6}
  
  # Ticket [a696379c1f0886615541a48b35bd8181a80e88f8]
  do_test autoinc-a69637.1 {
    db eval {
      CREATE TABLE ta69637_1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
      CREATE TABLE ta69637_2(z);
      CREATE TRIGGER ra69637_1 AFTER INSERT ON ta69637_2 BEGIN
        INSERT INTO ta69637_1(y) VALUES(new.z+1);
      END;
      INSERT INTO ta69637_2 VALUES(123);
      SELECT * FROM ta69637_1;
    }
  } {1 124}
  do_test autoinc-a69637.2 {
    db eval {
      CREATE VIEW va69637_2 AS SELECT * FROM ta69637_2;
      CREATE TRIGGER ra69637_2 INSTEAD OF INSERT ON va69637_2 BEGIN
        INSERT INTO ta69637_1(y) VALUES(new.z+10000);
      END;
      INSERT INTO va69637_2 VALUES(123);
      SELECT * FROM ta69637_1;
    }
  } {1 124 2 10123}
}



finish_test
Changes to test/bind.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21













-
+







# 2003 September 6
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the sqlite_bind API.
#
# $Id: bind.test,v 1.47 2009/02/20 03:55:05 drh Exp $
# $Id: bind.test,v 1.48 2009/07/22 07:27:57 danielk1977 Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

proc sqlite_step {stmt N VALS COLS} {
  upvar VALS vals
287
288
289
290
291
292
293
294

295
296
297
298
299
300
301
287
288
289
290
291
292
293

294
295
296
297
298
299
300
301







-
+







  sqlite3_bind_text $VM 2 hello\000there\000 11
  sqlite3_bind_text $VM 3 hello\000there\000 -1
  sqlite_step $VM N VALUES COLNAMES
  sqlite3_reset $VM
  execsql {SELECT * FROM t1}
} {hello hello hello}
set enc [db eval {PRAGMA encoding}]
if {$enc=="UTF-8"} {
if {$enc=="UTF-8" || $enc==""} {
  do_test bind-6.5 {
    execsql {SELECT  hex(a), hex(b), hex(c) FROM t1}
  } {68656C6C6F00746865726500 68656C6C6F007468657265 68656C6C6F}
} elseif {$enc=="UTF-16le"} {
  do_test bind-6.5 {
    execsql {SELECT  hex(a), hex(b), hex(c) FROM t1}
  } {680065006C006C006F000000740068006500720065000000 680065006C006C006F00000074006800650072006500 680065006C006C006F00}
Changes to test/boundary4.tcl.
16
17
18
19
20
21
22

23
24
25
26
27
28
29
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30







+







# $Id: boundary4.tcl,v 1.3 2009/01/02 15:45:48 shane Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Many of the boundary tests depend on a working 64-bit implementation.
if {![working_64bit_int]} { finish_test; return }
ifcapable !altertable     { finish_test; return }
}

expr srand(0)

# Generate interesting boundary numbers
#
foreach x {
Changes to test/boundary4.test.
16
17
18
19
20
21
22

23
24
25
26
27
28
29
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30







+







# $Id: boundary4.test,v 1.2 2009/01/02 15:45:48 shane Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Many of the boundary tests depend on a working 64-bit implementation.
if {![working_64bit_int]} { finish_test; return }
ifcapable !altertable     { finish_test; return }

do_test boundary4-1.1 {
  db eval {
    CREATE TABLE t1(a,x);
    INSERT INTO t1(oid,a,x) VALUES(549755813887,1,'0000007fffffffff');
    INSERT INTO t1(oid,a,x) VALUES(-8388608,2,'ffffffffff800000');
    INSERT INTO t1(oid,a,x) VALUES(0,3,'0000000000000000');
Changes to test/capi3c.test.
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23







-
+







#
#***********************************************************************
# This file implements regression tests for SQLite library.  
#
# This is a copy of the capi3.test file that has been adapted to
# test the new sqlite3_prepare_v2 interface.
#
# $Id: capi3c.test,v 1.22 2008/11/05 16:37:35 drh Exp $
# $Id: capi3c.test,v 1.23 2009/07/22 07:27:57 danielk1977 Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
1288
1289
1290
1291
1292
1293
1294

1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320





























































1321
1322
1288
1289
1290
1291
1292
1293
1294
1295


























1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358







+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


sqlite3_finalize $STMT

# For a multi-column result set where the same table column is repeated
# in multiple columns of the output, verify that doing a UTF-8 to UTF-16
# conversion (or vice versa) on one column does not change the value of
# the second.
#
ifcapable utf16 {
do_test capi3c-23.1 {
  set STMT [sqlite3_prepare_v2 db {SELECT b,b,b,b FROM t1} -1 TAIL]
  sqlite3_step $STMT
} {SQLITE_ROW}
do_test capi3c-23.2 {
  sqlite3_column_text16 $STMT 0
  sqlite3_column_text $STMT 1
} {one}
do_test capi3c-23.3 {
  sqlite3_column_text16 $STMT 2
  sqlite3_column_text $STMT 3
} {one}
sqlite3_finalize $STMT
do_test capi3c-23.4 {
  set STMT [sqlite3_prepare_v2 db {SELECT b||'x',b,b,b FROM t1} -1 TAIL]
  sqlite3_step $STMT
} {SQLITE_ROW}
do_test capi3c-23.5 {
  sqlite3_column_text16 $STMT 0
  sqlite3_column_text $STMT 1
} {one}
do_test capi3c-23.6 {
  sqlite3_column_text16 $STMT 2
  sqlite3_column_text $STMT 3
} {one}
sqlite3_finalize $STMT
  do_test capi3c-23.1 {
    set STMT [sqlite3_prepare_v2 db {SELECT b,b,b,b FROM t1} -1 TAIL]
    sqlite3_step $STMT
  } {SQLITE_ROW}
  do_test capi3c-23.2 {
    sqlite3_column_text16 $STMT 0
    sqlite3_column_text $STMT 1
  } {one}
  do_test capi3c-23.3 {
    sqlite3_column_text16 $STMT 2
    sqlite3_column_text $STMT 3
  } {one}
  sqlite3_finalize $STMT
  do_test capi3c-23.4 {
    set STMT [sqlite3_prepare_v2 db {SELECT b||'x',b,b,b FROM t1} -1 TAIL]
    sqlite3_step $STMT
  } {SQLITE_ROW}
  do_test capi3c-23.5 {
    sqlite3_column_text16 $STMT 0
    sqlite3_column_text $STMT 1
  } {one}
  do_test capi3c-23.6 {
    sqlite3_column_text16 $STMT 2
    sqlite3_column_text $STMT 3
  } {one}
  sqlite3_finalize $STMT
}

# Test decltype on some SELECT statements that contain sub-selects.
#
proc decltype {zSql} {
  set ret [list]
  set STMT [sqlite3_prepare_v2 db $zSql -1 TAIL]
  for {set i 0} {$i < [sqlite3_column_count $STMT]} {incr i} {
    lappend ret [sqlite3_column_decltype $STMT $i]
  }
  sqlite3_finalize $STMT
  return $ret
}
do_test capi3c-24.1 {
  execsql { CREATE TABLE t5(a INTEGER, b STRING, c DATETIME) }
  decltype {SELECT * FROM t5}
} {INTEGER STRING DATETIME}
do_test capi3c-24.2 {
  decltype {SELECT (SELECT c) FROM t5}
} {DATETIME}
do_test capi3c-24.3 {
  decltype {SELECT (SELECT * FROM (SELECT c)) FROM t5}
} {DATETIME}
do_test capi3c-24.4 {
  decltype {SELECT * FROM (SELECT * FROM t5 ORDER BY c LIMIT 1) ORDER BY b}
} {INTEGER STRING DATETIME}
do_test capi3c-24.5 {
  decltype {
    SELECT (SELECT x FROM (SELECT c AS x)) 
    FROM (SELECT * FROM t5 ORDER BY c LIMIT 1) ORDER BY b
  }
} {DATETIME}
do_test capi3c-24.3 {
  decltype {SELECT (SELECT x FROM (SELECT t5.a AS x)) FROM t5}
} {INTEGER}

finish_test
Added test/coalesce.test.




















































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 November 10
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# Additional test cases for the COALESCE() and IFNULL() functions.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl


do_test coalesce-1.0 {
  db eval {
    CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d);
    INSERT INTO t1 VALUES(1, null, null, null);
    INSERT INTO t1 VALUES(2, 2, 99, 99);
    INSERT INTO t1 VALUES(3, null, 3, 99);
    INSERT INTO t1 VALUES(4, null, null, 4);
    INSERT INTO t1 VALUES(5, null, null, null);
    INSERT INTO t1 VALUES(6, 22, 99, 99);
    INSERT INTO t1 VALUES(7, null, 33, 99);
    INSERT INTO t1 VALUES(8, null, null, 44);

    SELECT coalesce(b,c,d) FROM t1 ORDER BY a;
  }
} {{} 2 3 4 {} 22 33 44}
do_test coalesce-1.1 {
  db eval {
    SELECT coalesce(d+c+b,d+c,d) FROM t1 ORDER BY a;
  }
} {{} 200 102 4 {} 220 132 44}
do_test coalesce-1.2 {
  db eval {
    SELECT ifnull(d+c+b,ifnull(d+c,d)) FROM t1 ORDER BY a;
  }
} {{} 200 102 4 {} 220 132 44}
do_test coalesce-1.3 {
  db eval {
    SELECT ifnull(ifnull(d+c+b,d+c),d) FROM t1 ORDER BY a;
  }
} {{} 200 102 4 {} 220 132 44}
do_test coalesce-1.4 {
  db eval {
    SELECT ifnull(ifnull(b,c),d) FROM t1 ORDER BY a;
  }
} {{} 2 3 4 {} 22 33 44}
do_test coalesce-1.5 {
  db eval {
    SELECT ifnull(b,ifnull(c,d)) FROM t1 ORDER BY a;
  }
} {{} 2 3 4 {} 22 33 44}
do_test coalesce-1.6 {
  db eval {
    SELECT coalesce(b,NOT b,-b,abs(b),lower(b),length(b),min(b,5),b*123,c)
      FROM t1 ORDER BY a;
  }
} {{} 2 3 {} {} 22 33 {}}
do_test coalesce-1.7 {
  db eval {
    SELECT ifnull(nullif(a,4),99)
      FROM t1 ORDER BY a;
  }
} {1 2 3 99 5 6 7 8}
do_test coalesce-1.8 {
  db eval {
pragma vdbe_listing=on;
    SELECT coalesce(
      CASE WHEN b=2 THEN 123 END,
      CASE WHEN b=3 THEN 234 END,
      CASE WHEN c=3 THEN 345 WHEN c=33 THEN 456 END,
      d
    )
    FROM t1 ORDER BY a;
  }
} {{} 123 345 4 {} 99 456 44}


finish_test
Changes to test/corrupt.test.
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23







-
+







#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests to make sure SQLite does not crash or
# segfault if it sees a corrupt database file.
#
# $Id: corrupt.test,v 1.10 2008/08/25 12:14:09 drh Exp $
# $Id: corrupt.test,v 1.12 2009/07/13 09:41:45 danielk1977 Exp $

catch {file delete -force test.db test.db-journal test.bu}

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Construct a large database for testing.
170
171
172
173
174
175
176



















































































177
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

  db close
  sqlite3 db test.db
  catchsql {
    SELECT * FROM t1 WHERE x = 'abcde';
  }
} {1 {database disk image is malformed}}

do_test corrupt-4.1 {
  db close
  file delete -force test.db test.db-journal
  sqlite3 db test.db
  execsql {
    PRAGMA page_size = 1024;
    CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT);
  }
  for {set i 0} {$i < 10} {incr i} {
    set text [string repeat $i 220]
    execsql { INSERT INTO t1 VALUES($i, $text) }
  }
  execsql { CREATE INDEX i1 ON t1(b) }
} {}
do_test corrupt-4.2 {
  set iRoot [db one {SELECT rootpage FROM sqlite_master WHERE name = 'i1'}]
  set iOffset [hexio_get_int [hexio_read test.db [expr 12+($iRoot-1)*1024] 2]]
  set data [hexio_render_int32 [expr $iRoot - 1]]
  hexio_write test.db [expr ($iRoot-1)*1024 + $iOffset] $data
  db close
  sqlite3 db test.db

  # The following DELETE statement attempts to delete a cell stored on the
  # root page of index i1. After this cell is deleted it must be replaced
  # by a cell retrieved from the child page (a leaf) of the deleted cell.
  # This will fail, as the block modified the database image so that the
  # child page of the deleted cell is from a table (intkey) b-tree, not an
  # index b-tree as expected. At one point this was causing an assert()
  # to fail.
  catchsql { DELETE FROM t1 WHERE rowid = 3 }
} {1 {database disk image is malformed}}

do_test corrupt-5.1 {
  db close
  file delete -force test.db test.db-journal
  sqlite3 db test.db

  execsql { PRAGMA page_size = 1024 }
  set ct "CREATE TABLE t1(c0 "
  set i 0
  while {[string length $ct] < 950} { append ct ", c[incr i]" }
  append ct ")"
  execsql $ct
} {}

do_test corrupt-5.2 {
  db close
  hexio_write test.db 108 00000000 
  sqlite3 db test.db
  catchsql { SELECT * FROM sqlite_master }
} {1 {database disk image is malformed}}

# At one point, the specific corruption caused by this test case was
# causing a buffer overwrite. Although a crash was never demonstrated,
# running this testcase under valgrind revealed the problem.
do_test corrupt-6.1 {
  db close
  file delete -force test.db test.db-journal
  sqlite3 db test.db
  execsql { 
    PRAGMA page_size = 1024; CREATE TABLE t1(x);
  }

  # The root page of t1 is 1024 bytes in size. The header is 8 bytes, and
  # each of the cells inserted by the following INSERT statements consume
  # 16 bytes (including the 2 byte cell-offset array entry). So the page
  # can contain up to 63 cells.
  for {set i 0} {$i < 63} {incr i} {
    execsql { INSERT INTO t1 VALUES( randomblob(10) ) }
  }

  # Free the cell stored right at the end of the page (at offset pgsz-14).
  execsql { DELETE FROM t1 WHERE rowid=1 }
  set rootpage [db one {SELECT rootpage FROM sqlite_master WHERE name = 't1'}]
  db close

  set offset [expr ($rootpage * 1024)-14+2]
  hexio_write test.db $offset 00FF
  sqlite3 db test.db 

  catchsql { INSERT INTO t1 VALUES( randomblob(10) ) }
} {1 {database disk image is malformed}}

finish_test
Changes to test/corrupt7.test.
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24







-
+







#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests to make sure SQLite does not crash or
# segfault if it sees a corrupt database file.  It specifically focuses
# on corrupt cell offsets in a btree page.
#
# $Id: corrupt7.test,v 1.7 2009/06/09 13:42:25 drh Exp $
# $Id: corrupt7.test,v 1.8 2009/08/10 10:18:08 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# We must have the page_size pragma for these tests to work.
#
ifcapable !pager_pragmas {
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77

78
79
80
81
82
83
84
63
64
65
66
67
68
69

70
71
72
73
74
75
76

77
78
79
80
81
82
83
84







-
+






-
+







ifcapable oversize_cell_check {
  do_test corrupt7-2.1 {
    db close
    hexio_write test.db 1062 FF
    sqlite3 db test.db
    db eval {PRAGMA integrity_check(1)}
  } {{*** in database main ***
Page 2: sqlite3BtreeInitPage() returns error code 11}}
Page 2: btreeInitPage() returns error code 11}}
  do_test corrupt7-2.2 {
    db close
    hexio_write test.db 1062 04
    sqlite3 db test.db
    db eval {PRAGMA integrity_check(1)}
  } {{*** in database main ***
Page 2: sqlite3BtreeInitPage() returns error code 11}}
Page 2: btreeInitPage() returns error code 11}}
} else {
  do_test corrupt7-2.1 {
    db close
    hexio_write test.db 1062 FF
    sqlite3 db test.db
    db eval {PRAGMA integrity_check(1)}
  } {{*** in database main ***
Changes to test/corruptB.test.
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
16
17
18
19
20
21
22

23
24
25
26
27
28
29
30







-
+







# when there exists a page that is both an a descendent or ancestor of
# itself.
#
# Also test that an SQLITE_CORRUPT error is returned if a B-Tree page
# contains a (corrupt) reference to a page greater than the configured
# maximum page number.
#
# $Id: corruptB.test,v 1.3 2009/06/05 17:09:12 drh Exp $
# $Id: corruptB.test,v 1.4 2009/07/21 19:25:24 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl


do_test corruptB-1.1 {
  execsql {
150
151
152
153
154
155
156
157

158
159
160
161
162
163
164
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164







-
+







  db close
  file copy -force bak.db test.db
  hexio_write test.db [expr $offset+8] [hexio_render_int32 0x6FFFFFFF]
} {4}
do_test corruptB-2.1.2 {
  sqlite3 db test.db
  catchsql { SELECT * FROM t1 }
} {1 {database disk image is malformed}}
} {1 {database or disk is full}}

#---------------------------------------------------------------------------

# Corrupt the header-size field of a database record.
#
do_test corruptB-3.1.1 {
  db close
Changes to test/corruptC.test.
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
11
12
13
14
15
16
17

18
19
20
21
22
23
24
25







-
+







# This file implements regression tests for SQLite library.
#
# This file implements tests to make sure SQLite does not crash or
# segfault if it sees a corrupt database file.  It creates a base
# data base file, then tests that single byte corruptions in 
# increasingly larger quantities are handled gracefully.
#
# $Id: corruptC.test,v 1.13 2009/06/06 19:21:13 drh Exp $
# $Id: corruptC.test,v 1.14 2009/07/11 06:55:34 danielk1977 Exp $

catch {file delete -force test.db test.db-journal test.bu}

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Construct a compact, dense database for testing.
150
151
152
153
154
155
156



157
158
159



160
161
162
163
164
165
166
150
151
152
153
154
155
156
157
158
159



160
161
162
163
164
165
166
167
168
169







+
+
+
-
-
-
+
+
+







  hexio_write test.db 3119 [format %02x 0xdf]
  hexio_write test.db 4073 [format %02x 0xbf]

  sqlite3 db test.db
  catchsql {BEGIN; UPDATE t2 SET y='abcdef-uvwxyz'; ROLLBACK;}
  catchsql {PRAGMA integrity_check}
} {0 {{*** in database main ***
Page 4: btreeInitPage() returns error code 11}}}

# {0 {{*** in database main ***
Corruption detected in cell 710 on page 4
Multiple uses for byte 661 of page 4
Fragmented space is 249 byte reported as 21 on page 4}}}
# Corruption detected in cell 710 on page 4
# Multiple uses for byte 661 of page 4
# Fragmented space is 249 byte reported as 21 on page 4}}}

# test that a corrupt free cell size is handled (seed 169595)
do_test corruptC-2.6 {
  db close
  copy_file test.bu test.db

  # insert corrupt byte(s)
Added test/e_fkey.test.





























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 October 7
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file implements tests to verify the "testable statements" in the
# foreignkeys.in document.
#
# The tests in this file are arranged to mirror the structure of 
# foreignkey.in, with one exception: The statements in section 2, which 
# deals with enabling/disabling foreign key support, is tested first,
# before section 1. This is because some statements in section 2 deal
# with builds that do not include complete foreign key support (because
# either SQLITE_OMIT_TRIGGER or SQLITE_OMIT_FOREIGN_KEY was defined
# at build time).
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

proc eqp {sql {db db}} { uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db }

###########################################################################
### SECTION 2: Enabling Foreign Key Support
###########################################################################

#-------------------------------------------------------------------------
# /* EV: R-33710-56344 */
#
# Test builds neither OMIT_FOREIGN_KEY or OMIT_TRIGGER defined have 
# foreign key functionality.
#
ifcapable trigger&&foreignkey {
  do_test e_fkey-49 {
    execsql {
      PRAGMA foreign_keys = ON;
      CREATE TABLE p(i PRIMARY KEY);
      CREATE TABLE c(j REFERENCES p ON UPDATE CASCADE);
      INSERT INTO p VALUES('hello');
      INSERT INTO c VALUES('hello');
      UPDATE p SET i = 'world';
      SELECT * FROM c;
    }
  } {world}
}

#-------------------------------------------------------------------------
# /* EV: R-44697-61543 */
#
# Test the effects of defining OMIT_TRIGGER but not OMIT_FOREIGN_KEY.
#
# /* EV: R-22567-44039 */
# /* EV: R-41784-13339 */
#
# Specifically, test that "PRAGMA foreign_keys" is a no-op in this case.
# When using the pragma to query the current setting, 0 rows are returned.
#
reset_db
ifcapable !trigger&&foreignkey {
  do_test e_fkey-51.1 {
    execsql {
      PRAGMA foreign_keys = ON;
      CREATE TABLE p(i PRIMARY KEY);
      CREATE TABLE c(j REFERENCES p ON UPDATE CASCADE);
      INSERT INTO p VALUES('hello');
      INSERT INTO c VALUES('hello');
      UPDATE p SET i = 'world';
      SELECT * FROM c;
    }
  } {hello}
  do_test e_fkey-51.2 {
    execsql { PRAGMA foreign_key_list(c) }
  } {0 0 p j {} CASCADE {NO ACTION} NONE}
  do_test e_fkey-51.3 {
    execsql { PRAGMA foreign_keys }
  } {}
}


#-------------------------------------------------------------------------
# /* EV: R-58428-36660 */
#
# Test the effects of defining OMIT_FOREIGN_KEY.
#
# /* EV: R-58428-36660 */
#
# Specifically, test that foreign key constraints cannot even be parsed 
# in such a build.
#
reset_db
ifcapable !foreignkey {
  do_test e_fkey-52.1 {
    execsql { CREATE TABLE p(i PRIMARY KEY) }
    catchsql { CREATE TABLE c(j REFERENCES p ON UPDATE CASCADE) }
  } {1 {near "ON": syntax error}}
  do_test e_fkey-52.2 {
    # This is allowed, as in this build, "REFERENCES" is not a keyword.
    # The declared datatype of column j is "REFERENCES p".
    execsql { CREATE TABLE c(j REFERENCES p) }
  } {}
  do_test e_fkey-52.3 {
    execsql { PRAGMA table_info(c) }
  } {0 j {REFERENCES p} 0 {} 0}
  do_test e_fkey-52.4 {
    execsql { PRAGMA foreign_key_list(c) }
  } {}
  do_test e_fkey-52.5 {
    execsql { PRAGMA foreign_keys }
  } {}
}

ifcapable !foreignkey||!trigger { finish_test ; return }
reset_db


#-------------------------------------------------------------------------
# /* EV: R-07280-60510 */
#
# Test that even if foreign keys are supported by the build, they must
# be enabled using "PRAGMA foreign_keys = ON" (or similar).
#
# /* EV: R-59578-04990 */
#
# This also tests that foreign key constraints are disabled by default.
#
drop_all_tables
do_test e_fkey-53.1 {
  execsql {
    CREATE TABLE p(i PRIMARY KEY);
    CREATE TABLE c(j REFERENCES p ON UPDATE CASCADE);
    INSERT INTO p VALUES('hello');
    INSERT INTO c VALUES('hello');
    UPDATE p SET i = 'world';
    SELECT * FROM c;
  } 
} {hello}
do_test e_fkey-53.2 {
  execsql {
    DELETE FROM c;
    DELETE FROM p;
    PRAGMA foreign_keys = ON;
    INSERT INTO p VALUES('hello');
    INSERT INTO c VALUES('hello');
    UPDATE p SET i = 'world';
    SELECT * FROM c;
  } 
} {world}

#-------------------------------------------------------------------------
# /* EV: R-15278-54456 */
# /* EV: R-11255-19907 */
#
# Test that the application can use "PRAGMA foreign_keys" to query for
# whether or not foreign keys are currently enabled. This also tests
# the example code in section 2 of foreignkeys.in.
#
reset_db
do_test e_fkey-54.1 {
  execsql { PRAGMA foreign_keys }
} {0}
do_test e_fkey-54.2 {
  execsql { 
    PRAGMA foreign_keys = ON;
    PRAGMA foreign_keys;
  }
} {1}
do_test e_fkey-54.3 {
  execsql { 
    PRAGMA foreign_keys = OFF;
    PRAGMA foreign_keys;
  }
} {0}

#-------------------------------------------------------------------------
# /* EV: R-46649-58537 */
#
# Test that it is not possible to enable or disable foreign key support
# while not in auto-commit mode.
#
reset_db
do_test e_fkey-55.1 {
  execsql {
    PRAGMA foreign_keys = ON;
    CREATE TABLE t1(a UNIQUE, b);
    CREATE TABLE t2(c, d REFERENCES t1(a));
    INSERT INTO t1 VALUES(1, 2);
    INSERT INTO t2 VALUES(2, 1);
    BEGIN;
      PRAGMA foreign_keys = OFF;
  }
  catchsql {
      DELETE FROM t1
  }
} {1 {foreign key constraint failed}}
do_test e_fkey-55.2 {
  execsql { PRAGMA foreign_keys }
} {1}
do_test e_fkey-55.3 {
  execsql {
    COMMIT;
    PRAGMA foreign_keys = OFF;
    BEGIN;
      PRAGMA foreign_keys = ON;
      DELETE FROM t1;
      PRAGMA foreign_keys;
  }
} {0}
do_test e_fkey-55.4 {
  execsql COMMIT
} {}

###########################################################################
### SECTION 1: Introduction to Foreign Key Constraints
###########################################################################
execsql "PRAGMA foreign_keys = ON"

#-------------------------------------------------------------------------
# /* EV: R-04042-24825 */
#
# Verify that the syntax in the first example in section 1 is valid.
#
do_test e_fkey-38.1 {
  execsql {
    CREATE TABLE artist(
      artistid    INTEGER PRIMARY KEY, 
      artistname  TEXT
    );
    CREATE TABLE track(
      trackid     INTEGER, 
      trackname   TEXT, 
      trackartist INTEGER,
      FOREIGN KEY(trackartist) REFERENCES artist(artistid)
    );
  }
} {}

#-------------------------------------------------------------------------
# /* EV: R-61362-32087 */
#
# Attempting to insert a row into the 'track' table that corresponds
# to no row in the 'artist' table fails.
#
do_test e_fkey-39.1 {
  catchsql { INSERT INTO track VALUES(1, 'track 1', 1) }
} {1 {foreign key constraint failed}}
do_test e_fkey-39.2 {
  execsql { INSERT INTO artist VALUES(2, 'artist 1') }
  catchsql { INSERT INTO track VALUES(1, 'track 1', 1) }
} {1 {foreign key constraint failed}}
do_test e_fkey-39.2 {
  execsql { INSERT INTO track VALUES(1, 'track 1', 2) }
} {}

#-------------------------------------------------------------------------
# /* EV: R-24401-52400 */
#
# Attempting to delete a row from the 'artist' table while there are 
# dependent rows in the track table also fails.
#
do_test e_fkey-40.1 {
  catchsql { DELETE FROM artist WHERE artistid = 2 }
} {1 {foreign key constraint failed}}
do_test e_fkey-40.2 {
  execsql { 
    DELETE FROM track WHERE trackartist = 2;
    DELETE FROM artist WHERE artistid = 2;
  }
} {}

#-------------------------------------------------------------------------
# /* EV: R-23980-48859 */
#
# If the foreign key column (trackartist) in table 'track' is set to NULL,
# there is no requirement for a matching row in the 'artist' table.
#
do_test e_fkey-41.1 {
  execsql {
    INSERT INTO track VALUES(1, 'track 1', NULL);
    INSERT INTO track VALUES(2, 'track 2', NULL);
  }
} {}
do_test e_fkey-41.2 {
  execsql { SELECT * FROM artist }
} {}
do_test e_fkey-41.3 {
  # Setting the trackid to a non-NULL value fails, of course.
  catchsql { UPDATE track SET trackartist = 5 WHERE trackid = 1 }
} {1 {foreign key constraint failed}}
do_test e_fkey-41.4 {
  execsql {
    INSERT INTO artist VALUES(5, 'artist 5');
    UPDATE track SET trackartist = 5 WHERE trackid = 1;
  }
  catchsql { DELETE FROM artist WHERE artistid = 5}
} {1 {foreign key constraint failed}}
do_test e_fkey-41.5 {
  execsql { 
    UPDATE track SET trackartist = NULL WHERE trackid = 1;
    DELETE FROM artist WHERE artistid = 5;
  }
} {}

#-------------------------------------------------------------------------
# /* EV: R-52486-21352 */
#
# Test that the following is true fo all rows in the track table:
#
#   trackartist IS NULL OR 
#   EXISTS(SELECT 1 FROM artist WHERE artistid=trackartist)
#

# This procedure executes a test case to check that statement 
# R-52486-21352 is true after executing the SQL statement passed.
# as the second argument.
proc test_r52486_21352 {tn sql} {
  set res [catchsql $sql]
  set results {
    {0 {}} 
    {1 {PRIMARY KEY must be unique}} 
    {1 {foreign key constraint failed}}
  }
  if {[lsearch $results $res]<0} {
    error $res
  }

  do_test e_fkey-42.$tn {
    execsql {
      SELECT count(*) FROM track WHERE NOT (
        trackartist IS NULL OR 
        EXISTS(SELECT 1 FROM artist WHERE artistid=trackartist)
      )
    }
  } {0}
}

# Execute a series of random INSERT, UPDATE and DELETE operations
# (some of which may fail due to FK or PK constraint violations) on 
# the two tables in the example schema. Test that R-52486-21352
# is true after executing each operation.
#
set Template {
  {INSERT INTO track VALUES($t, 'track $t', $a)}
  {DELETE FROM track WHERE trackid = $t}
  {UPDATE track SET trackartist = $a WHERE trackid = $t}
  {INSERT INTO artist VALUES($a, 'artist $a')}
  {DELETE FROM artist WHERE artistid = $a}
  {UPDATE artist SET artistid = $a2 WHERE artistid = $a}
}
for {set i 0} {$i < 500} {incr i} {
  set a   [expr int(rand()*10)]
  set a2  [expr int(rand()*10)]
  set t   [expr int(rand()*50)]
  set sql [subst [lindex $Template [expr int(rand()*6)]]]

  test_r52486_21352 $i $sql
}

#-------------------------------------------------------------------------
# /* EV: R-42412-59321 */
#
# Check that a NOT NULL constraint can be added to the example schema
# to prohibit NULL child keys from being inserted.
#
drop_all_tables
do_test e_fkey-48.1 {
  execsql {
    CREATE TABLE artist(
      artistid    INTEGER PRIMARY KEY, 
      artistname  TEXT
    );
    CREATE TABLE track(
      trackid     INTEGER, 
      trackname   TEXT, 
      trackartist INTEGER NOT NULL,
      FOREIGN KEY(trackartist) REFERENCES artist(artistid)
    );
  }
} {}
do_test e_fkey-48.2 {
  catchsql { INSERT INTO track VALUES(14, 'Mr. Bojangles', NULL) }
} {1 {track.trackartist may not be NULL}}

#-------------------------------------------------------------------------
# /* EV: R-17902-59250 */
#
# Test an example from foreignkeys.html.
#
drop_all_tables
do_test e_fkey-43.1 {
  execsql {
    CREATE TABLE artist(
      artistid    INTEGER PRIMARY KEY, 
      artistname  TEXT
    );
    CREATE TABLE track(
      trackid     INTEGER, 
      trackname   TEXT, 
      trackartist INTEGER,
      FOREIGN KEY(trackartist) REFERENCES artist(artistid)
    );
    INSERT INTO artist VALUES(1, 'Dean Martin');
    INSERT INTO artist VALUES(2, 'Frank Sinatra');
    INSERT INTO track VALUES(11, 'That''s Amore', 1);
    INSERT INTO track VALUES(12, 'Christmas Blues', 1);
    INSERT INTO track VALUES(13, 'My Way', 2);
  }
} {}
do_test e_fkey-43.2 {
  catchsql { INSERT INTO track VALUES(14, 'Mr. Bojangles', 3) }
} {1 {foreign key constraint failed}}
do_test e_fkey-43.3 {
  execsql { INSERT INTO track VALUES(14, 'Mr. Bojangles', NULL) }
} {}
do_test e_fkey-43.4 {
  catchsql { 
    UPDATE track SET trackartist = 3 WHERE trackname = 'Mr. Bojangles';
  }
} {1 {foreign key constraint failed}}
do_test e_fkey-43.5 {
  execsql {
    INSERT INTO artist VALUES(3, 'Sammy Davis Jr.');
    UPDATE track SET trackartist = 3 WHERE trackname = 'Mr. Bojangles';
    INSERT INTO track VALUES(15, 'Boogie Woogie', 3);
  }
} {}

#-------------------------------------------------------------------------
# /* EV: R-15034-64331 */
#
# Test the second example from the first section of foreignkeys.html.
#
do_test e_fkey-44.1 {
  catchsql {
    DELETE FROM artist WHERE artistname = 'Frank Sinatra';
  }
} {1 {foreign key constraint failed}}
do_test e_fkey-44.2 {
  execsql {
    DELETE FROM track WHERE trackname = 'My Way';
    DELETE FROM artist WHERE artistname = 'Frank Sinatra';
  }
} {}
do_test e_fkey-44.3 {
  catchsql {
    UPDATE artist SET artistid=4 WHERE artistname = 'Dean Martin';
  }
} {1 {foreign key constraint failed}}
do_test e_fkey-44.4 {
  execsql {
    DELETE FROM track WHERE trackname IN('That''s Amore', 'Christmas Blues');
    UPDATE artist SET artistid=4 WHERE artistname = 'Dean Martin';
  }
} {}


#-------------------------------------------------------------------------
# /* EV: R-56032-24923 */
#
# Test that a foreign key constraint is satisifed if "for each row in the child
# table either one or more of the child key columns are NULL, or there exists a
# row in the parent table for which each parent key column contains a value
# equal to the value in its associated child key column".
#
# /* EV: R-57765-12380 */
#
# Test also that the comparison rules are used when testing if there 
# is a matching row in the parent table of a foreign key constraint.
#
drop_all_tables
do_test e_fkey-45.1 {
  execsql {
    CREATE TABLE par(p PRIMARY KEY);
    CREATE TABLE chi(c REFERENCES par);

    INSERT INTO par VALUES(1);
    INSERT INTO par VALUES('1');
    INSERT INTO par VALUES(X'31');
    SELECT typeof(p) FROM par;
  }
} {integer text blob}

proc test_efkey_45 {tn isError sql} {
  do_test e_fkey-45.$tn.1 "
    catchsql {$sql}
  " [lindex {{0 {}} {1 {foreign key constraint failed}}} $isError]

  do_test e_fkey-45.$tn.2 {
    execsql {
      SELECT * FROM chi WHERE c IS NOT NULL AND c NOT IN (SELECT p FROM par)
    }
  } {}
}

test_efkey_45 1 0 "INSERT INTO chi VALUES(1)"
test_efkey_45 2 1 "INSERT INTO chi VALUES('1.0')"
test_efkey_45 3 0 "INSERT INTO chi VALUES('1')"
test_efkey_45 4 1 "DELETE FROM par WHERE p = '1'"
test_efkey_45 5 0 "DELETE FROM chi WHERE c = '1'"
test_efkey_45 6 0 "DELETE FROM par WHERE p = '1'"
test_efkey_45 7 1 "INSERT INTO chi VALUES('1')"
test_efkey_45 8 0 "INSERT INTO chi VALUES(X'31')"
test_efkey_45 9 1 "INSERT INTO chi VALUES(X'32')"

#-------------------------------------------------------------------------
# /* EV: R-15796-47513 */
#
# Specifically, test that when comparing child and parent key values the
# default collation sequence of the parent key column is used.
#
drop_all_tables
do_test e_fkey-46.1 {
  execsql {
    CREATE TABLE t1(a COLLATE nocase PRIMARY KEY);
    CREATE TABLE t2(b REFERENCES t1);
  }
} {}
do_test e_fkey-46.2 {
  execsql {
    INSERT INTO t1 VALUES('oNe');
    INSERT INTO t2 VALUES('one');
    INSERT INTO t2 VALUES('ONE');
    UPDATE t2 SET b = 'OnE';
    UPDATE t1 SET a = 'ONE';
  }
} {}
do_test e_fkey-46.3 {
  catchsql { UPDATE t2 SET b = 'two' WHERE rowid = 1 }
} {1 {foreign key constraint failed}}
do_test e_fkey-46.4 {
  catchsql { DELETE FROM t1 WHERE rowid = 1 }
} {1 {foreign key constraint failed}}

#-------------------------------------------------------------------------
# /* EV: R-04240-13860 */
#
# Specifically, test that when comparing child and parent key values the
# affinity of the parent key column is applied to the child key value
# before the comparison takes place.
#
drop_all_tables
do_test e_fkey-47.1 {
  execsql {
    CREATE TABLE t1(a NUMERIC PRIMARY KEY);
    CREATE TABLE t2(b TEXT REFERENCES t1);
  }
} {}
do_test e_fkey-47.2 {
  execsql {
    INSERT INTO t1 VALUES(1);
    INSERT INTO t1 VALUES(2);
    INSERT INTO t1 VALUES('three');
    INSERT INTO t2 VALUES('2.0');
    SELECT b, typeof(b) FROM t2;
  }
} {2.0 text}
do_test e_fkey-47.3 {
  execsql { SELECT typeof(a) FROM t1 }
} {integer integer text}
do_test e_fkey-47.4 {
  catchsql { DELETE FROM t1 WHERE rowid = 2 }
} {1 {foreign key constraint failed}}

###########################################################################
### SECTION 3: Required and Suggested Database Indexes
###########################################################################

#-------------------------------------------------------------------------
# /* EV: R-13435-26311 */
#
# A parent key must be either a PRIMARY KEY, subject to a UNIQUE 
# constraint, or have a UNIQUE index created on it.
# 
# /* EV: R-00376-39212 */
#
# Also test that if a parent key is not subject to a PRIMARY KEY or UNIQUE
# constraint, but does have a UNIQUE index created on it, then the UNIQUE index
# must use the default collation sequences associated with the parent key
# columns.
#
drop_all_tables
do_test e_fkey-57.1 {
  execsql {
    CREATE TABLE t2(a REFERENCES t1(x));
  }
} {}
proc test_efkey_57 {tn isError sql} {
  catchsql { DROP TABLE t1 }
  execsql $sql
  do_test e_fkey-57.$tn {
    catchsql { INSERT INTO t2 VALUES(NULL) }
  } [lindex {{0 {}} {1 {foreign key mismatch}}} $isError]
}
test_efkey_57 2 0 { CREATE TABLE t1(x PRIMARY KEY) }
test_efkey_57 3 0 { CREATE TABLE t1(x UNIQUE) }
test_efkey_57 4 0 { CREATE TABLE t1(x); CREATE UNIQUE INDEX t1i ON t1(x) }
test_efkey_57 5 1 { 
  CREATE TABLE t1(x); 
  CREATE UNIQUE INDEX t1i ON t1(x COLLATE nocase);
}
test_efkey_57 6 1 { CREATE TABLE t1(x) }
test_efkey_57 7 1 { CREATE TABLE t1(x, y, PRIMARY KEY(x, y)) }
test_efkey_57 8 1 { CREATE TABLE t1(x, y, UNIQUE(x, y)) }
test_efkey_57 9 1 { 
  CREATE TABLE t1(x, y); 
  CREATE UNIQUE INDEX t1i ON t1(x, y);
}


#-------------------------------------------------------------------------
# This block tests an example in foreignkeys.html. Several testable
# statements refer to this example, as follows
#
# /* EV: R-27484-01467 */
#
# FK Constraints on child1, child2 and child3 are Ok.
#
# /* EV: R-51039-44840 */
#
# Problem with FK on child4.
#
# /* EV: R-01060-48788 */
#
# Problem with FK on child5.
#
# /* EV: R-63088-37469 */
#
# Problem with FK on child6 and child7.
#
drop_all_tables
do_test e_fkey-56.1 {
  execsql {
    CREATE TABLE parent(a PRIMARY KEY, b UNIQUE, c, d, e, f);
    CREATE UNIQUE INDEX i1 ON parent(c, d);
    CREATE INDEX i2 ON parent(e);
    CREATE UNIQUE INDEX i3 ON parent(f COLLATE nocase);

    CREATE TABLE child1(f, g REFERENCES parent(a));                       -- Ok
    CREATE TABLE child2(h, i REFERENCES parent(b));                       -- Ok
    CREATE TABLE child3(j, k, FOREIGN KEY(j, k) REFERENCES parent(c, d)); -- Ok
    CREATE TABLE child4(l, m REFERENCES parent(e));                       -- Err
    CREATE TABLE child5(n, o REFERENCES parent(f));                       -- Err
    CREATE TABLE child6(p, q, FOREIGN KEY(p,q) REFERENCES parent(b, c));  -- Err
    CREATE TABLE child7(r REFERENCES parent(c));                          -- Err
  }
} {}
do_test e_fkey-56.2 {
  execsql {
    INSERT INTO parent VALUES(1, 2, 3, 4, 5, 6);
    INSERT INTO child1 VALUES('xxx', 1);
    INSERT INTO child2 VALUES('xxx', 2);
    INSERT INTO child3 VALUES(3, 4);
  }
} {}
do_test e_fkey-56.2 {
  catchsql { INSERT INTO child4 VALUES('xxx', 5) }
} {1 {foreign key mismatch}}
do_test e_fkey-56.3 {
  catchsql { INSERT INTO child5 VALUES('xxx', 6) }
} {1 {foreign key mismatch}}
do_test e_fkey-56.4 {
  catchsql { INSERT INTO child6 VALUES(2, 3) }
} {1 {foreign key mismatch}}
do_test e_fkey-56.5 {
  catchsql { INSERT INTO child7 VALUES(3) }
} {1 {foreign key mismatch}}

#-------------------------------------------------------------------------
# /* EV: R-45488-08504 */
# /* EV: R-48391-38472 */
# /* EV: R-03108-63659 */
# /* EV: R-60781-26576 */
#
# Test errors in the database schema that are detected while preparing
# DML statements. The error text for these messages always matches 
# either "foreign key mismatch" or "no such table*" (using [string match]).
#
do_test e_fkey-66.1 {
  execsql {
    CREATE TABLE c1(c REFERENCES nosuchtable, d);

    CREATE TABLE p2(a, b, UNIQUE(a, b));
    CREATE TABLE c2(c, d, FOREIGN KEY(c, d) REFERENCES p2(a, x));

    CREATE TABLE p3(a PRIMARY KEY, b);
    CREATE TABLE c3(c REFERENCES p3(b), d);

    CREATE TABLE p4(a PRIMARY KEY, b);
    CREATE UNIQUE INDEX p4i ON p4(b COLLATE nocase);
    CREATE TABLE c4(c REFERENCES p4(b), d);

    CREATE TABLE p5(a PRIMARY KEY, b COLLATE nocase);
    CREATE UNIQUE INDEX p5i ON p5(b COLLATE binary);
    CREATE TABLE c5(c REFERENCES p5(b), d);

    CREATE TABLE p6(a PRIMARY KEY, b);
    CREATE TABLE c6(c, d, FOREIGN KEY(c, d) REFERENCES p6);

    CREATE TABLE p7(a, b, PRIMARY KEY(a, b));
    CREATE TABLE c7(c, d REFERENCES p7);
  }
} {}

foreach {tn tbl ptbl err} {
  2 c1 {} "no such table: main.nosuchtable"
  3 c2 p2 "foreign key mismatch"
  4 c3 p3 "foreign key mismatch"
  5 c4 p4 "foreign key mismatch"
  6 c5 p5 "foreign key mismatch"
  7 c6 p6 "foreign key mismatch"
  8 c7 p7 "foreign key mismatch"
} {
  do_test e_fkey-66.$tn.1 {
    catchsql "INSERT INTO $tbl VALUES('a', 'b')"
  } [list 1 $err]
  do_test e_fkey-66.$tn.2 {
    catchsql "UPDATE $tbl SET c = ?, d = ?"
  } [list 1 $err]
  do_test e_fkey-66.$tn.3 {
    catchsql "INSERT INTO $tbl SELECT ?, ?"
  } [list 1 $err]

  if {$ptbl ne ""} {
    do_test e_fkey-66.$tn.4 {
      catchsql "DELETE FROM $ptbl"
    } [list 1 $err]
    do_test e_fkey-66.$tn.5 {
      catchsql "UPDATE $ptbl SET a = ?, b = ?"
    } [list 1 $err]
    do_test e_fkey-66.$tn.6 {
      catchsql "INSERT INTO $ptbl SELECT ?, ?"
    } [list 1 $err]
  }
}

#-------------------------------------------------------------------------
# /* EV: R-19353-43643 */
#
# Test the example of foreign key mismatch errors caused by implicitly
# mapping a child key to the primary key of the parent table when the
# child key consists of a different number of columns to that primary key.
# 
drop_all_tables
do_test e_fkey-58.1 {
  execsql {
    CREATE TABLE parent2(a, b, PRIMARY KEY(a,b));

    CREATE TABLE child8(x, y, FOREIGN KEY(x,y) REFERENCES parent2);     -- Ok
    CREATE TABLE child9(x REFERENCES parent2);                          -- Err
    CREATE TABLE child10(x,y,z, FOREIGN KEY(x,y,z) REFERENCES parent2); -- Err
  }
} {}
do_test e_fkey-58.2 {
  execsql {
    INSERT INTO parent2 VALUES('I', 'II');
    INSERT INTO child8 VALUES('I', 'II');
  }
} {}
do_test e_fkey-58.3 {
  catchsql { INSERT INTO child9 VALUES('I') }
} {1 {foreign key mismatch}}
do_test e_fkey-58.4 {
  catchsql { INSERT INTO child9 VALUES('II') }
} {1 {foreign key mismatch}}
do_test e_fkey-58.5 {
  catchsql { INSERT INTO child9 VALUES(NULL) }
} {1 {foreign key mismatch}}
do_test e_fkey-58.6 {
  catchsql { INSERT INTO child10 VALUES('I', 'II', 'III') }
} {1 {foreign key mismatch}}
do_test e_fkey-58.7 {
  catchsql { INSERT INTO child10 VALUES(1, 2, 3) }
} {1 {foreign key mismatch}}
do_test e_fkey-58.8 {
  catchsql { INSERT INTO child10 VALUES(NULL, NULL, NULL) }
} {1 {foreign key mismatch}}

#-------------------------------------------------------------------------
# /* EV: R-23682-59820 */
#
# Test errors that are reported when creating the child table. 
# Specifically:
#
#   * different number of child and parent key columns, and
#   * child columns that do not exist.
#
# /* EV: R-33883-28833 */
#
# These errors are reported whether or not FK support is enabled.
#
drop_all_tables
foreach fk [list OFF ON] {
  execsql "PRAGMA foreign_keys = $fk"
  set i 0
  foreach {sql error} {
    "CREATE TABLE child1(a, b, FOREIGN KEY(a, b) REFERENCES p(c))"
      {number of columns in foreign key does not match the number of columns in the referenced table}
    "CREATE TABLE child2(a, b, FOREIGN KEY(a, b) REFERENCES p(c, d, e))"
      {number of columns in foreign key does not match the number of columns in the referenced table}
    "CREATE TABLE child2(a, b, FOREIGN KEY(a, c) REFERENCES p(c, d))"
      {unknown column "c" in foreign key definition}
    "CREATE TABLE child2(a, b, FOREIGN KEY(c, b) REFERENCES p(c, d))"
      {unknown column "c" in foreign key definition}
  } {
    do_test e_fkey-59.$fk.[incr i] {
      catchsql $sql
    } [list 1 $error]
  }
}

#-------------------------------------------------------------------------
# /* EV: R-47109-40581 */
#
# Test that a REFERENCING clause that does not specify parent key columns
# implicitly maps to the primary key of the parent table.
# 
do_test e_fkey-60.1 {
  execsql {
    CREATE TABLE p1(a, b, PRIMARY KEY(a, b));
    CREATE TABLE p2(a, b PRIMARY KEY);
    CREATE TABLE c1(c, d, FOREIGN KEY(c, d) REFERENCES p1);
    CREATE TABLE c2(a, b REFERENCES p2);
  }
} {}
proc test_efkey_60 {tn isError sql} {
  do_test e_fkey-60.$tn "
    catchsql {$sql}
  " [lindex {{0 {}} {1 {foreign key constraint failed}}} $isError]
}

test_efkey_60 2 1 "INSERT INTO c1 VALUES(239, 231)"
test_efkey_60 3 0 "INSERT INTO p1 VALUES(239, 231)"
test_efkey_60 4 0 "INSERT INTO c1 VALUES(239, 231)"
test_efkey_60 5 1 "INSERT INTO c2 VALUES(239, 231)"
test_efkey_60 6 0 "INSERT INTO p2 VALUES(239, 231)"
test_efkey_60 7 0 "INSERT INTO c2 VALUES(239, 231)"

#-------------------------------------------------------------------------
# /* EV: R-15417-28014 */
#
# Test that an index on on the child key columns of an FK constraint
# is optional.
#
# /* EV: R-15741-50893 */
#
# Also test that if an index is created on the child key columns, it does
# not make a difference whether or not it is a UNIQUE index.
#
drop_all_tables
do_test e_fkey-61.1 {
  execsql {
    CREATE TABLE parent(x, y, UNIQUE(y, x));
    CREATE TABLE c1(a, b, FOREIGN KEY(a, b) REFERENCES parent(x, y));
    CREATE TABLE c2(a, b, FOREIGN KEY(a, b) REFERENCES parent(x, y));
    CREATE TABLE c3(a, b, FOREIGN KEY(a, b) REFERENCES parent(x, y));
    CREATE INDEX c2i ON c2(a, b);
    CREATE UNIQUE INDEX c3i ON c2(b, a);
  }
} {}
proc test_efkey_61 {tn isError sql} {
  do_test e_fkey-61.$tn "
    catchsql {$sql}
  " [lindex {{0 {}} {1 {foreign key constraint failed}}} $isError]
}
foreach {tn c} [list 2 c1 3 c2 4 c3] {
  test_efkey_61 $tn.1 1 "INSERT INTO $c VALUES(1, 2)"
  test_efkey_61 $tn.2 0 "INSERT INTO parent VALUES(1, 2)"
  test_efkey_61 $tn.3 0 "INSERT INTO $c VALUES(1, 2)"

  execsql "DELETE FROM $c ; DELETE FROM parent"
}

#-------------------------------------------------------------------------
# /* EV: R-00279-52283 */
#
# Test an example showing that when a row is deleted from the parent 
# table, the child table is queried for orphaned rows as follows:
#
#   SELECT rowid FROM track WHERE trackartist = ?
#
# /* EV: R-23302-30956 */
#
# Also test that if the SELECT above would return any rows, a foreign
# key constraint is violated.
#
do_test e_fkey-62.1 {
  execsql {
    CREATE TABLE artist(
      artistid    INTEGER PRIMARY KEY, 
      artistname  TEXT
    );
    CREATE TABLE track(
      trackid     INTEGER, 
      trackname   TEXT, 
      trackartist INTEGER,
      FOREIGN KEY(trackartist) REFERENCES artist(artistid)
    );
  }
} {}
do_test e_fkey-62.2 {
  execsql {
    PRAGMA foreign_keys = OFF;
    EXPLAIN QUERY PLAN DELETE FROM artist WHERE 1;
    EXPLAIN QUERY PLAN SELECT rowid FROM track WHERE trackartist = ?;
  }
} {0 0 {TABLE artist} 0 0 {TABLE track}}
do_test e_fkey-62.3 {
  execsql { 
    PRAGMA foreign_keys = ON;
    EXPLAIN QUERY PLAN DELETE FROM artist WHERE 1;
  }
} {0 0 {TABLE artist} 0 0 {TABLE track}}
do_test e_fkey-62.4 {
  execsql {
    INSERT INTO artist VALUES(5, 'artist 5');
    INSERT INTO artist VALUES(6, 'artist 6');
    INSERT INTO artist VALUES(7, 'artist 7');
    INSERT INTO track VALUES(1, 'track 1', 5);
    INSERT INTO track VALUES(2, 'track 2', 6);
  }
} {}

do_test e_fkey-62.5 {
  concat \
    [execsql { SELECT rowid FROM track WHERE trackartist = 5 }]   \
    [catchsql { DELETE FROM artist WHERE artistid = 5 }]
} {1 1 {foreign key constraint failed}}

do_test e_fkey-62.6 {
  concat \
    [execsql { SELECT rowid FROM track WHERE trackartist = 7 }]   \
    [catchsql { DELETE FROM artist WHERE artistid = 7 }]
} {0 {}}

do_test e_fkey-62.7 {
  concat \
    [execsql { SELECT rowid FROM track WHERE trackartist = 6 }]   \
    [catchsql { DELETE FROM artist WHERE artistid = 6 }]
} {2 1 {foreign key constraint failed}}

#-------------------------------------------------------------------------
# /* EV: R-54172-55848 */
#
# Test that when a row is deleted from the parent table of an FK 
# constraint, the child table is queried for orphaned rows. The
# query is equivalent to:
#
#   SELECT rowid FROM <child-table> WHERE <child-key> = :parent_key_value
#
# /* EV: R-61616-46700 */
#
# Also test that when a row is inserted into the parent table, or when the 
# parent key values of an existing row are modified, a query equivalent
# to the following is planned. In some cases it is not executed, but it
# is always planned.
#
#   SELECT rowid FROM <child-table> WHERE <child-key> = :parent_key_value
#
#
drop_all_tables
do_test e_fkey-64.1 {
  execsql { CREATE TABLE parent(x, y, UNIQUE(y, x)) }
} {}
foreach {tn sql} {
  2 { 
    CREATE TABLE child(a, b, FOREIGN KEY(a, b) REFERENCES parent(x, y))
  }
  3 { 
    CREATE TABLE child(a, b, FOREIGN KEY(a, b) REFERENCES parent(x, y));
    CREATE INDEX childi ON child(a, b);
  }
  4 { 
    CREATE TABLE child(a, b, FOREIGN KEY(a, b) REFERENCES parent(x, y));
    CREATE UNIQUE INDEX childi ON child(b, a);
  }
} {
  execsql $sql

  execsql {PRAGMA foreign_keys = OFF}
  set delete [concat \
      [eqp "DELETE FROM parent WHERE 1"] \
      [eqp "SELECT rowid FROM child WHERE a = ? AND b = ?"]
  ]
  set update [concat \
      [eqp "UPDATE parent SET x=?, y=?"] \
      [eqp "SELECT rowid FROM child WHERE a = ? AND b = ?"] \
      [eqp "SELECT rowid FROM child WHERE a = ? AND b = ?"]
  ]
  execsql {PRAGMA foreign_keys = ON}

  do_test e_fkey-64.$tn.1 { eqp "DELETE FROM parent WHERE 1" } $delete
  do_test e_fkey-64.$tn.2 { eqp "UPDATE parent set x=?, y=?" } $update

  execsql {DROP TABLE child}
}

#-------------------------------------------------------------------------
# /* EV: R-14553-34013 */
#
# Test the example schema at the end of section 3. Also test that is
# is "efficient". In this case "efficient" means that foreign key
# related operations on the parent table do not provoke linear scans.
#
drop_all_tables
do_test e_fkey-63.1 {
  execsql {
    CREATE TABLE artist(
      artistid    INTEGER PRIMARY KEY, 
      artistname  TEXT
    );
    CREATE TABLE track(
      trackid     INTEGER,
      trackname   TEXT, 
      trackartist INTEGER REFERENCES artist
    );
    CREATE INDEX trackindex ON track(trackartist);
  }
} {}
do_test e_fkey-63.2 {
  eqp { INSERT INTO artist VALUES(?, ?) }
} {}
do_test e_fkey-63.3 {
  eqp { UPDATE artist SET artistid = ?, artistname = ? }
} [list \
  0 0 {TABLE artist} \
  0 0 {TABLE track WITH INDEX trackindex} \
  0 0 {TABLE track WITH INDEX trackindex}
]
do_test e_fkey-63.4 {
  eqp { DELETE FROM artist }
} [list \
  0 0 {TABLE artist} \
  0 0 {TABLE track WITH INDEX trackindex}
]


###########################################################################
### SECTION 4.1: Composite Foreign Key Constraints
###########################################################################

#-------------------------------------------------------------------------
# /* EV: R-41062-34431 */
#
# Check that parent and child keys must have the same number of columns.
#
foreach {tn sql err} {
  1 "CREATE TABLE c(jj REFERENCES p(x, y))" 
    {foreign key on jj should reference only one column of table p}

  2 "CREATE TABLE c(jj REFERENCES p())" {near ")": syntax error}

  3 "CREATE TABLE c(jj, FOREIGN KEY(jj) REFERENCES p(x, y))" 
    {number of columns in foreign key does not match the number of columns in the referenced table}

  4 "CREATE TABLE c(jj, FOREIGN KEY(jj) REFERENCES p())" 
    {near ")": syntax error}

  5 "CREATE TABLE c(ii, jj, FOREIGN KEY(jj, ii) REFERENCES p())" 
    {near ")": syntax error}

  6 "CREATE TABLE c(ii, jj, FOREIGN KEY(jj, ii) REFERENCES p(x))" 
    {number of columns in foreign key does not match the number of columns in the referenced table}

  7 "CREATE TABLE c(ii, jj, FOREIGN KEY(jj, ii) REFERENCES p(x,y,z))" 
    {number of columns in foreign key does not match the number of columns in the referenced table}
} {
  drop_all_tables
  do_test e_fkey-65.$tn [list catchsql $sql] [list 1 $err]
}
do_test e_fkey-65.8 {
  drop_all_tables
  execsql {
    CREATE TABLE p(x PRIMARY KEY);
    CREATE TABLE c(a, b, FOREIGN KEY(a,b) REFERENCES p);
  }
  catchsql {DELETE FROM p}
} {1 {foreign key mismatch}}
do_test e_fkey-65.9 {
  drop_all_tables
  execsql {
    CREATE TABLE p(x, y, PRIMARY KEY(x,y));
    CREATE TABLE c(a REFERENCES p);
  }
  catchsql {DELETE FROM p}
} {1 {foreign key mismatch}}


#-------------------------------------------------------------------------
# /* EV: R-24676-09859 */
#
# Test the example schema in the "Composite Foreign Key Constraints" 
# section.
#
do_test e_fkey-36.1 {
  execsql {
    CREATE TABLE album(
      albumartist TEXT,
      albumname TEXT,
      albumcover BINARY,
      PRIMARY KEY(albumartist, albumname)
    );
    CREATE TABLE song(
      songid INTEGER,
      songartist TEXT,
      songalbum TEXT,
      songname TEXT,
      FOREIGN KEY(songartist, songalbum) REFERENCES album(albumartist,albumname)
    );
  }
} {}

do_test e_fkey-36.2 {
  execsql {
    INSERT INTO album VALUES('Elvis Presley', 'Elvis'' Christmas Album', NULL);
    INSERT INTO song VALUES(
      1, 'Elvis Presley', 'Elvis'' Christmas Album', 'Here Comes Santa Clause'
    );
  }
} {}
do_test e_fkey-36.3 {
  catchsql {
    INSERT INTO song VALUES(2, 'Elvis Presley', 'Elvis Is Back!', 'Fever');
  }
} {1 {foreign key constraint failed}}


#-------------------------------------------------------------------------
# /* EV: R-33626-48418 */
#
# Check that if any of the child key columns in the above schema are NULL,
# there is no requirement for a corresponding parent key.
#
do_test e_fkey-37.1 {
  execsql {
    INSERT INTO song VALUES(2, 'Elvis Presley', NULL, 'Fever');
    INSERT INTO song VALUES(3, NULL, 'Elvis Is Back', 'Soldier Boy');
  }
} {}

###########################################################################
### SECTION 4.2: Deferred Foreign Key Constraints
###########################################################################

#-------------------------------------------------------------------------
# Note: R-35290-16460 is tested below.
#
# TODO: R-30323-21917

#-------------------------------------------------------------------------
# /* EV: R-09323-30470 */
#
# Test that if a statement violates an immediate FK constraint, and the
# database does not satisfy the FK constraint once all effects of the
# statement have been applied, an error is reported and the effects of
# the statement rolled back.
#
drop_all_tables
do_test e_fkey-33.1 {
  execsql {
    CREATE TABLE king(a, b, PRIMARY KEY(a));
    CREATE TABLE prince(c REFERENCES king, d);
  }
} {}

do_test e_fkey-33.2 {
  # Execute a statement that violates the immediate FK constraint.
  catchsql { INSERT INTO prince VALUES(1, 2) }
} {1 {foreign key constraint failed}}

do_test e_fkey-33.3 {
  # This time, use a trigger to fix the constraint violation before the
  # statement has finished executing. Then execute the same statement as
  # in the previous test case. This time, no error.
  execsql {
    CREATE TRIGGER kt AFTER INSERT ON prince WHEN
      NOT EXISTS (SELECT a FROM king WHERE a = new.c)
    BEGIN
      INSERT INTO king VALUES(new.c, NULL);
    END
  }
  execsql { INSERT INTO prince VALUES(1, 2) }
} {}

# Test that operating inside a transaction makes no difference to 
# immediate constraint violation handling.
do_test e_fkey-33.4 {
  execsql {
    BEGIN;
    INSERT INTO prince VALUES(2, 3);
    DROP TRIGGER kt;
  }
  catchsql { INSERT INTO prince VALUES(3, 4) }
} {1 {foreign key constraint failed}}
do_test e_fkey-33.5 {
  execsql {
    COMMIT;
    SELECT * FROM king;
  }
} {1 {} 2 {}}

#-------------------------------------------------------------------------
# /* EV: R-49178-21358 */
# /* EV: R-39692-12488 */
# /* EV: R-55147-47664 */
# /* EV: R-29604-30395 */
#
# Test that if a deferred constraint is violated within a transaction,
# nothing happens immediately and the database is allowed to persist
# in a state that does not satisfy the FK constraint. However attempts
# to COMMIT the transaction fail until the FK constraint is satisfied.
#
proc test_efkey_34 {tn isError sql} {
  do_test e_fkey-34.$tn "
    catchsql {$sql}
  " [lindex {{0 {}} {1 {foreign key constraint failed}}} $isError]
}
drop_all_tables

test_efkey_34  1 0 {
  CREATE TABLE ll(k PRIMARY KEY);
  CREATE TABLE kk(c REFERENCES ll DEFERRABLE INITIALLY DEFERRED);
}
test_efkey_34  2 0 "BEGIN"
test_efkey_34  3 0   "INSERT INTO kk VALUES(5)"
test_efkey_34  4 0   "INSERT INTO kk VALUES(10)"
test_efkey_34  5 1 "COMMIT"
test_efkey_34  6 0   "INSERT INTO ll VALUES(10)"
test_efkey_34  7 1 "COMMIT"
test_efkey_34  8 0   "INSERT INTO ll VALUES(5)"
test_efkey_34  9 0 "COMMIT"

#-------------------------------------------------------------------------
# /* EV: R-56844-61705 */
#
# When not running inside a transaction, a deferred constraint is similar
# to an immediate constraint (violations are reported immediately).
#
drop_all_tables
proc test_efkey_35 {tn isError sql} {
  do_test e_fkey-35.$tn "
    catchsql {$sql}
  " [lindex {{0 {}} {1 {foreign key constraint failed}}} $isError]
}
do_test e_fkey-35.1 {
  execsql {
    CREATE TABLE parent(x, y);
    CREATE UNIQUE INDEX pi ON parent(x, y);
    CREATE TABLE child(a, b,
      FOREIGN KEY(a, b) REFERENCES parent(x, y) DEFERRABLE INITIALLY DEFERRED
    );
  }
} {}
test_efkey_35 2 1 "INSERT INTO child  VALUES('x', 'y')"
test_efkey_35 3 0 "INSERT INTO parent VALUES('x', 'y')"
test_efkey_35 4 0 "INSERT INTO child  VALUES('x', 'y')"


#-------------------------------------------------------------------------
# /* EV: R-12782-61841 */
#
# Test that an FK constraint is made deferred by adding the following
# to the definition:
#
#   DEFERRABLE INITIALLY DEFERRED
#
# /* EV: R-09005-28791 */
#
# Also test that adding any of the following to a foreign key definition 
# makes the constraint IMMEDIATE:
#
#   NOT DEFERRABLE INITIALLY DEFERRED
#   NOT DEFERRABLE INITIALLY IMMEDIATE
#   NOT DEFERRABLE
#   DEFERRABLE INITIALLY IMMEDIATE
#   DEFERRABLE
#
# /* EV: R-35290-16460 */
#
# Foreign keys are IMMEDIATE by default (if there is no DEFERRABLE or NOT
# DEFERRABLE clause).
#
# /* EV: R-30323-21917 */  FKs are either IMMEDIATE or DEFERRED.
#
drop_all_tables
do_test e_fkey-29.1 {
  execsql {
    CREATE TABLE parent(x, y, z, PRIMARY KEY(x,y,z));
    CREATE TABLE c1(a, b, c,
      FOREIGN KEY(a, b, c) REFERENCES parent NOT DEFERRABLE INITIALLY DEFERRED
    );
    CREATE TABLE c2(a, b, c,
      FOREIGN KEY(a, b, c) REFERENCES parent NOT DEFERRABLE INITIALLY IMMEDIATE
    );
    CREATE TABLE c3(a, b, c,
      FOREIGN KEY(a, b, c) REFERENCES parent NOT DEFERRABLE
    );
    CREATE TABLE c4(a, b, c,
      FOREIGN KEY(a, b, c) REFERENCES parent DEFERRABLE INITIALLY IMMEDIATE
    );
    CREATE TABLE c5(a, b, c,
      FOREIGN KEY(a, b, c) REFERENCES parent DEFERRABLE
    );
    CREATE TABLE c6(a, b, c, FOREIGN KEY(a, b, c) REFERENCES parent);

    -- This FK constraint is the only deferrable one.
    CREATE TABLE c7(a, b, c,
      FOREIGN KEY(a, b, c) REFERENCES parent DEFERRABLE INITIALLY DEFERRED
    );

    INSERT INTO parent VALUES('a', 'b', 'c');
    INSERT INTO parent VALUES('d', 'e', 'f');
    INSERT INTO parent VALUES('g', 'h', 'i');
    INSERT INTO parent VALUES('j', 'k', 'l');
    INSERT INTO parent VALUES('m', 'n', 'o');
    INSERT INTO parent VALUES('p', 'q', 'r');
    INSERT INTO parent VALUES('s', 't', 'u');

    INSERT INTO c1 VALUES('a', 'b', 'c');
    INSERT INTO c2 VALUES('d', 'e', 'f');
    INSERT INTO c3 VALUES('g', 'h', 'i');
    INSERT INTO c4 VALUES('j', 'k', 'l');
    INSERT INTO c5 VALUES('m', 'n', 'o');
    INSERT INTO c6 VALUES('p', 'q', 'r');
    INSERT INTO c7 VALUES('s', 't', 'u');
  }
} {}

proc test_efkey_29 {tn sql isError} {
  do_test e_fkey-29.$tn "catchsql {$sql}" [
    lindex {{0 {}} {1 {foreign key constraint failed}}} $isError
  ]
}
test_efkey_29  2 "BEGIN"                                   0
test_efkey_29  3 "DELETE FROM parent WHERE x = 'a'"        1
test_efkey_29  4 "DELETE FROM parent WHERE x = 'd'"        1
test_efkey_29  5 "DELETE FROM parent WHERE x = 'g'"        1
test_efkey_29  6 "DELETE FROM parent WHERE x = 'j'"        1
test_efkey_29  7 "DELETE FROM parent WHERE x = 'm'"        1
test_efkey_29  8 "DELETE FROM parent WHERE x = 'p'"        1
test_efkey_29  9 "DELETE FROM parent WHERE x = 's'"        0
test_efkey_29 10 "COMMIT"                                  1
test_efkey_29 11 "ROLLBACK"                                0

test_efkey_29  9 "BEGIN"                                   0
test_efkey_29 10 "UPDATE parent SET z = 'z' WHERE z = 'c'" 1
test_efkey_29 11 "UPDATE parent SET z = 'z' WHERE z = 'f'" 1
test_efkey_29 12 "UPDATE parent SET z = 'z' WHERE z = 'i'" 1
test_efkey_29 13 "UPDATE parent SET z = 'z' WHERE z = 'l'" 1
test_efkey_29 14 "UPDATE parent SET z = 'z' WHERE z = 'o'" 1
test_efkey_29 15 "UPDATE parent SET z = 'z' WHERE z = 'r'" 1
test_efkey_29 16 "UPDATE parent SET z = 'z' WHERE z = 'u'" 0
test_efkey_29 17 "COMMIT"                                  1
test_efkey_29 18 "ROLLBACK"                                0

test_efkey_29 17 "BEGIN"                                   0
test_efkey_29 18 "INSERT INTO c1 VALUES(1, 2, 3)"          1
test_efkey_29 19 "INSERT INTO c2 VALUES(1, 2, 3)"          1
test_efkey_29 20 "INSERT INTO c3 VALUES(1, 2, 3)"          1
test_efkey_29 21 "INSERT INTO c4 VALUES(1, 2, 3)"          1
test_efkey_29 22 "INSERT INTO c5 VALUES(1, 2, 3)"          1
test_efkey_29 22 "INSERT INTO c6 VALUES(1, 2, 3)"          1
test_efkey_29 22 "INSERT INTO c7 VALUES(1, 2, 3)"          0
test_efkey_29 23 "COMMIT"                                  1
test_efkey_29 24 "INSERT INTO parent VALUES(1, 2, 3)"      0
test_efkey_29 25 "COMMIT"                                  0

test_efkey_29 26 "BEGIN"                                   0
test_efkey_29 27 "UPDATE c1 SET a = 10"                    1
test_efkey_29 28 "UPDATE c2 SET a = 10"                    1
test_efkey_29 29 "UPDATE c3 SET a = 10"                    1
test_efkey_29 30 "UPDATE c4 SET a = 10"                    1
test_efkey_29 31 "UPDATE c5 SET a = 10"                    1
test_efkey_29 31 "UPDATE c6 SET a = 10"                    1
test_efkey_29 31 "UPDATE c7 SET a = 10"                    0
test_efkey_29 32 "COMMIT"                                  1
test_efkey_29 33 "ROLLBACK"                                0

#-------------------------------------------------------------------------
# /* EV: R-35043-01546 */
#
# Test an example from foreignkeys.html dealing with a deferred foreign 
# key constraint.
#
do_test e_fkey-28.1 {
  drop_all_tables
  execsql {
    CREATE TABLE artist(
      artistid    INTEGER PRIMARY KEY, 
      artistname  TEXT
    );
    CREATE TABLE track(
      trackid     INTEGER,
      trackname   TEXT, 
      trackartist INTEGER REFERENCES artist(artistid) DEFERRABLE INITIALLY DEFERRED
    );
  }
} {}
do_test e_fkey-28.2 {
  execsql {
    BEGIN;
      INSERT INTO track VALUES(1, 'White Christmas', 5);
  }
  catchsql COMMIT
} {1 {foreign key constraint failed}}
do_test e_fkey-28.3 {
  execsql {
    INSERT INTO artist VALUES(5, 'Bing Crosby');
    COMMIT;
  }
} {}

#-------------------------------------------------------------------------
# /* EV: R-07223-48323 */
#
# Verify that a nested savepoint may be released without satisfying 
# deferred foreign key constraints.
#
drop_all_tables
do_test e_fkey-30.1 {
  execsql {
    CREATE TABLE t1(a PRIMARY KEY,
      b REFERENCES t1 DEFERRABLE INITIALLY DEFERRED
    );
    INSERT INTO t1 VALUES(1, 1);
    INSERT INTO t1 VALUES(2, 2);
    INSERT INTO t1 VALUES(3, 3);
  }
} {}
do_test e_fkey-30.2 {
  execsql {
    BEGIN;
      SAVEPOINT one;
        INSERT INTO t1 VALUES(4, 5);
      RELEASE one;
  }
} {}
do_test e_fkey-30.3 {
  catchsql COMMIT
} {1 {foreign key constraint failed}}
do_test e_fkey-30.4 {
  execsql {
    UPDATE t1 SET a = 5 WHERE a = 4;
    COMMIT;
  }
} {}


#-------------------------------------------------------------------------
# /* EV: R-44295-13823 */
#
# Check that a transaction savepoint (an outermost savepoint opened when
# the database was in auto-commit mode) cannot be released without
# satisfying deferred foreign key constraints. It may be rolled back.
#
do_test e_fkey-31.1 {
  execsql {
    SAVEPOINT one;
      SAVEPOINT two;
        INSERT INTO t1 VALUES(6, 7);
      RELEASE two;
  }
} {}
do_test e_fkey-31.2 {
  catchsql {RELEASE one}
} {1 {foreign key constraint failed}}
do_test e_fkey-31.3 {
  execsql {
      UPDATE t1 SET a = 7 WHERE a = 6;
    RELEASE one;
  }
} {}
do_test e_fkey-31.4 {
  execsql {
    SAVEPOINT one;
      SAVEPOINT two;
        INSERT INTO t1 VALUES(9, 10);
      RELEASE two;
  }
} {}
do_test e_fkey-31.5 {
  catchsql {RELEASE one}
} {1 {foreign key constraint failed}}
do_test e_fkey-31.6 {
  execsql {ROLLBACK TO one ; RELEASE one}
} {}

#-------------------------------------------------------------------------
# /* EV: R-37736-42616 */
#
# Test that if a COMMIT operation fails due to deferred foreign key 
# constraints, any nested savepoints remain open.
#
do_test e_fkey-32.1 {
  execsql {
    DELETE FROM t1 WHERE a>3;
    SELECT * FROM t1;
  }
} {1 1 2 2 3 3}
do_test e_fkey-32.2 {
  execsql {
    BEGIN;
      INSERT INTO t1 VALUES(4, 4);
      SAVEPOINT one;
        INSERT INTO t1 VALUES(5, 6);
        SELECT * FROM t1;
  }
} {1 1 2 2 3 3 4 4 5 6}
do_test e_fkey-32.3 {
  catchsql COMMIT
} {1 {foreign key constraint failed}}
do_test e_fkey-32.4 {
  execsql {
    ROLLBACK TO one;
    COMMIT;
    SELECT * FROM t1;
  }
} {1 1 2 2 3 3 4 4}

do_test e_fkey-32.5 {
  execsql {
    SAVEPOINT a;
      INSERT INTO t1 VALUES(5, 5);
      SAVEPOINT b;
        INSERT INTO t1 VALUES(6, 7);
        SAVEPOINT c;
          INSERT INTO t1 VALUES(7, 8);
  }
} {}
do_test e_fkey-32.6 {
  catchsql {RELEASE a}
} {1 {foreign key constraint failed}}
do_test e_fkey-32.7 {
  execsql  {ROLLBACK TO c}
  catchsql {RELEASE a}
} {1 {foreign key constraint failed}}
do_test e_fkey-32.8 {
  execsql  {
    ROLLBACK TO b;
    RELEASE a;
    SELECT * FROM t1;
  }
} {1 1 2 2 3 3 4 4 5 5}

###########################################################################
### SECTION 4.3: ON DELETE and ON UPDATE Actions
###########################################################################

#-------------------------------------------------------------------------
# /* EV: R-48270-44282 */
#
# Test that configured ON DELETE and ON UPDATE actions take place when
# deleting or modifying rows of the parent table, respectively.
#
# /* EV: R-48124-63225 */
#
# Test that a single FK constraint may have different actions configured
# for ON DELETE and ON UPDATE.
#
do_test e_fkey-16.1 {
  execsql {
    CREATE TABLE p(a, b PRIMARY KEY, c);
    CREATE TABLE c1(d, e, f DEFAULT 'k0' REFERENCES p 
      ON UPDATE SET DEFAULT
      ON DELETE SET NULL
    );

    INSERT INTO p VALUES(0, 'k0', '');
    INSERT INTO p VALUES(1, 'k1', 'I');
    INSERT INTO p VALUES(2, 'k2', 'II');
    INSERT INTO p VALUES(3, 'k3', 'III');

    INSERT INTO c1 VALUES(1, 'xx', 'k1');
    INSERT INTO c1 VALUES(2, 'xx', 'k2');
    INSERT INTO c1 VALUES(3, 'xx', 'k3');
  }
} {}
do_test e_fkey-16.2 {
  execsql {
    UPDATE p SET b = 'k4' WHERE a = 1;
    SELECT * FROM c1;
  }
} {1 xx k0 2 xx k2 3 xx k3}
do_test e_fkey-16.3 {
  execsql {
    DELETE FROM p WHERE a = 2;
    SELECT * FROM c1;
  }
} {1 xx k0 2 xx {} 3 xx k3}
do_test e_fkey-16.4 {
  execsql {
    CREATE UNIQUE INDEX pi ON p(c);
    REPLACE INTO p VALUES(5, 'k5', 'III');
    SELECT * FROM c1;
  }
} {1 xx k0 2 xx {} 3 xx {}}

#-------------------------------------------------------------------------
# /* EV: R-33326-45252 */
#
# Each foreign key in the system has an ON UPDATE and ON DELETE action,
# either "NO ACTION", "RESTRICT", "SET NULL", "SET DEFAULT" or "CASCADE".
#
# /* EV: R-19803-45884 */
#
# If none is specified explicitly, "NO ACTION" is the default.
# 
drop_all_tables
do_test e_fkey-17.1 {
  execsql {
    CREATE TABLE parent(x PRIMARY KEY, y);
    CREATE TABLE child1(a, 
      b REFERENCES parent ON UPDATE NO ACTION ON DELETE RESTRICT
    );
    CREATE TABLE child2(a, 
      b REFERENCES parent ON UPDATE RESTRICT ON DELETE SET NULL
    );
    CREATE TABLE child3(a, 
      b REFERENCES parent ON UPDATE SET NULL ON DELETE SET DEFAULT
    );
    CREATE TABLE child4(a, 
      b REFERENCES parent ON UPDATE SET DEFAULT ON DELETE CASCADE
    );

    -- Create some foreign keys that use the default action - "NO ACTION"
    CREATE TABLE child5(a, b REFERENCES parent ON UPDATE CASCADE);
    CREATE TABLE child6(a, b REFERENCES parent ON DELETE RESTRICT);
    CREATE TABLE child7(a, b REFERENCES parent ON DELETE NO ACTION);
    CREATE TABLE child8(a, b REFERENCES parent ON UPDATE NO ACTION);
  }
} {}

foreach {tn zTab lRes} {
  2 child1 {0 0 parent b {} {NO ACTION} RESTRICT NONE}
  3 child2 {0 0 parent b {} RESTRICT {SET NULL} NONE}
  4 child3 {0 0 parent b {} {SET NULL} {SET DEFAULT} NONE}
  5 child4 {0 0 parent b {} {SET DEFAULT} CASCADE NONE}
  6 child5 {0 0 parent b {} CASCADE {NO ACTION} NONE}
  7 child6 {0 0 parent b {} {NO ACTION} RESTRICT NONE}
  8 child7 {0 0 parent b {} {NO ACTION} {NO ACTION} NONE}
  9 child8 {0 0 parent b {} {NO ACTION} {NO ACTION} NONE}
} {
  do_test e_fkey-17.$tn { execsql "PRAGMA foreign_key_list($zTab)" } $lRes
}

#-------------------------------------------------------------------------
# /* EV: R-19971-54976 */
#
# Test that "NO ACTION" means that nothing happens to a child row when
# it's parent row is updated or deleted.
#
drop_all_tables
do_test e_fkey-18.1 {
  execsql {
    CREATE TABLE parent(p1, p2, PRIMARY KEY(p1, p2));
    CREATE TABLE child(c1, c2, 
      FOREIGN KEY(c1, c2) REFERENCES parent
      ON UPDATE NO ACTION
      ON DELETE NO ACTION
      DEFERRABLE INITIALLY DEFERRED
    );
    INSERT INTO parent VALUES('j', 'k');
    INSERT INTO parent VALUES('l', 'm');
    INSERT INTO child VALUES('j', 'k');
    INSERT INTO child VALUES('l', 'm');
  }
} {}
do_test e_fkey-18.2 {
  execsql {
    BEGIN;
      UPDATE parent SET p1='k' WHERE p1='j';
      DELETE FROM parent WHERE p1='l';
      SELECT * FROM child;
  }
} {j k l m}
do_test e_fkey-18.3 {
  catchsql COMMIT
} {1 {foreign key constraint failed}}
do_test e_fkey-18.4 {
  execsql ROLLBACK
} {}

#-------------------------------------------------------------------------
# /* EV: R-04272-38653 */
#
# Test that "RESTRICT" means the application is prohibited from deleting
# or updating a parent table row when there exists one or more child keys
# mapped to it.
#
drop_all_tables
do_test e_fkey-18.1 {
  execsql {
    CREATE TABLE parent(p1, p2);
    CREATE UNIQUE INDEX parent_i ON parent(p1, p2);
    CREATE TABLE child1(c1, c2, 
      FOREIGN KEY(c2, c1) REFERENCES parent(p1, p2) ON DELETE RESTRICT
    );
    CREATE TABLE child2(c1, c2, 
      FOREIGN KEY(c2, c1) REFERENCES parent(p1, p2) ON UPDATE RESTRICT
    );
  }
} {}
do_test e_fkey-18.2 {
  execsql {
    INSERT INTO parent VALUES('a', 'b');
    INSERT INTO parent VALUES('c', 'd');
    INSERT INTO child1 VALUES('b', 'a');
    INSERT INTO child2 VALUES('d', 'c');
  }
} {}
do_test e_fkey-18.3 {
  catchsql { DELETE FROM parent WHERE p1 = 'a' }
} {1 {foreign key constraint failed}}
do_test e_fkey-18.4 {
  catchsql { UPDATE parent SET p2 = 'e' WHERE p1 = 'c' }
} {1 {foreign key constraint failed}}

#-------------------------------------------------------------------------
# /* EV: R-37997-42187 */
# 
# Test that RESTRICT is slightly different from NO ACTION for IMMEDIATE
# constraints, in that it is enforced immediately, not at the end of the 
# statement.
#
drop_all_tables
do_test e_fkey-19.1 {
  execsql {
    CREATE TABLE parent(x PRIMARY KEY);
    CREATE TABLE child1(c REFERENCES parent ON UPDATE RESTRICT);
    CREATE TABLE child2(c REFERENCES parent ON UPDATE NO ACTION);

    INSERT INTO parent VALUES('key1');
    INSERT INTO parent VALUES('key2');
    INSERT INTO child1 VALUES('key1');
    INSERT INTO child2 VALUES('key2');

    CREATE TRIGGER parent_t AFTER UPDATE ON parent BEGIN
      UPDATE child1 set c = new.x WHERE c = old.x;
      UPDATE child2 set c = new.x WHERE c = old.x;
    END;
  }
} {}
do_test e_fkey-19.2 {
  catchsql { UPDATE parent SET x = 'key one' WHERE x = 'key1' }
} {1 {foreign key constraint failed}}
do_test e_fkey-19.3 {
  execsql { 
    UPDATE parent SET x = 'key two' WHERE x = 'key2';
    SELECT * FROM child2;
  }
} {{key two}}

drop_all_tables
do_test e_fkey-19.4 {
  execsql {
    CREATE TABLE parent(x PRIMARY KEY);
    CREATE TABLE child1(c REFERENCES parent ON DELETE RESTRICT);
    CREATE TABLE child2(c REFERENCES parent ON DELETE NO ACTION);

    INSERT INTO parent VALUES('key1');
    INSERT INTO parent VALUES('key2');
    INSERT INTO child1 VALUES('key1');
    INSERT INTO child2 VALUES('key2');

    CREATE TRIGGER parent_t AFTER DELETE ON parent BEGIN
      UPDATE child1 SET c = NULL WHERE c = old.x;
      UPDATE child2 SET c = NULL WHERE c = old.x;
    END;
  }
} {}
do_test e_fkey-19.5 {
  catchsql { DELETE FROM parent WHERE x = 'key1' }
} {1 {foreign key constraint failed}}
do_test e_fkey-19.6 {
  execsql { 
    DELETE FROM parent WHERE x = 'key2';
    SELECT * FROM child2;
  }
} {{}}

drop_all_tables
do_test e_fkey-19.7 {
  execsql {
    CREATE TABLE parent(x PRIMARY KEY);
    CREATE TABLE child1(c REFERENCES parent ON DELETE RESTRICT);
    CREATE TABLE child2(c REFERENCES parent ON DELETE NO ACTION);

    INSERT INTO parent VALUES('key1');
    INSERT INTO parent VALUES('key2');
    INSERT INTO child1 VALUES('key1');
    INSERT INTO child2 VALUES('key2');
  }
} {}
do_test e_fkey-19.8 {
  catchsql { REPLACE INTO parent VALUES('key1') }
} {1 {foreign key constraint failed}}
do_test e_fkey-19.9 {
  execsql { 
    REPLACE INTO parent VALUES('key2');
    SELECT * FROM child2;
  }
} {key2}

#-------------------------------------------------------------------------
# /* EV: R-24179-60523 */
# 
# Test that RESTRICT is enforced immediately, even for a DEFERRED constraint.
#
drop_all_tables
do_test e_fkey-20.1 {
  execsql {
    CREATE TABLE parent(x PRIMARY KEY);
    CREATE TABLE child1(c REFERENCES parent ON UPDATE RESTRICT
      DEFERRABLE INITIALLY DEFERRED
    );
    CREATE TABLE child2(c REFERENCES parent ON UPDATE NO ACTION
      DEFERRABLE INITIALLY DEFERRED
    );

    INSERT INTO parent VALUES('key1');
    INSERT INTO parent VALUES('key2');
    INSERT INTO child1 VALUES('key1');
    INSERT INTO child2 VALUES('key2');
    BEGIN;
  }
} {}
do_test e_fkey-20.2 {
  catchsql { UPDATE parent SET x = 'key one' WHERE x = 'key1' }
} {1 {foreign key constraint failed}}
do_test e_fkey-20.3 {
  execsql { UPDATE parent SET x = 'key two' WHERE x = 'key2' }
} {}
do_test e_fkey-20.4 {
  catchsql COMMIT
} {1 {foreign key constraint failed}}
do_test e_fkey-20.5 {
  execsql {
    UPDATE child2 SET c = 'key two';
    COMMIT;
  }
} {}

drop_all_tables
do_test e_fkey-20.6 {
  execsql {
    CREATE TABLE parent(x PRIMARY KEY);
    CREATE TABLE child1(c REFERENCES parent ON DELETE RESTRICT
      DEFERRABLE INITIALLY DEFERRED
    );
    CREATE TABLE child2(c REFERENCES parent ON DELETE NO ACTION
      DEFERRABLE INITIALLY DEFERRED
    );

    INSERT INTO parent VALUES('key1');
    INSERT INTO parent VALUES('key2');
    INSERT INTO child1 VALUES('key1');
    INSERT INTO child2 VALUES('key2');
    BEGIN;
  }
} {}
do_test e_fkey-20.7 {
  catchsql { DELETE FROM parent WHERE x = 'key1' }
} {1 {foreign key constraint failed}}
do_test e_fkey-20.8 {
  execsql { DELETE FROM parent WHERE x = 'key2' }
} {}
do_test e_fkey-20.9 {
  catchsql COMMIT
} {1 {foreign key constraint failed}}
do_test e_fkey-20.10 {
  execsql {
    UPDATE child2 SET c = NULL;
    COMMIT;
  }
} {}

#-------------------------------------------------------------------------
# /* EV: R-03353-05327 */
#
# Test SET NULL actions.
#
drop_all_tables
do_test e_fkey-21.1 {
  execsql {
    CREATE TABLE pA(x PRIMARY KEY);
    CREATE TABLE cA(c REFERENCES pA ON DELETE SET NULL);
    CREATE TABLE cB(c REFERENCES pA ON UPDATE SET NULL);

    INSERT INTO pA VALUES(X'ABCD');
    INSERT INTO pA VALUES(X'1234');
    INSERT INTO cA VALUES(X'ABCD');
    INSERT INTO cB VALUES(X'1234');
  }
} {}
do_test e_fkey-21.2 {
  execsql {
    DELETE FROM pA WHERE rowid = 1;
    SELECT quote(x) FROM pA;
  }
} {X'1234'}
do_test e_fkey-21.3 {
  execsql {
    SELECT quote(c) FROM cA;
  }
} {NULL}
do_test e_fkey-21.4 {
  execsql {
    UPDATE pA SET x = X'8765' WHERE rowid = 2;
    SELECT quote(x) FROM pA;
  }
} {X'8765'}
do_test e_fkey-21.5 {
  execsql { SELECT quote(c) FROM cB }
} {NULL}

#-------------------------------------------------------------------------
# /* EV: R-43054-54832 */
#
# Test SET DEFAULT actions.
#
drop_all_tables
do_test e_fkey-22.1 {
  execsql {
    CREATE TABLE pA(x PRIMARY KEY);
    CREATE TABLE cA(c DEFAULT X'0000' REFERENCES pA ON DELETE SET DEFAULT);
    CREATE TABLE cB(c DEFAULT X'9999' REFERENCES pA ON UPDATE SET DEFAULT);

    INSERT INTO pA(rowid, x) VALUES(1, X'0000');
    INSERT INTO pA(rowid, x) VALUES(2, X'9999');
    INSERT INTO pA(rowid, x) VALUES(3, X'ABCD');
    INSERT INTO pA(rowid, x) VALUES(4, X'1234');

    INSERT INTO cA VALUES(X'ABCD');
    INSERT INTO cB VALUES(X'1234');
  }
} {}
do_test e_fkey-22.2 {
  execsql {
    DELETE FROM pA WHERE rowid = 3;
    SELECT quote(x) FROM pA;
  }
} {X'0000' X'9999' X'1234'}
do_test e_fkey-22.3 {
  execsql { SELECT quote(c) FROM cA }
} {X'0000'}
do_test e_fkey-22.4 {
  execsql {
    UPDATE pA SET x = X'8765' WHERE rowid = 4;
    SELECT quote(x) FROM pA;
  }
} {X'0000' X'9999' X'8765'}
do_test e_fkey-22.5 {
  execsql { SELECT quote(c) FROM cB }
} {X'9999'}

#-------------------------------------------------------------------------
# /* EV: R-61376-57267 */
# /* EV: R-61809-62207 */
#
# Test ON DELETE CASCADE actions.
#
drop_all_tables
do_test e_fkey-23.1 {
  execsql {
    CREATE TABLE p1(a, b UNIQUE);
    CREATE TABLE c1(c REFERENCES p1(b) ON DELETE CASCADE, d);
    INSERT INTO p1 VALUES(NULL, NULL);
    INSERT INTO p1 VALUES(4, 4);
    INSERT INTO p1 VALUES(5, 5);
    INSERT INTO c1 VALUES(NULL, NULL);
    INSERT INTO c1 VALUES(4, 4);
    INSERT INTO c1 VALUES(5, 5);
    SELECT count(*) FROM c1;
  }
} {3}
do_test e_fkey-23.2 {
  execsql {
    DELETE FROM p1 WHERE a = 4;
    SELECT d, c FROM c1;
  }
} {{} {} 5 5}
do_test e_fkey-23.3 {
  execsql {
    DELETE FROM p1;
    SELECT d, c FROM c1;
  }
} {{} {}}
do_test e_fkey-23.4 {
  execsql { SELECT * FROM p1 }
} {}


#-------------------------------------------------------------------------
# /* EV: R-61376-57267 */
# /* EV: R-13877-64542 */
#
# Test ON UPDATE CASCADE actions.
#
drop_all_tables
do_test e_fkey-24.1 {
  execsql {
    CREATE TABLE p1(a, b UNIQUE);
    CREATE TABLE c1(c REFERENCES p1(b) ON UPDATE CASCADE, d);
    INSERT INTO p1 VALUES(NULL, NULL);
    INSERT INTO p1 VALUES(4, 4);
    INSERT INTO p1 VALUES(5, 5);
    INSERT INTO c1 VALUES(NULL, NULL);
    INSERT INTO c1 VALUES(4, 4);
    INSERT INTO c1 VALUES(5, 5);
    SELECT count(*) FROM c1;
  }
} {3}
do_test e_fkey-24.2 {
  execsql {
    UPDATE p1 SET b = 10 WHERE b = 5;
    SELECT d, c FROM c1;
  }
} {{} {} 4 4 5 10}
do_test e_fkey-24.3 {
  execsql {
    UPDATE p1 SET b = 11 WHERE b = 4;
    SELECT d, c FROM c1;
  }
} {{} {} 4 11 5 10}
do_test e_fkey-24.4 {
  execsql { 
    UPDATE p1 SET b = 6 WHERE b IS NULL;
    SELECT d, c FROM c1;
  }
} {{} {} 4 11 5 10}
do_test e_fkey-23.5 {
  execsql { SELECT * FROM p1 }
} {{} 6 4 11 5 10}

#-------------------------------------------------------------------------
# /* EV: R-51329-33438 */
#
# Test an example from the "ON DELETE and ON UPDATE Actions" section 
# of foreignkeys.html.
#
drop_all_tables
do_test e_fkey-15.1 {
  execsql {
    CREATE TABLE artist(
      artistid    INTEGER PRIMARY KEY, 
      artistname  TEXT
    );
    CREATE TABLE track(
      trackid     INTEGER,
      trackname   TEXT, 
      trackartist INTEGER REFERENCES artist(artistid) ON UPDATE CASCADE
    );

    INSERT INTO artist VALUES(1, 'Dean Martin');
    INSERT INTO artist VALUES(2, 'Frank Sinatra');
    INSERT INTO track VALUES(11, 'That''s Amore', 1);
    INSERT INTO track VALUES(12, 'Christmas Blues', 1);
    INSERT INTO track VALUES(13, 'My Way', 2);
  }
} {}
do_test e_fkey-15.2 {
  execsql {
    UPDATE artist SET artistid = 100 WHERE artistname = 'Dean Martin';
  }
} {}
do_test e_fkey-15.3 {
  execsql { SELECT * FROM artist }
} {2 {Frank Sinatra} 100 {Dean Martin}}
do_test e_fkey-15.4 {
  execsql { SELECT * FROM track }
} {11 {That's Amore} 100 12 {Christmas Blues} 100 13 {My Way} 2}


#-------------------------------------------------------------------------
# /* EV: R-53968-51642 */
#
# Verify that adding an FK action does not absolve the user of the 
# requirement not to violate the foreign key constraint.
#
drop_all_tables
do_test e_fkey-25.1 {
  execsql {
    CREATE TABLE parent(a COLLATE nocase, b, c, PRIMARY KEY(c, a));
    CREATE TABLE child(d DEFAULT 'a', e, f DEFAULT 'c',
      FOREIGN KEY(f, d) REFERENCES parent ON UPDATE SET DEFAULT
    );

    INSERT INTO parent VALUES('A', 'b', 'c');
    INSERT INTO parent VALUES('ONE', 'two', 'three');
    INSERT INTO child VALUES('one', 'two', 'three');
  }
} {}
do_test e_fkey-25.2 {
  execsql {
    BEGIN;
      UPDATE parent SET a = '' WHERE a = 'oNe';
      SELECT * FROM child;
  }
} {a two c}
do_test e_fkey-25.3 {
  execsql {
    ROLLBACK;
    DELETE FROM parent WHERE a = 'A';
    SELECT * FROM parent;
  }
} {ONE two three}
do_test e_fkey-25.4 {
  catchsql { UPDATE parent SET a = '' WHERE a = 'oNe' }
} {1 {foreign key constraint failed}}


#-------------------------------------------------------------------------
# /* EV: R-07065-59588 */
# /* EV: R-28220-46694 */
#
# Test an example from the "ON DELETE and ON UPDATE Actions" section 
# of foreignkeys.html. This example shows that adding an "ON DELETE DEFAULT"
# clause does not abrogate the need to satisfy the foreign key constraint
# (R-28220-46694).
#
drop_all_tables
do_test e_fkey-14.1 {
  execsql {
    CREATE TABLE artist(
      artistid    INTEGER PRIMARY KEY, 
      artistname  TEXT
    );
    CREATE TABLE track(
      trackid     INTEGER,
      trackname   TEXT, 
      trackartist INTEGER DEFAULT 0 REFERENCES artist(artistid) ON DELETE SET DEFAULT
    );
    INSERT INTO artist VALUES(3, 'Sammy Davis Jr.');
    INSERT INTO track VALUES(14, 'Mr. Bojangles', 3);
  }
} {}
do_test e_fkey-14.2 {
  catchsql { DELETE FROM artist WHERE artistname = 'Sammy Davis Jr.' }
} {1 {foreign key constraint failed}}
do_test e_fkey-14.3 {
  execsql {
    INSERT INTO artist VALUES(0, 'Unknown Artist');
    DELETE FROM artist WHERE artistname = 'Sammy Davis Jr.';
  }
} {}
do_test e_fkey-14.4 {
  execsql { SELECT * FROM artist }
} {0 {Unknown Artist}}
do_test e_fkey-14.5 {
  execsql { SELECT * FROM track }
} {14 {Mr. Bojangles} 0}

#-------------------------------------------------------------------------
# /* EV: R-09564-22170 */
#
# Check that the order of steps in an UPDATE or DELETE on a parent 
# table is as follows:
#
#   1. Execute applicable BEFORE trigger programs,
#   2. Check local (non foreign key) constraints,
#   3. Update or delete the row in the parent table,
#   4. Perform any required foreign key actions,
#   5. Execute applicable AFTER trigger programs. 
#
drop_all_tables
do_test e_fkey-27.1 {
  proc maxparent {args} { db one {SELECT max(x) FROM parent} }
  db func maxparent maxparent

  execsql {
    CREATE TABLE parent(x PRIMARY KEY);

    CREATE TRIGGER bu BEFORE UPDATE ON parent BEGIN
      INSERT INTO parent VALUES(new.x-old.x);
    END;
    CREATE TABLE child(
      a DEFAULT (maxparent()) REFERENCES parent ON UPDATE SET DEFAULT
    );
    CREATE TRIGGER au AFTER UPDATE ON parent BEGIN
      INSERT INTO parent VALUES(new.x+old.x);
    END;

    INSERT INTO parent VALUES(1);
    INSERT INTO child VALUES(1);
  }
} {}
do_test e_fkey-27.2 {
  execsql {
    UPDATE parent SET x = 22;
    SELECT * FROM parent UNION ALL SELECT 'xxx' UNION ALL SELECT a FROM child;
  }
} {22 21 23 xxx 22}
do_test e_fkey-27.3 {
  execsql {
    DELETE FROM child;
    DELETE FROM parent;
    INSERT INTO parent VALUES(-1);
    INSERT INTO child VALUES(-1);
    UPDATE parent SET x = 22;
    SELECT * FROM parent UNION ALL SELECT 'xxx' UNION ALL SELECT a FROM child;
  }
} {22 23 21 xxx 23}


#-------------------------------------------------------------------------
# /* EV: R-27383-10246 */
#
# Verify that ON UPDATE actions only actually take place if the parent key
# is set to a new value that is distinct from the old value. The default
# collation sequence and affinity are used to determine if the new value
# is 'distinct' from the old or not.
#
drop_all_tables
do_test e_fkey-26.1 {
  execsql {
    CREATE TABLE zeus(a INTEGER COLLATE NOCASE, b, PRIMARY KEY(a, b));
    CREATE TABLE apollo(c, d, 
      FOREIGN KEY(c, d) REFERENCES zeus ON UPDATE CASCADE
    );
    INSERT INTO zeus VALUES('abc', 'xyz');
    INSERT INTO apollo VALUES('ABC', 'xyz');
  }
  execsql {
    UPDATE zeus SET a = 'aBc';
    SELECT * FROM apollo;
  }
} {ABC xyz}
do_test e_fkey-26.2 {
  execsql {
    UPDATE zeus SET a = 1, b = 1;
    SELECT * FROM apollo;
  }
} {1 1}
do_test e_fkey-26.3 {
  execsql {
    UPDATE zeus SET a = 1, b = 1;
    SELECT typeof(c), c, typeof(d), d FROM apollo;
  }
} {integer 1 integer 1}
do_test e_fkey-26.4 {
  execsql {
    UPDATE zeus SET a = '1';
    SELECT typeof(c), c, typeof(d), d FROM apollo;
  }
} {integer 1 integer 1}
do_test e_fkey-26.5 {
  execsql {
    UPDATE zeus SET b = '1';
    SELECT typeof(c), c, typeof(d), d FROM apollo;
  }
} {integer 1 text 1}
do_test e_fkey-26.6 {
  execsql {
    UPDATE zeus SET b = NULL;
    SELECT typeof(c), c, typeof(d), d FROM apollo;
  }
} {integer 1 null {}}

#-------------------------------------------------------------------------
# /* EV: R-58589-50781 */
#
# Test an example from the "ON DELETE and ON UPDATE Actions" section 
# of foreignkeys.html. This example demonstrates that ON UPDATE actions
# only take place if at least one parent key column is set to a value 
# that is distinct from its previous value.
#
drop_all_tables
do_test e_fkey-13.1 {
  execsql {
    CREATE TABLE parent(x PRIMARY KEY);
    CREATE TABLE child(y REFERENCES parent ON UPDATE SET NULL);
    INSERT INTO parent VALUES('key');
    INSERT INTO child VALUES('key');
  }
} {}
do_test e_fkey-13.2 {
  execsql {
    UPDATE parent SET x = 'key';
    SELECT IFNULL(y, 'null') FROM child;
  }
} {key}
do_test e_fkey-13.3 {
  execsql {
    UPDATE parent SET x = 'key2';
    SELECT IFNULL(y, 'null') FROM child;
  }
} {null}

###########################################################################
### SECTION 5: CREATE, ALTER and DROP TABLE commands
###########################################################################

#-------------------------------------------------------------------------
# /* EV: R-36018-21755 */
# /* EV: R-25384-39337 */
# 
# Test that parent keys are not checked when tables are created.
#
# Child keys are checked to ensure all component columns exist. If parent
# key columns are explicitly specified, SQLite checks to make sure there
# are the same number of columns in the child and parent keys. (TODO: This
# is tested but does not correspond to any testable statement.)
#
# /* EV: R-08908-23439 */
#
# Also test that the above statements are true regardless of whether or not
# foreign keys are enabled:  "A CREATE TABLE command operates the same whether
# or not foreign key constraints are enabled."
# 
foreach {tn zCreateTbl lRes} {
  1 "CREATE TABLE t1(a, b REFERENCES t1)"                            {0 {}}
  2 "CREATE TABLE t1(a, b REFERENCES t2)"                            {0 {}}
  3 "CREATE TABLE t1(a, b, FOREIGN KEY(a,b) REFERENCES t1)"          {0 {}}
  4 "CREATE TABLE t1(a, b, FOREIGN KEY(a,b) REFERENCES t2)"          {0 {}}
  5 "CREATE TABLE t1(a, b, FOREIGN KEY(a,b) REFERENCES t2)"          {0 {}}
  6 "CREATE TABLE t1(a, b, FOREIGN KEY(a,b) REFERENCES t2(n,d))"     {0 {}}
  7 "CREATE TABLE t1(a, b, FOREIGN KEY(a,b) REFERENCES t1(a,b))"     {0 {}}

  A "CREATE TABLE t1(a, b, FOREIGN KEY(c,b) REFERENCES t2)"          
     {1 {unknown column "c" in foreign key definition}}
  B "CREATE TABLE t1(a, b, FOREIGN KEY(c,b) REFERENCES t2(d))"          
     {1 {number of columns in foreign key does not match the number of columns in the referenced table}}
} {
  do_test e_fkey-5.$tn.off {
    drop_all_tables
    execsql {PRAGMA foreign_keys = OFF}
    catchsql $zCreateTbl
  } $lRes
  do_test e_fkey-5.$tn.on {
    drop_all_tables
    execsql {PRAGMA foreign_keys = ON}
    catchsql $zCreateTbl
  } $lRes
}

#-------------------------------------------------------------------------
# /* EV: R-47952-62498 */
#
proc test_efkey_6 {tn zAlter isError} {
  drop_all_tables 

  do_test e_fkey-6.$tn.1 "
    execsql { CREATE TABLE tbl(a, b) }
    [list catchsql $zAlter]
  " [lindex {{0 {}} {1 {Cannot add a REFERENCES column with non-NULL default value}}} $isError]

}

test_efkey_6 1 "ALTER TABLE tbl ADD COLUMN c REFERENCES xx" 0
test_efkey_6 2 "ALTER TABLE tbl ADD COLUMN c DEFAULT NULL REFERENCES xx" 0
test_efkey_6 3 "ALTER TABLE tbl ADD COLUMN c DEFAULT 0 REFERENCES xx" 1

#-------------------------------------------------------------------------
# /* EV: R-47080-02069 */
#
# Test that ALTER TABLE adjusts REFERENCES clauses when the parent table
# is RENAMED.
#
# /* EV: R-63827-54774 */
#
# Test that these adjustments are visible in the sqlite_master table.
#
do_test e_fkey-7.1 {
  drop_all_tables
  execsql {
    CREATE TABLE 'p 1 "parent one"'(a REFERENCES 'p 1 "parent one"', b, PRIMARY KEY(b));

    CREATE TABLE c1(c, d REFERENCES 'p 1 "parent one"' ON UPDATE CASCADE);
    CREATE TABLE c2(e, f, FOREIGN KEY(f) REFERENCES 'p 1 "parent one"' ON UPDATE CASCADE);
    CREATE TABLE c3(e, 'f col 2', FOREIGN KEY('f col 2') REFERENCES 'p 1 "parent one"' ON UPDATE CASCADE);

    INSERT INTO 'p 1 "parent one"' VALUES(1, 1);
    INSERT INTO c1 VALUES(1, 1);
    INSERT INTO c2 VALUES(1, 1);
    INSERT INTO c3 VALUES(1, 1);

    -- CREATE TABLE q(a, b, PRIMARY KEY(b));
  }
} {}
do_test e_fkey-7.2 {
  execsql { ALTER TABLE 'p 1 "parent one"' RENAME TO p }
} {}
do_test e_fkey-7.3 {
  execsql {
    UPDATE p SET a = 'xxx', b = 'xxx';
    SELECT * FROM p;
    SELECT * FROM c1;
    SELECT * FROM c2;
    SELECT * FROM c3;
  }
} {xxx xxx 1 xxx 1 xxx 1 xxx}
do_test e_fkey-7.4 {
  execsql { SELECT sql FROM sqlite_master WHERE type = 'table'}
} [list                                                                     \
  {CREATE TABLE "p"(a REFERENCES "p", b, PRIMARY KEY(b))}                   \
  {CREATE TABLE c1(c, d REFERENCES "p" ON UPDATE CASCADE)}                  \
  {CREATE TABLE c2(e, f, FOREIGN KEY(f) REFERENCES "p" ON UPDATE CASCADE)}  \
  {CREATE TABLE c3(e, 'f col 2', FOREIGN KEY('f col 2') REFERENCES "p" ON UPDATE CASCADE)} \
]

#-------------------------------------------------------------------------
# /* EV: R-14208-23986 */
# /* EV: R-11078-03945 */
#
# Check that a DROP TABLE does an implicit DELETE FROM. Which does not
# cause any triggers to fire, but does fire foreign key actions.
#
do_test e_fkey-8.1 {
  drop_all_tables
  execsql {
    CREATE TABLE p(a, b, PRIMARY KEY(a, b));

    CREATE TABLE c1(c, d, FOREIGN KEY(c, d) REFERENCES p ON DELETE SET NULL);
    CREATE TABLE c2(c, d, FOREIGN KEY(c, d) REFERENCES p ON DELETE SET DEFAULT);
    CREATE TABLE c3(c, d, FOREIGN KEY(c, d) REFERENCES p ON DELETE CASCADE);
    CREATE TABLE c4(c, d, FOREIGN KEY(c, d) REFERENCES p ON DELETE RESTRICT);
    CREATE TABLE c5(c, d, FOREIGN KEY(c, d) REFERENCES p ON DELETE NO ACTION);

    CREATE TABLE c6(c, d, 
      FOREIGN KEY(c, d) REFERENCES p ON DELETE RESTRICT 
      DEFERRABLE INITIALLY DEFERRED
    );
    CREATE TABLE c7(c, d, 
      FOREIGN KEY(c, d) REFERENCES p ON DELETE NO ACTION
      DEFERRABLE INITIALLY DEFERRED
    );

    CREATE TABLE log(msg);
    CREATE TRIGGER tt AFTER DELETE ON p BEGIN
      INSERT INTO log VALUES('delete ' || old.rowid);
    END;
  }
} {}

do_test e_fkey-8.2 {
  execsql {
    INSERT INTO p VALUES('a', 'b');
    INSERT INTO c1 VALUES('a', 'b');
    INSERT INTO c2 VALUES('a', 'b');
    INSERT INTO c3 VALUES('a', 'b');
    BEGIN;
      DROP TABLE p;
      SELECT * FROM c1;
  }
} {{} {}}
do_test e_fkey-8.3 {
  execsql { SELECT * FROM c2 }
} {{} {}}
do_test e_fkey-8.4 {
  execsql { SELECT * FROM c3 }
} {}
do_test e_fkey-8.5 {
  execsql { SELECT * FROM log }
} {}
do_test e_fkey-8.6 {
  execsql ROLLBACK
} {}
do_test e_fkey-8.7 {
  execsql {
    BEGIN;
      DELETE FROM p;
      SELECT * FROM log;
    ROLLBACK;
  }
} {{delete 1}}

#-------------------------------------------------------------------------
# /* EV: R-32768-47925 */
#
# If an IMMEDIATE foreign key fails as a result of a DROP TABLE, the
# DROP TABLE command fails.
#
do_test e_fkey-9.1 {
  execsql { 
    DELETE FROM c1;
    DELETE FROM c2;
    DELETE FROM c3;
  }
  execsql { INSERT INTO c5 VALUES('a', 'b') }
  catchsql { DROP TABLE p }
} {1 {foreign key constraint failed}}
do_test e_fkey-9.2 {
  execsql { SELECT * FROM p }
} {a b}
do_test e_fkey-9.3 {
  catchsql {
    BEGIN;
      DROP TABLE p;
  }
} {1 {foreign key constraint failed}}
do_test e_fkey-9.4 {
  execsql {
    SELECT * FROM p;
    SELECT * FROM c5;
    ROLLBACK;
  }
} {a b a b}

#-------------------------------------------------------------------------
# /* EV: R-05903-08460 */
#
# If a DEFERRED foreign key fails as a result of a DROP TABLE, attempting
# to commit the transaction fails unless the violation is fixed.
#
do_test e_fkey-10.1 {
  execsql { 
    DELETE FROM c1 ; DELETE FROM c2 ; DELETE FROM c3 ;
    DELETE FROM c4 ; DELETE FROM c5 ; DELETE FROM c6 ;
    DELETE FROM c7 
  }
} {}
do_test e_fkey-10.2 {
  execsql { INSERT INTO c7 VALUES('a', 'b') }
  execsql {
    BEGIN;
      DROP TABLE p;
  }
} {}
do_test e_fkey-10.3 {
  catchsql COMMIT
} {1 {foreign key constraint failed}}
do_test e_fkey-10.4 {
  execsql { CREATE TABLE p(a, b, PRIMARY KEY(a, b)) }
  catchsql COMMIT
} {1 {foreign key constraint failed}}
do_test e_fkey-10.5 {
  execsql { INSERT INTO p VALUES('a', 'b') }
  execsql COMMIT
} {}

#-------------------------------------------------------------------------
# /* EV: R-57242-37005 */
#
# Any "foreign key mismatch" errors encountered while running an implicit
# "DELETE FROM tbl" are ignored.
#
drop_all_tables
do_test e_fkey-11.1 {
  execsql {
    PRAGMA foreign_keys = OFF;

    CREATE TABLE p(a PRIMARY KEY, b REFERENCES nosuchtable);
    CREATE TABLE c1(c, d, FOREIGN KEY(c, d) REFERENCES a);
    CREATE TABLE c2(c REFERENCES p(b), d);
    CREATE TABLE c3(c REFERENCES p ON DELETE SET NULL, d);

    INSERT INTO p VALUES(1, 2);
    INSERT INTO c1 VALUES(1, 2);
    INSERT INTO c2 VALUES(1, 2);
    INSERT INTO c3 VALUES(1, 2);
  }
} {}
do_test e_fkey-11.2 {
  execsql { PRAGMA foreign_keys = ON }
  catchsql { DELETE FROM p }
} {1 {no such table: main.nosuchtable}}
do_test e_fkey-11.3 {
  execsql {
    BEGIN;
      DROP TABLE p;
      SELECT * FROM c3;
    ROLLBACK;
  }
} {{} 2}
do_test e_fkey-11.4 {
  execsql { CREATE TABLE nosuchtable(x PRIMARY KEY) }
  catchsql { DELETE FROM p }
} {1 {foreign key mismatch}}
do_test e_fkey-11.5 {
  execsql { DROP TABLE c1 }
  catchsql { DELETE FROM p }
} {1 {foreign key mismatch}}
do_test e_fkey-11.6 {
  execsql { DROP TABLE c2 }
  execsql { DELETE FROM p }
} {}

#-------------------------------------------------------------------------
# /* EV: R-54142-41346 */
#
# Test that the special behaviours of ALTER and DROP TABLE are only
# activated when foreign keys are enabled. Special behaviours are:
#
#   1. ADD COLUMN not allowing a REFERENCES clause with a non-NULL 
#      default value.
#   2. Modifying foreign key definitions when a parent table is RENAMEd.
#   3. Running an implicit DELETE FROM command as part of DROP TABLE.
#
do_test e_fkey-12.1.1 {
  drop_all_tables
  execsql { CREATE TABLE t1(a, b) }
  catchsql { ALTER TABLE t1 ADD COLUMN c DEFAULT 'xxx' REFERENCES t2 }
} {1 {Cannot add a REFERENCES column with non-NULL default value}}
do_test e_fkey-12.1.2 {
  execsql { PRAGMA foreign_keys = OFF }
  execsql { ALTER TABLE t1 ADD COLUMN c DEFAULT 'xxx' REFERENCES t2 }
  execsql { SELECT sql FROM sqlite_master WHERE name = 't1' }
} {{CREATE TABLE t1(a, b, c DEFAULT 'xxx' REFERENCES t2)}}
do_test e_fkey-12.1.3 {
  execsql { PRAGMA foreign_keys = ON }
} {}

do_test e_fkey-12.2.1 {
  drop_all_tables
  execsql {
    CREATE TABLE p(a UNIQUE);
    CREATE TABLE c(b REFERENCES p(a));
    BEGIN;
      ALTER TABLE p RENAME TO parent;
      SELECT sql FROM sqlite_master WHERE name = 'c';
    ROLLBACK;
  }
} {{CREATE TABLE c(b REFERENCES "parent"(a))}}
do_test e_fkey-12.2.2 {
  execsql {
    PRAGMA foreign_keys = OFF;
    ALTER TABLE p RENAME TO parent;
    SELECT sql FROM sqlite_master WHERE name = 'c';
  }
} {{CREATE TABLE c(b REFERENCES p(a))}}
do_test e_fkey-12.2.3 {
  execsql { PRAGMA foreign_keys = ON }
} {}

do_test e_fkey-12.3.1 {
  drop_all_tables
  execsql {
    CREATE TABLE p(a UNIQUE);
    CREATE TABLE c(b REFERENCES p(a) ON DELETE SET NULL);
    INSERT INTO p VALUES('x');
    INSERT INTO c VALUES('x');
    BEGIN;
      DROP TABLE p;
      SELECT * FROM c;
    ROLLBACK;
  }
} {{}}
do_test e_fkey-12.3.2 {
  execsql {
    PRAGMA foreign_keys = OFF;
    DROP TABLE p;
    SELECT * FROM c;
  }
} {x}
do_test e_fkey-12.3.3 {
  execsql { PRAGMA foreign_keys = ON }
} {}

###########################################################################
### SECTION 6: Limits and Unsupported Features
###########################################################################

#-------------------------------------------------------------------------
# /* EV: R-24728-13230 */
# /* EV: R-24450-46174 */
#
# Test that MATCH clauses are parsed, but SQLite treats every foreign key
# constraint as if it were "MATCH SIMPLE".
#
foreach zMatch [list SIMPLE PARTIAL FULL Simple parTIAL FuLL ] {
  drop_all_tables
  do_test e_fkey-1.$zMatch.1 {
    execsql "
      CREATE TABLE p(a, b, c, PRIMARY KEY(b, c));
      CREATE TABLE c(d, e, f, FOREIGN KEY(e, f) REFERENCES p MATCH $zMatch);
    "
  } {}
  do_test e_fkey-1.$zMatch.2 {
    execsql { INSERT INTO p VALUES(1, 2, 3)         }

    # MATCH SIMPLE behaviour: Allow any child key that contains one or more
    # NULL value to be inserted. Non-NULL values do not have to map to any
    # parent key values, so long as at least one field of the child key is
    # NULL.
    execsql { INSERT INTO c VALUES('w', 2, 3)       }
    execsql { INSERT INTO c VALUES('x', 'x', NULL)  }
    execsql { INSERT INTO c VALUES('y', NULL, 'x')  }
    execsql { INSERT INTO c VALUES('z', NULL, NULL) }

    # Check that the FK is enforced properly if there are no NULL values 
    # in the child key columns.
    catchsql { INSERT INTO c VALUES('a', 2, 4) }
  } {1 {foreign key constraint failed}}
}

#-------------------------------------------------------------------------
# /* EV: R-21599-16038 */
#
# Test that SQLite does not support the SET CONSTRAINT statement. And
# that it is possible to create both immediate and deferred constraints.
#
drop_all_tables
do_test e_fkey-2.1 {
  catchsql { SET CONSTRAINTS ALL IMMEDIATE }
} {1 {near "SET": syntax error}}
do_test e_fkey-2.2 {
  catchsql { SET CONSTRAINTS ALL DEFERRED }
} {1 {near "SET": syntax error}}

do_test e_fkey-2.3 {
  execsql {
    CREATE TABLE p(a, b, PRIMARY KEY(a, b));
    CREATE TABLE cd(c, d, 
      FOREIGN KEY(c, d) REFERENCES p DEFERRABLE INITIALLY DEFERRED);
    CREATE TABLE ci(c, d, 
      FOREIGN KEY(c, d) REFERENCES p DEFERRABLE INITIALLY IMMEDIATE);
    BEGIN;
  }
} {}
do_test e_fkey-2.4 {
  catchsql { INSERT INTO ci VALUES('x', 'y') }
} {1 {foreign key constraint failed}}
do_test e_fkey-2.5 {
  catchsql { INSERT INTO cd VALUES('x', 'y') }
} {0 {}}
do_test e_fkey-2.6 {
  catchsql { COMMIT }
} {1 {foreign key constraint failed}}
do_test e_fkey-2.7 {
  execsql { 
    DELETE FROM cd;
    COMMIT;
  }
} {}

#-------------------------------------------------------------------------
# /* EV: R-42264-30503 */
#
# Test that the maximum recursion depth of foreign key action programs is
# governed by the SQLITE_MAX_TRIGGER_DEPTH and SQLITE_LIMIT_TRIGGER_DEPTH
# settings.
#
proc test_on_delete_recursion {limit} {
  drop_all_tables
  execsql { 
    BEGIN;
    CREATE TABLE t0(a PRIMARY KEY, b);
    INSERT INTO t0 VALUES('x0', NULL);
  }
  for {set i 1} {$i <= $limit} {incr i} {
    execsql "
      CREATE TABLE t$i (
        a PRIMARY KEY, b REFERENCES t[expr $i-1] ON DELETE CASCADE
      );
      INSERT INTO t$i VALUES('x$i', 'x[expr $i-1]');
    "
  }
  execsql COMMIT
  catchsql "
    DELETE FROM t0;
    SELECT count(*) FROM t$limit;
  "
}
proc test_on_update_recursion {limit} {
  drop_all_tables
  execsql { 
    BEGIN;
    CREATE TABLE t0(a PRIMARY KEY);
    INSERT INTO t0 VALUES('xxx');
  }
  for {set i 1} {$i <= $limit} {incr i} {
    set j [expr $i-1]

    execsql "
      CREATE TABLE t$i (a PRIMARY KEY REFERENCES t$j ON UPDATE CASCADE);
      INSERT INTO t$i VALUES('xxx');
    "
  }
  execsql COMMIT
  catchsql "
    UPDATE t0 SET a = 'yyy';
    SELECT NOT (a='yyy') FROM t$limit;
  "
}

do_test e_fkey-3.1.1 {
  test_on_delete_recursion $SQLITE_MAX_TRIGGER_DEPTH
} {0 0}
do_test e_fkey-3.1.2 {
  test_on_delete_recursion [expr $SQLITE_MAX_TRIGGER_DEPTH+1]
} {1 {too many levels of trigger recursion}}
do_test e_fkey-3.1.3 {
  sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 5
  test_on_delete_recursion 5
} {0 0}
do_test e_fkey-3.1.4 {
  test_on_delete_recursion 6
} {1 {too many levels of trigger recursion}}
do_test e_fkey-3.1.5 {
  sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1000000
} {5}
do_test e_fkey-3.2.1 {
  test_on_update_recursion $SQLITE_MAX_TRIGGER_DEPTH
} {0 0}
do_test e_fkey-3.2.2 {
  test_on_update_recursion [expr $SQLITE_MAX_TRIGGER_DEPTH+1]
} {1 {too many levels of trigger recursion}}
do_test e_fkey-3.2.3 {
  sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 5
  test_on_update_recursion 5
} {0 0}
do_test e_fkey-3.2.4 {
  test_on_update_recursion 6
} {1 {too many levels of trigger recursion}}
do_test e_fkey-3.2.5 {
  sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1000000
} {5}

#-------------------------------------------------------------------------
# /* EV: R-51769-32730 */
#
# The setting of the recursive_triggers pragma does not affect foreign
# key actions.
#
foreach recursive_triggers_setting [list 0 1 ON OFF] {
  drop_all_tables
  execsql "PRAGMA recursive_triggers = $recursive_triggers_setting"

  do_test e_fkey-4.$recursive_triggers_setting.1 {
    execsql {
      CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1 ON DELETE CASCADE);
      INSERT INTO t1 VALUES(1, NULL);
      INSERT INTO t1 VALUES(2, 1);
      INSERT INTO t1 VALUES(3, 2);
      INSERT INTO t1 VALUES(4, 3);
      INSERT INTO t1 VALUES(5, 4);
      SELECT count(*) FROM t1;
    }
  } {5}
  do_test e_fkey-4.$recursive_triggers_setting.2 {
    execsql { SELECT count(*) FROM t1 WHERE a = 1 }
  } {1}
  do_test e_fkey-4.$recursive_triggers_setting.3 {
    execsql { 
      DELETE FROM t1 WHERE a = 1;
      SELECT count(*) FROM t1;
    }
  } {0}
}

finish_test
Changes to test/expr.test.
161
162
163
164
165
166
167

























168
169
170
171
172
173
174
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







test_expr expr-1.108 {i1=0} {1%0} {{}}
test_expr expr-1.109 {i1=0} {1/0} {{}}

if {[working_64bit_int]} {
  test_expr expr-1.110 {i1=0} {-9223372036854775807/-1} 9223372036854775807
}

test_expr expr-1.111 {i1=NULL, i2=8} {i1 IS i2} 0
test_expr expr-1.112 {i1=NULL, i2=NULL} {i1 IS i2} 1
test_expr expr-1.113 {i1=6, i2=NULL} {i1 IS i2} 0
test_expr expr-1.114 {i1=6, i2=6} {i1 IS i2} 1
test_expr expr-1.115 {i1=NULL, i2=8} \
  {CASE WHEN i1 IS i2 THEN 'yes' ELSE 'no' END} no
test_expr expr-1.116 {i1=NULL, i2=NULL} \
  {CASE WHEN i1 IS i2 THEN 'yes' ELSE 'no' END} yes
test_expr expr-1.117 {i1=6, i2=NULL} \
  {CASE WHEN i1 IS i2 THEN 'yes' ELSE 'no' END} no
test_expr expr-1.118 {i1=8, i2=8} \
  {CASE WHEN i1 IS i2 THEN 'yes' ELSE 'no' END} yes
test_expr expr-1.119 {i1=NULL, i2=8} {i1 IS NOT i2} 1
test_expr expr-1.120 {i1=NULL, i2=NULL} {i1 IS NOT i2} 0
test_expr expr-1.121 {i1=6, i2=NULL} {i1 IS NOT i2} 1
test_expr expr-1.122 {i1=6, i2=6} {i1 IS NOT i2} 0
test_expr expr-1.123 {i1=NULL, i2=8} \
  {CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} yes
test_expr expr-1.124 {i1=NULL, i2=NULL} \
  {CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} no
test_expr expr-1.125 {i1=6, i2=NULL} \
  {CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} yes
test_expr expr-1.126 {i1=8, i2=8} \
  {CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} no

ifcapable floatingpoint {
  test_expr expr-2.1 {r1=1.23, r2=2.34} {r1+r2} 3.57
  test_expr expr-2.2 {r1=1.23, r2=2.34} {r1-r2} -1.11
  test_expr expr-2.3 {r1=1.23, r2=2.34} {r1*r2} 2.8782
}
set tcl_precision 15
ifcapable floatingpoint {
Changes to test/fkey1.test.
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56







-
+







      y TEXT
    );
  }
} {}
do_test fkey1-1.2 {
  execsql {
    CREATE TABLE t3(
      a INTEGER REFERENCES t2 ON INSERT RESTRICT,
      a INTEGER REFERENCES t2,
      b INTEGER REFERENCES t1,
      FOREIGN KEY (a,b) REFERENCES t2(x,y)
    );
  }
} {}

do_test fkey1-2.1 {
76
77
78
79
80
81
82
83
84
85



86
87
88
89
90
91
92
93
94
95
96



97
98
99
100
101
102
103
76
77
78
79
80
81
82



83
84
85
86
87
88
89
90
91
92
93



94
95
96
97
98
99
100
101
102
103







-
-
-
+
+
+








-
-
-
+
+
+







    CREATE TABLE t5(a PRIMARY KEY, b, c);
    CREATE TABLE t6(
      d REFERENCES t5,
      e REFERENCES t5(c)
    );
    PRAGMA foreign_key_list(t6);
  }
} [concat            \
  {0 0 t5 e c RESTRICT RESTRICT NONE}       \
  {1 0 t5 d {} RESTRICT RESTRICT NONE}      \
} [concat                                         \
  {0 0 t5 e c {NO ACTION} {NO ACTION} NONE}       \
  {1 0 t5 d {} {NO ACTION} {NO ACTION} NONE}      \
]
do_test fkey1-3.2 {
  execsql {
    CREATE TABLE t7(d, e, f,
      FOREIGN KEY (d, e) REFERENCES t5(a, b)
    );
    PRAGMA foreign_key_list(t7);
  }
} [concat                        \
  {0 0 t5 d a RESTRICT RESTRICT NONE} \
  {0 1 t5 e b RESTRICT RESTRICT NONE} \
} [concat                                   \
  {0 0 t5 d a {NO ACTION} {NO ACTION} NONE} \
  {0 1 t5 e b {NO ACTION} {NO ACTION} NONE} \
]
do_test fkey1-3.3 {
  execsql {
    CREATE TABLE t8(d, e, f,
      FOREIGN KEY (d, e) REFERENCES t5 ON DELETE CASCADE ON UPDATE SET NULL
    );
    PRAGMA foreign_key_list(t8);
Added test/fkey2.test.














































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for foreign keys.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable {!foreignkey||!trigger} {
  finish_test
  return
}

#-------------------------------------------------------------------------
# Test structure:
#
# fkey2-1.*: Simple tests to check that immediate and deferred foreign key 
#            constraints work when not inside a transaction.
#            
# fkey2-2.*: Tests to verify that deferred foreign keys work inside
#            explicit transactions (i.e that processing really is deferred).
#
# fkey2-3.*: Tests that a statement transaction is rolled back if an
#            immediate foreign key constraint is violated.
#
# fkey2-4.*: Test that FK actions may recurse even when recursive triggers
#            are disabled.
#
# fkey2-5.*: Check that if foreign-keys are enabled, it is not possible
#            to write to an FK column using the incremental blob API.
#
# fkey2-6.*: Test that FK processing is automatically disabled when 
#            running VACUUM.
#
# fkey2-7.*: Test using an IPK as the key in the child (referencing) table.
#
# fkey2-8.*: Test that enabling/disabling foreign key support while a 
#            transaction is active is not possible.
#
# fkey2-9.*: Test SET DEFAULT actions.
#
# fkey2-10.*: Test errors.
#
# fkey2-11.*: Test CASCADE actions.
#
# fkey2-12.*: Test RESTRICT actions.
#
# fkey2-13.*: Test that FK processing is performed when a row is REPLACED by
#             an UPDATE or INSERT statement.
#
# fkey2-14.*: Test the ALTER TABLE and DROP TABLE commands.
#
# fkey2-15.*: Test that if there are no (known) outstanding foreign key 
#             constraint violations in the database, inserting into a parent
#             table or deleting from a child table does not cause SQLite
#             to check if this has repaired an outstanding violation.
#
# fkey2-16.*: Test that rows that refer to themselves may be inserted, 
#             updated and deleted.
#
# fkey2-17.*: Test that the "count_changes" pragma does not interfere with
#             FK constraint processing.
# 
# fkey2-18.*: Test that the authorization callback is invoked when processing
#             FK constraints.
#
# fkey2-genfkey.*: Tests that were used with the shell tool .genfkey
#            command. Recycled to test the built-in implementation.
#


execsql { PRAGMA foreign_keys = on }

set FkeySimpleSchema {
  PRAGMA foreign_keys = on;
  CREATE TABLE t1(a PRIMARY KEY, b);
  CREATE TABLE t2(c REFERENCES t1(a) /D/ , d);

  CREATE TABLE t3(a PRIMARY KEY, b);
  CREATE TABLE t4(c REFERENCES t3 /D/, d);

  CREATE TABLE t7(a, b INTEGER PRIMARY KEY);
  CREATE TABLE t8(c REFERENCES t7 /D/, d);

  CREATE TABLE t9(a REFERENCES nosuchtable, b);
  CREATE TABLE t10(a REFERENCES t9(c) /D/, b);
}


set FkeySimpleTests {
  1.1  "INSERT INTO t2 VALUES(1, 3)"      {1 {foreign key constraint failed}}
  1.2  "INSERT INTO t1 VALUES(1, 2)"      {0 {}}
  1.3  "INSERT INTO t2 VALUES(1, 3)"      {0 {}}
  1.4  "INSERT INTO t2 VALUES(2, 4)"      {1 {foreign key constraint failed}}
  1.5  "INSERT INTO t2 VALUES(NULL, 4)"   {0 {}}
  1.6  "UPDATE t2 SET c=2 WHERE d=4"      {1 {foreign key constraint failed}}
  1.7  "UPDATE t2 SET c=1 WHERE d=4"      {0 {}}
  1.9  "UPDATE t2 SET c=1 WHERE d=4"      {0 {}}
  1.10 "UPDATE t2 SET c=NULL WHERE d=4"   {0 {}}
  1.11 "DELETE FROM t1 WHERE a=1"         {1 {foreign key constraint failed}}
  1.12 "UPDATE t1 SET a = 2"              {1 {foreign key constraint failed}}
  1.13 "UPDATE t1 SET a = 1"              {0 {}}

  2.1  "INSERT INTO t4 VALUES(1, 3)"      {1 {foreign key constraint failed}}
  2.2  "INSERT INTO t3 VALUES(1, 2)"      {0 {}}
  2.3  "INSERT INTO t4 VALUES(1, 3)"      {0 {}}

  4.1  "INSERT INTO t8 VALUES(1, 3)"      {1 {foreign key constraint failed}}
  4.2  "INSERT INTO t7 VALUES(2, 1)"      {0 {}}
  4.3  "INSERT INTO t8 VALUES(1, 3)"      {0 {}}
  4.4  "INSERT INTO t8 VALUES(2, 4)"      {1 {foreign key constraint failed}}
  4.5  "INSERT INTO t8 VALUES(NULL, 4)"   {0 {}}
  4.6  "UPDATE t8 SET c=2 WHERE d=4"      {1 {foreign key constraint failed}}
  4.7  "UPDATE t8 SET c=1 WHERE d=4"      {0 {}}
  4.9  "UPDATE t8 SET c=1 WHERE d=4"      {0 {}}
  4.10 "UPDATE t8 SET c=NULL WHERE d=4"   {0 {}}
  4.11 "DELETE FROM t7 WHERE b=1"         {1 {foreign key constraint failed}}
  4.12 "UPDATE t7 SET b = 2"              {1 {foreign key constraint failed}}
  4.13 "UPDATE t7 SET b = 1"              {0 {}}
  4.14 "INSERT INTO t8 VALUES('a', 'b')"  {1 {foreign key constraint failed}}
  4.15 "UPDATE t7 SET b = 5"              {1 {foreign key constraint failed}}
  4.16 "UPDATE t7 SET rowid = 5"          {1 {foreign key constraint failed}}
  4.17 "UPDATE t7 SET a = 10"             {0 {}}

  5.1  "INSERT INTO t9 VALUES(1, 3)"      {1 {no such table: main.nosuchtable}}
  5.2  "INSERT INTO t10 VALUES(1, 3)"     {1 {foreign key mismatch}}
}

do_test fkey2-1.1.0 {
  execsql [string map {/D/ {}} $FkeySimpleSchema]
} {}
foreach {tn zSql res} $FkeySimpleTests {
  do_test fkey2-1.1.$tn { catchsql $zSql } $res
}
drop_all_tables

do_test fkey2-1.2.0 {
  execsql [string map {/D/ {DEFERRABLE INITIALLY DEFERRED}} $FkeySimpleSchema]
} {}
foreach {tn zSql res} $FkeySimpleTests {
  do_test fkey2-1.2.$tn { catchsql $zSql } $res
}
drop_all_tables

do_test fkey2-1.3.0 {
  execsql [string map {/D/ {}} $FkeySimpleSchema]
  execsql { PRAGMA count_changes = 1 }
} {}
foreach {tn zSql res} $FkeySimpleTests {
  if {$res == "0 {}"} { set res {0 1} }
  do_test fkey2-1.3.$tn { catchsql $zSql } $res
}
execsql { PRAGMA count_changes = 0 }
drop_all_tables

do_test fkey2-1.4.0 {
  execsql [string map {/D/ {}} $FkeySimpleSchema]
  execsql { PRAGMA count_changes = 1 }
} {}
foreach {tn zSql res} $FkeySimpleTests {
  if {$res == "0 {}"} { set res {0 1} }
  execsql BEGIN
  do_test fkey2-1.4.$tn { catchsql $zSql } $res
  execsql COMMIT
}
execsql { PRAGMA count_changes = 0 }
drop_all_tables

# Special test: When the parent key is an IPK, make sure the affinity of
# the IPK is not applied to the child key value before it is inserted
# into the child table.
do_test fkey2-1.5.1 {
  execsql {
    CREATE TABLE i(i INTEGER PRIMARY KEY);
    CREATE TABLE j(j REFERENCES i);
    INSERT INTO i VALUES(35);
    INSERT INTO j VALUES('35.0');
    SELECT j, typeof(j) FROM j;
  }
} {35.0 text}
do_test fkey2-1.5.2 {
  catchsql { DELETE FROM i }
} {1 {foreign key constraint failed}}

# Same test using a regular primary key with integer affinity.
drop_all_tables
do_test fkey2-1.6.1 {
  execsql {
    CREATE TABLE i(i INT UNIQUE);
    CREATE TABLE j(j REFERENCES i(i));
    INSERT INTO i VALUES('35.0');
    INSERT INTO j VALUES('35.0');
    SELECT j, typeof(j) FROM j;
    SELECT i, typeof(i) FROM i;
  }
} {35.0 text 35 integer}
do_test fkey2-1.6.2 {
  catchsql { DELETE FROM i }
} {1 {foreign key constraint failed}}

# Use a collation sequence on the parent key.
drop_all_tables
do_test fkey2-1.7.1 {
  execsql {
    CREATE TABLE i(i TEXT COLLATE nocase PRIMARY KEY);
    CREATE TABLE j(j TEXT COLLATE binary REFERENCES i(i));
    INSERT INTO i VALUES('SQLite');
    INSERT INTO j VALUES('sqlite');
  }
  catchsql { DELETE FROM i }
} {1 {foreign key constraint failed}}

# Use the parent key collation even if it is default and the child key
# has an explicit value.
drop_all_tables
do_test fkey2-1.7.2 {
  execsql {
    CREATE TABLE i(i TEXT PRIMARY KEY);        -- Colseq is "BINARY"
    CREATE TABLE j(j TEXT COLLATE nocase REFERENCES i(i));
    INSERT INTO i VALUES('SQLite');
  }
  catchsql { INSERT INTO j VALUES('sqlite') }
} {1 {foreign key constraint failed}}
do_test fkey2-1.7.3 {
  execsql {
    INSERT INTO i VALUES('sqlite');
    INSERT INTO j VALUES('sqlite');
    DELETE FROM i WHERE i = 'SQLite';
  }
  catchsql { DELETE FROM i WHERE i = 'sqlite' }
} {1 {foreign key constraint failed}}

#-------------------------------------------------------------------------
# This section (test cases fkey2-2.*) contains tests to check that the
# deferred foreign key constraint logic works.
#
proc fkey2-2-test {tn nocommit sql {res {}}} {
  if {$res eq "FKV"} {
    set expected {1 {foreign key constraint failed}}
  } else {
    set expected [list 0 $res]
  }
  do_test fkey2-2.$tn [list catchsql $sql] $expected
  if {$nocommit} {
    do_test fkey2-2.${tn}c {
      catchsql COMMIT
    } {1 {foreign key constraint failed}}
  }
}

fkey2-2-test 1 0 {
  CREATE TABLE node(
    nodeid PRIMARY KEY,
    parent REFERENCES node DEFERRABLE INITIALLY DEFERRED
  );
  CREATE TABLE leaf(
    cellid PRIMARY KEY,
    parent REFERENCES node DEFERRABLE INITIALLY DEFERRED
  );
}

fkey2-2-test 1  0 "INSERT INTO node VALUES(1, 0)"       FKV
fkey2-2-test 2  0 "BEGIN"
fkey2-2-test 3  1   "INSERT INTO node VALUES(1, 0)"
fkey2-2-test 4  0   "UPDATE node SET parent = NULL"
fkey2-2-test 5  0 "COMMIT"
fkey2-2-test 6  0 "SELECT * FROM node" {1 {}}

fkey2-2-test 7  0 "BEGIN"
fkey2-2-test 8  1   "INSERT INTO leaf VALUES('a', 2)"
fkey2-2-test 9  1   "INSERT INTO node VALUES(2, 0)"
fkey2-2-test 10 0   "UPDATE node SET parent = 1 WHERE nodeid = 2"
fkey2-2-test 11 0 "COMMIT"
fkey2-2-test 12 0 "SELECT * FROM node" {1 {} 2 1}
fkey2-2-test 13 0 "SELECT * FROM leaf" {a 2}

fkey2-2-test 14 0 "BEGIN"
fkey2-2-test 15 1   "DELETE FROM node WHERE nodeid = 2"
fkey2-2-test 16 0   "INSERT INTO node VALUES(2, NULL)"
fkey2-2-test 17 0 "COMMIT"
fkey2-2-test 18 0 "SELECT * FROM node" {1 {} 2 {}}
fkey2-2-test 19 0 "SELECT * FROM leaf" {a 2}

fkey2-2-test 20 0 "BEGIN"
fkey2-2-test 21 0   "INSERT INTO leaf VALUES('b', 1)"
fkey2-2-test 22 0   "SAVEPOINT save"
fkey2-2-test 23 0     "DELETE FROM node WHERE nodeid = 1"
fkey2-2-test 24 0   "ROLLBACK TO save"
fkey2-2-test 25 0 "COMMIT"
fkey2-2-test 26 0 "SELECT * FROM node" {1 {} 2 {}}
fkey2-2-test 27 0 "SELECT * FROM leaf" {a 2 b 1}

fkey2-2-test 28 0 "BEGIN"
fkey2-2-test 29 0   "INSERT INTO leaf VALUES('c', 1)"
fkey2-2-test 30 0   "SAVEPOINT save"
fkey2-2-test 31 0     "DELETE FROM node WHERE nodeid = 1"
fkey2-2-test 32 1   "RELEASE save"
fkey2-2-test 33 1   "DELETE FROM leaf WHERE cellid = 'b'"
fkey2-2-test 34 0   "DELETE FROM leaf WHERE cellid = 'c'"
fkey2-2-test 35 0 "COMMIT"
fkey2-2-test 36 0 "SELECT * FROM node" {2 {}} 
fkey2-2-test 37 0 "SELECT * FROM leaf" {a 2}

fkey2-2-test 38 0 "SAVEPOINT outer"
fkey2-2-test 39 1   "INSERT INTO leaf VALUES('d', 3)"
fkey2-2-test 40 1 "RELEASE outer"    FKV
fkey2-2-test 41 1   "INSERT INTO leaf VALUES('e', 3)"
fkey2-2-test 42 0   "INSERT INTO node VALUES(3, 2)"
fkey2-2-test 43 0 "RELEASE outer"

fkey2-2-test 44 0 "SAVEPOINT outer"
fkey2-2-test 45 1   "DELETE FROM node WHERE nodeid=3"
fkey2-2-test 47 0   "INSERT INTO node VALUES(3, 2)"
fkey2-2-test 48 0 "ROLLBACK TO outer"
fkey2-2-test 49 0 "RELEASE outer"

fkey2-2-test 50 0 "SAVEPOINT outer"
fkey2-2-test 51 1   "INSERT INTO leaf VALUES('f', 4)"
fkey2-2-test 52 1   "SAVEPOINT inner"
fkey2-2-test 53 1     "INSERT INTO leaf VALUES('g', 4)"
fkey2-2-test 54 1  "RELEASE outer"   FKV
fkey2-2-test 55 1   "ROLLBACK TO inner"
fkey2-2-test 56 0  "COMMIT"          FKV
fkey2-2-test 57 0   "INSERT INTO node VALUES(4, NULL)"
fkey2-2-test 58 0 "RELEASE outer"
fkey2-2-test 59 0 "SELECT * FROM node" {2 {} 3 2 4 {}}
fkey2-2-test 60 0 "SELECT * FROM leaf" {a 2 d 3 e 3 f 4}

# The following set of tests check that if a statement that affects 
# multiple rows violates some foreign key constraints, then strikes a 
# constraint that causes the statement-transaction to be rolled back, 
# the deferred constraint counter is correctly reset to the value it 
# had before the statement-transaction was opened.
#
fkey2-2-test 61 0 "BEGIN"
fkey2-2-test 62 0   "DELETE FROM leaf"
fkey2-2-test 63 0   "DELETE FROM node"
fkey2-2-test 64 1   "INSERT INTO leaf VALUES('a', 1)"
fkey2-2-test 65 1   "INSERT INTO leaf VALUES('b', 2)"
fkey2-2-test 66 1   "INSERT INTO leaf VALUES('c', 1)"
do_test fkey2-2-test-67 {
  catchsql          "INSERT INTO node SELECT parent, 3 FROM leaf"
} {1 {column nodeid is not unique}}
fkey2-2-test 68 0 "COMMIT"           FKV
fkey2-2-test 69 1   "INSERT INTO node VALUES(1, NULL)"
fkey2-2-test 70 0   "INSERT INTO node VALUES(2, NULL)"
fkey2-2-test 71 0 "COMMIT"

fkey2-2-test 72 0 "BEGIN"
fkey2-2-test 73 1   "DELETE FROM node"
fkey2-2-test 74 0   "INSERT INTO node(nodeid) SELECT DISTINCT parent FROM leaf"
fkey2-2-test 75 0 "COMMIT"

#-------------------------------------------------------------------------
# Test cases fkey2-3.* test that a program that executes foreign key
# actions (CASCADE, SET DEFAULT, SET NULL etc.) or tests FK constraints
# opens a statement transaction if required.
#
# fkey2-3.1.*: Test UPDATE statements.
# fkey2-3.2.*: Test DELETE statements.
#
drop_all_tables
do_test fkey2-3.1.1 {
  execsql {
    CREATE TABLE ab(a PRIMARY KEY, b);
    CREATE TABLE cd(
      c PRIMARY KEY REFERENCES ab ON UPDATE CASCADE ON DELETE CASCADE, 
      d
    );
    CREATE TABLE ef(
      e REFERENCES cd ON UPDATE CASCADE, 
      f, CHECK (e!=5)
    );
  }
} {}
do_test fkey2-3.1.2 {
  execsql {
    INSERT INTO ab VALUES(1, 'b');
    INSERT INTO cd VALUES(1, 'd');
    INSERT INTO ef VALUES(1, 'e');
  }
} {}
do_test fkey2-3.1.3 {
  catchsql { UPDATE ab SET a = 5 }
} {1 {constraint failed}}
do_test fkey2-3.1.4 {
  execsql { SELECT * FROM ab }
} {1 b}
do_test fkey2-3.1.4 {
  execsql BEGIN;
  catchsql { UPDATE ab SET a = 5 }
} {1 {constraint failed}}
do_test fkey2-3.1.5 {
  execsql COMMIT;
  execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef }
} {1 b 1 d 1 e}

do_test fkey2-3.2.1 {
  execsql BEGIN;
  catchsql { DELETE FROM ab }
} {1 {foreign key constraint failed}}
do_test fkey2-3.2.2 {
  execsql COMMIT
  execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef }
} {1 b 1 d 1 e}

#-------------------------------------------------------------------------
# Test cases fkey2-4.* test that recursive foreign key actions 
# (i.e. CASCADE) are allowed even if recursive triggers are disabled.
#
drop_all_tables
do_test fkey2-4.1 {
  execsql {
    CREATE TABLE t1(
      node PRIMARY KEY, 
      parent REFERENCES t1 ON DELETE CASCADE
    );
    CREATE TABLE t2(node PRIMARY KEY, parent);
    CREATE TRIGGER t2t AFTER DELETE ON t2 BEGIN
      DELETE FROM t2 WHERE parent = old.node;
    END;
    INSERT INTO t1 VALUES(1, NULL);
    INSERT INTO t1 VALUES(2, 1);
    INSERT INTO t1 VALUES(3, 1);
    INSERT INTO t1 VALUES(4, 2);
    INSERT INTO t1 VALUES(5, 2);
    INSERT INTO t1 VALUES(6, 3);
    INSERT INTO t1 VALUES(7, 3);
    INSERT INTO t2 SELECT * FROM t1;
  }
} {}
do_test fkey2-4.2 {
  execsql { PRAGMA recursive_triggers = off }
  execsql { 
    BEGIN;
      DELETE FROM t1 WHERE node = 1;
      SELECT node FROM t1;
  }
} {}
do_test fkey2-4.3 {
  execsql { 
      DELETE FROM t2 WHERE node = 1;
      SELECT node FROM t2;
    ROLLBACK;
  }
} {4 5 6 7}
do_test fkey2-4.4 {
  execsql { PRAGMA recursive_triggers = on }
  execsql { 
    BEGIN;
      DELETE FROM t1 WHERE node = 1;
      SELECT node FROM t1;
  }
} {}
do_test fkey2-4.3 {
  execsql { 
      DELETE FROM t2 WHERE node = 1;
      SELECT node FROM t2;
    ROLLBACK;
  }
} {}

#-------------------------------------------------------------------------
# Test cases fkey2-5.* verify that the incremental blob API may not
# write to a foreign key column while foreign-keys are enabled.
#
drop_all_tables
ifcapable incrblob {
  do_test fkey2-5.1 {
    execsql {
      CREATE TABLE t1(a PRIMARY KEY, b);
      CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1(a));
      INSERT INTO t1 VALUES('hello', 'world');
      INSERT INTO t2 VALUES('key', 'hello');
    }
  } {}
  do_test fkey2-5.2 {
    set rc [catch { set fd [db incrblob t2 b 1] } msg]
    list $rc $msg
  } {1 {cannot open foreign key column for writing}}
  do_test fkey2-5.3 {
    set rc [catch { set fd [db incrblob -readonly t2 b 1] } msg]
    close $fd
    set rc
  } {0}
  do_test fkey2-5.4 {
    execsql { PRAGMA foreign_keys = off }
    set rc [catch { set fd [db incrblob t2 b 1] } msg]
    close $fd
    set rc
  } {0}
  do_test fkey2-5.5 {
    execsql { PRAGMA foreign_keys = on }
  } {}
}

drop_all_tables
ifcapable vacuum {
  do_test fkey2-6.1 {
    execsql {
      CREATE TABLE t1(a REFERENCES t2(c), b);
      CREATE TABLE t2(c UNIQUE, b);
      INSERT INTO t2 VALUES(1, 2);
      INSERT INTO t1 VALUES(1, 2);
      VACUUM;
    }
  } {}
}

#-------------------------------------------------------------------------
# Test that it is possible to use an INTEGER PRIMARY KEY as the child key
# of a foreign constraint.
# 
drop_all_tables
do_test fkey2-7.1 {
  execsql {
    CREATE TABLE t1(a PRIMARY KEY, b);
    CREATE TABLE t2(c INTEGER PRIMARY KEY REFERENCES t1, b);
  }
} {}
do_test fkey2-7.2 {
  catchsql { INSERT INTO t2 VALUES(1, 'A'); }
} {1 {foreign key constraint failed}}
do_test fkey2-7.3 {
  execsql { 
    INSERT INTO t1 VALUES(1, 2);
    INSERT INTO t1 VALUES(2, 3);
    INSERT INTO t2 VALUES(1, 'A');
  }
} {}
do_test fkey2-7.4 {
  execsql { UPDATE t2 SET c = 2 }
} {}
do_test fkey2-7.5 {
  catchsql { UPDATE t2 SET c = 3 }
} {1 {foreign key constraint failed}}
do_test fkey2-7.6 {
  catchsql { DELETE FROM t1 WHERE a = 2 }
} {1 {foreign key constraint failed}}
do_test fkey2-7.7 {
  execsql { DELETE FROM t1 WHERE a = 1 }
} {}
do_test fkey2-7.8 {
  catchsql { UPDATE t1 SET a = 3 }
} {1 {foreign key constraint failed}}
do_test fkey2-7.9 {
  catchsql { UPDATE t2 SET rowid = 3 }
} {1 {foreign key constraint failed}}

#-------------------------------------------------------------------------
# Test that it is not possible to enable/disable FK support while a
# transaction is open.
# 
drop_all_tables
proc fkey2-8-test {tn zSql value} {
  do_test fkey-2.8.$tn.1 [list execsql $zSql] {}
  do_test fkey-2.8.$tn.2 { execsql "PRAGMA foreign_keys" } $value
}
fkey2-8-test  1 { PRAGMA foreign_keys = 0     } 0
fkey2-8-test  2 { PRAGMA foreign_keys = 1     } 1
fkey2-8-test  3 { BEGIN                       } 1
fkey2-8-test  4 { PRAGMA foreign_keys = 0     } 1
fkey2-8-test  5 { COMMIT                      } 1
fkey2-8-test  6 { PRAGMA foreign_keys = 0     } 0
fkey2-8-test  7 { BEGIN                       } 0
fkey2-8-test  8 { PRAGMA foreign_keys = 1     } 0
fkey2-8-test  9 { COMMIT                      } 0
fkey2-8-test 10 { PRAGMA foreign_keys = 1     } 1
fkey2-8-test 11 { PRAGMA foreign_keys = off   } 0
fkey2-8-test 12 { PRAGMA foreign_keys = on    } 1
fkey2-8-test 13 { PRAGMA foreign_keys = no    } 0
fkey2-8-test 14 { PRAGMA foreign_keys = yes   } 1
fkey2-8-test 15 { PRAGMA foreign_keys = false } 0
fkey2-8-test 16 { PRAGMA foreign_keys = true  } 1

#-------------------------------------------------------------------------
# The following tests, fkey2-9.*, test SET DEFAULT actions.
#
drop_all_tables
do_test fkey2-9.1.1 {
  execsql {
    CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
    CREATE TABLE t2(
      c INTEGER PRIMARY KEY,
      d INTEGER DEFAULT 1 REFERENCES t1 ON DELETE SET DEFAULT
    );
    DELETE FROM t1;
  }
} {}
do_test fkey2-9.1.2 {
  execsql {
    INSERT INTO t1 VALUES(1, 'one');
    INSERT INTO t1 VALUES(2, 'two');
    INSERT INTO t2 VALUES(1, 2);
    SELECT * FROM t2;
    DELETE FROM t1 WHERE a = 2;
    SELECT * FROM t2;
  }
} {1 2 1 1}
do_test fkey2-9.1.3 {
  execsql {
    INSERT INTO t1 VALUES(2, 'two');
    UPDATE t2 SET d = 2;
    DELETE FROM t1 WHERE a = 1;
    SELECT * FROM t2;
  }
} {1 2}
do_test fkey2-9.1.4 {
  execsql { SELECT * FROM t1 }
} {2 two}
do_test fkey2-9.1.5 {
  catchsql { DELETE FROM t1 }
} {1 {foreign key constraint failed}}

do_test fkey2-9.2.1 {
  execsql {
    CREATE TABLE pp(a, b, c, PRIMARY KEY(b, c));
    CREATE TABLE cc(d DEFAULT 3, e DEFAULT 1, f DEFAULT 2,
        FOREIGN KEY(f, d) REFERENCES pp 
        ON UPDATE SET DEFAULT 
        ON DELETE SET NULL
    );
    INSERT INTO pp VALUES(1, 2, 3);
    INSERT INTO pp VALUES(4, 5, 6);
    INSERT INTO pp VALUES(7, 8, 9);
  }
} {}
do_test fkey2-9.2.2 {
  execsql {
    INSERT INTO cc VALUES(6, 'A', 5);
    INSERT INTO cc VALUES(6, 'B', 5);
    INSERT INTO cc VALUES(9, 'A', 8);
    INSERT INTO cc VALUES(9, 'B', 8);
    UPDATE pp SET b = 1 WHERE a = 7;
    SELECT * FROM cc;
  }
} {6 A 5 6 B 5 3 A 2 3 B 2}
do_test fkey2-9.2.3 {
  execsql {
    DELETE FROM pp WHERE a = 4;
    SELECT * FROM cc;
  }
} {{} A {} {} B {} 3 A 2 3 B 2}

#-------------------------------------------------------------------------
# The following tests, fkey2-10.*, test "foreign key mismatch" and 
# other errors.
#
set tn 0
foreach zSql [list {
  CREATE TABLE p(a PRIMARY KEY, b);
  CREATE TABLE c(x REFERENCES p(c));
} {
  CREATE TABLE c(x REFERENCES v(y));
  CREATE VIEW v AS SELECT x AS y FROM c;
} {
  CREATE TABLE p(a, b, PRIMARY KEY(a, b));
  CREATE TABLE c(x REFERENCES p);
} {
  CREATE TABLE p(a COLLATE binary, b);
  CREATE UNIQUE INDEX i ON p(a COLLATE nocase);
  CREATE TABLE c(x REFERENCES p(a));
}] {
  drop_all_tables
  do_test fkey2-10.1.[incr tn] {
    execsql $zSql
    catchsql { INSERT INTO c DEFAULT VALUES }
  } {1 {foreign key mismatch}}
}

# "rowid" cannot be used as part of a child or parent key definition 
# unless it happens to be the name of an explicitly declared column.
#
do_test fkey2-10.2.1 {
  drop_all_tables
  catchsql {
    CREATE TABLE t1(a PRIMARY KEY, b);
    CREATE TABLE t2(c, d, FOREIGN KEY(rowid) REFERENCES t1(a));
  }
} {1 {unknown column "rowid" in foreign key definition}}
do_test fkey2-10.2.2 {
  drop_all_tables
  catchsql {
    CREATE TABLE t1(a PRIMARY KEY, b);
    CREATE TABLE t2(rowid, d, FOREIGN KEY(rowid) REFERENCES t1(a));
  }
} {0 {}}
do_test fkey2-10.2.1 {
  drop_all_tables
  catchsql {
    CREATE TABLE t1(a, b);
    CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(rowid));
    INSERT INTO t1(rowid, a, b) VALUES(1, 1, 1);
    INSERT INTO t2 VALUES(1, 1);
  }
} {1 {foreign key mismatch}}
do_test fkey2-10.2.2 {
  drop_all_tables
  catchsql {
    CREATE TABLE t1(rowid PRIMARY KEY, b);
    CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(rowid));
    INSERT INTO t1(rowid, b) VALUES(1, 1);
    INSERT INTO t2 VALUES(1, 1);
  }
} {0 {}}


#-------------------------------------------------------------------------
# The following tests, fkey2-11.*, test CASCADE actions.
#
drop_all_tables
do_test fkey2-11.1.1 {
  execsql {
    CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
    CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(a) ON UPDATE CASCADE);

    INSERT INTO t1 VALUES(10, 100);
    INSERT INTO t2 VALUES(10, 100);
    UPDATE t1 SET a = 15;
    SELECT * FROM t2;
  }
} {15 100}

#-------------------------------------------------------------------------
# The following tests, fkey2-12.*, test RESTRICT actions.
#
drop_all_tables
do_test fkey2-12.1.1 {
  execsql {
    CREATE TABLE t1(a, b PRIMARY KEY);
    CREATE TABLE t2(
      x REFERENCES t1 ON UPDATE RESTRICT DEFERRABLE INITIALLY DEFERRED 
    );
    INSERT INTO t1 VALUES(1, 'one');
    INSERT INTO t1 VALUES(2, 'two');
    INSERT INTO t1 VALUES(3, 'three');
  }
} {}
do_test fkey2-12.1.2 { 
  execsql "BEGIN"
  execsql "INSERT INTO t2 VALUES('two')"
} {}
do_test fkey2-12.1.3 { 
  execsql "UPDATE t1 SET b = 'four' WHERE b = 'one'"
} {}
do_test fkey2-12.1.4 { 
  catchsql "UPDATE t1 SET b = 'five' WHERE b = 'two'"
} {1 {foreign key constraint failed}}
do_test fkey2-12.1.5 { 
  execsql "DELETE FROM t1 WHERE b = 'two'"
} {}
do_test fkey2-12.1.6 { 
  catchsql "COMMIT"
} {1 {foreign key constraint failed}}
do_test fkey2-12.1.7 { 
  execsql {
    INSERT INTO t1 VALUES(2, 'two');
    COMMIT;
  }
} {}

drop_all_tables
do_test fkey2-12.2.1 {
  execsql {
    CREATE TABLE t1(x COLLATE NOCASE PRIMARY KEY);
    CREATE TRIGGER tt1 AFTER DELETE ON t1 
      WHEN EXISTS ( SELECT 1 FROM t2 WHERE old.x = y )
    BEGIN
      INSERT INTO t1 VALUES(old.x);
    END;
    CREATE TABLE t2(y REFERENCES t1);
    INSERT INTO t1 VALUES('A');
    INSERT INTO t1 VALUES('B');
    INSERT INTO t2 VALUES('a');
    INSERT INTO t2 VALUES('b');

    SELECT * FROM t1;
    SELECT * FROM t2;
  }
} {A B a b}
do_test fkey2-12.2.2 {
  execsql { DELETE FROM t1 }
  execsql {
    SELECT * FROM t1;
    SELECT * FROM t2;
  }
} {A B a b}
do_test fkey2-12.2.3 {
  execsql {
    DROP TABLE t2;
    CREATE TABLE t2(y REFERENCES t1 ON DELETE RESTRICT);
    INSERT INTO t2 VALUES('a');
    INSERT INTO t2 VALUES('b');
  }
  catchsql { DELETE FROM t1 }
} {1 {foreign key constraint failed}}
do_test fkey2-12.2.4 {
  execsql {
    SELECT * FROM t1;
    SELECT * FROM t2;
  }
} {A B a b}

drop_all_tables
do_test fkey2-12.3.1 {
  execsql {
    CREATE TABLE up(
      c00, c01, c02, c03, c04, c05, c06, c07, c08, c09,
      c10, c11, c12, c13, c14, c15, c16, c17, c18, c19,
      c20, c21, c22, c23, c24, c25, c26, c27, c28, c29,
      c30, c31, c32, c33, c34, c35, c36, c37, c38, c39,
      PRIMARY KEY(c34, c35)
    );
    CREATE TABLE down(
      c00, c01, c02, c03, c04, c05, c06, c07, c08, c09,
      c10, c11, c12, c13, c14, c15, c16, c17, c18, c19,
      c20, c21, c22, c23, c24, c25, c26, c27, c28, c29,
      c30, c31, c32, c33, c34, c35, c36, c37, c38, c39,
      FOREIGN KEY(c39, c38) REFERENCES up ON UPDATE CASCADE
    );
  }
} {}
do_test fkey2-12.3.2 {
  execsql {
    INSERT INTO up(c34, c35) VALUES('yes', 'no');
    INSERT INTO down(c39, c38) VALUES('yes', 'no');
    UPDATE up SET c34 = 'possibly';
    SELECT c38, c39 FROM down;
    DELETE FROM down;
  }
} {no possibly}
do_test fkey2-12.3.3 {
  catchsql { INSERT INTO down(c39, c38) VALUES('yes', 'no') }
} {1 {foreign key constraint failed}}
do_test fkey2-12.3.4 {
  execsql { 
    INSERT INTO up(c34, c35) VALUES('yes', 'no');
    INSERT INTO down(c39, c38) VALUES('yes', 'no');
  }
  catchsql { DELETE FROM up WHERE c34 = 'yes' }
} {1 {foreign key constraint failed}}
do_test fkey2-12.3.5 {
  execsql { 
    DELETE FROM up WHERE c34 = 'possibly';
    SELECT c34, c35 FROM up;
    SELECT c39, c38 FROM down;
  }
} {yes no yes no}

#-------------------------------------------------------------------------
# The following tests, fkey2-13.*, test that FK processing is performed
# when rows are REPLACEd.
#
drop_all_tables
do_test fkey2-13.1.1 {
  execsql {
    CREATE TABLE pp(a UNIQUE, b, c, PRIMARY KEY(b, c));
    CREATE TABLE cc(d, e, f UNIQUE, FOREIGN KEY(d, e) REFERENCES pp);
    INSERT INTO pp VALUES(1, 2, 3);
    INSERT INTO cc VALUES(2, 3, 1);
  }
} {}
foreach {tn stmt} {
  1   "REPLACE INTO pp VALUES(1, 4, 5)"
  2   "REPLACE INTO pp(rowid, a, b, c) VALUES(1, 2, 3, 4)"
} {
  do_test fkey2-13.1.$tn.1 {
    catchsql $stmt
  } {1 {foreign key constraint failed}}
  do_test fkey2-13.1.$tn.2 {
    execsql {
      SELECT * FROM pp;
      SELECT * FROM cc;
    }
  } {1 2 3 2 3 1}
  do_test fkey2-13.1.$tn.3 {
    execsql BEGIN;
    catchsql $stmt
  } {1 {foreign key constraint failed}}
  do_test fkey2-13.1.$tn.4 {
    execsql {
      COMMIT;
      SELECT * FROM pp;
      SELECT * FROM cc;
    }
  } {1 2 3 2 3 1}
}
do_test fkey2-13.1.3 {
  execsql { 
    REPLACE INTO pp(rowid, a, b, c) VALUES(1, 2, 2, 3);
    SELECT rowid, * FROM pp;
    SELECT * FROM cc;
  }
} {1 2 2 3 2 3 1}
do_test fkey2-13.1.4 {
  execsql { 
    REPLACE INTO pp(rowid, a, b, c) VALUES(2, 2, 2, 3);
    SELECT rowid, * FROM pp;
    SELECT * FROM cc;
  }
} {2 2 2 3 2 3 1}

#-------------------------------------------------------------------------
# The following tests, fkey2-14.*, test that the "DROP TABLE" and "ALTER
# TABLE" commands work as expected wrt foreign key constraints.
#
# fkey2-14.1*: ALTER TABLE ADD COLUMN
# fkey2-14.2*: ALTER TABLE RENAME TABLE
# fkey2-14.3*: DROP TABLE
#
drop_all_tables
ifcapable altertable {
  do_test fkey2-14.1.1 {
    # Adding a column with a REFERENCES clause is not supported.
    execsql { 
      CREATE TABLE t1(a PRIMARY KEY);
      CREATE TABLE t2(a, b);
    }
    catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
  } {0 {}}
  do_test fkey2-14.1.2 {
    catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
  } {0 {}}
  do_test fkey2-14.1.3 {
    catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
  } {0 {}}
  do_test fkey2-14.1.4 {
    catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}
  } {1 {Cannot add a REFERENCES column with non-NULL default value}}
  do_test fkey2-14.1.5 {
    catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }
  } {1 {Cannot add a REFERENCES column with non-NULL default value}}
  do_test fkey2-14.1.6 {
    execsql { 
      PRAGMA foreign_keys = off;
      ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
      PRAGMA foreign_keys = on;
      SELECT sql FROM sqlite_master WHERE name='t2';
    }
  } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
  
  
  # Test the sqlite_rename_parent() function directly.
  #
  proc test_rename_parent {zCreate zOld zNew} {
    db eval {SELECT sqlite_rename_parent($zCreate, $zOld, $zNew)}
  }
  do_test fkey2-14.2.1.1 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
  } {{CREATE TABLE t1(a REFERENCES "t3")}}
  do_test fkey2-14.2.1.2 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
  } {{CREATE TABLE t1(a REFERENCES t2)}}
  do_test fkey2-14.2.1.3 {
    test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
  } {{CREATE TABLE t1(a REFERENCES "t3")}}
  
  # Test ALTER TABLE RENAME TABLE a bit.
  #
  do_test fkey2-14.2.2.1 {
    drop_all_tables
    execsql {
      CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1);
      CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2);
      CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
    }
    execsql { SELECT sql FROM sqlite_master WHERE type = 'table'}
  } [list \
    {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1)}                     \
    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)}    \
    {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)}  \
  ]
  do_test fkey2-14.2.2.2 {
    execsql { ALTER TABLE t1 RENAME TO t4 }
    execsql { SELECT sql FROM sqlite_master WHERE type = 'table'}
  } [list \
    {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4")}                    \
    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)}     \
    {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
  ]
  do_test fkey2-14.2.2.3 {
    catchsql { INSERT INTO t3 VALUES(1, 2, 3) }
  } {1 {foreign key constraint failed}}
  do_test fkey2-14.2.2.4 {
    execsql { INSERT INTO t4 VALUES(1, NULL) }
  } {}
  do_test fkey2-14.2.2.5 {
    catchsql { UPDATE t4 SET b = 5 }
  } {1 {foreign key constraint failed}}
  do_test fkey2-14.2.2.6 {
    catchsql { UPDATE t4 SET b = 1 }
  } {0 {}}
  do_test fkey2-14.2.2.7 {
    execsql { INSERT INTO t3 VALUES(1, NULL, 1) }
  } {}
}

do_test fkey-2.14.3.1 {
  drop_all_tables
  execsql {
    CREATE TABLE t1(a, b REFERENCES nosuchtable);
    DROP TABLE t1;
  }
} {}
do_test fkey-2.14.3.2 {
  execsql {
    CREATE TABLE t1(a PRIMARY KEY, b);
    INSERT INTO t1 VALUES('a', 1);
    CREATE TABLE t2(x REFERENCES t1);
    INSERT INTO t2 VALUES('a');
  }
} {}
do_test fkey-2.14.3.3 {
  catchsql { DROP TABLE t1 }
} {1 {foreign key constraint failed}}
do_test fkey-2.14.3.4 {
  execsql {
    DELETE FROM t2;
    DROP TABLE t1;
  }
} {}
do_test fkey-2.14.3.4 {
  catchsql { INSERT INTO t2 VALUES('x') }
} {1 {no such table: main.t1}}
do_test fkey-2.14.3.5 {
  execsql {
    CREATE TABLE t1(x PRIMARY KEY);
    INSERT INTO t1 VALUES('x');
  }
  execsql { INSERT INTO t2 VALUES('x') }
} {}
do_test fkey-2.14.3.6 {
  catchsql { DROP TABLE t1 }
} {1 {foreign key constraint failed}}
do_test fkey-2.14.3.7 {
  execsql {
    DROP TABLE t2;
    DROP TABLE t1;
  }
} {}
do_test fkey-2.14.3.8 {
  execsql {
    CREATE TABLE pp(x, y, PRIMARY KEY(x, y));
    CREATE TABLE cc(a, b, FOREIGN KEY(a, b) REFERENCES pp(x, z));
  }
  catchsql { INSERT INTO cc VALUES(1, 2) }
} {1 {foreign key mismatch}}
do_test fkey-2.14.3.9 {
  execsql { DROP TABLE cc }
} {}
do_test fkey-2.14.3.10 {
  execsql {
    CREATE TABLE cc(a, b, 
      FOREIGN KEY(a, b) REFERENCES pp DEFERRABLE INITIALLY DEFERRED
    );
  }
  execsql {
    INSERT INTO pp VALUES('a', 'b');
    INSERT INTO cc VALUES('a', 'b');
    BEGIN;
      DROP TABLE pp;
      CREATE TABLE pp(a, b, c, PRIMARY KEY(b, c));
      INSERT INTO pp VALUES(1, 'a', 'b');
    COMMIT;
  }
} {}
do_test fkey-2.14.3.11 {
  execsql { 
    BEGIN;
      DROP TABLE cc;
      DROP TABLE pp;
    COMMIT;
  }
} {}
do_test fkey-2.14.3.12 {
  execsql {
    CREATE TABLE b1(a, b);
    CREATE TABLE b2(a, b REFERENCES b1);
    DROP TABLE b1;
  }
} {}
do_test fkey-2.14.3.13 {
  execsql {
    CREATE TABLE b3(a, b REFERENCES b2 DEFERRABLE INITIALLY DEFERRED);
    DROP TABLE b2;
  }
} {}

# Test that nothing goes wrong when dropping a table that refers to a view.
# Or dropping a view that an existing FK (incorrectly) refers to. Or either
# of the above scenarios with a virtual table.
drop_all_tables
do_test fkey-2.14.4.1 {
  execsql {
    CREATE TABLE t1(x REFERENCES v); 
    CREATE VIEW v AS SELECT * FROM t1;
  }
} {}
do_test fkey-2.14.4.2 {
  execsql {
    DROP VIEW v;
  }
} {}
ifcapable vtab {
  register_echo_module db
  do_test fkey-2.14.4.3 {
    execsql { CREATE VIRTUAL TABLE v USING echo(t1) }
  } {}
  do_test fkey-2.14.4.2 {
    execsql {
      DROP TABLE v;
    }
  } {}
}

#-------------------------------------------------------------------------
# The following tests, fkey2-15.*, test that unnecessary FK related scans 
# and lookups are avoided when the constraint counters are zero.
#
drop_all_tables
proc execsqlS {zSql} {
  set ::sqlite_search_count 0
  set ::sqlite_found_count 0
  set res [uplevel [list execsql $zSql]]
  concat [expr $::sqlite_found_count + $::sqlite_search_count] $res
}
do_test fkey2-15.1.1 {
  execsql {
    CREATE TABLE pp(a PRIMARY KEY, b);
    CREATE TABLE cc(x, y REFERENCES pp DEFERRABLE INITIALLY DEFERRED);
    INSERT INTO pp VALUES(1, 'one');
    INSERT INTO pp VALUES(2, 'two');
    INSERT INTO cc VALUES('neung', 1);
    INSERT INTO cc VALUES('song', 2);
  }
} {}
do_test fkey2-15.1.2 {
  execsqlS { INSERT INTO pp VALUES(3, 'three') }
} {0}
do_test fkey2-15.1.3 {
  execsql {
    BEGIN;
      INSERT INTO cc VALUES('see', 4);    -- Violates deferred constraint
  }
  execsqlS { INSERT INTO pp VALUES(5, 'five') }
} {2}
do_test fkey2-15.1.4 {
  execsql { DELETE FROM cc WHERE x = 'see' }
  execsqlS { INSERT INTO pp VALUES(6, 'six') }
} {0}
do_test fkey2-15.1.5 {
  execsql COMMIT
} {}
do_test fkey2-15.1.6 {
  execsql BEGIN
  execsqlS {
    DELETE FROM cc WHERE x = 'neung';
    ROLLBACK;
  }
} {1}
do_test fkey2-15.1.7 {
  execsql { 
    BEGIN;
    DELETE FROM pp WHERE a = 2;
  }
  execsqlS {
    DELETE FROM cc WHERE x = 'neung';
    ROLLBACK;
  }
} {2}

#-------------------------------------------------------------------------
# This next block of tests, fkey2-16.*, test that rows that refer to
# themselves may be inserted and deleted.
#
foreach {tn zSchema} {
  1 { CREATE TABLE self(a INTEGER PRIMARY KEY, b REFERENCES self(a)) }
  2 { CREATE TABLE self(a PRIMARY KEY, b REFERENCES self(a)) }
  3 { CREATE TABLE self(a UNIQUE, b INTEGER PRIMARY KEY REFERENCES self(a)) }
} {
  drop_all_tables
  do_test fkey2-16.1.$tn.1 {
    execsql $zSchema
    execsql { INSERT INTO self VALUES(13, 13) }
  } {}
  do_test fkey2-16.1.$tn.2 {
    execsql { UPDATE self SET a = 14, b = 14 }
  } {}

  do_test fkey2-16.1.$tn.3 {
    catchsql { UPDATE self SET b = 15 }
  } {1 {foreign key constraint failed}}

  do_test fkey2-16.1.$tn.4 {
    catchsql { UPDATE self SET a = 15 }
  } {1 {foreign key constraint failed}}

  do_test fkey2-16.1.$tn.5 {
    catchsql { UPDATE self SET a = 15, b = 16 }
  } {1 {foreign key constraint failed}}

  do_test fkey2-16.1.$tn.6 {
    catchsql { UPDATE self SET a = 17, b = 17 }
  } {0 {}}

  do_test fkey2-16.1.$tn.7 {
    execsql { DELETE FROM self }
  } {}
  do_test fkey2-16.1.$tn.8 {
    catchsql { INSERT INTO self VALUES(20, 21) }
  } {1 {foreign key constraint failed}}
}

#-------------------------------------------------------------------------
# This next block of tests, fkey2-17.*, tests that if "PRAGMA count_changes"
# is turned on statements that violate immediate FK constraints return
# SQLITE_CONSTRAINT immediately, not after returning a number of rows.
# Whereas statements that violate deferred FK constraints return the number
# of rows before failing.
#
# Also test that rows modified by FK actions are not counted in either the
# returned row count or the values returned by sqlite3_changes(). Like
# trigger related changes, they are included in sqlite3_total_changes() though.
#
drop_all_tables
do_test fkey2-17.1.1 {
  execsql { PRAGMA count_changes = 1 }
  execsql { 
    CREATE TABLE one(a, b, c, UNIQUE(b, c));
    CREATE TABLE two(d, e, f, FOREIGN KEY(e, f) REFERENCES one(b, c));
    INSERT INTO one VALUES(1, 2, 3);
  }
} {1}
do_test fkey2-17.1.2 {
  set STMT [sqlite3_prepare_v2 db "INSERT INTO two VALUES(4, 5, 6)" -1 dummy]
  sqlite3_step $STMT
} {SQLITE_CONSTRAINT}
do_test fkey2-17.1.3 {
  sqlite3_step $STMT
} {SQLITE_MISUSE}
do_test fkey2-17.1.4 {
  sqlite3_finalize $STMT
} {SQLITE_CONSTRAINT}
do_test fkey2-17.1.5 {
  execsql {
    INSERT INTO one VALUES(2, 3, 4);
    INSERT INTO one VALUES(3, 4, 5);
    INSERT INTO two VALUES(1, 2, 3);
    INSERT INTO two VALUES(2, 3, 4);
    INSERT INTO two VALUES(3, 4, 5);
  }
} {1 1 1 1 1}
do_test fkey2-17.1.6 {
  catchsql {
    BEGIN;
      INSERT INTO one VALUES(0, 0, 0);
      UPDATE two SET e=e+1, f=f+1;
  }
} {1 {foreign key constraint failed}}
do_test fkey2-17.1.7 {
  execsql { SELECT * FROM one }
} {1 2 3 2 3 4 3 4 5 0 0 0}
do_test fkey2-17.1.8 {
  execsql { SELECT * FROM two }
} {1 2 3 2 3 4 3 4 5}
do_test fkey2-17.1.9 {
  execsql COMMIT
} {}
do_test fkey2-17.1.10 {
  execsql {
    CREATE TABLE three(
      g, h, i, 
      FOREIGN KEY(h, i) REFERENCES one(b, c) DEFERRABLE INITIALLY DEFERRED
    );
  }
} {}
do_test fkey2-17.1.11 {
  set STMT [sqlite3_prepare_v2 db "INSERT INTO three VALUES(7, 8, 9)" -1 dummy]
  sqlite3_step $STMT
} {SQLITE_ROW}
do_test fkey2-17.1.12 {
  sqlite3_column_text $STMT 0
} {1}
do_test fkey2-17.1.13 {
  sqlite3_step $STMT
} {SQLITE_CONSTRAINT}
do_test fkey2-17.1.14 {
  sqlite3_finalize $STMT
} {SQLITE_CONSTRAINT}

drop_all_tables
do_test fkey2-17.2.1 {
  execsql {
    CREATE TABLE high("a'b!" PRIMARY KEY, b);
    CREATE TABLE low(
      c, 
      "d&6" REFERENCES high ON UPDATE CASCADE ON DELETE CASCADE
    );
  }
} {}
do_test fkey2-17.2.2 {
  execsql {
    INSERT INTO high VALUES('a', 'b');
    INSERT INTO low VALUES('b', 'a');
  }
  db changes
} {1}
set nTotal [db total_changes]
do_test fkey2-17.2.3 {
  execsql { UPDATE high SET "a'b!" = 'c' }
} {1}
do_test fkey2-17.2.4 {
  db changes
} {1}
do_test fkey2-17.2.5 {
  expr [db total_changes] - $nTotal
} {2}
do_test fkey2-17.2.6 {
  execsql { SELECT * FROM high ; SELECT * FROM low }
} {c b b c}
do_test fkey2-17.2.7 {
  execsql { DELETE FROM high }
} {1}
do_test fkey2-17.2.8 {
  db changes
} {1}
do_test fkey2-17.2.9 {
  expr [db total_changes] - $nTotal
} {4}
do_test fkey2-17.2.10 {
  execsql { SELECT * FROM high ; SELECT * FROM low }
} {}
execsql { PRAGMA count_changes = 0 }

#-------------------------------------------------------------------------
# Test that the authorization callback works.
#

ifcapable auth {
  do_test fkey2-18.1 {
    execsql {
      CREATE TABLE long(a, b PRIMARY KEY, c);
      CREATE TABLE short(d, e, f REFERENCES long);
      CREATE TABLE mid(g, h, i REFERENCES long DEFERRABLE INITIALLY DEFERRED);
    }
  } {}

  proc auth {args} {eval lappend ::authargs $args ; return SQLITE_OK}
  db auth auth

  # An insert on the parent table must read the child key of any deferred
  # foreign key constraints. But not the child key of immediate constraints.
  set authargs {}
  do_test fkey2-18.2 {
    execsql { INSERT INTO long VALUES(1, 2, 3) }
    set authargs
  } {SQLITE_INSERT long {} main {} SQLITE_READ mid i main {}}

  # An insert on the child table of an immediate constraint must read the
  # parent key columns (to see if it is a violation or not).
  set authargs {}
  do_test fkey2-18.3 {
    execsql { INSERT INTO short VALUES(1, 3, 2) }
    set authargs
  } {SQLITE_INSERT short {} main {} SQLITE_READ long b main {}}
  
  # As must an insert on the child table of a deferred constraint.
  set authargs {}
  do_test fkey2-18.4 {
    execsql { INSERT INTO mid VALUES(1, 3, 2) }
    set authargs
  } {SQLITE_INSERT mid {} main {} SQLITE_READ long b main {}}

  do_test fkey2-18.5 {
    execsql {
      CREATE TABLE nought(a, b PRIMARY KEY, c);
      CREATE TABLE cross(d, e, f,
        FOREIGN KEY(e) REFERENCES nought(b) ON UPDATE CASCADE
      );
    }
    execsql { INSERT INTO nought VALUES(2, 1, 2) }
    execsql { INSERT INTO cross VALUES(0, 1, 0) }
    set authargs [list]
    execsql { UPDATE nought SET b = 5 }
    set authargs
  } {SQLITE_UPDATE nought b main {} SQLITE_READ cross e main {} SQLITE_READ cross e main {} SQLITE_READ nought b main {} SQLITE_READ nought b main {} SQLITE_READ nought b main {} SQLITE_UPDATE cross e main {} SQLITE_READ nought b main {} SQLITE_READ cross e main {} SQLITE_READ nought b main {} SQLITE_READ nought b main {}}

  do_test fkey2-18.6 {
    execsql {SELECT * FROM cross}
  } {0 5 0}

  do_test fkey2-18.7 {
    execsql {
      CREATE TABLE one(a INTEGER PRIMARY KEY, b);
      CREATE TABLE two(b, c REFERENCES one);
      INSERT INTO one VALUES(101, 102);
    }
    set authargs [list]
    execsql { INSERT INTO two VALUES(100, 101); }
    set authargs
  } {SQLITE_INSERT two {} main {} SQLITE_READ one a main {}}

  # Return SQLITE_IGNORE to requests to read from the parent table. This
  # causes inserts of non-NULL keys into the child table to fail.
  #
  rename auth {}
  proc auth {args} {
    if {[lindex $args 1] == "long"} {return SQLITE_IGNORE}
    return SQLITE_OK
  }
  do_test fkey2-18.8 {
    catchsql { INSERT INTO short VALUES(1, 3, 2) }
  } {1 {foreign key constraint failed}}
  do_test fkey2-18.9 {
    execsql { INSERT INTO short VALUES(1, 3, NULL) }
  } {}
  do_test fkey2-18.10 {
    execsql { SELECT * FROM short }
  } {1 3 2 1 3 {}}
  do_test fkey2-18.11 {
    catchsql { UPDATE short SET f = 2 WHERE f IS NULL }
  } {1 {foreign key constraint failed}}

  db auth {}
  unset authargs
}

#-------------------------------------------------------------------------
# The following block of tests, those prefixed with "fkey2-genfkey.", are 
# the same tests that were used to test the ".genfkey" command provided 
# by the shell tool. So these tests show that the built-in foreign key 
# implementation is more or less compatible with the triggers generated 
# by genfkey.
#
drop_all_tables
do_test fkey2-genfkey.1.1 {
  execsql {
    CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(b, c));
    CREATE TABLE t2(e REFERENCES t1, f);
    CREATE TABLE t3(g, h, i, FOREIGN KEY (h, i) REFERENCES t1(b, c));
  }
} {}
do_test fkey2-genfkey.1.2 {
  catchsql { INSERT INTO t2 VALUES(1, 2) }
} {1 {foreign key constraint failed}}
do_test fkey2-genfkey.1.3 {
  execsql {
    INSERT INTO t1 VALUES(1, 2, 3);
    INSERT INTO t2 VALUES(1, 2);
  }
} {}
do_test fkey2-genfkey.1.4 {
  execsql { INSERT INTO t2 VALUES(NULL, 3) }
} {}
do_test fkey2-genfkey.1.5 {
  catchsql { UPDATE t2 SET e = 5 WHERE e IS NULL }
} {1 {foreign key constraint failed}}
do_test fkey2-genfkey.1.6 {
  execsql { UPDATE t2 SET e = 1 WHERE e IS NULL }
} {}
do_test fkey2-genfkey.1.7 {
  execsql { UPDATE t2 SET e = NULL WHERE f = 3 }
} {}
do_test fkey2-genfkey.1.8 {
  catchsql { UPDATE t1 SET a = 10 }
} {1 {foreign key constraint failed}}
do_test fkey2-genfkey.1.9 {
  catchsql { UPDATE t1 SET a = NULL }
} {1 {datatype mismatch}}
do_test fkey2-genfkey.1.10 {
  catchsql { DELETE FROM t1 }
} {1 {foreign key constraint failed}}
do_test fkey2-genfkey.1.11 {
  execsql { UPDATE t2 SET e = NULL }
} {}
do_test fkey2-genfkey.1.12 {
  execsql { 
    UPDATE t1 SET a = 10;
    DELETE FROM t1;
    DELETE FROM t2;
  }
} {}
do_test fkey2-genfkey.1.13 {
  execsql {
    INSERT INTO t3 VALUES(1, NULL, NULL);
    INSERT INTO t3 VALUES(1, 2, NULL);
    INSERT INTO t3 VALUES(1, NULL, 3);
  }
} {}
do_test fkey2-genfkey.1.14 {
  catchsql { INSERT INTO t3 VALUES(3, 1, 4) }
} {1 {foreign key constraint failed}}
do_test fkey2-genfkey.1.15 {
  execsql { 
    INSERT INTO t1 VALUES(1, 1, 4);
    INSERT INTO t3 VALUES(3, 1, 4);
  }
} {}
do_test fkey2-genfkey.1.16 {
  catchsql { DELETE FROM t1 }
} {1 {foreign key constraint failed}}
do_test fkey2-genfkey.1.17 {
  catchsql { UPDATE t1 SET b = 10}
} {1 {foreign key constraint failed}}
do_test fkey2-genfkey.1.18 {
  execsql { UPDATE t1 SET a = 10}
} {}
do_test fkey2-genfkey.1.19 {
  catchsql { UPDATE t3 SET h = 'hello' WHERE i = 3}
} {1 {foreign key constraint failed}}

drop_all_tables
do_test fkey2-genfkey.2.1 {
  execsql {
    CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(b, c));
    CREATE TABLE t2(e REFERENCES t1 ON UPDATE CASCADE ON DELETE CASCADE, f);
    CREATE TABLE t3(g, h, i, 
        FOREIGN KEY (h, i) 
        REFERENCES t1(b, c) ON UPDATE CASCADE ON DELETE CASCADE
    );
  }
} {}
do_test fkey2-genfkey.2.2 {
  execsql {
    INSERT INTO t1 VALUES(1, 2, 3);
    INSERT INTO t1 VALUES(4, 5, 6);
    INSERT INTO t2 VALUES(1, 'one');
    INSERT INTO t2 VALUES(4, 'four');
  }
} {}
do_test fkey2-genfkey.2.3 {
  execsql {
    UPDATE t1 SET a = 2 WHERE a = 1;
    SELECT * FROM t2;
  }
} {2 one 4 four}
do_test fkey2-genfkey.2.4 {
  execsql {
    DELETE FROM t1 WHERE a = 4;
    SELECT * FROM t2;
  }
} {2 one}

do_test fkey2-genfkey.2.5 {
  execsql {
    INSERT INTO t3 VALUES('hello', 2, 3);
    UPDATE t1 SET c = 2;
    SELECT * FROM t3;
  }
} {hello 2 2}
do_test fkey2-genfkey.2.6 {
  execsql {
    DELETE FROM t1;
    SELECT * FROM t3;
  }
} {}

drop_all_tables
do_test fkey2-genfkey.3.1 {
  execsql {
    CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(c, b));
    CREATE TABLE t2(e REFERENCES t1 ON UPDATE SET NULL ON DELETE SET NULL, f);
    CREATE TABLE t3(g, h, i, 
        FOREIGN KEY (h, i) 
        REFERENCES t1(b, c) ON UPDATE SET NULL ON DELETE SET NULL
    );
  }
} {}
do_test fkey2-genfkey.3.2 {
  execsql {
    INSERT INTO t1 VALUES(1, 2, 3);
    INSERT INTO t1 VALUES(4, 5, 6);
    INSERT INTO t2 VALUES(1, 'one');
    INSERT INTO t2 VALUES(4, 'four');
  }
} {}
do_test fkey2-genfkey.3.3 {
  execsql {
    UPDATE t1 SET a = 2 WHERE a = 1;
    SELECT * FROM t2;
  }
} {{} one 4 four}
do_test fkey2-genfkey.3.4 {
  execsql {
    DELETE FROM t1 WHERE a = 4;
    SELECT * FROM t2;
  }
} {{} one {} four}
do_test fkey2-genfkey.3.5 {
  execsql {
    INSERT INTO t3 VALUES('hello', 2, 3);
    UPDATE t1 SET c = 2;
    SELECT * FROM t3;
  }
} {hello {} {}}
do_test fkey2-genfkey.3.6 {
  execsql {
    UPDATE t3 SET h = 2, i = 2;
    DELETE FROM t1;
    SELECT * FROM t3;
  }
} {hello {} {}}

finish_test
Added test/fkey3.test.
















































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for foreign keys.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable {!foreignkey||!trigger} {
  finish_test
  return
}

# Create a table and some data to work with.
#
do_test fkey3-1.1 {
  execsql {
    PRAGMA foreign_keys=ON;
    CREATE TABLE t1(x INTEGER PRIMARY KEY);
    INSERT INTO t1 VALUES(100);
    INSERT INTO t1 VALUES(101);
    CREATE TABLE t2(y INTEGER REFERENCES t1 (x));
    INSERT INTO t2 VALUES(100);
    INSERT INTO t2 VALUES(101);
    SELECT 1, x FROM t1;
    SELECT 2, y FROM t2;
  }
} {1 100 1 101 2 100 2 101}

do_test fkey3-1.2 {
  catchsql {
    DELETE FROM t1 WHERE x=100;
  }
} {1 {foreign key constraint failed}}

do_test fkey3-1.3 {
  catchsql {
    DROP TABLE t1;
  }
} {1 {foreign key constraint failed}}

do_test fkey3-1.4 {
  execsql {
    DROP TABLE t2;
  }
} {}

do_test fkey3-1.5 {
  execsql {
    DROP TABLE t1;
  }
} {}

do_test fkey3-2.1 {
  execsql {
    PRAGMA foreign_keys=ON;
    CREATE TABLE t1(x INTEGER PRIMARY KEY);
    INSERT INTO t1 VALUES(100);
    INSERT INTO t1 VALUES(101);
    CREATE TABLE t2(y INTEGER PRIMARY KEY REFERENCES t1 (x) ON UPDATE SET NULL);
  }
  execsql {
    INSERT INTO t2 VALUES(100);
    INSERT INTO t2 VALUES(101);
    SELECT 1, x FROM t1;
    SELECT 2, y FROM t2;
  }
} {1 100 1 101 2 100 2 101}

finish_test
Added test/fkey_malloc.test.




































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 September 22
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !foreignkey||!trigger {
  finish_test
  return
}
source $testdir/malloc_common.tcl

do_malloc_test fkey_malloc-1 -sqlprep {
  PRAGMA foreign_keys = 1;
  CREATE TABLE t1(a PRIMARY KEY, b UNIQUE);
  CREATE TABLE t2(x REFERENCES t1 ON UPDATE CASCADE ON DELETE CASCADE);
} -sqlbody {
  INSERT INTO t1 VALUES('aaa', 1);
  INSERT INTO t2 VALUES('aaa');
  UPDATE t1 SET a = 'bbb';
  DELETE FROM t1;
}

do_malloc_test fkey_malloc-2 -sqlprep {
  PRAGMA foreign_keys = 1;
  CREATE TABLE t1(a, b, UNIQUE(a, b));
} -sqlbody {
  CREATE TABLE t2(x, y, 
    FOREIGN KEY(x, y) REFERENCES t1(a, b) DEFERRABLE INITIALLY DEFERRED
  );
  BEGIN;
    INSERT INTO t2 VALUES('a', 'b');
    INSERT INTO t1 VALUES('a', 'b');
    UPDATE t1 SET a = 'c';
    DELETE FROM t2;
    INSERT INTO t2 VALUES('d', 'b');
    UPDATE t2 SET x = 'c';
  COMMIT;
}

do_malloc_test fkey_malloc-3 -sqlprep {
  PRAGMA foreign_keys = 1;
  CREATE TABLE t1(x INTEGER PRIMARY KEY);
  CREATE TABLE t2(y DEFAULT 14 REFERENCES t1(x) ON UPDATE SET DEFAULT);
  CREATE TABLE t3(y REFERENCES t1 ON UPDATE SET NULL);
  INSERT INTO t1 VALUES(13);
  INSERT INTO t2 VALUES(13);
  INSERT INTO t3 VALUES(13);
} -sqlbody {
  UPDATE t1 SET x = 14;
}

proc catch_fk_error {zSql} {
  set rc [catch {db eval $zSql} msg]
  if {$rc==0} {
    return $msg
  }
  if {[string match {*foreign key*} $msg]} {
    return ""
  }
  if {$msg eq "out of memory"} {
    error 1
  }
  error $msg
}

do_malloc_test fkey_malloc-4 -sqlprep {
  PRAGMA foreign_keys = 1;
  CREATE TABLE t1(x INTEGER PRIMARY KEY, y UNIQUE);
  CREATE TABLE t2(z REFERENCES t1(x), a REFERENCES t1(y));
  CREATE TABLE t3(x);
  CREATE TABLE t4(z REFERENCES t3);
  CREATE TABLE t5(x, y);
  CREATE TABLE t6(z REFERENCES t5(x));
  CREATE INDEX i51 ON t5(x);
  CREATE INDEX i52 ON t5(y, x);
  INSERT INTO t1 VALUES(1, 2);
} -tclbody {
  catch_fk_error {INSERT INTO t2 VALUES(1, 3)}
  catch_fk_error {INSERT INTO t4 VALUES(2)}
  catch_fk_error {INSERT INTO t6 VALUES(2)}
}

do_malloc_test fkey_malloc-5 -sqlprep {
  PRAGMA foreign_keys = 1;
  CREATE TABLE t1(x, y, PRIMARY KEY(x, y));
  CREATE TABLE t2(a, b, FOREIGN KEY(a, b) REFERENCES t1 ON UPDATE CASCADE);
  INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t2 VALUES(1, 2);
} -sqlbody {
  UPDATE t1 SET x = 5;
}

do_malloc_test fkey_malloc-6 -sqlprep {
  PRAGMA foreign_keys = 1;
  CREATE TABLE t1(
    x PRIMARY KEY, 
    y REFERENCES t1 ON DELETE RESTRICT ON UPDATE SET DEFAULT
  );
  INSERT INTO t1 VALUES('abc', 'abc');
  INSERT INTO t1 VALUES('def', 'def');
} -sqlbody {
  INSERT INTO t1 VALUES('ghi', 'ghi');
  DELETE FROM t1 WHERE rowid>1;
  UPDATE t1 SET x='jkl', y='jkl';
}

do_malloc_test fkey_malloc-7 -sqlprep {
  PRAGMA foreign_keys = 1;
  CREATE TABLE x(a, b, PRIMARY KEY(a, b));
  CREATE TABLE y(c, d,
    FOREIGN KEY(d, c) REFERENCES x DEFERRABLE INITIALLY DEFERRED
  );
  CREATE TABLE z(e, f, FOREIGN KEY(e, f) REFERENCES x);
} -sqlbody {
  DROP TABLE y;
  DROP TABLE x;
}

finish_test


Changes to test/fts3expr.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21













-
+







# 2006 September 9
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the FTS3 module.
#
# $Id: fts3expr.test,v 1.7 2009/03/12 15:43:48 danielk1977 Exp $
# $Id: fts3expr.test,v 1.9 2009/07/28 16:44:26 danielk1977 Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
118
119
120
121
122
123
124
125

126
127



128
129
130
131
132
133
134
118
119
120
121
122
123
124

125
126
127
128
129
130
131
132
133
134
135
136
137







-
+


+
+
+







do_test fts3expr-1.11 {
  test_fts3expr {one two*}
} {AND {PHRASE 3 0 one} {PHRASE 3 0 two+}}

do_test fts3expr-1.14 {
  test_fts3expr {a:one two}
} {AND {PHRASE 0 0 one} {PHRASE 3 0 two}}
do_test fts3expr-1.15 {
do_test fts3expr-1.15.1 {
  test_fts3expr {one b:two}
} {AND {PHRASE 3 0 one} {PHRASE 1 0 two}}
do_test fts3expr-1.15.2 {
  test_fts3expr {one B:two}
} {AND {PHRASE 3 0 one} {PHRASE 1 0 two}}

do_test fts3expr-1.16 {
  test_fts3expr {one AND two AND three AND four AND five}
} [list AND \
        [list AND \
              [list AND \
                    [list AND {PHRASE 3 0 one} {PHRASE 3 0 two}] \
459
460
461
462
463
464
465
466















467
468
469

470
471
472
473
474
475
476
477

478
479
480
462
463
464
465
466
467
468

469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499







-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



+








+



  11 "one two OR four five NOT three" {3 7 11 15 19 23 24 25 26 27 31}

  12 "(one two OR four five) NOT three" {3 11 19 24 25 26 27}

  13 "((((((one two OR four five)))))) NOT three" {3 11 19 24 25 26 27}

} {
  do_test fts3expr-6.$id {
  do_test fts3expr-6.1.$id {
    execsql { SELECT rowid FROM t1 WHERE t1 MATCH $expr ORDER BY rowid }
  } $res
}

set sqlite_fts3_enable_parentheses 0
foreach {id expr res} {
  1 "one -two three"  {5 13 21 29}
  2 "-two one three"  {5 13 21 29}
  3 "one three -two"  {5 13 21 29}
  4 "-one -two three" {4 12 20 28}
  5 "three -one -two" {4 12 20 28}
  6 "-one three -two" {4 12 20 28}
} {
  do_test fts3expr-6.2.$id {
    execsql { SELECT rowid FROM t1 WHERE t1 MATCH $expr ORDER BY rowid }
  } $res
}
set sqlite_fts3_enable_parentheses 1

do_test fts3expr-7.1 {
  execsql {
    CREATE VIRTUAL TABLE test USING fts3 (keyword);
    INSERT INTO test VALUES ('abc');
    SELECT * FROM test WHERE keyword MATCH '""';
  }
} {}


set sqlite_fts3_enable_parentheses 0
finish_test
Changes to test/func.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20













-







# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing built-in functions.
#
# $Id: func.test,v 1.93 2009/06/19 16:44:41 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create a table to work with.
#
do_test func-0.0 {
1153
1154
1155
1156
1157
1158
1159












1160
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171







+
+
+
+
+
+
+
+
+
+
+
+

do_test func-27.2 {
  catchsql {SELECT coalesce(1)}
} {1 {wrong number of arguments to function coalesce()}}
do_test func-27.3 {
  catchsql {SELECT coalesce(1,2)}
} {0 1}

# Ticket 2d401a94287b5
# Unknown function in a DEFAULT expression causes a segfault.
#
do_test func-28.1 {
  db eval {
    CREATE TABLE t28(x, y DEFAULT(nosuchfunc(1)));
  }
  catchsql {
    INSERT INTO t28(x) VALUES(1);
  }
} {1 {unknown function: nosuchfunc()}}

finish_test
Changes to test/icu.test.
22
23
24
25
26
27
28
29

30
31
32
33
34

35
36
37
38
39
40
41
22
23
24
25
26
27
28

29
30
31
32
33

34
35
36
37
38
39
40
41







-
+




-
+








# Create a table to work with.
#
execsql {CREATE TABLE test1(i1 int, i2 int, r1 real, r2 real, t1 text, t2 text)}
execsql {INSERT INTO test1 VALUES(1,2,1.1,2.2,'hello','world')}
proc test_expr {name settings expr result} {
  do_test $name [format {
    db one {
    lindex [db eval {
      BEGIN; 
      UPDATE test1 SET %s; 
      SELECT %s FROM test1; 
      ROLLBACK;
    }
    }] 0
  } $settings $expr] $result
}

# Tests of the REGEXP operator.
#
test_expr icu-1.1 {i1='hello'} {i1 REGEXP 'hello'}  1
test_expr icu-1.2 {i1='hello'} {i1 REGEXP '.ello'}  1
Changes to test/incrblob.test.
305
306
307
308
309
310
311
312

313
314
315
316
317
318
319
320
















321
322
323
324
325
326
327
305
306
307
308
309
310
311

312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343







-
+








+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







do_test incrblob-4.7 {
  set rc [catch {
    set ::blob [db incrblob blobs i 2]
  } msg ] 
  list $rc $msg
} {1 {cannot open value of type null}}

do_test incrblob-4.8 {
do_test incrblob-4.8.1 {
  execsql {
    INSERT INTO blobs(k, v, i) VALUES(X'010203040506070809', 'hello', 'world');
  }
  set rc [catch {
    set ::blob [db incrblob blobs k 3]
  } msg ] 
  list $rc $msg
} {1 {cannot open indexed column for writing}}
do_test incrblob-4.8.2 {
  execsql {
    CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
    INSERT INTO t3 VALUES(1, 2);
  }
  set rc [catch {
    set ::blob [db incrblob -readonly t3 a 1]
  } msg ] 
  list $rc $msg
} {1 {cannot open value of type null}}
do_test incrblob-4.8.3 {
  set rc [catch {
    set ::blob [db incrblob -readonly t3 rowid 1]
  } msg ] 
  list $rc $msg
} {1 {no such column: "rowid"}}

do_test incrblob-4.9.1 {
  set rc [catch {
    set ::blob [db incrblob -readonly blobs k 3]
  } msg]
} {0}
do_test incrblob-4.9.2 {
Changes to test/incrblob2.test.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Test that it is possible to have two open blob handles on a single
# blob object.
#
# $Id: incrblob2.test,v 1.10 2009/03/16 13:19:36 danielk1977 Exp $
# $Id: incrblob2.test,v 1.11 2009/06/29 06:00:37 danielk1977 Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable {!autovacuum || !pragma || !incrblob} {
  finish_test
270
271
272
273
274
275
276
277
278
279



280
281


282




283
284




285
286
287
288
289
290
291
270
271
272
273
274
275
276



277
278
279
280
281
282
283

284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300







-
-
-
+
+
+


+
+
-
+
+
+
+


+
+
+
+







  do_test incrblob2-5.4 {
    close $blob
    execsql BEGIN db2
    catchsql { INSERT INTO t1 VALUES(4, 'pqrst') } db2
  } {0 {}}

  do_test incrblob2-5.5 {
    set blob [db incrblob -readonly t1 data 1]
    catchsql { INSERT INTO t1 VALUES(5, 'uvwxy') } db2
  } {1 {database table is locked}}
    set rc [catch { db incrblob -readonly t1 data 1 } msg]
    list $rc $msg
  } {1 {database table is locked: t1}}

  do_test incrblob2-5.6 {
    execsql { PRAGMA read_uncommitted=1 }
    set blob [db incrblob -readonly t1 data 4]
    close $blob
    read $blob
  } {pqrst}

  do_test incrblob2-5.7 {
    catchsql { INSERT INTO t1 VALUES(3, 'klmno') } db2
  } {0 {}}

  do_test incrblob2-5.8 {
    close $blob
  } {}

  db2 close
  db close
  sqlite3_enable_shared_cache $::enable_shared_cache
}

#--------------------------------------------------------------------------
Changes to test/incrvacuum2.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25










26
27
28
29
30
31
32













-
+











-
-
-
-
-
-
-
-
-
-







# 2007 May 04
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the incremental vacuum feature.
#
# $Id: incrvacuum2.test,v 1.5 2008/05/07 07:13:16 danielk1977 Exp $
# $Id: incrvacuum2.test,v 1.6 2009/07/25 13:42:50 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If this build of the library does not support auto-vacuum, omit this
# whole file.
ifcapable {!autovacuum || !pragma} {
  finish_test
  return
}

# If the OMIT_INCRBLOB symbol was defined at compile time, there
# is no zeroblob() function available. So create a similar
# function here using Tcl. It doesn't return a blob, but it returns
# data of the required length, which is good enough for this
# test file.
ifcapable !incrblob {
  proc zeroblob {n} { string repeat 0 $n }
  db function zeroblob zeroblob
}


# Create a database in incremental vacuum mode that has many
# pages on the freelist.
#
do_test incrvacuum2-1.1 {
  execsql {
    PRAGMA page_size=1024;
Added test/init.test.















































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the effects of a failure in 
# sqlite3_initialize().
#
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

db close

foreach {t failed rc started} {
  1.1 {}       SQLITE_OK    {mutex mem pcache}
  1.2 {mutex}  SQLITE_ERROR {}
  1.3 {mem}    SQLITE_ERROR {mutex}
  1.4 {pcache} SQLITE_ERROR {mutex mem}
} {
  do_test init-$t.1 {
    eval init_wrapper_install $failed
    sqlite3_initialize
  } $rc
  do_test init-$t.2 {
    init_wrapper_query
  } $started
  do_test init-$t.3 {
    sqlite3_shutdown
    init_wrapper_query
  } {}
  do_test init-$t.4 {
    sqlite3_initialize
  } $rc
  do_test init-$t.5 {
    init_wrapper_query
  } $started
  do_test init-$t.6 {
    init_wrapper_clear
    sqlite3_initialize
  } SQLITE_OK
  do_test init-$t.7 {
    init_wrapper_query
  } {mutex mem pcache}
  do_test init-$t.8 {
    init_wrapper_uninstall
  } {}
}

source $testdir/malloc_common.tcl
if {$MEMDEBUG} {
  do_malloc_test init-2 -tclprep {
    db close
    init_wrapper_install
  } -tclbody {
    set rc [sqlite3_initialize]
    if {[string match "SQLITE*NOMEM" $rc]} {error "out of memory"}
  } -cleanup {
    set zRepeat "transient"
    if {$::iRepeat} {set zRepeat "persistent"}
    do_test init-2.$zRepeat.$::n.x {
      init_wrapper_clear
      sqlite3_initialize
    } SQLITE_OK
    init_wrapper_uninstall
  }
}

autoinstall_test_functions
finish_test

Added test/intarray.test.













































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 November 10
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for the "intarray" object implemented
# in test_intarray.c.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !vtab {
  return
}

do_test intarray-1.0 {
  db eval {
    CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
  }
  for {set i 1} {$i<=999} {incr i} {
    set b [format {x%03d} $i]
    db eval {INSERT INTO t1(a,b) VALUES($i,$b)}
  }
  db eval {
    CREATE TABLE t2(x INTEGER PRIMARY KEY, y);
    INSERT INTO t2 SELECT * FROM t1;
    SELECT b FROM t1 WHERE a IN (12,34,56,78) ORDER BY a
  }
} {x012 x034 x056 x078}

do_test intarray-1.1 {
  set ia1 [sqlite3_intarray_create db ia1]
  set ia2 [sqlite3_intarray_create db ia2]
  set ia3 [sqlite3_intarray_create db ia3]
  set ia4 [sqlite3_intarray_create db ia4]
  db eval {
    SELECT type, name FROM sqlite_temp_master
     ORDER BY name
  }
} {table ia1 table ia2 table ia3 table ia4}

do_test intarray-1.2 {
  db eval {
    SELECT b FROM t1 WHERE a IN ia3 ORDER BY a
  }
} {}

do_test intarray-1.3 {
  sqlite3_intarray_bind $ia3 45 123 678
  db eval {
    SELECT b FROM t1 WHERE a IN ia3 ORDER BY a
  }
} {x045 x123 x678}

do_test intarray-1.4 {
  db eval {
    SELECT count(b) FROM t1 WHERE a NOT IN ia3 ORDER BY a
  }
} {996}

#explain {SELECT b FROM t1 WHERE a NOT IN ia3}

do_test intarray-1.5 {
  set cmd sqlite3_intarray_bind
  lappend cmd $ia1
  for {set i 1} {$i<=999} {incr i} {
    lappend cmd $i
    lappend cmd [expr {$i+1000}]
    lappend cmd [expr {$i+2000}]
  }
  eval $cmd
  db eval {
    REPLACE INTO t1 SELECT * FROM t2;
    DELETE FROM t1 WHERE a NOT IN ia1;
    SELECT count(*) FROM t1;
  }
} {999}

do_test intarray-1.6 {
  db eval {
    DELETE FROM t1 WHERE a IN ia1;
    SELECT count(*) FROM t1;
  }
} {0}

do_test intarray-2.1 {
  db eval {
    CREATE TEMP TABLE t3(p,q);
    INSERT INTO t3 SELECT * FROM t2;
    SELECT count(*) FROM t3 WHERE p IN ia1;
  }
} {999}

do_test intarray-2.2 {
  set ia5 [sqlite3_intarray_create db ia5]
  db eval {
    SELECT count(*) FROM t3 WHERE p IN ia1;
  }
} {999}

finish_test
Changes to test/io.test.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
9
10
11
12
13
14
15

16
17
18
19
20
21
22







-







#
#***********************************************************************
#
# The focus of this file is testing some specific characteristics of the 
# IO traffic generated by SQLite (making sure SQLite is not writing out
# more database pages than it has to, stuff like that).
#
# $Id: io.test,v 1.21 2009/03/28 07:03:42 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

db close
sqlite3_simulate_device
sqlite3 db test.db -vfs devsym
421
422
423
424
425
426
427

428
429

430
431
432




433
434
435
436
437
438
439
420
421
422
423
424
425
426
427
428

429



430
431
432
433
434
435
436
437
438
439
440







+

-
+
-
-
-
+
+
+
+







#   1) The directory in which the journal file is created, (unix only)
#   2) The journal file (to sync the page data),
#   3) The database file.
#
# Normally, when the SAFE_APPEND flag is not set, there is another fsync()
# on the journal file between steps (2) and (3) above.
#
set expected_sync_count 2
if {$::tcl_platform(platform)=="unix"} {
  set expected_sync_count 3
  ifcapable dirsync {
} else {
  set expected_sync_count 2
}
    incr expected_sync_count
  }
}

do_test io-4.1 {
  execsql { DELETE FROM abc }
  nSync
  execsql { INSERT INTO abc VALUES('a', 'b') }
  nSync
} $expected_sync_count

Changes to test/join.test.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for joins, including outer joins.
#
# $Id: join.test,v 1.26 2008/12/05 00:00:07 drh Exp $
# $Id: join.test,v 1.27 2009/07/01 16:12:08 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test join-1.1 {
  execsql {
    CREATE TABLE t1(a,b,c);
305
306
307
308
309
310
311
312
313

314
315

316
317
318
319
320
321
322
305
306
307
308
309
310
311


312


313
314
315
316
317
318
319
320







-
-
+
-
-
+







} {1 {cannot join using column a - column not present in both tables}}
do_test join-3.4.2 {
  catchsql {
    SELECT * FROM t1 JOIN t2 USING(d);
  }
} {1 {cannot join using column d - column not present in both tables}}
do_test join-3.5 {
  catchsql {
    SELECT * FROM t1 USING(a);
  catchsql { SELECT * FROM t1 USING(a) }
  }
} {0 {1 2 3 2 3 4 3 4 5}}
} {1 {a JOIN clause is required before USING}}
do_test join-3.6 {
  catchsql {
    SELECT * FROM t1 JOIN t2 ON t3.a=t2.b;
  }
} {1 {no such column: t3.a}}
do_test join-3.7 {
  catchsql {
573
574
575
576
577
578
579
580

































































581
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644








+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

  do_test join-10.3 {
    execsql {
      SELECT * FROM t23 LEFT JOIN (SELECT * FROM t24);
    }
  } {1 2 3 {} {} {}}

} ;# ifcapable subquery

#-------------------------------------------------------------------------
# The following tests are to ensure that bug b73fb0bd64 is fixed.
#
do_test join-11.1 {
  drop_all_tables
  execsql {
    CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT);
    CREATE TABLE t2(a INTEGER PRIMARY KEY, b TEXT);
    INSERT INTO t1 VALUES(1,'abc');
    INSERT INTO t1 VALUES(2,'def');
    INSERT INTO t2 VALUES(1,'abc');
    INSERT INTO t2 VALUES(2,'def');
    SELECT * FROM t1 NATURAL JOIN t2;
  }
} {1 abc 2 def}

do_test join-11.2 {
  execsql { SELECT a FROM t1 JOIN t1 USING (a)}
} {1 2}
do_test join-11.3 {
  execsql { SELECT a FROM t1 JOIN t1 AS t2 USING (a)}
} {1 2}
do_test join-11.3 {
  execsql { SELECT * FROM t1 NATURAL JOIN t1 AS t2}
} {1 abc 2 def}
do_test join-11.4 {
  execsql { SELECT * FROM t1 NATURAL JOIN t1 }
} {1 abc 2 def}

do_test join-11.5 {
  drop_all_tables
  execsql {
    CREATE TABLE t1(a COLLATE nocase, b);
    CREATE TABLE t2(a, b);
    INSERT INTO t1 VALUES('ONE', 1);
    INSERT INTO t1 VALUES('two', 2);
    INSERT INTO t2 VALUES('one', 1);
    INSERT INTO t2 VALUES('two', 2);
  }
} {}
do_test join-11.6 {
  execsql { SELECT * FROM t1 NATURAL JOIN t2 }
} {ONE 1 two 2}
do_test join-11.7 {
  execsql { SELECT * FROM t2 NATURAL JOIN t1 }
} {two 2}

do_test join-11.8 {
  drop_all_tables
  execsql {
    CREATE TABLE t1(a, b TEXT);
    CREATE TABLE t2(b INTEGER, a);
    INSERT INTO t1 VALUES('one', '1.0');
    INSERT INTO t1 VALUES('two', '2');
    INSERT INTO t2 VALUES(1, 'one');
    INSERT INTO t2 VALUES(2, 'two');
  }
} {}
do_test join-11.9 {
  execsql { SELECT * FROM t1 NATURAL JOIN t2 }
} {one 1.0 two 2}
do_test join-11.10 {
  execsql { SELECT * FROM t2 NATURAL JOIN t1 }
} {1 one 2 two}

finish_test
Added test/lock7.test.





























































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 August 17
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Check that reading the database schema from within an active transaction
# does not establish a SHARED lock on the database file if one is not
# already held (or, more accurately, that the SHARED lock is released after
# reading the database schema).
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test lock7-1.1 {
  execsql { CREATE TABLE t1(a, b) }
  db close

  sqlite3 db1 test.db
  sqlite3 db2 test.db

  db1 eval {BEGIN}
  db2 eval {BEGIN}
} {}

do_test lock7-1.2 {
  execsql { PRAGMA lock_status } db1
} {main unlocked temp closed}
do_test lock7-1.3 {
  execsql { PRAGMA lock_status } db2
} {main unlocked temp closed}

do_test lock7-1.4 {
  catchsql { INSERT INTO t1 VALUES(1, 1) } db1
} {0 {}}
do_test lock7-1.5 {
  catchsql { INSERT INTO t1 VALUES(2, 2) } db2
} {1 {database is locked}}

do_test lock7-1.6 {
  execsql { PRAGMA lock_status } db1
} {main reserved temp closed}
do_test lock7-1.7 {
  execsql { PRAGMA lock_status } db2
} {main unlocked temp closed}

do_test lock7-1.8 {
  execsql { COMMIT } db1
} {}

db1 close
db2 close

finish_test

Changes to test/malloc.test.
861
862
863
864
865
866
867



























868
869
870
871
872
873
874
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    do_test malloc-36.$zRepeat.${::n}.unlocked {
      execsql {INSERT INTO t1 VALUES(3, 4)} db2
    } {}
    db2 close
  }
  catch { db2 close }
}

ifcapable stat2 {
  do_malloc_test 38 -tclprep {
    add_test_collate db 0 0 1
    execsql {
      ANALYZE;
      CREATE TABLE t4(x COLLATE test_collate);
      CREATE INDEX t4x ON t4(x);
      INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 0, 'aaa');
      INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 1, 'aaa');
      INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 2, 'aaa');
      INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 3, 'aaa');
      INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 4, 'aaa');
      INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 5, 'aaa');
      INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 6, 'aaa');
      INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 7, 'aaa');
      INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 8, 'aaa');
      INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 9, 'aaa');
    }
    db close
    sqlite3 db test.db
    sqlite3_db_config_lookaside db 0 0 0
    add_test_collate db 0 0 1
  } -sqlbody {
    SELECT * FROM t4 AS t41, t4 AS t42 WHERE t41.x>'ddd' AND t42.x>'ccc'
  }
}

# Ensure that no file descriptors were leaked.
do_test malloc-99.X {
  catch {db close}
  set sqlite_open_file_count
} {0}

Changes to test/mallocI.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21













-
+







# 2008 August 01
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This test script checks malloc failures in various obscure operations.
# 
# $Id: mallocI.test,v 1.1 2008/08/02 03:50:39 drh Exp $
# $Id: mallocI.test,v 1.3 2009/08/10 04:26:39 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl

# Malloc failures in a view.
#
35
36
37
38
39
40
41
42




















43
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63








+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

# Malloc failure while creating a table from a SELECT statement.
#
do_malloc_test mallocI-3 -sqlprep {
  CREATE TABLE t1(a,b,c);
} -sqlbody {
  CREATE TABLE t2 AS SELECT b,c FROM t1;
}

# This tests that a malloc failure that occurs while passing the schema
# does not result in a SHARED lock being left on the database file.
#
do_malloc_test mallocI-4 -tclprep {
  sqlite3 db2 test.db
  db2 eval {
    CREATE TABLE t1(a, b, c);
    CREATE TABLE t2(a, b, c);
  }
} -sqlbody {
  SELECT * FROM t1
} -cleanup {
  do_test mallocI-4.$::n.2 {
    # If this INSERT is possible then [db] does not hold a shared lock
    # on the database file.
    catchsql { INSERT INTO t1 VALUES(1, 2, 3) } db2
  } {0 {}}
}
catch { db2 close }

finish_test
Changes to test/memsubsys1.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21













-
+







# 2008 June 18
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains tests of the memory allocation subsystem
#
# $Id: memsubsys1.test,v 1.15 2009/04/11 14:46:43 drh Exp $
# $Id: memsubsys1.test,v 1.17 2009/07/18 14:36:24 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
sqlite3_reset_auto_extension

# This procedure constructs a new database in test.db.  It fills
# this database with many small records (enough to force multiple
Changes to test/misc2.test.
14
15
16
17
18
19
20





21
22
23
24
25
26
27
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32







+
+
+
+
+







# left out of other test files.
#
# $Id: misc2.test,v 1.28 2007/09/12 17:01:45 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# The tests in this file were written before SQLite supported recursive
# trigger invocation, and some tests depend on that to pass. So disable
# recursive triggers for this file.
catchsql { pragma recursive_triggers = off } 

ifcapable {trigger} {
# Test for ticket #360
#
do_test misc2-1.1 {
  catchsql {
    CREATE TABLE FOO(bar integer);
    CREATE TRIGGER foo_insert BEFORE INSERT ON foo BEGIN
354
355
356
357
358
359
360

361
362
363
364
365
366
367
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373







+







    execsql {SELECT * FROM t1}
  } {1 2 3 4 5 6 7 8 9 10}
}

db close
file delete -force test.db
sqlite3 db test.db
catchsql { pragma recursive_triggers = off } 

# Ticket #453.  If the SQL ended with "-", the tokenizer was calling that
# an incomplete token, which caused problem.  The solution was to just call
# it a minus sign.
#
do_test misc2-8.1 {
  catchsql {-}
Changes to test/misc7.test.
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
20












-
+







# 2006 September 4
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# $Id: misc7.test,v 1.28 2009/02/10 05:45:42 danielk1977 Exp $
# $Id: misc7.test,v 1.29 2009/07/16 18:21:18 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test misc7-1-misuse {
  c_misuse_test
} {}
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
362
363
364
365
366
367
368










369
370
371
372
373
374
375







-
-
-
-
-
-
-
-
-
-








do_test misc7-16.X {
  execsql {
    SELECT count(*) FROM t3;
  }
} {32}

set sqlite_pager_n_sort_bucket 4
do_test misc7-17 {
  execsql {
    PRAGMA integrity_check;
    VACUUM;
    PRAGMA integrity_check;
  }
} {ok ok}
set sqlite_pager_n_sort_bucket 0

#----------------------------------------------------------------------
# Test the situation where a hot-journal is discovered but write-access
# to it is denied. This should return SQLITE_BUSY.
#
# These tests do not work on windows due to restrictions in the
# windows file system.
#
Changes to test/nan.test.
309
310
311
312
313
314
315
316

317
318
319
320
309
310
311
312
313
314
315

316
317
318
319
320







-
+




} {-9.88131291682493e-324 real}

do_test nan-4.20 {
  db eval {DELETE FROM t1}
  set big [string repeat 9 10000].0e-9000
  db eval "INSERT INTO t1 VALUES($big)"
  db eval {SELECT x, typeof(x) FROM t1}
} {{} null}
} {inf real}



finish_test
Changes to test/notnull.test.
497
498
499
500
501
502
503
504

































505

497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539








+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
  catchsql {
    DELETE FROM t1;
    INSERT INTO t1 VALUES(1,2,3,4,5);
    UPDATE t1 SET e=null, a=b, b=a;
    SELECT * FROM t1 ORDER BY a;
  }
} {1 {t1.e may not be NULL}}

# Test that bug 29ab7be99f is fixed.
#
do_test notnull-5.1 {
  execsql {
    DROP TABLE IF EXISTS t1;
    CREATE TABLE t1(a, b NOT NULL);
    CREATE TABLE t2(c, d);
    INSERT INTO t2 VALUES(3, 4);
    INSERT INTO t2 VALUES(5, NULL);
  }
}  {}
do_test notnull-5.2 {
  catchsql {
    INSERT INTO t1 VALUES(1, 2);
    INSERT INTO t1 SELECT * FROM t2;
  }
} {1 {t1.b may not be NULL}}
do_test notnull-5.3 {
  execsql { SELECT * FROM t1 }
} {1 2}
do_test notnull-5.4 {
  catchsql {
    DELETE FROM t1;
    BEGIN;
      INSERT INTO t1 VALUES(1, 2);
      INSERT INTO t1 SELECT * FROM t2;
    COMMIT;
  }
} {1 {t1.b may not be NULL}}
do_test notnull-5.5 {
  execsql { SELECT * FROM t1 }
} {1 2}

finish_test

Deleted test/pager.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582






































































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is page cache subsystem.
#
# $Id: pager.test,v 1.35 2009/06/05 17:09:12 drh Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl

if {[info commands pager_open]!=""} {
db close

# Basic sanity check.  Open and close a pager.
#
do_test pager-1.0 {
  catch {file delete -force ptf1.db}
  catch {file delete -force ptf1.db-journal}
  set v [catch {
    set ::p1 [pager_open ptf1.db 10]
  } msg]
} {0}
do_test pager-1.1 {
  pager_stats $::p1
} {ref 0 page 0 max 10 size -1 state 0 err 0 hit 0 miss 0 ovfl 0}
do_test pager-1.2 {
  pager_pagecount $::p1
} {0}
do_test pager-1.3 {
  pager_stats $::p1
} {ref 0 page 0 max 10 size -1 state 0 err 0 hit 0 miss 0 ovfl 0}
do_test pager-1.4 {
  pager_close $::p1
} {}

# Try to write a few pages.
#
do_test pager-2.1 {
  set v [catch {
    set ::p1 [pager_open ptf1.db 10]
  } msg]
} {0}
#do_test pager-2.2 {
#  set v [catch {
#    set ::g1 [page_get $::p1 0]
#  } msg]
#  lappend v $msg
#} {1 SQLITE_ERROR}
do_test pager-2.3.1 {
  set ::gx [page_lookup $::p1 1]
} {}
do_test pager-2.3.2 {
  pager_stats $::p1
} {ref 0 page 0 max 10 size -1 state 0 err 0 hit 0 miss 0 ovfl 0}
do_test pager-2.3.3 {
  set v [catch {
    set ::g1 [page_get $::p1 1]
  } msg]
  if {$v} {lappend v $msg}
  set v
} {0}
do_test pager-2.3.3 {
  pager_stats $::p1
} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
do_test pager-2.3.4 {
  set ::gx [page_lookup $::p1 1]
  expr {$::gx!=""}
} {1}
do_test pager-2.3.5 {
  page_unref $::gx
  pager_stats $::p1
} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
do_test pager-2.3.6 {
  expr {$::g1==$::gx}
} {1}
do_test pager-2.3.7 {
  pager_stats $::p1
} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
do_test pager-2.4 {
  pager_stats $::p1
} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
do_test pager-2.5 {
  pager_pagecount $::p1
} {0}
do_test pager-2.6 {
  pager_stats $::p1
} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
do_test pager-2.7 {
  page_number $::g1
} {1}
do_test pager-2.8 {
  page_read $::g1
} {}
do_test pager-2.9 {
  page_unref $::g1
} {}

# Update 24/03/2007: Even though the ref-count has dropped to zero, the
# pager-cache still contains some pages. Previously, it was always true
# that if there were no references to a pager it was empty.
do_test pager-2.10 {
  pager_stats $::p1
} {ref 0 page 1 max 10 size -1 state 0 err 0 hit 0 miss 1 ovfl 0}
do_test pager-2.11 {
  set ::g1 [page_get $::p1 1]
  expr {$::g1!=0}
} {1}
do_test pager-2.12 {
  page_number $::g1
} {1}
do_test pager-2.13 {
  pager_stats $::p1
} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 1 miss 1 ovfl 0}
do_test pager-2.14 {
  set v [catch {
    page_write $::g1 "Page-One"
  } msg]
  lappend v $msg
} {0 {}}
do_test pager-2.15 {
  pager_stats $::p1
} {ref 1 page 1 max 10 size 1 state 2 err 0 hit 1 miss 1 ovfl 0}
do_test pager-2.16 {
  page_read $::g1
} {Page-One}
do_test pager-2.17 {
  set v [catch {
    pager_commit $::p1
  } msg]
  lappend v $msg
} {0 {}}
do_test pager-2.20 {
  pager_stats $::p1
} {ref 1 page 1 max 10 size -1 state 1 err 0 hit 2 miss 1 ovfl 0}
do_test pager-2.19 {
  pager_pagecount $::p1
} {1}
do_test pager-2.21 {
  pager_stats $::p1
} {ref 1 page 1 max 10 size 1 state 1 err 0 hit 2 miss 1 ovfl 0}
do_test pager-2.22 {
  page_unref $::g1
} {}
do_test pager-2.23 {
  pager_stats $::p1
} {ref 0 page 1 max 10 size -1 state 0 err 0 hit 2 miss 1 ovfl 0}
do_test pager-2.24 {
  set v [catch {
    page_get $::p1 1
  } ::g1]
  if {$v} {lappend v $::g1}
  set v
} {0}
do_test pager-2.25 {
  page_read $::g1
} {Page-One}
do_test pager-2.26 {
  set v [catch {
    page_write $::g1 {page-one}
  } msg]
  lappend v $msg
} {0 {}}
do_test pager-2.27 {
  page_read $::g1
} {page-one}
do_test pager-2.28 {
  set v [catch {
    pager_rollback $::p1
  } msg]
  lappend v $msg
} {0 {}}
do_test pager-2.29 {
  page_unref $::g1
  set ::g1 [page_get $::p1 1]
  page_read $::g1
} {Page-One}
do_test pager-2.99 {
  page_unref $::g1
  pager_close $::p1
} {}

do_test pager-3.1 {
  set v [catch {
    set ::p1 [pager_open ptf1.db 15]
  } msg]
  if {$v} {lappend v $msg}
  set v
} {0}
do_test pager-3.2 {
  pager_pagecount $::p1
} {1}
do_test pager-3.3 {
  set v [catch {
    set ::g(1) [page_get $::p1 1]
  } msg]
  if {$v} {lappend v $msg}
  set v
} {0}
do_test pager-3.4 {
  page_read $::g(1)
} {Page-One}
do_test pager-3.5 {
  for {set i 2} {$i<=20} {incr i} {
    set gx [page_get $::p1 $i]
    page_write $gx "Page-$i"
    page_unref $gx
  }
  pager_commit $::p1
  page_unref $::g(1)
} {}
for {set i 2} {$i<=20} {incr i} {
  do_test pager-3.6.[expr {$i-1}] [subst {
    set gx \[page_get $::p1 $i\]
    set v \[page_read \$gx\]
    page_unref \$gx
    set v
  }] "Page-$i"
}
for {set i 1} {$i<=20} {incr i} {
  regsub -all CNT {
    set ::g1 [page_get $::p1 CNT]
    set ::g2 [page_get $::p1 CNT]
    set ::vx [page_read $::g2]
    expr {$::g1==$::g2}
  } $i body;
  do_test pager-3.7.$i.1 $body {1}
  regsub -all CNT {
    page_unref $::g2
    set vy [page_read $::g1]
    expr {$vy==$::vx}
  } $i body;
  do_test pager-3.7.$i.2 $body {1}
  regsub -all CNT {
    page_unref $::g1
    set gx [page_get $::p1 CNT]
    set vy [page_read $gx]
    page_unref $gx
    expr {$vy==$::vx}
  } $i body;
  do_test pager-3.7.$i.3 $body {1}
}
do_test pager-3.99 {
  pager_close $::p1
} {}

# tests of the checkpoint mechanism and api
#
do_test pager-4.0 {
  set v [catch {
    file delete -force ptf1.db
    set ::p1 [pager_open ptf1.db 15]
  } msg]
  if {$v} {lappend v $msg}
  set v
} {0}
do_test pager-4.1 {
  set g1 [page_get $::p1 1]
  page_write $g1 "Page-1 v0"
  for {set i 2} {$i<=20} {incr i} {
    set gx [page_get $::p1 $i]
    page_write $gx "Page-$i v0"
    page_unref $gx
  }
  pager_commit $::p1
} {}
for {set i 1} {$i<=20} {incr i} {
  do_test pager-4.2.$i {
    set gx [page_get $p1 $i]
    set v [page_read $gx]
    page_unref $gx
    set v
  } "Page-$i v0"
}
do_test pager-4.3 {
  lrange [pager_stats $::p1] 0 1
} {ref 1}
do_test pager-4.4 {
  lrange [pager_stats $::p1] 8 9
} {state 1}

for {set i 1} {$i<20} {incr i} {
  do_test pager-4.5.$i.0 {
    set res {}
    for {set j 2} {$j<=20} {incr j} {
      set gx [page_get $p1 $j]
      set value [page_read $gx]
      page_unref $gx
      set shouldbe "Page-$j v[expr {$i-1}]"
      if {$value!=$shouldbe} {
        lappend res $value $shouldbe
      }
    }
    set res
  } {}
  do_test pager-4.5.$i.1 {
    page_write $g1 "Page-1 v$i"
    lrange [pager_stats $p1] 8 9
  } {state 2}
  do_test pager-4.5.$i.2 {
    for {set j 2} {$j<=20} {incr j} {
      set gx [page_get $p1 $j]
      page_write $gx "Page-$j v$i"
      page_unref $gx
      if {$j==$i} {
        pager_stmt_begin $p1
      }
    }
  } {}
  do_test pager-4.5.$i.3 {
    set res {}
    for {set j 2} {$j<=20} {incr j} {
      set gx [page_get $p1 $j]
      set value [page_read $gx]
      page_unref $gx
      set shouldbe "Page-$j v$i"
      if {$value!=$shouldbe} {
        lappend res $value $shouldbe
      }
    }
    set res
  } {}
  do_test pager-4.5.$i.4 {
    pager_rollback $p1
    set res {}
    for {set j 2} {$j<=20} {incr j} {
      set gx [page_get $p1 $j]
      set value [page_read $gx]
      page_unref $gx
      set shouldbe "Page-$j v[expr {$i-1}]"
      if {$value!=$shouldbe} {
        lappend res $value $shouldbe
      }
    }
    set res
  } {}
  do_test pager-4.5.$i.5 {
    page_write $g1 "Page-1 v$i"
    lrange [pager_stats $p1] 8 9
  } {state 2}
  do_test pager-4.5.$i.6 {
    for {set j 2} {$j<=20} {incr j} {
      set gx [page_get $p1 $j]
      page_write $gx "Page-$j v$i"
      page_unref $gx
      if {$j==$i} {
        pager_stmt_begin $p1
      }
    }
  } {}
  do_test pager-4.5.$i.7 {
    pager_stmt_rollback $p1
    for {set j 2} {$j<=20} {incr j} {
      set gx [page_get $p1 $j]
      set value [page_read $gx]
      page_unref $gx
      if {$j<=$i || $i==1} {
        set shouldbe "Page-$j v$i"
      } else {
        set shouldbe "Page-$j v[expr {$i-1}]"
      }
      if {$value!=$shouldbe} {
        lappend res $value $shouldbe
      }
    }
    set res
  } {}
  do_test pager-4.5.$i.8 {
    for {set j 2} {$j<=20} {incr j} {
      set gx [page_get $p1 $j]
      page_write $gx "Page-$j v$i"
      page_unref $gx
      if {$j==$i} {
        pager_stmt_begin $p1
      }
    }
  } {}
  do_test pager-4.5.$i.9 {
    pager_stmt_commit $p1
    for {set j 2} {$j<=20} {incr j} {
      set gx [page_get $p1 $j]
      set value [page_read $gx]
      page_unref $gx
      set shouldbe "Page-$j v$i"
      if {$value!=$shouldbe} {
        lappend res $value $shouldbe
      }
    }
    set res
  } {}
  do_test pager-4.5.$i.10 {
    pager_commit $p1
    lrange [pager_stats $p1] 8 9
  } {state 1}
}

# Test that nothing bad happens when sqlite3pager_set_cachesize() is
# called with a negative argument.
do_test pager-4.6.1 {
  pager_close [pager_open ptf2.db -15]
} {}

# Test truncate on an in-memory database is Ok.
ifcapable memorydb {
  do_test pager-4.6.2 {
    set ::p2 [pager_open :memory: 10]
    pager_truncate $::p2 0
  } {}
  do_test pager-4.6.3 {
    set page1 [page_get $::p2 1]
    for {set i 1} {$i<5} {incr i} {
      set p [page_get $::p2 $i]
      page_write $p "Page $i"
      pager_commit $::p2
      page_unref $p
    }
    page_unref $page1
    pager_truncate $::p2 3
  } {}
  do_test pager-4.6.4 {
    pager_close $::p2
  } {}
}

do_test pager-4.99 {
  page_unref $::g1
  pager_close $::p1
} {}



  file delete -force ptf1.db

} ;# end if( not mem: and has pager_open command );

if 0 {
# Ticket #615: an assertion fault inside the pager.  It is a benign
# fault, but we might as well test for it.
#
do_test pager-5.1 {
  sqlite3 db test.db
  execsql {
    BEGIN;
    CREATE TABLE t1(x);
    PRAGMA synchronous=off;
    COMMIT;
  }
} {}
}

# The following tests cover rolling back hot journal files. 
# They can't be run on windows because the windows version of 
# SQLite holds a mandatory exclusive lock on journal files it has open.
# 
# They cannot be run during the journaltest permutation because 
# "PRAGMA synchronous = 0" is used.
#
if {$tcl_platform(platform)!="windows" && (
      0 == [info exists ::permutations_test_prefix] 
   || $::permutations_test_prefix ne "journaltest"
)} {
do_test pager-6.1 {
  file delete -force test2.db
  file delete -force test2.db-journal
  sqlite3 db2 test2.db
  execsql {
    PRAGMA synchronous = 0;
    CREATE TABLE abc(a, b, c);
    INSERT INTO abc VALUES(1, 2, randstr(200,200));
    INSERT INTO abc VALUES(1, 2, randstr(200,200));
    INSERT INTO abc VALUES(1, 2, randstr(200,200));
    INSERT INTO abc VALUES(1, 2, randstr(200,200));
    INSERT INTO abc VALUES(1, 2, randstr(200,200));
    INSERT INTO abc VALUES(1, 2, randstr(200,200));
    INSERT INTO abc VALUES(1, 2, randstr(200,200));
    INSERT INTO abc VALUES(1, 2, randstr(200,200));
    INSERT INTO abc VALUES(1, 2, randstr(200,200));
    BEGIN;
    UPDATE abc SET c = randstr(200,200);
  } db2
  copy_file test2.db test.db
  copy_file test2.db-journal test.db-journal

  set f [open test.db-journal a]
  fconfigure $f -encoding binary
  seek $f [expr [file size test.db-journal] - 1032] start
  puts -nonewline $f "\00\00\00\00"
  close $f

  sqlite3 db test.db
  execsql {
    SELECT sql FROM sqlite_master
  }
} {{CREATE TABLE abc(a, b, c)}}

do_test pager-6.2 {
  copy_file test2.db test.db
  copy_file test2.db-journal test.db-journal

  set f [open test.db-journal a]
  fconfigure $f -encoding binary
  seek $f [expr [file size test.db-journal] - 1032] start
  puts -nonewline $f "\00\00\00\FF"
  close $f

  sqlite3 db test.db
  execsql {
    SELECT sql FROM sqlite_master
  }
} {{CREATE TABLE abc(a, b, c)}}

do_test pager-6.3 {
  copy_file test2.db test.db
  copy_file test2.db-journal test.db-journal

  set f [open test.db-journal a]
  fconfigure $f -encoding binary
  seek $f [expr [file size test.db-journal] - 4] start
  puts -nonewline $f "\00\00\00\00"
  close $f

  sqlite3 db test.db
  execsql {
    SELECT sql FROM sqlite_master
  }
} {{CREATE TABLE abc(a, b, c)}}

do_test pager-6.4.1 {
  execsql {
    BEGIN;
    SELECT sql FROM sqlite_master;
  }
  copy_file test2.db-journal test.db-journal;
  sqlite3 db3 test.db
  catchsql {
    BEGIN;
    SELECT sql FROM sqlite_master;
  } db3;
} {1 {database is locked}}
do_test pager-6.4.2 {
  file delete -force test.db-journal
  catchsql {
    SELECT sql FROM sqlite_master;
  } db3;
} {0 {{CREATE TABLE abc(a, b, c)}}}
do_test pager-6.4.3 {
  db3 close
  execsql {
    COMMIT;
  }
} {}

do_test pager-6.5 {
  copy_file test2.db test.db
  copy_file test2.db-journal test.db-journal

  set f [open test.db-journal a]
  fconfigure $f -encoding binary
  puts -nonewline $f "hello"
  puts -nonewline $f "\x00\x00\x00\x05\x01\x02\x03\x04"
  puts -nonewline $f "\xd9\xd5\x05\xf9\x20\xa1\x63\xd7"
  close $f

  sqlite3 db test.db
  execsql {
    SELECT sql FROM sqlite_master
  }
} {{CREATE TABLE abc(a, b, c)}}

do_test pager-6.5 {
  db2 close
} {}
}
finish_test
Deleted test/pager2.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414






























































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is page cache subsystem.
#
# $Id: pager2.test,v 1.9 2008/12/30 17:55:00 drh Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Don't run this test file if the pager test interface [pager_open] is not
# available, or the library was compiled without in-memory database support.
#
if {[info commands pager_open]!=""} {
ifcapable memorydb {
db close

# Basic sanity check.  Open and close a pager.
#
do_test pager2-1.0 {
  set v [catch {
    set ::p1 [pager_open :memory: 10]
  } msg]
} {0}
do_test pager2-1.1 {
  pager_stats $::p1
} {ref 0 page 0 max 10 size 0 state 4 err 0 hit 0 miss 0 ovfl 0}
do_test pager2-1.2 {
  pager_pagecount $::p1
} {0}
do_test pager2-1.3 {
  pager_stats $::p1
} {ref 0 page 0 max 10 size 0 state 4 err 0 hit 0 miss 0 ovfl 0}
do_test pager2-1.4 {
  pager_close $::p1
} {}

# Try to write a few pages.
#
do_test pager2-2.1 {
  set v [catch {
    set ::p1 [pager_open :memory: 10]
  } msg]
} {0}
#do_test pager2-2.2 {
#  set v [catch {
#    set ::g1 [page_get $::p1 0]
#  } msg]
#  lappend v $msg
#} {1 SQLITE_ERROR}
do_test pager2-2.3.1 {
  set ::gx [page_lookup $::p1 1]
} {}
do_test pager2-2.3.2 {
  pager_stats $::p1
} {ref 0 page 0 max 10 size 0 state 4 err 0 hit 0 miss 0 ovfl 0}
do_test pager2-2.3.3 {
  set v [catch {
    set ::g1 [page_get $::p1 1]
  } msg]
  if {$v} {lappend v $msg}
  set v
} {0}
do_test pager2-2.3.3 {
  pager_stats $::p1
} {ref 1 page 1 max 10 size 0 state 4 err 0 hit 0 miss 1 ovfl 0}
do_test pager2-2.3.4 {
  set ::gx [page_lookup $::p1 1]
  page_unref $::gx
  expr {$::gx!=""}
} {1}
do_test pager2-2.3.5 {
  pager_stats $::p1
} {ref 1 page 1 max 10 size 0 state 4 err 0 hit 0 miss 1 ovfl 0}
do_test pager2-2.3.6 {
  expr {$::g1==$::gx}
} {1}
do_test pager2-2.3.7 {
  pager_stats $::p1
} {ref 1 page 1 max 10 size 0 state 4 err 0 hit 0 miss 1 ovfl 0}
do_test pager2-2.4 {
  pager_stats $::p1
} {ref 1 page 1 max 10 size 0 state 4 err 0 hit 0 miss 1 ovfl 0}
do_test pager2-2.5 {
  pager_pagecount $::p1
} {0}
do_test pager2-2.6 {
  pager_stats $::p1
} {ref 1 page 1 max 10 size 0 state 4 err 0 hit 0 miss 1 ovfl 0}
do_test pager2-2.7 {
  page_number $::g1
} {1}
do_test pager2-2.8 {
  page_read $::g1
} {}
do_test pager2-2.9 {
  page_unref $::g1
} {}
do_test pager2-2.10 {
  pager_stats $::p1
} {ref 0 page 1 max 10 size 0 state 4 err 0 hit 0 miss 1 ovfl 0}
do_test pager2-2.11 {
  set ::g1 [page_get $::p1 1]
  expr {$::g1!=0}
} {1}
do_test pager2-2.12 {
  page_number $::g1
} {1}
do_test pager2-2.13 {
  pager_stats $::p1
} {ref 1 page 1 max 10 size 0 state 4 err 0 hit 1 miss 1 ovfl 0}
do_test pager2-2.14 {
  set v [catch {
    page_write $::g1 "Page-One"
  } msg]
  lappend v $msg
} {0 {}}
do_test pager2-2.15 {
  pager_stats $::p1
} {ref 1 page 1 max 10 size 1 state 4 err 0 hit 1 miss 1 ovfl 0}
do_test pager2-2.16 {
  page_read $::g1
} {Page-One}
do_test pager2-2.17 {
  set v [catch {
    pager_commit $::p1
  } msg]
  lappend v $msg
} {0 {}}
do_test pager2-2.20 {
  pager_stats $::p1
} {ref 1 page 1 max 10 size 1 state 4 err 0 hit 1 miss 1 ovfl 0}
do_test pager2-2.19 {
  pager_pagecount $::p1
} {1}
do_test pager2-2.21 {
  pager_stats $::p1
} {ref 1 page 1 max 10 size 1 state 4 err 0 hit 1 miss 1 ovfl 0}
do_test pager2-2.22 {
  page_unref $::g1
} {}
do_test pager2-2.23 {
  pager_stats $::p1
} {ref 0 page 1 max 10 size 1 state 4 err 0 hit 1 miss 1 ovfl 0}
do_test pager2-2.24 {
  set v [catch {
    page_get $::p1 1
  } ::g1]
  if {$v} {lappend v $::g1}
  set v
} {0}
do_test pager2-2.25 {
  page_read $::g1
} {Page-One}
do_test pager2-2.26 {
  set v [catch {
    page_write $::g1 {page-one}
  } msg]
  lappend v $msg
} {0 {}}
do_test pager2-2.27 {
  page_read $::g1
} {page-one}
do_test pager2-2.28 {
  set v [catch {
    pager_rollback $::p1
  } msg]
  lappend v $msg
} {0 {}}
do_test pager2-2.29 {
  page_unref $::g1
  set ::g1 [page_get $::p1 1]
  page_read $::g1
} {Page-One}
do_test pager2-2.99 {
  page_unref $::g1
} {}

#do_test pager2-3.1 {
#  set v [catch {
#    set ::p1 [pager_open :memory: 15]
#  } msg]
#  if {$v} {lappend v $msg}
#  set v
#} {0}
do_test pager2-3.2 {
  pager_pagecount $::p1
} {1}
do_test pager2-3.3 {
  set v [catch {
    set ::g(1) [page_get $::p1 1]
  } msg]
  if {$v} {lappend v $msg}
  set v
} {0}
do_test pager2-3.4 {
  page_read $::g(1)
} {Page-One}
do_test pager2-3.5 {
  for {set i 2} {$i<=20} {incr i} {
    set gx [page_get $::p1 $i]
    page_write $gx "Page-$i"
    page_unref $gx
  }
  pager_commit $::p1
  page_unref $::g(1)
} {}
for {set i 2} {$i<=20} {incr i} {
  set page1 [page_get $::p1 1]
  do_test pager2-3.6.[expr {$i-1}] [subst {
    set gx \[page_get $::p1 $i\]
    set v \[page_read \$gx\]
    page_unref \$gx
    set v
  }] "Page-$i"
  page_unref $page1
}
for {set i 1} {$i<=20} {incr i} {
  set page1 [page_get $::p1 1]
  regsub -all CNT {
    set ::g1 [page_get $::p1 CNT]
    set ::g2 [page_get $::p1 CNT]
    set ::vx [page_read $::g2]
    expr {$::g1==$::g2}
  } $i body;
  do_test pager2-3.7.$i.1 $body {1}
  regsub -all CNT {
    page_unref $::g2
    set vy [page_read $::g1]
    expr {$vy==$::vx}
  } $i body;
  do_test pager2-3.7.$i.2 $body {1}
  regsub -all CNT {
    page_unref $::g1
    set gx [page_get $::p1 CNT]
    set vy [page_read $gx]
    page_unref $gx
    expr {$vy==$::vx}
  } $i body;
  do_test pager2-3.7.$i.3 $body {1}
  page_unref $page1
}
do_test pager2-3.99 {
  pager_close $::p1
} {}

# tests of the checkpoint mechanism and api
#
do_test pager2-4.0 {
  set v [catch {
    set ::p1 [pager_open :memory: 15]
  } msg]
  if {$v} {lappend v $msg}
  set v
} {0}
do_test pager2-4.1 {
  set g1 [page_get $::p1 1]
  page_write $g1 "Page-1 v0"
  for {set i 2} {$i<=20} {incr i} {
    set gx [page_get $::p1 $i]
    page_write $gx "Page-$i v0"
    page_unref $gx
  }
  pager_commit $::p1
} {}
for {set i 1} {$i<=20} {incr i} {
  do_test pager2-4.2.$i {
    set gx [page_get $p1 $i]
    set v [page_read $gx]
    page_unref $gx
    set v
  } "Page-$i v0"
}
do_test pager2-4.3 {
  lrange [pager_stats $::p1] 0 1
} {ref 1}
do_test pager2-4.4 {
  lrange [pager_stats $::p1] 8 9
} {state 4}

for {set i 1} {$i<20} {incr i} {
  do_test pager2-4.5.$i.0 {
    set res {}
    for {set j 2} {$j<=20} {incr j} {
      set gx [page_get $p1 $j]
      set value [page_read $gx]
      page_unref $gx
      set shouldbe "Page-$j v[expr {$i-1}]"
      if {$value!=$shouldbe} {
        lappend res $value $shouldbe
      }
    }
    set res
  } {}
  do_test pager2-4.5.$i.1 {
    page_write $g1 "Page-1 v$i"
    lrange [pager_stats $p1] 8 9
  } {state 4}
  do_test pager2-4.5.$i.2 {
    for {set j 2} {$j<=20} {incr j} {
      set gx [page_get $p1 $j]
      page_write $gx "Page-$j v$i"
      page_unref $gx
      if {$j==$i} {
        pager_stmt_begin $p1
      }
    }
  } {}
  do_test pager2-4.5.$i.3 {
    set res {}
    for {set j 2} {$j<=20} {incr j} {
      set gx [page_get $p1 $j]
      set value [page_read $gx]
      page_unref $gx
      set shouldbe "Page-$j v$i"
      if {$value!=$shouldbe} {
        lappend res $value $shouldbe
      }
    }
    set res
  } {}
  do_test pager2-4.5.$i.4 {
    pager_rollback $p1
    set res {}
    for {set j 2} {$j<=20} {incr j} {
      set gx [page_get $p1 $j]
      set value [page_read $gx]
      page_unref $gx
      set shouldbe "Page-$j v[expr {$i-1}]"
      if {$value!=$shouldbe} {
        lappend res $value $shouldbe
      }
    }
    set res
  } {}
  do_test pager2-4.5.$i.5 {
    page_write $g1 "Page-1 v$i"
    lrange [pager_stats $p1] 8 9
  } {state 4}
  do_test pager2-4.5.$i.6 {
    for {set j 2} {$j<=20} {incr j} {
      set gx [page_get $p1 $j]
      page_write $gx "Page-$j v$i"
      page_unref $gx
      if {$j==$i} {
        pager_stmt_begin $p1
      }
    }
  } {}
  do_test pager2-4.5.$i.7 {
    pager_stmt_rollback $p1
    for {set j 2} {$j<=20} {incr j} {
      set gx [page_get $p1 $j]
      set value [page_read $gx]
      page_unref $gx
      if {$j<=$i || $i==1} {
        set shouldbe "Page-$j v$i"
      } else {
        set shouldbe "Page-$j v[expr {$i-1}]"
      }
      if {$value!=$shouldbe} {
        lappend res $value $shouldbe
      }
    }
    set res
  } {}
  do_test pager2-4.5.$i.8 {
    for {set j 2} {$j<=20} {incr j} {
      set gx [page_get $p1 $j]
      page_write $gx "Page-$j v$i"
      page_unref $gx
      if {$j==$i} {
        pager_stmt_begin $p1
      }
    }
  } {}
  do_test pager2-4.5.$i.9 {
    pager_stmt_commit $p1
    for {set j 2} {$j<=20} {incr j} {
      set gx [page_get $p1 $j]
      set value [page_read $gx]
      page_unref $gx
      set shouldbe "Page-$j v$i"
      if {$value!=$shouldbe} {
        lappend res $value $shouldbe
      }
    }
    set res
  } {}
  do_test pager2-4.5.$i.10 {
    pager_commit $p1
    lrange [pager_stats $p1] 8 9
  } {state 4}
}

do_test pager2-4.99 {
  page_unref $::g1
  pager_close $::p1
} {}

} ;# ifcapable inmemory
} ;# end if( has pager_open command );


finish_test
Deleted test/pager3.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73









































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is page cache subsystem.
#
# $Id: pager3.test,v 1.3 2005/03/29 03:11:00 danielk1977 Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl

# This test makes sure the database file is truncated back to the correct
# length on a rollback.
#
# After some preliminary setup, a transaction is start at NOTE (1).
# The create table on the following line allocates an additional page
# at the end of the database file.  But that page is not written because
# the database still has a RESERVED lock, not an EXCLUSIVE lock.  The
# new page is held in memory and the size of the file is unchanged.
# The insert at NOTE (2) begins adding additional pages.  Then it hits
# a constraint error and aborts.  The abort causes sqlite3OsTruncate()
# to be called to restore the file to the same length as it was after
# the create table.  But the create table results had not yet been
# written so the file is actually lengthened by this truncate.  Finally,
# the rollback at NOTE (3) is called to undo all the changes since the
# begin.  This rollback should truncate the database again.
# 
# This test was added because the second truncate at NOTE (3) was not
# occurring on early versions of SQLite 3.0.
#
ifcapable tempdb {
  do_test pager3-1.1 {
    execsql {
      create table t1(a unique, b);
      insert into t1 values(1, 'abcdefghijklmnopqrstuvwxyz');
      insert into t1 values(2, 'abcdefghijklmnopqrstuvwxyz');
      update t1 set b=b||a||b;
      update t1 set b=b||a||b;
      update t1 set b=b||a||b;
      update t1 set b=b||a||b;
      update t1 set b=b||a||b;
      update t1 set b=b||a||b;
      create temp table t2 as select * from t1;
      begin;                  ------- NOTE (1)
      create table t3(x);
    }
    catchsql {
      insert into t1 select 4-a, b from t2;  ----- NOTE (2)
    }
    execsql {
      rollback;  ------- NOTE (3)
    }
    db close
    sqlite3 db test.db
    set r ok
    ifcapable {integrityck} {
      set r [execsql {
        pragma integrity_check;
      }]
    }
    set r
  } ok
}

finish_test
Changes to test/pcache2.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21













-
+







# 2008 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file is focused on testing the pcache module.
#
# $Id: pcache2.test,v 1.3 2008/11/13 16:21:50 danielk1977 Exp $
# $Id: pcache2.test,v 1.5 2009/07/18 14:36:24 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl


# Set up a pcache memory pool so that we can easily track how many
# pages are being used for cache.
41
42
43
44
45
46
47

48
49
50
51
52
53
54
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55







+







} {2}
do_test pcache2-1.3 {
  file delete -force test2.db test2.db-journal
  sqlite3 db2 test2.db
  db2 eval {PRAGMA cache_size=50}
  lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 1
} {4}


# Make lots of changes on the first connection.  Verify that the
# page cache usage does not grow to consume the page space set aside
# for the second connection.
#
do_test pcache2-1.4 {
  db eval {
Changes to test/permutations.test.
1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19











-
+







# 2008 June 21
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# $Id: permutations.test,v 1.50 2009/05/13 14:46:10 danielk1977 Exp $
# $Id: permutations.test,v 1.51 2009/07/01 18:09:02 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Argument processing.
#
#puts "PERM-DEBUG: argv=$argv"
479
480
481
482
483
484
485
486


487
488
489
490
491
492







493
494
495
496
497
498
499
479
480
481
482
483
484
485

486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507







-
+
+






+
+
+
+
+
+
+







    Run tests using the allocator in mem3.c.
  } -exclude {
    autovacuum.test           delete3.test              manydb.test
    bigrow.test               incrblob2.test            memdb.test
    bitvec.test               index2.test               memsubsys1.test
    capi3c.test               ioerr.test                memsubsys2.test
    capi3.test                join3.test                pagesize.test
    collate5.test             limit.test
    collate5.test             limit.test                backup_ioerr.test
    backup_malloc.test
  } -initialize {
    catch {db close}
    sqlite3_reset_auto_extension
    sqlite3_shutdown
    sqlite3_config_heap 25000000 0
    sqlite3_config_lookaside 0 0
    ifcapable mem5 {
      # If both memsys3 and memsys5 are enabled in the build, the call to
      # [sqlite3_config_heap] will initialize the system to use memsys5.
      # The following overrides this preference and installs the memsys3
      # allocator.
      sqlite3_install_memsys3
    }
    install_malloc_faultsim 1 
    sqlite3_initialize
    autoinstall_test_functions
  } -shutdown {
    catch {db close}
    sqlite3_shutdown
    sqlite3_config_heap 0 0
Changes to test/pragma.test.
529
530
531
532
533
534
535
536

537
538
539
540
541
542
543
529
530
531
532
533
534
535

536
537
538
539
540
541
542
543







-
+







db nullvalue {}
ifcapable {foreignkey} {
  do_test pragma-6.3.1 {
    execsql {
      CREATE TABLE t3(a int references t2(b), b UNIQUE);
      pragma foreign_key_list(t3);
    }
  } {0 0 t2 a b RESTRICT RESTRICT NONE}
  } {0 0 t2 a b {NO ACTION} {NO ACTION} NONE}
  do_test pragma-6.3.2 {
    execsql {
      pragma foreign_key_list;
    }
  } {}
  do_test pragma-6.3.3 {
    execsql {
Changes to test/quick.test.
54
55
56
57
58
59
60

61
62
63
64
65
66
67
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68







+







  crash3.test
  crash4.test
  crash5.test
  crash6.test
  crash7.test
  delete3.test
  fts3.test
  fkey_malloc.test
  fuzz.test
  fuzz3.test
  fuzz_malloc.test
  in2.test
  loadext.test
  memleak.test
  misc7.test
Changes to test/savepoint.test.
1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19











-
+







# 2008 December 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# $Id: savepoint.test,v 1.12 2009/02/04 10:09:04 danielk1977 Exp $
# $Id: savepoint.test,v 1.13 2009/07/18 08:30:45 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl


#----------------------------------------------------------------------
# The following tests - savepoint-1.* - test that the SAVEPOINT, RELEASE
265
266
267
268
269
270
271

272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331





























































332
333
334
335
336
337
338
265
266
267
268
269
270
271
272




























































273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340







+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







  execsql COMMIT
} {}

#------------------------------------------------------------------------
# Test some logic errors to do with the savepoint feature.
# 

ifcapable incrblob {
do_test savepoint-5.1.1 {
  execsql {
    CREATE TABLE blobs(x);
    INSERT INTO blobs VALUES('a twentyeight character blob');
  }
  set fd [db incrblob blobs x 1]
  puts -nonewline $fd "hello"
  catchsql {SAVEPOINT abc}
} {1 {cannot open savepoint - SQL statements in progress}}
do_test savepoint-5.1.2 {
  close $fd
  catchsql {SAVEPOINT abc}
} {0 {}}

do_test savepoint-5.2 {
  execsql  {RELEASE abc}
  catchsql {RELEASE abc}
} {1 {no such savepoint: abc}}

do_test savepoint-5.3.1 {
  execsql  {SAVEPOINT abc}
  catchsql {ROLLBACK TO def}
} {1 {no such savepoint: def}}
do_test savepoint-5.3.2 {
  execsql  {SAVEPOINT def}
  set fd [db incrblob -readonly blobs x 1]
  catchsql {ROLLBACK TO def}
} {1 {cannot rollback savepoint - SQL statements in progress}}
do_test savepoint-5.3.3 {
  catchsql  {RELEASE def}
} {0 {}}
do_test savepoint-5.3.4 {
  close $fd
  execsql  {savepoint def}
  set fd [db incrblob blobs x 1]
  catchsql {release def}
} {1 {cannot release savepoint - SQL statements in progress}}
do_test savepoint-5.3.5 {
  close $fd
  execsql {release abc}
} {}

do_test savepoint-5.4.1 {
  execsql {
    SAVEPOINT main;
    INSERT INTO blobs VALUES('another blob');
  }
} {}
do_test savepoint-5.4.2 {
  sqlite3 db2 test.db
  execsql { BEGIN ; SELECT * FROM blobs } db2
  catchsql { RELEASE main }
} {1 {database is locked}}
do_test savepoint-5.4.3 {
  db2 close
  catchsql { RELEASE main }
} {0 {}}
do_test savepoint-5.4.4 {
  execsql { SELECT x FROM blobs WHERE rowid = 2 }
} {{another blob}}
  do_test savepoint-5.1.1 {
    execsql {
      CREATE TABLE blobs(x);
      INSERT INTO blobs VALUES('a twentyeight character blob');
    }
    set fd [db incrblob blobs x 1]
    puts -nonewline $fd "hello"
    catchsql {SAVEPOINT abc}
  } {1 {cannot open savepoint - SQL statements in progress}}
  do_test savepoint-5.1.2 {
    close $fd
    catchsql {SAVEPOINT abc}
  } {0 {}}
  
  do_test savepoint-5.2 {
    execsql  {RELEASE abc}
    catchsql {RELEASE abc}
  } {1 {no such savepoint: abc}}
  
  do_test savepoint-5.3.1 {
    execsql  {SAVEPOINT abc}
    catchsql {ROLLBACK TO def}
  } {1 {no such savepoint: def}}
  do_test savepoint-5.3.2 {
    execsql  {SAVEPOINT def}
    set fd [db incrblob -readonly blobs x 1]
    catchsql {ROLLBACK TO def}
  } {1 {cannot rollback savepoint - SQL statements in progress}}
  do_test savepoint-5.3.3 {
    catchsql  {RELEASE def}
  } {0 {}}
  do_test savepoint-5.3.4 {
    close $fd
    execsql  {savepoint def}
    set fd [db incrblob blobs x 1]
    catchsql {release def}
  } {1 {cannot release savepoint - SQL statements in progress}}
  do_test savepoint-5.3.5 {
    close $fd
    execsql {release abc}
  } {}
  
  do_test savepoint-5.4.1 {
    execsql {
      SAVEPOINT main;
      INSERT INTO blobs VALUES('another blob');
    }
  } {}
  do_test savepoint-5.4.2 {
    sqlite3 db2 test.db
    execsql { BEGIN ; SELECT * FROM blobs } db2
    catchsql { RELEASE main }
  } {1 {database is locked}}
  do_test savepoint-5.4.3 {
    db2 close
    catchsql { RELEASE main }
  } {0 {}}
  do_test savepoint-5.4.4 {
    execsql { SELECT x FROM blobs WHERE rowid = 2 }
  } {{another blob}}
}

#-------------------------------------------------------------------------
# The following tests, savepoint-6.*, test an incr-vacuum inside of a
# couple of nested savepoints.
#
ifcapable {autovacuum && pragma} {
  db close
Changes to test/schema.test.
359
360
361
362
363
364
365




















366
367
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



  # The schema cookie now has the same value as it did when SQL statement
  # $::STMT was prepared. So unless it has been expired, it would be
  # possible to run the "CREATE TABLE t4" statement and create a
  # duplicate table.
  list [sqlite3_step $::STMT] [sqlite3_finalize $::STMT]
} {SQLITE_ERROR SQLITE_SCHEMA}

do_test schema-13.1 {
  set S [sqlite3_prepare_v2 db "SELECT * FROM sqlite_master" -1 dummy]
  db function hello hello
  db function hello {}
  db auth auth
  proc auth {args} {
    if {[lindex $args 0] == "SQLITE_READ"} {return SQLITE_DENY}
    return SQLITE_OK
  }
  sqlite3_step $S
} {SQLITE_SCHEMA}

do_test schema-13.2 {
  sqlite3_step $S
} {SQLITE_SCHEMA}

do_test schema-13.3 {
  sqlite3_finalize $S
} {SQLITE_SCHEMA}

finish_test
Changes to test/selectC.test.
147
148
149
150
151
152
153

154
155
156
157
158
159
160
161
162
163
164
165













166
167
147
148
149
150
151
152
153
154












155
156
157
158
159
160
161
162
163
164
165
166
167
168
169







+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+


      FROM t1
     ORDER BY x DESC
  }
} {CCC AAA AAA}

# The following query used to leak memory.  Verify that has been fixed.
#
ifcapable trigger {
do_test selectC-2.1 {
  catchsql {
    CREATE TABLE t21a(a,b);
    INSERT INTO t21a VALUES(1,2);
    CREATE TABLE t21b(n);
    CREATE TRIGGER r21 AFTER INSERT ON t21b BEGIN
      SELECT a FROM t21a WHERE a>new.x UNION ALL
      SELECT b FROM t21a WHERE b>new.x ORDER BY 1 LIMIT 2;
    END;
    INSERT INTO t21b VALUES(6);
  }
} {1 {no such column: new.x}}
  do_test selectC-2.1 {
    catchsql {
      CREATE TABLE t21a(a,b);
      INSERT INTO t21a VALUES(1,2);
      CREATE TABLE t21b(n);
      CREATE TRIGGER r21 AFTER INSERT ON t21b BEGIN
        SELECT a FROM t21a WHERE a>new.x UNION ALL
        SELECT b FROM t21a WHERE b>new.x ORDER BY 1 LIMIT 2;
      END;
      INSERT INTO t21b VALUES(6);
    }
  } {1 {no such column: new.x}}
}

finish_test
Added test/sharedlock.test.























































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 July 2
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# $Id: sharedlock.test,v 1.1 2009/07/02 17:21:58 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
db close

ifcapable !shared_cache {
  finish_test
  return
}

set ::enable_shared_cache [sqlite3_enable_shared_cache 1]
sqlite3 db  test.db
sqlite3 db2 test.db

do_test sharedlock-1.1 {
  execsql {
    CREATE TABLE t1(a, b);
    INSERT INTO t1 VALUES(1, 'one');
    INSERT INTO t1 VALUES(2, 'two');
  }
} {}

do_test sharedlock-1.2 {
  set res [list]
  db eval { SELECT * FROM t1 ORDER BY rowid } {
    lappend res $a $b
    if {$a == 1} { catch { db  eval "INSERT INTO t1 VALUES(3, 'three')" } }

    # This should fail. Connection [db] has a read-lock on t1, which should
    # prevent connection [db2] from obtaining the write-lock it needs to
    # modify t1. At one point there was a bug causing the previous INSERT
    # to drop the read-lock belonging to [db].
    if {$a == 2} { catch { db2 eval "INSERT INTO t1 VALUES(4, 'four')"  } }
  }
  set res
} {1 one 2 two 3 three}

db close
db2 close

sqlite3_enable_shared_cache $::enable_shared_cache
finish_test

Changes to test/speed3.test.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







#    May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The 
# focus of this script is testing that the overflow-page related
# enhancements added after version 3.3.17 speed things up.
#
# $Id: speed3.test,v 1.5 2007/10/09 08:29:33 danielk1977 Exp $
# $Id: speed3.test,v 1.6 2009/07/09 02:48:24 shane Exp $
#

#---------------------------------------------------------------------
# Test plan:
#
# If auto-vacuum is enabled for the database, the following cases
# should show performance improvement with respect to 3.3.17.
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
101
102
103
104
105
106
107












108
109
110
111
112
113
114







-
-
-
-
-
-
-
-
-
-
-
-







  db_leave db
# puts "1: [array get stats1]"
# puts "2: [array get stats2]"
  puts "Incrvacuum: Read $stats1(read), wrote $stats1(write)"
  puts "Normal    : Read $stats2(read), wrote $stats2(write)"
}

proc overflow_report {db} {
  set bt [btree_from_db db]
  set csr [btree_cursor $bt 3 0]

  for {btree_first $csr} {![btree_eof $csr]} {btree_next $csr} {
    puts "[btree_ovfl_info $bt $csr]"
  }

  btree_close_cursor $csr
  
}

proc reset_db {} {
  db close
  sqlite3 db test.db
  db eval { 
    PRAGMA main.cache_size = 200000;
    PRAGMA main.auto_vacuum = 'incremental';
    ATTACH 'test2.db' AS 'aux'; 
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164
165
166

167
168
169
170
171
172







-










-






    PRAGMA aux.auto_vacuum;
  }
} {2 0}

# Delete all content in a table, one row at a time.
#
#io_log db
#overflow_report db
reset_db
speed_trial speed3-1.incrvacuum $::NROW row {DELETE FROM main.t1 WHERE 1}
speed_trial speed3-1.normal     $::NROW row {DELETE FROM aux.t1 WHERE 1}
io_log db

# Select the "C" column (located at the far end of the overflow 
# chain) from each table row.
#
#db eval {PRAGMA incremental_vacuum(500000)}
populate_t1 db
#overflow_report db
reset_db
speed_trial speed3-2.incrvacuum $::NROW row {SELECT c FROM main.t1}
speed_trial speed3-2.normal     $::NROW row {SELECT c FROM aux.t1}
io_log db

finish_test
Changes to test/tableapi.test.
8
9
10
11
12
13
14
15

16
17
18





19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42


43
44
45
46
47
48
49







-
+



+
+
+
+
+



















-
-







#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the sqlite_exec_printf() and
# sqlite_get_table_printf() APIs.
#
# $Id: tableapi.test,v 1.20 2008/07/31 02:05:05 shane Exp $
# $Id: tableapi.test,v 1.21 2009/07/17 14:37:25 shane Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !gettable {
  finish_test
  return
}

ifcapable memdebug {
  source $testdir/malloc_common.tcl
}

do_test tableapi-1.0 {
  set ::dbx [sqlite3_open test.db]
  catch {sqlite_exec_printf $::dbx {DROP TABLE xyz} {}}
  sqlite3_exec_printf $::dbx {CREATE TABLE %s(a int, b text)} xyz
} {0 {}}
do_test tableapi-1.1 {
  sqlite3_exec_printf $::dbx {
    INSERT INTO xyz VALUES(1,'%q')
  } {Hi Y'all}
} {0 {}}
do_test tableapi-1.2 {
  sqlite3_exec_printf $::dbx {SELECT * FROM xyz} {}
} {0 {a b 1 {Hi Y'all}}}

ifcapable gettable {

do_test tableapi-2.1 {
  sqlite3_get_table_printf $::dbx {
    BEGIN TRANSACTION;
    SELECT * FROM xyz WHERE b='%q'
  } {Hi Y'all}
} {0 1 2 a b 1 {Hi Y'all}}
do_test tableapi-2.2 {
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
113
114
115
116
117
118
119



120
121
122
123
124
125
126







-
-
-







  }
} {0 3 2 a b 52 NULL 50 (50) 42 (42)}
do_test tableapi-2.7 {
  sqlite3_get_table_printf $::dbx {
    SELECT * FROM xyz WHERE a>1000
  } {}
} {0 0 0}

}; # end ifcapable gettable


# Repeat all tests with the empty_result_callbacks pragma turned on
#
do_test tableapi-3.1 {
  sqlite3_get_table_printf $::dbx {
    ROLLBACK;
    PRAGMA empty_result_callbacks = ON;
Changes to test/tclsqlite.test.
565
566
567
568
569
570
571



572
573
574
575
576
577
578
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581







+
+
+







} {1}
do_test tcl-11.2 {
  db exists {SELECT 0 FROM t4 WHERE x==6}
} {1}
do_test tcl-11.3 {
  db exists {SELECT 1 FROM t4 WHERE x==8}
} {0}
do_test tcl-11.3.1 {
  tcl_objproc db exists {SELECT 1 FROM t4 WHERE x==8}
} {0}

do_test tcl-12.1 {
  unset -nocomplain a b c version
  set version [db version]
  scan $version "%d.%d.%d" a b c
  expr $a*1000000 + $b*1000 + $c
} [sqlite3_libversion_number]
Changes to test/tester.tcl.
953
954
955
956
957
958
959














960
961
962
963
964
965
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979







+
+
+
+
+
+
+
+
+
+
+
+
+
+






    set t [open $to w]
    fconfigure $t -translation binary
    puts -nonewline $t [read $f [file size $from]]
    close $t
    close $f
  }
}

# Drop all tables in database [db]
proc drop_all_tables {{db db}} {
  set pk [$db one "PRAGMA foreign_keys"]
  $db eval "PRAGMA foreign_keys = OFF"
  foreach {t type} [$db eval {
    SELECT name, type FROM sqlite_master 
    WHERE type IN('table', 'view') AND name NOT like 'sqlite_%'
  }] {
    $db eval "DROP $type $t"
  }
  $db eval " PRAGMA foreign_keys = $pk "
}


# If the library is compiled with the SQLITE_DEFAULT_AUTOVACUUM macro set
# to non-zero, then set the global variable $AUTOVACUUM to 1.
set AUTOVACUUM $sqlite_options(default_autovacuum)

source $testdir/thread_common.tcl
Changes to test/thread2.test.
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206

207
208
209
210
211



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233



234
235
236
237
238
239
240
188
189
190
191
192
193
194



195
196
197
198
199
200
201
202
203
204
205
206
207


208
209
210
211
212
213
214
215
216
217
218
219
220



221
222
223
224
225
226
227


228
229
230
231
232
233
234
235
236
237







-
-
-









+



-
-
+
+
+










-
-
-







-
-
+
+
+








do_test thread2-3.20 {
  thread_create A test.db
  thread_compile A {SELECT a FROM t1 LIMIT 3}
  thread_step A
  set STMT [thread_stmt_get A]
  set DB [thread_db_get A]
  thread_halt A
} {}
do_test thread2-3.21 {
  sqlite3_step $STMT
} SQLITE_ROW
do_test thread2-3.22 {
  sqlite3_column_int $STMT 0
} 2
do_test thread2-3.23 {
  # The unlock fails here.  But because we never check the return
  # code from sqlite3OsUnlock (because we cannot do anything about it
  # if it fails) we do not realize that an error has occurred.
  breakpoint
  sqlite3_finalize $STMT
} SQLITE_OK
do_test thread2-3.25 {
  sqlite3_close $DB
} SQLITE_OK
  thread_db_put A $DB
  thread_halt A
} {}

do_test thread2-3.30 {
  thread_create A test.db
  thread_compile A {BEGIN}
  thread_step A
  thread_finalize A
  thread_compile A {SELECT a FROM t1 LIMIT 1}
  thread_step A
  thread_finalize A
  set DB [thread_db_get A]
  thread_halt A
} {}
do_test thread2-3.31 {
  set STMT [sqlite3_prepare $DB {INSERT INTO t1 VALUES(99,'error')} -1 TAIL]
  sqlite3_step $STMT
} SQLITE_ERROR
do_test thread2-3.32 {
  sqlite3_finalize $STMT
} SQLITE_MISUSE
do_test thread2-3.33 {
  sqlite3_close $DB
} SQLITE_OK
  thread_db_put A $DB
  thread_halt A
} {}

# VERY important to set the override flag back to its true value.
#
set threadsOverrideEachOthersLocks $orig_threadOverride

# Also important to halt the worker threads, which are using spin
# locks and eating away CPU cycles.
Added test/tkt-2ea2425d34.test.































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 September 2
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests to verify that ticket [2ea2425d34be] has been
# fixed.  
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test tkt-2ea24-1.1 {
  db eval {
    PRAGMA encoding=UTF16;
    CREATE TABLE t1(a,b);
    INSERT INTO t1 VALUES(1,'abc');
    INSERT INTO t1 VALUES(2,'def');
    INSERT INTO t1 VALUES(3,'ghi');
    SELECT a FROM t1 WHERE length(b)<10 AND b<>'def' ORDER BY a;
  }
} {1 3}

finish_test
Added test/tkt-3fe897352e.test.





















































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 October 23
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests to verify that ticket [3fe897352e8d8] has been
# fixed.  
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test tkt-3fe89-1.1 {
  db close
  sqlite3 db :memory:
  db eval {
    PRAGMA encoding=UTF8;
    CREATE TABLE t1(x);
    INSERT INTO t1 VALUES(hex_to_utf16be('D800'));
    SELECT hex(x) FROM t1;
  }
} {EDA080}
do_test tkt-3fe89-1.2 {
  db eval {
    DELETE FROM t1;
    INSERT INTO t1 VALUES(hex_to_utf16le('00D8'));
    SELECT hex(x) FROM t1;
  }
} {EDA080}
do_test tkt-3fe89-1.3 {
  db eval {
    DELETE FROM t1;
    INSERT INTO t1 VALUES(hex_to_utf16be('DFFF'));
    SELECT hex(x) FROM t1;
  }
} {EDBFBF}
do_test tkt-3fe89-1.4 {
  db eval {
    DELETE FROM t1;
    INSERT INTO t1 VALUES(hex_to_utf16le('FFDF'));
    SELECT hex(x) FROM t1;
  }
} {EDBFBF}


finish_test
Added test/tkt-4a03edc4c8.test.














































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 September 23
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests to verify that
# ticket [4a03edc4c8c028c93e9269f64fc5e97f632c1166] has been fixed.  
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test tkt-4a03ed-1.1 {
  db eval {
    CREATE TABLE t1(
      a INTEGER PRIMARY KEY ON CONFLICT REPLACE,
      b UNIQUE ON CONFLICT FAIL
    );
    INSERT INTO t1 VALUES(1, 1);
    INSERT INTO t1 VALUES(2, 2);
  }
  catchsql {
    BEGIN;
      INSERT INTO t1 VALUES(1, 2);
    COMMIT;
  }
} {1 {column b is not unique}}
do_test tkt-4a03ed-1.2 {
  db eval {
    PRAGMA integrity_check;
  }
} {ok}
do_test tkt-4a03ed-1.3 {
  db eval {
    SELECT * FROM t1 ORDER BY a;
  }
} {1 1 2 2}

finish_test
Added test/tkt-5ee23731f.test.










































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 October 13
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests to verify that ticket [5ee23731f15] has been
# fixed.  
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test tkt-5ee237-1.1 {
  db close
  file delete -force test.db
  sqlite3 db test.db
  db eval {
    CREATE TABLE t1(x UNIQUE);
    INSERT INTO t1 VALUES(1);
    INSERT INTO t1 VALUES(2);
    INSERT INTO t1 SELECT x+2 FROM t1;
    INSERT INTO t1 SELECT x+4 FROM t1;
    INSERT INTO t1 SELECT x+8 FROM t1;
  }
  db close
  sqlite3 db test.db -readonly 1
  set rc [catch {
    db eval {SELECT rowid, x FROM t1 ORDER BY x} {
      db eval {UPDATE t1 SET x=x+1 WHERE rowid=:rowid}
    }
  } msg]
  lappend rc $msg
} {1 {attempt to write a readonly database}}

finish_test
Added test/tkt-94c04eaadb.test.








































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 October 19
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

if {[info commands sqlite3async_initialize] eq ""} {
  # The async logic is not built into this system
  finish_test
  return
}

# Create a database.
do_test tkt-94c94-1.1 {
  execsql { CREATE TABLE t1(a, b) }
} {}

# Grow the file to larger than 4096MB (2^32 bytes)
db close
if {[catch {fake_big_file 4096 [pwd]/test.db} msg]} {
  puts "**** Unable to create a file larger than 4096 MB. *****"
  finish_test
  return
}

# Switch to async mode.
sqlite3async_initialize "" 1
sqlite3 db test.db
sqlite3 db2 test.db

# Read from and write to the db just past the 4096MB mark.
#
do_test tkt-94c94-2.1 {
  execsql { CREATE TABLE t2(x, y) } db
} {}
do_test tkt-94c94-2.2 {
breakpoint
  execsql { INSERT INTO t2 VALUES(1, 2) } db2
} {}
do_test tkt-94c94-2.3 {
  execsql { SELECT * FROM t2 } db
} {1 2}
do_test tkt-94c94-2.4 {
  sqlite3async_control halt idle
  sqlite3async_start
  sqlite3async_wait
} {}
do_test tkt-94c94-2.5 {
  execsql { SELECT * FROM t2 } db
} {1 2}
do_test tkt-94c94-2.6 {
  sqlite3async_start
  sqlite3async_wait
} {}

db close
db2 close
sqlite3async_start
sqlite3async_wait
sqlite3async_shutdown

finish_test
Added test/tkt-d82e3f3721.txt.















































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 September 2
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests to verify that ticket [d82e3f3721] has been
# fixed.  
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test tkt-d82e3-1.1 {
  db eval {
    CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
    INSERT INTO t1 VALUES(null,'abc');
    INSERT INTO t1 VALUES(null,'def');
    DELETE FROM t1;
    INSERT INTO t1 VALUES(null,'ghi');
    SELECT * FROM t1;
  }
} {3 ghi}
do_test tkt-d82e3-1.2 {
  db eval {
    CREATE TEMP TABLE t2(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
    INSERT INTO t2 VALUES(null,'jkl');
    INSERT INTO t2 VALUES(null,'mno');
    DELETE FROM t2;
    INSERT INTO t2 VALUES(null,'pqr');
    SELECT * FROM t2;
  }
} {3 pqr}
do_test tkt-d82e3-1.3 {
  db eval {
    SELECT 'main', * FROM main.sqlite_sequence
    UNION ALL
    SELECT 'temp', * FROM temp.sqlite_sequence
    ORDER BY 2
  }
} {main t1 3 temp t2 3}
do_test tkt-d82e3-1.4 {
  db eval {
    VACUUM;
    SELECT 'main', * FROM main.sqlite_sequence
    UNION ALL
    SELECT 'temp', * FROM temp.sqlite_sequence
    ORDER BY 2
  }
} {main t1 3 temp t2 3}

sqlite3 db2 test.db
do_test tkt-d82e3-2.1 {
  db eval {
    CREATE TEMP TABLE t3(x);
    INSERT INTO t3 VALUES(1);
  }
  db2 eval {
    CREATE TABLE t3(y,z);
    INSERT INTO t3 VALUES(8,9);
  }
  db eval {
    SELECT * FROM temp.t3 JOIN main.t3;
  }
} {1 8 9}
do_test tkt-d82e3-2.2 {
  db eval {
    VACUUM;
    SELECT * FROM temp.t3 JOIN main.t3;
  }
} {1 8 9}

finish_test
Added test/tkt-f777251dc7a.test.



































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 October 16
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests to verify that ticket [f777251dc7a] has been
# fixed.  
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test tkt-f7772-1.1 {
  execsql {
     CREATE TEMP TABLE t1(x UNIQUE);
     INSERT INTO t1 VALUES(1);
     CREATE TABLE t2(x, y);
     INSERT INTO t2 VALUES(1, 2);
     CREATE TEMP TABLE t3(w, z);
  }
} {}

proc force_rollback {} {
  catch {db eval {INSERT OR ROLLBACK INTO t1 VALUES(1)}}
}
db function force_rollback force_rollback

do_test tkt-f7772-1.2 {
  catchsql {
    BEGIN IMMEDIATE;
    SELECT x, force_rollback(), EXISTS(SELECT 1 FROM t3 WHERE w=x) FROM t2;
  }
} {1 {callback requested query abort}}
do_test tkt-f7772-1.3 {
  sqlite3_get_autocommit db
} {1}

do_test tkt-f7772-2.1 {
  execsql {
     DROP TABLE IF EXISTS t1;
     DROP TABLE IF EXISTS t2;
     DROP TABLE IF EXISTS t3;

     CREATE TEMP TABLE t1(x UNIQUE);
     INSERT INTO t1 VALUES(1);
     CREATE TABLE t2(x, y);
     INSERT INTO t2 VALUES(1, 2);
  }
} {}
do_test tkt-f7772-2.2 {
  execsql {
    BEGIN IMMEDIATE;
    CREATE TEMP TABLE t3(w, z);
  }
  catchsql {
    SELECT x, force_rollback(), EXISTS(SELECT 1 FROM t3 WHERE w=x) FROM t2
  }
} {1 {callback requested query abort}}
do_test tkt-f7772-2.3 {
  sqlite3_get_autocommit db
} {1}

do_test tkt-f7772-3.1 {
  execsql {
    DROP TABLE IF EXISTS t1;
    DROP TABLE IF EXISTS t2;
    DROP TABLE IF EXISTS t3;

    CREATE TEMP TABLE t1(x);
    CREATE TABLE t2(x);
    CREATE TABLE t3(x);
  
    INSERT INTO t1 VALUES(1);
    INSERT INTO t1 VALUES(2);
    INSERT INTO t2 VALUES(1);
    INSERT INTO t2 VALUES(2);
  }
} {}

proc ins {} { db eval {INSERT INTO t3 VALUES('hello')} }
db function ins ins

do_test tkt-f7772-3.2 {
  execsql {
    SELECT ins() AS x FROM t2 UNION ALL SELECT ins() AS x FROM t1
  }
} {{} {} {} {}}
do_test tkt-f7772-3.3 {
  execsql { SELECT * FROM t3 }
} {hello hello hello hello}

finish_test
Changes to test/tkt3201.test.
65
66
67
68
69
70
71































72
73
74
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



  }
  execsql { SELECT a, b, c, d FROM t1, t3 }
} {1 one 2 two}

do_test tkt3201-7 {
  execsql { SELECT a, b, c, d FROM t1, t3 WHERE a < c }
} {1 one 2 two}

# Ticket [efc02f977919]
#
ifcapable trigger {
  do_test tkt3201-4.0 {
    db eval {
     CREATE TABLE t4(x);
     CREATE TABLE t4_log(x);
     CREATE TRIGGER r4_1 AFTER INSERT ON t4 WHEN new.x=1 BEGIN
       INSERT INTO t4_log(x) VALUES(new.x);
     END;
     CREATE TRIGGER r4_2 AFTER INSERT ON t4 WHEN new.x=2 BEGIN
       INSERT INTO t4_log(x) VALUES(new.x);
     END;
     CREATE TRIGGER r4_3 AFTER INSERT ON t4 WHEN new.x=3 BEGIN
       INSERT INTO t4_log(x) VALUES(new.x);
     END;
     CREATE TRIGGER r4_4 AFTER INSERT ON t4 WHEN new.x=4 BEGIN
       INSERT INTO t4_log(x) VALUES(new.x);
     END;
     INSERT INTO t4 VALUES(1);
     INSERT INTO t4 VALUES(2);
     INSERT INTO t4 VALUES(3);
     INSERT INTO t4 VALUES(4);
     SELECT * FROM t4_log;
    }
  } {1 2 3 4}
}





finish_test
Changes to test/tkt3731.test.
13
14
15
16
17
18
19





20
21
22
23
24
25
26
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31







+
+
+
+
+








set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable {!trigger} {
  finish_test
  return
}

# The tests in this file were written before SQLite supported recursive
# trigger invocation, and some tests depend on that to pass. So disable
# recursive triggers for this file.
catchsql { pragma recursive_triggers = off } 

do_test tkt3731-1.1 {
  execsql {
    CREATE TABLE t1(a PRIMARY KEY, b);
    CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
      INSERT INTO t1 VALUES(new.a || '+', new.b || '+');
    END;
Added test/tkt3810.test.























































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 August 1
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Tests to make sure #3810 is fixed.
#
# $Id: tkt3810.test,v 1.4 2009/08/06 17:43:31 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable {!trigger} {
  finish_test
  return
}

# Create a table using the first database connection.
#
do_test tkt3810-1.1 {
  execsql {
    CREATE TABLE t1(x);
    INSERT INTO t1 VALUES(123);
    SELECT * FROM t1;
    CREATE TABLE t2(y);
    CREATE TABLE t3(z);
  }
} 123

# Create a second connection to the same database.  Make sure the
# schema of the database has been parsed by the second connection.
#
do_test tkt3810-2 {
  sqlite3 db2 test.db
  execsql {
    SELECT * FROM t1;
  } db2
} 123

# DROP the table using the second connection.  The table no longer exists
# but the first connection does not yet know this.  Then try to create a TEMP
# trigger in the first connection that references the table that was dropped.
#
do_test tkt3810-3 {
  execsql {DROP TABLE t1} db2
  execsql {
     CREATE TEMP TRIGGER r1 AFTER INSERT ON t1 BEGIN
       INSERT INTO t2 VALUES(new.rowid);
     END;
  }
  catchsql {
    SELECT * FROM t3;
  }
} {0 {}}

# Trigger still exists in the sqlite_temp_master table, but now it is
# an orphan.
#
do_test tkt3810-4 {
  execsql {SELECT name FROM sqlite_temp_master ORDER BY name}
} {r1}

# Because it is an orphan, it cannot be dropped.
#
do_test tkt3810-5 {
  catchsql {DROP TRIGGER r1}
} {1 {no such trigger: r1}}

# Create a table t1 then drop the table in order to drop the orphaned
# trigger.
#
do_test tkt3810-6 {
  execsql {CREATE TABLE t1(x)} db2
  execsql {DROP TABLE t1}
  execsql {
    SELECT name FROM sqlite_temp_master;
  }
} {}

db2 close

finish_test
Changes to test/tkt3832.test.
14
15
16
17
18
19
20




21
22
23
24
25
26
27
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31







+
+
+
+







# A segfault when using a BEFORE trigger on an INSERT and inserting
# a NULL into the INTEGER PRIMARY KEY.
#
# $Id: tkt3832.test,v 1.1 2009/05/01 02:08:04 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable {!trigger} {
  finish_test
  return
}


do_test tkt3832-1.1 {
  db eval {
    CREATE TABLE t1(a INT, b INTEGER PRIMARY KEY);
    CREATE TABLE log(x);
    CREATE TRIGGER t1r1 BEFORE INSERT ON t1 BEGIN
Changes to test/tkt3838.test.
16
17
18
19
20
21
22




23
24
25
26
27
28
29
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33







+
+
+
+







# Verify that this has been fixed.
#
# $Id: tkt3838.test,v 1.1 2009/05/05 12:54:50 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !altertable {
  finish_test
  return
}

do_test tkt3838-1.1 {
  db eval {
    PRAGMA encoding=UTF16;
    CREATE TABLE t1(x);
    INSERT INTO t1 VALUES(1);
    ALTER TABLE t1 ADD COLUMN b INTEGER DEFAULT '999';
Changes to test/tkt3929.test.
11
12
13
14
15
16
17




18
19
20
21
22
23
24
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28







+
+
+
+







#
# Tests to verify ticket #3929 is fixed.
#
# $Id: tkt3929.test,v 1.1 2009/06/23 11:53:09 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable {!trigger} {
  finish_test
  return
}

do_test tkt3929-1.0 {
  execsql {
    PRAGMA page_size = 1024;
    CREATE TABLE t1(a, b);
    CREATE INDEX i1 ON t1(a, b);
    CREATE TRIGGER t1_t1 AFTER INSERT ON t1 BEGIN
Added test/tkt3935.test.

























































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 July 1
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests to verify that ticket #3935 has been fixed.
#
# $Id: tkt3935.test,v 1.2 2009/07/01 16:12:08 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test tkt3935.1 {
  execsql {
    CREATE TABLE t1(a, b);
    CREATE TABLE t2(c, d);
  }
} {}

do_test tkt3935.2 {
  execsql { SELECT j1.b FROM ( SELECT * FROM t1 INNER JOIN t2 ON a=c ) AS j1 }
} {}
do_test tkt3935.3 {
  execsql { SELECT j1.b FROM (t1 INNER JOIN t2 ON a=c) AS j1 }
} {}


do_test tkt3935.4 {
  catchsql { SELECT a FROM (t1) AS t ON b USING(a) }
} {1 {a JOIN clause is required before ON}}
do_test tkt3935.5 {
  catchsql { SELECT a FROM (t1) AS t ON b }
} {1 {a JOIN clause is required before ON}}
do_test tkt3935.6 {
  catchsql { SELECT a FROM (SELECT * FROM t1) AS t ON b USING(a) }
} {1 {a JOIN clause is required before ON}}
do_test tkt3935.7 {
  catchsql { SELECT a FROM (SELECT * FROM t1) AS t ON b }
} {1 {a JOIN clause is required before ON}}
do_test tkt3935.8 {
  catchsql { SELECT a FROM t1 AS t ON b }
} {1 {a JOIN clause is required before ON}}
do_test tkt3935.9 {
  catchsql { SELECT a FROM t1 AS t ON b USING(a) }
} {1 {a JOIN clause is required before ON}}
do_test tkt3935.10 {
  catchsql { SELECT a FROM t1 AS t USING(a) }
} {1 {a JOIN clause is required before USING}}

finish_test
Added test/tkt3992.test.

















































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# $Id: tkt3992.test,v 1.1 2009/07/27 10:05:06 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test tkt3992-1.1 {
  execsql {
    CREATE TABLE parameters1(
       mountcnt    INT NOT NULL CHECK (typeof(mountcnt) == 'integer'),
       version     REAL NOT NULL
    );
    INSERT INTO parameters1(mountcnt, version) VALUES(1, 1.0);

    CREATE TABLE parameters2(
       mountcnt    INT NOT NULL CHECK (typeof(mountcnt) == 'integer'),
       version     REAL CHECK (typeof(version) == 'real')
    );
    INSERT INTO parameters2(mountcnt, version) VALUES(1, 1.0);
  }
} {}

do_test tkt3992-1.2 {
  execsql {
    UPDATE parameters1 SET mountcnt = mountcnt + 1;
    SELECT * FROM parameters1;
  }
} {2 1.0}

do_test tkt3992-1.3 {
  execsql {
    UPDATE parameters2 SET mountcnt = mountcnt + 1;
    SELECT * FROM parameters2;
  }
} {2 1.0}

ifcapable altertable {
  do_test tkt3992-2.1 {
    execsql {
      CREATE TABLE t1(a, b);
      INSERT INTO t1 VALUES(1, 2);
      ALTER TABLE t1 ADD COLUMN c DEFAULT 3;
      SELECT * FROM t1;
    }
  } {1 2 3}
  do_test tkt3992-2.2 {
    execsql {
      UPDATE t1 SET a = 'one';
      SELECT * FROM t1;
    }
  } {one 2 3}
}

ifcapable trigger {
  db function tcl eval
  do_test tkt3992-2.3 {
    execsql {
      CREATE TABLE t2(a REAL, b REAL, c REAL);
      INSERT INTO t2 VALUES(1, 2, 3);
      CREATE TRIGGER tr2 BEFORE UPDATE ON t2 BEGIN
        SELECT tcl('set res', typeof(new.c));
      END;
  
      UPDATE t2 SET a = 'I';
    }
    set res
  } {real}
}


finish_test
Added test/tkt3997.test.









































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Tests to make sure #3997 is fixed.
#
# $Id: tkt3997.test,v 1.1 2009/07/28 13:30:31 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

proc reverse {lhs rhs} {
  return [string compare $rhs $lhs]
}
proc usual {lhs rhs} {
  return [string compare $lhs $rhs]
}

db collate reverse reverse
db collate usual usual

do_test tkt3997-1.1 {
  execsql {
    create table mytext(name BLOB);
    INSERT INTO mytext VALUES('abc');
    INSERT INTO mytext VALUES('acd');
    INSERT INTO mytext VALUES('afe');
  }
} {}
do_test tkt3997-1.2 {
  execsql { 
    SELECT name 
    FROM mytext 
    ORDER BY name COLLATE reverse 
  }
} {afe acd abc}
do_test tkt3997-1.3 {
  execsql { 
    SELECT name 
    FROM (SELECT name FROM mytext)  
    ORDER BY name COLLATE reverse 
  }
} {afe acd abc}

do_test tkt3997-2.1 {
  execsql { 
    CREATE TABLE mytext2(name COLLATE reverse);
    INSERT INTO mytext2 SELECT name FROM mytext;
  }
} {}
do_test tkt3997-2.2 {
  execsql { 
    SELECT name 
    FROM (SELECT name FROM mytext2)  
    ORDER BY name
  }
} {afe acd abc}
do_test tkt3997-2.3 {
  execsql { 
    SELECT name 
    FROM (SELECT name FROM mytext2)
    ORDER BY name COLLATE usual
  }
} {abc acd afe}

finish_test
Added test/tkt4018.test.

























































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 August 20
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests to verify that ticket #4018 has been
# fixed.  
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

proc testsql {sql} {
  set fd [open tf_main.tcl w]
  puts $fd [subst -nocommands {
    sqlite3_test_control_pending_byte 0x0010000
    sqlite3 db test.db
    set rc [catch { db eval {$sql} } msg]
    puts -nonewline "[set rc] {[set msg]}"
    flush stdout
    exit
  }]
  close $fd
  set fd [open "| [info nameofexec] ./tf_main.tcl" r] 
  set res [read $fd]
  close $fd
  return $res
}

do_test tkt4018-1.1 {
  execsql {
    CREATE TABLE t1(a, b);
    BEGIN;
    SELECT * FROM t1;
  }
} {}

# The database is locked by connection [db]. Open and close a second
# connection to test.db 10000 times. If file-descriptors are not being
# reused, then the process will quickly exceed its maximum number of
# file descriptors (1024 by default on linux).
do_test tkt4018-1.2 {
  for {set i 0} {$i < 10000} {incr i} {
    sqlite3 db2 test.db
    db2 close
  }
} {}

# Now check that connection [db] is still holding a SHARED lock by
# having a second process try to write the db.
do_test tkt4018-1.3 {
  testsql {INSERT INTO t1 VALUES(3, 4)}
} {1 {database is locked}}

# Sanity checking. Have [db] release the lock and then retry the
# INSERT from the previous test case.
do_test tkt4018-1.4 {
  db eval COMMIT
  testsql {INSERT INTO t1 VALUES(3, 4)}
} {0 {}}

# Check that reusing a file descriptor cannot change a read-only 
# connection into a read-write connection.
do_test tkt4018-2.1 {
  sqlite3 db2 test.db
  execsql {INSERT INTO t1 VALUES(1, 2)} db2
} {}
do_test tkt4018-2.2 {
  execsql {
    BEGIN;
    SELECT * FROM t1 ORDER BY a;
  }
} {1 2 3 4}
do_test tkt4018-2.3 {
  db2 close
  sqlite3 db2 test.db -readonly 1
  execsql COMMIT
  catchsql {INSERT INTO t1 VALUES(5, 6)} db2
} {1 {attempt to write a readonly database}}
db2 close

finish_test
Changes to test/trigger1.test.
59
60
61
62
63
64
65
66
67
68



69
70
71
72
73
74



75
76
77
78
79
80
81



82
83
84
85
86
87
88



89
90
91
92
93
94
95



96
97
98
99
100
101
102
103



104
105
106


107
108
109
110
111
112
113
114
115




116
117
118
119
120
121
122
123
124




125
126
127
128
129
130

131
132
133
134
135
136

137
138
139
140
141
142
143


144
145
146
147
148
149
150
151
152
153
154
155
156




157
158
159
160
161
162
163
59
60
61
62
63
64
65



66
67
68
69
70
71



72
73
74
75
76
77
78



79
80
81
82
83
84
85



86
87
88
89
90
91
92



93
94
95
96
97
98
99
100



101
102
103
104


105
106
107
108
109
110
111




112
113
114
115
116
117
118
119
120




121
122
123
124
125
126
127
128
129

130
131
132
133
134
135

136
137
138
139
140
141


142
143
144
145
146
147
148
149
150
151
152




153
154
155
156
157
158
159
160
161
162
163







-
-
-
+
+
+



-
-
-
+
+
+




-
-
-
+
+
+




-
-
-
+
+
+




-
-
-
+
+
+





-
-
-
+
+
+

-
-
+
+





-
-
-
-
+
+
+
+





-
-
-
-
+
+
+
+





-
+





-
+





-
-
+
+









-
-
-
-
+
+
+
+







  catchsql {
     CREATE TRIGGER trig UPDATE ON t1 FOR EACH STATEMENT BEGIN
        SELECT * FROM sqlite_master;
     END;
  }
} {1 {near "STATEMENT": syntax error}}
execsql {
	CREATE TRIGGER tr1 INSERT ON t1 BEGIN
	  INSERT INTO t1 values(1);
 	END;
        CREATE TRIGGER tr1 INSERT ON t1 BEGIN
          INSERT INTO t1 values(1);
         END;
}
do_test trigger1-1.2.0 {
    catchsql {
	CREATE TRIGGER IF NOT EXISTS tr1 DELETE ON t1 BEGIN
	    SELECT * FROM sqlite_master;
 	END
        CREATE TRIGGER IF NOT EXISTS tr1 DELETE ON t1 BEGIN
            SELECT * FROM sqlite_master;
         END
     }
} {0 {}}
do_test trigger1-1.2.1 {
    catchsql {
	CREATE TRIGGER tr1 DELETE ON t1 BEGIN
	    SELECT * FROM sqlite_master;
 	END
        CREATE TRIGGER tr1 DELETE ON t1 BEGIN
            SELECT * FROM sqlite_master;
         END
     }
} {1 {trigger tr1 already exists}}
do_test trigger1-1.2.2 {
    catchsql {
	CREATE TRIGGER "tr1" DELETE ON t1 BEGIN
	    SELECT * FROM sqlite_master;
 	END
        CREATE TRIGGER "tr1" DELETE ON t1 BEGIN
            SELECT * FROM sqlite_master;
         END
     }
} {1 {trigger "tr1" already exists}}
do_test trigger1-1.2.3 {
    catchsql {
	CREATE TRIGGER [tr1] DELETE ON t1 BEGIN
	    SELECT * FROM sqlite_master;
 	END
        CREATE TRIGGER [tr1] DELETE ON t1 BEGIN
            SELECT * FROM sqlite_master;
         END
     }
} {1 {trigger [tr1] already exists}}

do_test trigger1-1.3 {
    catchsql {
	BEGIN;
	CREATE TRIGGER tr2 INSERT ON t1 BEGIN
	    SELECT * from sqlite_master; END;
        BEGIN;
        CREATE TRIGGER tr2 INSERT ON t1 BEGIN
            SELECT * from sqlite_master; END;
        ROLLBACK;
	CREATE TRIGGER tr2 INSERT ON t1 BEGIN
	    SELECT * from sqlite_master; END;
        CREATE TRIGGER tr2 INSERT ON t1 BEGIN
            SELECT * from sqlite_master; END;
    }
} {0 {}}

do_test trigger1-1.4 {
    catchsql {
	DROP TRIGGER IF EXISTS tr1;
	CREATE TRIGGER tr1 DELETE ON t1 BEGIN
	    SELECT * FROM sqlite_master;
	END
        DROP TRIGGER IF EXISTS tr1;
        CREATE TRIGGER tr1 DELETE ON t1 BEGIN
            SELECT * FROM sqlite_master;
        END
    }
} {0 {}}

do_test trigger1-1.5 {
    execsql {
	BEGIN;
	DROP TRIGGER tr2;
	ROLLBACK;
	DROP TRIGGER tr2;
        BEGIN;
        DROP TRIGGER tr2;
        ROLLBACK;
        DROP TRIGGER tr2;
    }
} {}

do_test trigger1-1.6.1 {
    catchsql {
	DROP TRIGGER IF EXISTS biggles;
        DROP TRIGGER IF EXISTS biggles;
    }
} {0 {}}

do_test trigger1-1.6.2 {
    catchsql {
	DROP TRIGGER biggles;
        DROP TRIGGER biggles;
    }
} {1 {no such trigger: biggles}}

do_test trigger1-1.7 {
    catchsql {
	DROP TABLE t1;
	DROP TRIGGER tr1;
        DROP TABLE t1;
        DROP TRIGGER tr1;
    }
} {1 {no such trigger: tr1}}

ifcapable tempdb {
  execsql {
    CREATE TEMP TABLE temp_table(a);
  }
  do_test trigger1-1.8 {
    execsql {
  	CREATE TRIGGER temp_trig UPDATE ON temp_table BEGIN
  	    SELECT * from sqlite_master;
  	END;
  	SELECT count(*) FROM sqlite_master WHERE name = 'temp_trig';
          CREATE TRIGGER temp_trig UPDATE ON temp_table BEGIN
              SELECT * from sqlite_master;
          END;
          SELECT count(*) FROM sqlite_master WHERE name = 'temp_trig';
    } 
  } {0}
}

do_test trigger1-1.9 {
  catchsql {
    CREATE TRIGGER tr1 AFTER UPDATE ON sqlite_master BEGIN
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413

414
415
416
417
418
419
420
399
400
401
402
403
404
405

406
407
408
409
410
411
412

413
414
415
416
417
418
419
420







-
+






-
+







}
do_test trigger1-6.1 {
  execsql {SELECT type, name FROM sqlite_master}
} [concat $view_v1 {table t2}]
do_test trigger1-6.2 {
  execsql {
    CREATE TRIGGER t2 BEFORE DELETE ON t2 BEGIN
      SELECT RAISE(ABORT,'deletes are not allows');
      SELECT RAISE(ABORT,'deletes are not permitted');
    END;
    SELECT type, name FROM sqlite_master;
  }
} [concat $view_v1 {table t2 trigger t2}]
do_test trigger1-6.3 {
  catchsql {DELETE FROM t2}
} {1 {deletes are not allows}}
} {1 {deletes are not permitted}}
do_test trigger1-6.4 {
  execsql {SELECT * FROM t2}
} {3 4 7 8}
do_test trigger1-6.5 {
  db close
  sqlite3 db test.db
  execsql {SELECT type, name FROM sqlite_master}
635
636
637
638
639
640
641




























































642
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

  }
  catchsql { UPDATE tA SET a = 'abc' }
} {1 {datatype mismatch}}
do_test trigger1-15.2 {
  catchsql { INSERT INTO tA VALUES('abc', 2, 3) }
} {1 {datatype mismatch}}

# Ticket #3947:  Do not allow qualified table names on INSERT, UPDATE, and
# DELETE statements within triggers.  Actually, this has never been allowed
# by the grammar.  But the error message is confusing: one simply gets a
# "syntax error".  That has now been changed to give a full error message.
#
do_test trigger1-16.1 {
  db eval {
    CREATE TABLE t16(a,b,c);
    CREATE INDEX t16a ON t16(a);
    CREATE INDEX t16b ON t16(b);
  }
  catchsql {
    CREATE TRIGGER main.t16err1 AFTER INSERT ON tA BEGIN
      INSERT INTO main.t16 VALUES(1,2,3);
    END;
  }
} {1 {qualified table names are not allowed on INSERT, UPDATE, and DELETE statements within triggers}}
do_test trigger1-16.2 {
  catchsql {
    CREATE TRIGGER main.t16err2 AFTER INSERT ON tA BEGIN
      UPDATE main.t16 SET rowid=rowid+1;
    END;
  }
} {1 {qualified table names are not allowed on INSERT, UPDATE, and DELETE statements within triggers}}
do_test trigger1-16.3 {
  catchsql {
    CREATE TRIGGER main.t16err3 AFTER INSERT ON tA BEGIN
      DELETE FROM main.t16;
    END;
  }
} {1 {qualified table names are not allowed on INSERT, UPDATE, and DELETE statements within triggers}}
do_test trigger1-16.4 {
  catchsql {
    CREATE TRIGGER main.t16err4 AFTER INSERT ON tA BEGIN
      UPDATE t16 NOT INDEXED SET rowid=rowid+1;
    END;
  }
} {1 {the NOT INDEXED clause is not allowed on UPDATE or DELETE statements within triggers}}
do_test trigger1-16.5 {
  catchsql {
    CREATE TRIGGER main.t16err5 AFTER INSERT ON tA BEGIN
      UPDATE t16 INDEXED BY t16a SET rowid=rowid+1 WHERE a=1;
    END;
  }
} {1 {the INDEXED BY clause is not allowed on UPDATE or DELETE statements within triggers}}
do_test trigger1-16.6 {
  catchsql {
    CREATE TRIGGER main.t16err6 AFTER INSERT ON tA BEGIN
      DELETE FROM t16 NOT INDEXED WHERE a=123;
    END;
  }
} {1 {the NOT INDEXED clause is not allowed on UPDATE or DELETE statements within triggers}}
do_test trigger1-16.7 {
  catchsql {
    CREATE TRIGGER main.t16err7 AFTER INSERT ON tA BEGIN
      DELETE FROM t16 INDEXED BY t16a WHERE a=123;
    END;
  }
} {1 {the INDEXED BY clause is not allowed on UPDATE or DELETE statements within triggers}}

finish_test
Changes to test/trigger2.test.
49
50
51
52
53
54
55





56
57
58
59
60
61
62
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67







+
+
+
+
+








set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable {!trigger} {
  finish_test
  return
}

# The tests in this file were written before SQLite supported recursive
# trigger invocation, and some tests depend on that to pass. So disable
# recursive triggers for this file.
catchsql { pragma recursive_triggers = off } 

# 1.
ifcapable subquery {
  set ii 0
  set tbl_definitions [list \
  	{CREATE TABLE tbl (a, b);}                                      \
  	{CREATE TABLE tbl (a INTEGER PRIMARY KEY, b);}                  \
Changes to test/trigger3.test.
13
14
15
16
17
18
19
20





21
22
23
24


25
26
27

28
29
30
31
32
33



34
35
36
37
38
39

40
41
42
43
44
45
46
47


48
49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65


66
67
68
69
70
71

72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106


107
108
109
110
111
112
113
114
115
116
117

118
119
120
121

122
123
124
125
126
127


128
129
130
131
132
133


134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
149



150
151
152
153
154
155
156
157
158
159
160
161
162



163
164
165
166
167
168

169
170
171
172
173

174
175
176
177
178

179
180
181
182
183
184
185
186
187
188
189
190
13
14
15
16
17
18
19
20
21
22
23
24
25
26



27
28
29
30

31
32
33
34



35
36
37
38
39
40
41
42

43
44
45
46
47
48
49


50
51
52
53
54
55
56
57
58
59
60

61
62
63
64
65
66
67


68
69
70
71
72
73
74

75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

102
103
104
105
106
107
108


109
110
111
112
113
114
115
116
117
118
119
120

121
122
123
124

125
126
127
128
129


130
131
132
133
134
135


136
137
138
139
140
141
142
143
144

145
146
147
148
149
150



151
152
153
154
155
156
157
158
159
160
161
162
163



164
165
166
167
168
169
170
171

172
173
174
175
176

177
178
179
180
181

182
183
184
185
186
187
188
189
190
191
192
193
194








+
+
+
+
+

-
-
-
+
+


-
+



-
-
-
+
+
+





-
+






-
-
+
+









-
+






-
-
+
+





-
+






-
+



















-
+






-
-
+
+










-
+



-
+




-
-
+
+




-
-
+
+







-
+





-
-
-
+
+
+










-
-
-
+
+
+





-
+




-
+




-
+













set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable {!trigger} {
  finish_test
  return
}

# The tests in this file were written before SQLite supported recursive }
# trigger invocation, and some tests depend on that to pass. So disable
# recursive triggers for this file.
catchsql { pragma recursive_triggers = off } 

# Test that we can cause ROLLBACK, FAIL and ABORT correctly
# catchsql { DROP TABLE tbl; }
catchsql { CREATE TABLE tbl (a, b, c) }

#
catchsql { CREATE TABLE tbl(a, b ,c) }
execsql {
    CREATE TRIGGER before_tbl_insert BEFORE INSERT ON tbl BEGIN SELECT CASE 
	WHEN (new.a = 4) THEN RAISE(IGNORE) END;
        WHEN (new.a = 4) THEN RAISE(IGNORE) END;
    END;

    CREATE TRIGGER after_tbl_insert AFTER INSERT ON tbl BEGIN SELECT CASE 
	WHEN (new.a = 1) THEN RAISE(ABORT,    'Trigger abort') 
	WHEN (new.a = 2) THEN RAISE(FAIL,     'Trigger fail') 
	WHEN (new.a = 3) THEN RAISE(ROLLBACK, 'Trigger rollback') END;
        WHEN (new.a = 1) THEN RAISE(ABORT,    'Trigger abort') 
        WHEN (new.a = 2) THEN RAISE(FAIL,     'Trigger fail') 
        WHEN (new.a = 3) THEN RAISE(ROLLBACK, 'Trigger rollback') END;
    END;
}
# ABORT
do_test trigger3-1.1 {
    catchsql {
	BEGIN;
        BEGIN;
        INSERT INTO tbl VALUES (5, 5, 6);
        INSERT INTO tbl VALUES (1, 5, 6);
    }
} {1 {Trigger abort}}
do_test trigger3-1.2 {
    execsql {
	SELECT * FROM tbl;
	ROLLBACK;
        SELECT * FROM tbl;
        ROLLBACK;
    }
} {5 5 6}
do_test trigger3-1.3 {
    execsql {SELECT * FROM tbl}
} {}

# FAIL
do_test trigger3-2.1 {
    catchsql {
	BEGIN;
        BEGIN;
        INSERT INTO tbl VALUES (5, 5, 6);
        INSERT INTO tbl VALUES (2, 5, 6);
    }
} {1 {Trigger fail}}
do_test trigger3-2.2 {
    execsql {
	SELECT * FROM tbl;
	ROLLBACK;
        SELECT * FROM tbl;
        ROLLBACK;
    }
} {5 5 6 2 5 6}
# ROLLBACK
do_test trigger3-3.1 {
    catchsql {
	BEGIN;
        BEGIN;
        INSERT INTO tbl VALUES (5, 5, 6);
        INSERT INTO tbl VALUES (3, 5, 6);
    }
} {1 {Trigger rollback}}
do_test trigger3-3.2 {
    execsql {
	SELECT * FROM tbl;
        SELECT * FROM tbl;
    }
} {}

# Verify that a ROLLBACK trigger works like a FAIL trigger if
# we are not within a transaction.  Ticket #3035.
#
do_test trigger3-3.3 {
    catchsql {COMMIT}
    catchsql {
        INSERT INTO tbl VALUES (3, 9, 10);
    }
} {1 {Trigger rollback}}
do_test trigger3-3.4 {
    execsql {SELECT * FROM tbl}
} {}

# IGNORE
do_test trigger3-4.1 {
    catchsql {
	BEGIN;
        BEGIN;
        INSERT INTO tbl VALUES (5, 5, 6);
        INSERT INTO tbl VALUES (4, 5, 6);
    }
} {0 {}}
do_test trigger3-4.2 {
    execsql {
	SELECT * FROM tbl;
	ROLLBACK;
        SELECT * FROM tbl;
        ROLLBACK;
    }
} {5 5 6}

# Check that we can also do RAISE(IGNORE) for UPDATE and DELETE
execsql {DROP TABLE tbl;}
execsql {CREATE TABLE tbl (a, b, c);}
execsql {INSERT INTO tbl VALUES(1, 2, 3);}
execsql {INSERT INTO tbl VALUES(4, 5, 6);}
execsql {
    CREATE TRIGGER before_tbl_update BEFORE UPDATE ON tbl BEGIN
	SELECT CASE WHEN (old.a = 1) THEN RAISE(IGNORE) END;
        SELECT CASE WHEN (old.a = 1) THEN RAISE(IGNORE) END;
    END;

    CREATE TRIGGER before_tbl_delete BEFORE DELETE ON tbl BEGIN
	SELECT CASE WHEN (old.a = 1) THEN RAISE(IGNORE) END;
        SELECT CASE WHEN (old.a = 1) THEN RAISE(IGNORE) END;
    END;
}
do_test trigger3-5.1 {
    execsql {
	UPDATE tbl SET c = 10;
	SELECT * FROM tbl;
        UPDATE tbl SET c = 10;
        SELECT * FROM tbl;
    }
} {1 2 3 4 5 10}
do_test trigger3-5.2 {
    execsql {
	DELETE FROM tbl;
	SELECT * FROM tbl;
        DELETE FROM tbl;
        SELECT * FROM tbl;
    }
} {1 2 3}

# Check that RAISE(IGNORE) works correctly for nested triggers:
execsql {CREATE TABLE tbl2(a, b, c)}
execsql {
    CREATE TRIGGER after_tbl2_insert AFTER INSERT ON tbl2 BEGIN
	UPDATE tbl SET c = 10;
        UPDATE tbl SET c = 10;
        INSERT INTO tbl2 VALUES (new.a, new.b, new.c);
    END;
}
do_test trigger3-6 {
    execsql {
	INSERT INTO tbl2 VALUES (1, 2, 3);
	SELECT * FROM tbl2;
	SELECT * FROM tbl;
        INSERT INTO tbl2 VALUES (1, 2, 3);
        SELECT * FROM tbl2;
        SELECT * FROM tbl;
    }
} {1 2 3 1 2 3 1 2 3}

# Check that things also work for view-triggers

ifcapable view {

execsql {CREATE VIEW tbl_view AS SELECT * FROM tbl}
execsql {
    CREATE TRIGGER tbl_view_insert INSTEAD OF INSERT ON tbl_view BEGIN
	SELECT CASE WHEN (new.a = 1) THEN RAISE(ROLLBACK, 'View rollback')
	            WHEN (new.a = 2) THEN RAISE(IGNORE) 
	            WHEN (new.a = 3) THEN RAISE(ABORT, 'View abort') END;
        SELECT CASE WHEN (new.a = 1) THEN RAISE(ROLLBACK, 'View rollback')
                    WHEN (new.a = 2) THEN RAISE(IGNORE) 
                    WHEN (new.a = 3) THEN RAISE(ABORT, 'View abort') END;
    END;
}

do_test trigger3-7.1 {
    catchsql {
	INSERT INTO tbl_view VALUES(1, 2, 3);
        INSERT INTO tbl_view VALUES(1, 2, 3);
    }
} {1 {View rollback}}
do_test trigger3-7.2 {
    catchsql {
	INSERT INTO tbl_view VALUES(2, 2, 3);
        INSERT INTO tbl_view VALUES(2, 2, 3);
    }
} {0 {}}
do_test trigger3-7.3 {
    catchsql {
	INSERT INTO tbl_view VALUES(3, 2, 3);
        INSERT INTO tbl_view VALUES(3, 2, 3);
    }
} {1 {View abort}}

} ;# ifcapable view

integrity_check trigger3-8.1

catchsql { DROP TABLE tbl; } 
catchsql { DROP TABLE tbl2; } 
catchsql { DROP VIEW tbl_view; }

finish_test
Changes to test/trigger8.test.
28
29
30
31
32
33
34

35
36
37
38
39
40
41
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42







+







# heap, use 1000.
#
set nStatement 10000
if {$tcl_platform(platform) == "symbian"} {
  set nStatement 1000
}

set nStatement 5
do_test trigger8-1.1 {
  execsql {
    CREATE TABLE t1(x);
    CREATE TABLE t2(y);
  }
  set sql "CREATE TRIGGER r${nStatement} AFTER INSERT ON t1 BEGIN\n"
  for {set i 0} {$i<$nStatement} {incr i} {
Changes to test/trigger9.test.
71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100







-
+














-
+







      END;
      DELETE FROM t1;
      SELECT * FROM t2;
  }
} {1 2 3}
do_test trigger9-1.3.2 {
  has_rowdata {DELETE FROM t1}
} 1
} 0
do_test trigger9-1.3.3 { execsql { ROLLBACK } } {}

do_test trigger9-1.4.1 {
  execsql {
    BEGIN;
      CREATE TRIGGER trig1 BEFORE DELETE ON t1 WHEN old.x='1' BEGIN
        INSERT INTO t2 VALUES(old.rowid);
      END;
      DELETE FROM t1;
      SELECT * FROM t2;
  }
} {1}
do_test trigger9-1.4.2 {
  has_rowdata {DELETE FROM t1}
} 1
} 0
do_test trigger9-1.4.3 { execsql { ROLLBACK } } {}

do_test trigger9-1.5.1 {
  execsql {
    BEGIN;
      CREATE TRIGGER trig1 BEFORE UPDATE ON t1 BEGIN
        INSERT INTO t2 VALUES(old.rowid);
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132
133
134
135
136
137

138
139
140
141
142
143
144
145







-
+














-
+







      END;
      UPDATE t1 SET y = '';
      SELECT * FROM t2;
  }
} {1 2 3}
do_test trigger9-1.6.2 {
  has_rowdata {UPDATE t1 SET y = ''}
} 1
} 0
do_test trigger9-1.6.3 { execsql { ROLLBACK } } {}

do_test trigger9-1.7.1 {
  execsql {
    BEGIN;
      CREATE TRIGGER trig1 BEFORE UPDATE ON t1 WHEN old.x>='2' BEGIN
        INSERT INTO t2 VALUES(old.x);
      END;
      UPDATE t1 SET y = '';
      SELECT * FROM t2;
  }
} {2 3}
do_test trigger9-1.7.2 {
  has_rowdata {UPDATE t1 SET y = ''}
} 1
} 0
do_test trigger9-1.7.3 { execsql { ROLLBACK } } {}

do_test trigger9-3.1 {
  execsql {
    CREATE TABLE t3(a, b);
    INSERT INTO t3 VALUES(1, 'one');
    INSERT INTO t3 VALUES(2, 'two');
Changes to test/triggerA.test.
75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89







-
+







  }
} {1 10 2 3 4 5 6 7 8 9 five four three}
do_test triggerA-1.6 {
  db eval {
     CREATE VIEW v5 AS SELECT x, b FROM t1, t2 WHERE y=c;
     SELECT * FROM v5;
  }
} {1 103 2 203 3 305 4 404 5 504 6 603 7 705 8 805 9 904 10 1003}
} {10 1003 9 904 8 805 7 705 6 603 5 504 4 404 3 305 2 203 1 103}

# Create INSTEAD OF triggers on the views.  Run UPDATE and DELETE statements
# using those triggers.  Verify correct operation.
#
do_test triggerA-2.1 {
  db eval {
     CREATE TABLE result2(a,b);
Added test/triggerC.test.























































































































































































































































































































































































































































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 August 24
#
# The author disclaims copyright to this source code.  In place of
# a legal notice', here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable {!trigger} {
  finish_test
  return
}

#-------------------------------------------------------------------------
# Test organization:
#
# triggerC-1.*: Haphazardly designed trigger related tests that were useful
#               during an upgrade of the triggers sub-system.
# 
# triggerC-2.*:
#
# triggerC-3.*:
#
# triggerC-4.*:
#
# triggerC-5.*: Test that when recursive triggers are enabled DELETE 
#               triggers are fired when rows are deleted as part of OR
#               REPLACE conflict resolution. And that they are not fired
#               if recursive triggers are not enabled.
#
# triggerC-6.*: Test that the recursive_triggers pragma returns correct
#               results when invoked without an argument.
#

# Enable recursive triggers for this file.
#
execsql { PRAGMA recursive_triggers = on }

#sqlite3_db_config_lookaside db 0 0 0

#-------------------------------------------------------------------------
# This block of tests, triggerC-1.*, are not aimed at any specific
# property of the triggers sub-system. They were created to debug
# specific problems while modifying SQLite to support recursive
# triggers. They are left here in case they can help debug the
# same problems again.
#
do_test triggerC-1.1 {
  execsql {
    CREATE TABLE t1(a, b, c);
    CREATE TABLE log(t, a1, b1, c1, a2, b2, c2);
    CREATE TRIGGER trig1 BEFORE INSERT ON t1 BEGIN
      INSERT INTO log VALUES('before', NULL, NULL, NULL, new.a, new.b, new.c);
    END;
    CREATE TRIGGER trig2 AFTER INSERT ON t1 BEGIN
      INSERT INTO log VALUES('after', NULL, NULL, NULL, new.a, new.b, new.c);
    END;
    CREATE TRIGGER trig3 BEFORE UPDATE ON t1 BEGIN
      INSERT INTO log VALUES('before', old.a,old.b,old.c, new.a,new.b,new.c);
    END;
    CREATE TRIGGER trig4 AFTER UPDATE ON t1 BEGIN
      INSERT INTO log VALUES('after', old.a,old.b,old.c, new.a,new.b,new.c);
    END;

    CREATE TRIGGER trig5 BEFORE DELETE ON t1 BEGIN
      INSERT INTO log VALUES('before', old.a,old.b,old.c, NULL,NULL,NULL);
    END;
    CREATE TRIGGER trig6 AFTER DELETE ON t1 BEGIN
      INSERT INTO log VALUES('after', old.a,old.b,old.c, NULL,NULL,NULL);
    END;
  }
} {}
do_test triggerC-1.2 {
  execsql {
    INSERT INTO t1 VALUES('A', 'B', 'C');
    SELECT * FROM log;
  }
} {before {} {} {} A B C after {} {} {} A B C}
do_test triggerC-1.3 {
  execsql { SELECT * FROM t1 }
} {A B C}
do_test triggerC-1.4 {
  execsql {
    DELETE FROM log;
    UPDATE t1 SET a = 'a';
    SELECT * FROM log;
  }
} {before A B C a B C after A B C a B C}
do_test triggerC-1.5 {
  execsql { SELECT * FROM t1 }
} {a B C}
do_test triggerC-1.6 {
  execsql {
    DELETE FROM log;
    DELETE FROM t1;
    SELECT * FROM log;
  }
} {before a B C {} {} {} after a B C {} {} {}}
do_test triggerC-1.7 {
  execsql { SELECT * FROM t1 }
} {}
do_test triggerC-1.8 {
  execsql {
    CREATE TABLE t4(a, b);
    CREATE TRIGGER t4t AFTER DELETE ON t4 BEGIN
      SELECT RAISE(ABORT, 'delete is not supported');
    END;
  }
} {}
do_test triggerC-1.9 {
  execsql { INSERT INTO t4 VALUES(1, 2) }
  catchsql { DELETE FROM t4 }
} {1 {delete is not supported}}
do_test triggerC-1.10 {
  execsql { SELECT * FROM t4 }
} {1 2}
do_test triggerC-1.11 {
  execsql {
    CREATE TABLE t5 (a primary key, b, c);
    INSERT INTO t5 values (1, 2, 3);
    CREATE TRIGGER au_tbl AFTER UPDATE ON t5 BEGIN
      UPDATE OR IGNORE t5 SET a = new.a, c = 10;
    END;
  }
} {}
do_test triggerC-1.12 {
  catchsql { UPDATE OR REPLACE t5 SET a = 4 WHERE a = 1 }
} {1 {too many levels of trigger recursion}}
do_test triggerC-1.13 {
  execsql {
    CREATE TABLE t6(a INTEGER PRIMARY KEY, b);
    INSERT INTO t6 VALUES(1, 2);
    create trigger r1 after update on t6 for each row begin
      SELECT 1;
    end;
    UPDATE t6 SET a=a; 
  }
} {}
do_test triggerC-1.14 {
  execsql {
    DROP TABLE t1;
    CREATE TABLE cnt(n);
    INSERT INTO cnt VALUES(0);
    CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE, c, d, e);
    CREATE INDEX t1cd ON t1(c,d);
    CREATE TRIGGER t1r1 AFTER UPDATE ON t1 BEGIN UPDATE cnt SET n=n+1; END;
    INSERT INTO t1 VALUES(1,2,3,4,5);
    INSERT INTO t1 VALUES(6,7,8,9,10);
    INSERT INTO t1 VALUES(11,12,13,14,15);
  }
} {}
do_test triggerC-1.15 {
  catchsql { UPDATE OR ROLLBACK t1 SET a=100 }
} {1 {PRIMARY KEY must be unique}}


#-------------------------------------------------------------------------
# This block of tests, triggerC-2.*, tests that recursive trigger
# programs (triggers that fire themselves) work. More specifically,
# this block focuses on recursive INSERT triggers.
#
do_test triggerC-2.1.0 {
  execsql {
    CREATE TABLE t2(a PRIMARY KEY);
  }
} {}

foreach {n tdefn rc} {
  1 { 
    CREATE TRIGGER t2_trig AFTER INSERT ON t2 WHEN (new.a>0) BEGIN
      INSERT INTO t2 VALUES(new.a - 1);
    END; 
  } {0 {10 9 8 7 6 5 4 3 2 1 0}}

  2 {
    CREATE TRIGGER t2_trig AFTER INSERT ON t2 BEGIN
      SELECT CASE WHEN new.a==2 THEN RAISE(IGNORE) ELSE NULL END;
      INSERT INTO t2 VALUES(new.a - 1);
    END;
  } {0 {10 9 8 7 6 5 4 3 2}}

  3 { 
    CREATE TRIGGER t2_trig BEFORE INSERT ON t2 WHEN (new.a>0) BEGIN
      INSERT INTO t2 VALUES(new.a - 1);
    END; 
  } {0 {0 1 2 3 4 5 6 7 8 9 10}}

  4 { 
    CREATE TRIGGER t2_trig BEFORE INSERT ON t2 BEGIN
      SELECT CASE WHEN new.a==2 THEN RAISE(IGNORE) ELSE NULL END;
      INSERT INTO t2 VALUES(new.a - 1);
    END;
  } {0 {3 4 5 6 7 8 9 10}}

  5 { 
    CREATE TRIGGER t2_trig BEFORE INSERT ON t2 BEGIN
      INSERT INTO t2 VALUES(new.a - 1);
    END;
  } {1 {too many levels of trigger recursion}}

  6 { 
    CREATE TRIGGER t2_trig AFTER INSERT ON t2 WHEN (new.a>0) BEGIN
      INSERT OR IGNORE INTO t2 VALUES(new.a);
    END;
  } {0 10}

  7 { 
    CREATE TRIGGER t2_trig BEFORE INSERT ON t2 WHEN (new.a>0) BEGIN
      INSERT OR IGNORE INTO t2 VALUES(new.a);
    END;
  } {1 {too many levels of trigger recursion}}
} {
  do_test triggerC-2.1.$n {
    catchsql { DROP TRIGGER t2_trig }
    execsql  { DELETE FROM t2 }
    execsql  $tdefn
    catchsql {
      INSERT INTO t2 VALUES(10);
      SELECT * FROM t2;
    }
  } $rc
}

do_test triggerC-2.2 {
  execsql {
    CREATE TABLE t22(x);

    CREATE TRIGGER t22a AFTER INSERT ON t22 BEGIN
      INSERT INTO t22 SELECT x + (SELECT max(x) FROM t22) FROM t22;
    END;
    CREATE TRIGGER t22b BEFORE INSERT ON t22 BEGIN
      SELECT CASE WHEN (SELECT count(*) FROM t22) >= 100
                  THEN RAISE(IGNORE)
                  ELSE NULL END;
    END;

    INSERT INTO t22 VALUES(1);
    SELECT count(*) FROM t22;
  }
} {100}

do_test triggerC-2.3 {
  execsql {
    CREATE TABLE t23(x PRIMARY KEY);

    CREATE TRIGGER t23a AFTER INSERT ON t23 BEGIN
      INSERT INTO t23 VALUES(new.x + 1);
    END;

    CREATE TRIGGER t23b BEFORE INSERT ON t23 BEGIN
      SELECT CASE WHEN new.x>500
                  THEN RAISE(IGNORE)
                  ELSE NULL END;
    END;

    INSERT INTO t23 VALUES(1);
    SELECT count(*) FROM t23;
  }
} {500}
 

#-----------------------------------------------------------------------
# This block of tests, triggerC-3.*, test that SQLite throws an exception
# when it detects excessive recursion.
#
do_test triggerC-3.1.1 {
  execsql {
    CREATE TABLE t3(a, b);
    CREATE TRIGGER t3i AFTER INSERT ON t3 BEGIN
      DELETE FROM t3 WHERE rowid = new.rowid;
    END;
    CREATE TRIGGER t3d AFTER DELETE ON t3 BEGIN
      INSERT INTO t3 VALUES(old.a, old.b);
    END;
  }
} {}
do_test triggerC-3.1.2 {
  catchsql { INSERT INTO t3 VALUES(0,0) }
} {1 {too many levels of trigger recursion}}
do_test triggerC-3.1.3 {
  execsql { SELECT * FROM t3 }
} {}

do_test triggerC-3.2.1 {
  execsql {
    CREATE TABLE t3b(x);
    CREATE TRIGGER t3bi AFTER INSERT ON t3b WHEN new.x<2000 BEGIN
      INSERT INTO t3b VALUES(new.x+1);
    END;
  }
  catchsql {
    INSERT INTO t3b VALUES(1);
  }
} {1 {too many levels of trigger recursion}}
do_test triggerC-3.2.2 {
  db eval {SELECT * FROM t3b}
} {}

do_test triggerC-3.3.1 {
  catchsql {
    INSERT INTO t3b VALUES(1001);
  }
} {0 {}}
do_test triggerC-3.3.2 {
  db eval {SELECT count(*), max(x), min(x) FROM t3b}
} {1000 2000 1001}

do_test triggerC-3.4.1 {
  catchsql {
    DELETE FROM t3b;
    INSERT INTO t3b VALUES(999);
  }
} {1 {too many levels of trigger recursion}}
do_test triggerC-3.4.2 {
  db eval {SELECT count(*), max(x), min(x) FROM t3b}
} {0 {} {}}

do_test triggerC-3.5.1 {
  sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 100
  catchsql {
    INSERT INTO t3b VALUES(1901);
  }
} {0 {}}
do_test triggerC-3.5.2 {
  db eval {SELECT count(*), max(x), min(x) FROM t3b}
} {100 2000 1901}

do_test triggerC-3.5.3 {
  catchsql {
    DELETE FROM t3b;
    INSERT INTO t3b VALUES(1900);
  }
} {1 {too many levels of trigger recursion}}
do_test triggerC-3.5.4 {
  db eval {SELECT count(*), max(x), min(x) FROM t3b}
} {0 {} {}}

do_test triggerC-3.6.1 {
  sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1
  catchsql {
    INSERT INTO t3b VALUES(2000);
  }
} {0 {}}
do_test triggerC-3.6.2 {
  db eval {SELECT count(*), max(x), min(x) FROM t3b}
} {1 2000 2000}

do_test triggerC-3.6.3 {
  catchsql {
    DELETE FROM t3b;
    INSERT INTO t3b VALUES(1999);
  }
} {1 {too many levels of trigger recursion}}
do_test triggerC-3.6.4 {
  db eval {SELECT count(*), max(x), min(x) FROM t3b}
} {0 {} {}}
sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1000
      

#-----------------------------------------------------------------------
# This next block of tests, triggerC-4.*, checks that affinity 
# transformations and constraint processing is performed at the correct 
# times relative to BEFORE and AFTER triggers.
#
# For an INSERT statement, for each row to be inserted:
#
#   1. Apply affinities to non-rowid values to be inserted.
#   2. Fire BEFORE triggers.
#   3. Process constraints.
#   4. Insert new record.
#   5. Fire AFTER triggers.
#
# If the value of the rowid field is to be automatically assigned, it is
# set to -1 in the new.* record. Even if it is explicitly set to NULL
# by the INSERT statement.
#
# For an UPDATE statement, for each row to be deleted:
#
#   1. Apply affinities to non-rowid values to be inserted.
#   2. Fire BEFORE triggers.
#   3. Process constraints.
#   4. Insert new record.
#   5. Fire AFTER triggers.
#
# For a DELETE statement, for each row to be deleted:
#
#   1. Fire BEFORE triggers.
#   2. Remove database record.
#   3. Fire AFTER triggers.
#
# When a numeric value that as an exact integer representation is stored
# in a column with REAL affinity, it is actually stored as an integer.
# These tests check that the typeof() such values is always 'real',
# not 'integer'.
#
# triggerC-4.1.*: Check that affinity transformations are made before
#                 triggers are invoked.
#
do_test triggerC-4.1.1 {
  catchsql { DROP TABLE log }
  catchsql { DROP TABLE t4 }
  execsql {
    CREATE TABLE log(t);
    CREATE TABLE t4(a TEXT,b INTEGER,c REAL);
    CREATE TRIGGER t4bi BEFORE INSERT ON t4 BEGIN
      INSERT INTO log VALUES(new.rowid || ' ' || typeof(new.rowid) || ' ' ||
                             new.a     || ' ' || typeof(new.a)     || ' ' ||
                             new.b     || ' ' || typeof(new.b)     || ' ' ||
                             new.c     || ' ' || typeof(new.c)
      );
    END;
    CREATE TRIGGER t4ai AFTER INSERT ON t4 BEGIN
      INSERT INTO log VALUES(new.rowid || ' ' || typeof(new.rowid) || ' ' ||
                             new.a     || ' ' || typeof(new.a)     || ' ' ||
                             new.b     || ' ' || typeof(new.b)     || ' ' ||
                             new.c     || ' ' || typeof(new.c)
      );
    END;
    CREATE TRIGGER t4bd BEFORE DELETE ON t4 BEGIN
      INSERT INTO log VALUES(old.rowid || ' ' || typeof(old.rowid) || ' ' ||
                             old.a     || ' ' || typeof(old.a)     || ' ' ||
                             old.b     || ' ' || typeof(old.b)     || ' ' ||
                             old.c     || ' ' || typeof(old.c)
      );
    END;
    CREATE TRIGGER t4ad AFTER DELETE ON t4 BEGIN
      INSERT INTO log VALUES(old.rowid || ' ' || typeof(old.rowid) || ' ' ||
                             old.a     || ' ' || typeof(old.a)     || ' ' ||
                             old.b     || ' ' || typeof(old.b)     || ' ' ||
                             old.c     || ' ' || typeof(old.c)
      );
    END;
    CREATE TRIGGER t4bu BEFORE UPDATE ON t4 BEGIN
      INSERT INTO log VALUES(old.rowid || ' ' || typeof(old.rowid) || ' ' ||
                             old.a     || ' ' || typeof(old.a)     || ' ' ||
                             old.b     || ' ' || typeof(old.b)     || ' ' ||
                             old.c     || ' ' || typeof(old.c)
      );
      INSERT INTO log VALUES(new.rowid || ' ' || typeof(new.rowid) || ' ' ||
                             new.a     || ' ' || typeof(new.a)     || ' ' ||
                             new.b     || ' ' || typeof(new.b)     || ' ' ||
                             new.c     || ' ' || typeof(new.c)
      );
    END;
    CREATE TRIGGER t4au AFTER UPDATE ON t4 BEGIN
      INSERT INTO log VALUES(old.rowid || ' ' || typeof(old.rowid) || ' ' ||
                             old.a     || ' ' || typeof(old.a)     || ' ' ||
                             old.b     || ' ' || typeof(old.b)     || ' ' ||
                             old.c     || ' ' || typeof(old.c)
      );
      INSERT INTO log VALUES(new.rowid || ' ' || typeof(new.rowid) || ' ' ||
                             new.a     || ' ' || typeof(new.a)     || ' ' ||
                             new.b     || ' ' || typeof(new.b)     || ' ' ||
                             new.c     || ' ' || typeof(new.c)
      );
    END;
  }
} {}
foreach {n insert log} {

  2 { 
   INSERT INTO t4 VALUES('1', '1', '1');
   DELETE FROM t4;
  } {
    -1 integer 1 text 1 integer 1.0 real 
     1 integer 1 text 1 integer 1.0 real
     1 integer 1 text 1 integer 1.0 real 
     1 integer 1 text 1 integer 1.0 real
  }

  3 { 
   INSERT INTO t4(rowid,a,b,c) VALUES(45, 45, 45, 45);
   DELETE FROM t4;
  } {
    45 integer 45 text 45 integer 45.0 real
    45 integer 45 text 45 integer 45.0 real
    45 integer 45 text 45 integer 45.0 real
    45 integer 45 text 45 integer 45.0 real
  }

  4 { 
   INSERT INTO t4(rowid,a,b,c) VALUES(-42.0, -42.0, -42.0, -42.0);
   DELETE FROM t4;
  } {
    -42 integer -42.0 text -42 integer -42.0 real 
    -42 integer -42.0 text -42 integer -42.0 real
    -42 integer -42.0 text -42 integer -42.0 real 
    -42 integer -42.0 text -42 integer -42.0 real
  }

  5 { 
   INSERT INTO t4(rowid,a,b,c) VALUES(NULL, -42.4, -42.4, -42.4);
   DELETE FROM t4;
  } {
    -1 integer -42.4 text -42.4 real -42.4 real
     1 integer -42.4 text -42.4 real -42.4 real
     1 integer -42.4 text -42.4 real -42.4 real
     1 integer -42.4 text -42.4 real -42.4 real
  }

  6 { 
   INSERT INTO t4 VALUES(7, 7, 7);
   UPDATE t4 SET a=8, b=8, c=8;
  } {
    -1 integer 7 text 7 integer 7.0 real
     1 integer 7 text 7 integer 7.0 real
     1 integer 7 text 7 integer 7.0 real
     1 integer 8 text 8 integer 8.0 real
     1 integer 7 text 7 integer 7.0 real
     1 integer 8 text 8 integer 8.0 real
  }

  7 { 
   UPDATE t4 SET rowid=2;
  } {
     1 integer 8 text 8 integer 8.0 real
     2 integer 8 text 8 integer 8.0 real
     1 integer 8 text 8 integer 8.0 real
     2 integer 8 text 8 integer 8.0 real
  }

  8 { 
   UPDATE t4 SET a='9', b='9', c='9';
  } {
     2 integer 8 text 8 integer 8.0 real
     2 integer 9 text 9 integer 9.0 real
     2 integer 8 text 8 integer 8.0 real
     2 integer 9 text 9 integer 9.0 real
  }

  9 { 
   UPDATE t4 SET a='9.1', b='9.1', c='9.1';
  } {
     2 integer 9   text 9   integer 9.0 real
     2 integer 9.1 text 9.1 real    9.1 real
     2 integer 9   text 9   integer 9.0 real
     2 integer 9.1 text 9.1 real    9.1 real
  }
} {
  do_test triggerC-4.1.$n {
    eval concat [execsql " 
      DELETE FROM log;
      $insert ; 
      SELECT * FROM log;
    "]
  } [join $log " "]
} 

#-------------------------------------------------------------------------
# This block of tests, triggerC-5.*, test that DELETE triggers are fired
# if a row is deleted as a result of OR REPLACE conflict resolution.
#
do_test triggerC-5.1.0 {
  execsql {
    DROP TABLE IF EXISTS t5;
    CREATE TABLE t5(a INTEGER PRIMARY KEY, b);
    CREATE UNIQUE INDEX t5i ON t5(b);
    INSERT INTO t5 VALUES(1, 'a');
    INSERT INTO t5 VALUES(2, 'b');
    INSERT INTO t5 VALUES(3, 'c');

    CREATE TABLE t5g(a, b, c);
    CREATE TRIGGER t5t BEFORE DELETE ON t5 BEGIN
      INSERT INTO t5g VALUES(old.a, old.b, (SELECT count(*) FROM t5));
    END;
  }
} {}
foreach {n dml t5g t5} {
  1 "DELETE FROM t5 WHERE a=2"                        {2 b 3} {1 a 3 c}
  2 "INSERT OR REPLACE INTO t5 VALUES(2, 'd')"        {2 b 3} {1 a 2 d 3 c}
  3 "UPDATE OR REPLACE t5 SET a = 2 WHERE a = 3"      {2 b 3} {1 a 2 c}
  4 "INSERT OR REPLACE INTO t5 VALUES(4, 'b')"        {2 b 3} {1 a 3 c 4 b}
  5 "UPDATE OR REPLACE t5 SET b = 'b' WHERE b = 'c'"  {2 b 3} {1 a 3 b}
  6 "INSERT OR REPLACE INTO t5 VALUES(2, 'c')"        {2 b 3 3 c 2} {1 a 2 c}
  7 "UPDATE OR REPLACE t5 SET a=1, b='b' WHERE a = 3" {1 a 3 2 b 2} {1 b}
} {
  do_test triggerC-5.1.$n {
    execsql "
      BEGIN;
        $dml ;
        SELECT * FROM t5g;
        SELECT * FROM t5;
      ROLLBACK;
    "
  } [concat $t5g $t5]
}
do_test triggerC-5.2.0 {
  execsql {
    DROP TRIGGER t5t;
    CREATE TRIGGER t5t AFTER DELETE ON t5 BEGIN
      INSERT INTO t5g VALUES(old.a, old.b, (SELECT count(*) FROM t5));
    END;
  }
} {}
foreach {n dml t5g t5} {
  1 "DELETE FROM t5 WHERE a=2"                        {2 b 2} {1 a 3 c}
  2 "INSERT OR REPLACE INTO t5 VALUES(2, 'd')"        {2 b 2} {1 a 2 d 3 c}
  3 "UPDATE OR REPLACE t5 SET a = 2 WHERE a = 3"      {2 b 2} {1 a 2 c}
  4 "INSERT OR REPLACE INTO t5 VALUES(4, 'b')"        {2 b 2} {1 a 3 c 4 b}
  5 "UPDATE OR REPLACE t5 SET b = 'b' WHERE b = 'c'"  {2 b 2} {1 a 3 b}
  6 "INSERT OR REPLACE INTO t5 VALUES(2, 'c')"        {2 b 2 3 c 1} {1 a 2 c}
  7 "UPDATE OR REPLACE t5 SET a=1, b='b' WHERE a = 3" {1 a 2 2 b 1} {1 b}
} {
  do_test triggerC-5.2.$n {
    execsql "
      BEGIN;
        $dml ;
        SELECT * FROM t5g;
        SELECT * FROM t5;
      ROLLBACK;
    "
  } [concat $t5g $t5]
}
do_test triggerC-5.3.0 {
  execsql { PRAGMA recursive_triggers = off }
} {}
foreach {n dml t5g t5} {
  1 "DELETE FROM t5 WHERE a=2"                        {2 b 2} {1 a 3 c}
  2 "INSERT OR REPLACE INTO t5 VALUES(2, 'd')"        {} {1 a 2 d 3 c}
  3 "UPDATE OR REPLACE t5 SET a = 2 WHERE a = 3"      {} {1 a 2 c}
  4 "INSERT OR REPLACE INTO t5 VALUES(4, 'b')"        {} {1 a 3 c 4 b}
  5 "UPDATE OR REPLACE t5 SET b = 'b' WHERE b = 'c'"  {} {1 a 3 b}
  6 "INSERT OR REPLACE INTO t5 VALUES(2, 'c')"        {} {1 a 2 c}
  7 "UPDATE OR REPLACE t5 SET a=1, b='b' WHERE a = 3" {} {1 b}
} {
  do_test triggerC-5.3.$n {
    execsql "
      BEGIN;
        $dml ;
        SELECT * FROM t5g;
        SELECT * FROM t5;
      ROLLBACK;
    "
  } [concat $t5g $t5]
}
do_test triggerC-5.3.8 {
  execsql { PRAGMA recursive_triggers = on }
} {}

#-------------------------------------------------------------------------
# This block of tests, triggerC-6.*, tests that "PRAGMA recursive_triggers"
# statements return the current value of the recursive triggers flag.
#
do_test triggerC-6.1 {
  execsql { PRAGMA recursive_triggers }
} {1}
do_test triggerC-6.2 {
  execsql { 
    PRAGMA recursive_triggers = off;
    PRAGMA recursive_triggers;
  }
} {0}
do_test triggerC-6.3 {
  execsql { 
    PRAGMA recursive_triggers = on;
    PRAGMA recursive_triggers;
  }
} {1}

#-------------------------------------------------------------------------
# Test some of the "undefined behaviour" associated with triggers. The
# undefined behaviour occurs when a row being updated or deleted is 
# manipulated by a BEFORE trigger.
# 
do_test triggerC-7.1 {
  execsql {
    CREATE TABLE t8(x);
    CREATE TABLE t7(a, b);
    INSERT INTO t7 VALUES(1, 2);
    INSERT INTO t7 VALUES(3, 4);
    INSERT INTO t7 VALUES(5, 6);
    CREATE TRIGGER t7t BEFORE UPDATE ON t7 BEGIN
      DELETE FROM t7 WHERE a = 1;
    END;
    CREATE TRIGGER t7ta AFTER UPDATE ON t7 BEGIN
      INSERT INTO t8 VALUES('after fired ' || old.rowid || '->' || new.rowid);
    END;
  }
} {}
do_test triggerC-7.2 {
  execsql {
    BEGIN;
      UPDATE t7 SET b=7 WHERE a = 5;
      SELECT * FROM t7;
      SELECT * FROM t8;
    ROLLBACK;
  }
} {3 4 5 7 {after fired 3->3}}
do_test triggerC-7.3 {
  execsql {
    BEGIN;
      UPDATE t7 SET b=7 WHERE a = 1;
      SELECT * FROM t7;
      SELECT * FROM t8;
    ROLLBACK;
  }
} {3 4 5 6}

do_test triggerC-7.4 {
  execsql {
    DROP TRIGGER t7t;
    CREATE TRIGGER t7t BEFORE UPDATE ON t7 WHEN (old.rowid!=1 OR new.rowid!=8)
    BEGIN
      UPDATE t7 set rowid = 8 WHERE rowid=1;
    END;
  }
} {}
do_test triggerC-7.5 {
  execsql {
    BEGIN;
      UPDATE t7 SET b=7 WHERE a = 5;
      SELECT rowid, * FROM t7;
      SELECT * FROM t8;
    ROLLBACK;
  }
} {2 3 4 3 5 7 8 1 2 {after fired 1->8} {after fired 3->3}}
do_test triggerC-7.6 {
  execsql {
    BEGIN;
      UPDATE t7 SET b=7 WHERE a = 1;
      SELECT rowid, * FROM t7;
      SELECT * FROM t8;
    ROLLBACK;
  }
} {2 3 4 3 5 6 8 1 2 {after fired 1->8}}

do_test triggerC-7.7 {
  execsql {
    DROP TRIGGER t7t;
    DROP TRIGGER t7ta;
    CREATE TRIGGER t7t BEFORE DELETE ON t7 BEGIN
      UPDATE t7 set rowid = 8 WHERE rowid=1;
    END;
    CREATE TRIGGER t7ta AFTER DELETE ON t7 BEGIN
      INSERT INTO t8 VALUES('after fired ' || old.rowid);
    END;
  }
} {}
do_test triggerC-7.8 {
  execsql {
    BEGIN;
      DELETE FROM t7 WHERE a = 3;
      SELECT rowid, * FROM t7;
      SELECT * FROM t8;
    ROLLBACK;
  }
} {3 5 6 8 1 2 {after fired 2}}
do_test triggerC-7.9 {
  execsql {
    BEGIN;
      DELETE FROM t7 WHERE a = 1;
      SELECT rowid, * FROM t7;
      SELECT * FROM t8;
    ROLLBACK;
  }
} {2 3 4 3 5 6 8 1 2}

# Ticket [e25d9ea771febc9c311928c1c01c3163dcb26643]
# 
do_test triggerC-9.1 {
  execsql {
    CREATE TABLE t9(a,b);
    CREATE INDEX t9b ON t9(b);
    INSERT INTO t9 VALUES(1,0);
    INSERT INTO t9 VALUES(2,1);
    INSERT INTO t9 VALUES(3,2);
    INSERT INTO t9 SELECT a+3, a+2 FROM t9;
    INSERT INTO t9 SELECT a+6, a+5 FROM t9;
    SELECT a FROM t9 ORDER BY a;
  }
} {1 2 3 4 5 6 7 8 9 10 11 12}
do_test triggerC-9.2 {
  execsql {
    CREATE TRIGGER t9r1 AFTER DELETE ON t9 BEGIN
      DELETE FROM t9 WHERE b=old.a;
    END;
    DELETE FROM t9 WHERE b=4;
    SELECT a FROM t9 ORDER BY a;
  }
} {1 2 3 4}
 



finish_test
Changes to test/types.test.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. Specfically
# it tests that the different storage classes (integer, real, text etc.)
# all work correctly.
#
# $Id: types.test,v 1.19 2006/06/27 12:51:13 drh Exp $
# $Id: types.test,v 1.20 2009/06/29 06:00:37 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Tests in this file are organized roughly as follows:
#
# types-1.*.*: Test that values are stored using the expected storage
132
133
134
135
136
137
138

139
140
141
142
143
144
145
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146







+







}

# Open the table with root-page $rootpage at the btree
# level. Return a list that is the length of each record
# in the table, in the tables default scanning order.
proc record_sizes {rootpage} {
  set bt [btree_open test.db 10 0]
  btree_begin_transaction $bt
  set c [btree_cursor $bt $rootpage 0]
  btree_first $c
  while 1 {
    lappend res [btree_payload_size $c]
    if {[btree_next $c]} break
  }
  btree_close_cursor $c
Changes to test/vtab1.test.
1150
1151
1152
1153
1154
1155
1156

1157
1158
1159
1160
1161
1162







1163
1164
1165
1150
1151
1152
1153
1154
1155
1156
1157






1158
1159
1160
1161
1162
1163
1164
1165
1166
1167







+
-
-
-
-
-
-
+
+
+
+
+
+
+



    set echo_module_fail($method,t2) "the $method method has failed"
    catchsql { INSERT INTO echo_t2 VALUES(7, 8, 9) }
  } "1 {echo-vtab-error: the $method method has failed}"
  unset echo_module_fail($method,t2)
  incr tn
}

ifcapable altertable {
do_test vtab1-16.$tn {
  set echo_module_fail(xRename,t2) "the xRename method has failed"
  catchsql { ALTER TABLE echo_t2 RENAME TO another_name }
} "1 {echo-vtab-error: the xRename method has failed}"
unset echo_module_fail(xRename,t2)
incr tn
  do_test vtab1-16.$tn {
    set echo_module_fail(xRename,t2) "the xRename method has failed"
    catchsql { ALTER TABLE echo_t2 RENAME TO another_name }
  } "1 {echo-vtab-error: the xRename method has failed}"
  unset echo_module_fail(xRename,t2)
  incr tn
}

unset -nocomplain echo_module_begin_fail
finish_test
Changes to test/vtab5.test.
130
131
132
133
134
135
136

137
138
139
140
141






142
143
144
145
146
147
148
130
131
132
133
134
135
136
137





138
139
140
141
142
143
144
145
146
147
148
149
150







+
-
-
-
-
-
+
+
+
+
+
+







  catchsql {
    CREATE INDEX echo_strings_i ON echo_strings(str);
  }
} {1 {virtual tables may not be indexed}}

# Test that it is impossible to add a column to a virtual table.
#
ifcapable altertable {
do_test vtab5.4.2 {
  catchsql {
    ALTER TABLE echo_strings ADD COLUMN col2;
  }
} {1 {virtual tables may not be altered}}
  do_test vtab5.4.2 {
    catchsql {
      ALTER TABLE echo_strings ADD COLUMN col2;
    }
  } {1 {virtual tables may not be altered}}
}

# Test that it is impossible to rename a virtual table.
# UPDATE: It is now possible.
#
# do_test vtab5.4.3 {
#   catchsql {
#     ALTER TABLE echo_strings RENAME TO echo_strings2;
Changes to test/vtab6.test.
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24







-
+







#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for joins, including outer joins involving
# virtual tables. The test cases in this file are copied from the file
# join.test, and some of the comments still reflect that.
#
# $Id: vtab6.test,v 1.4 2008/07/12 14:52:21 drh Exp $
# $Id: vtab6.test,v 1.5 2009/07/01 16:12:08 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !vtab {
  finish_test
  return
261
262
263
264
265
266
267
268
269

270
271

272
273
274
275
276
277
278
261
262
263
264
265
266
267


268


269
270
271
272
273
274
275
276







-
-
+
-
-
+







} {1 {cannot have both ON and USING clauses in the same join}}
do_test vtab6-3.4 {
  catchsql {
    SELECT * FROM t1 JOIN t2 USING(a);
  }
} {1 {cannot join using column a - column not present in both tables}}
do_test vtab6-3.5 {
  catchsql {
    SELECT * FROM t1 USING(a);
  catchsql { SELECT * FROM t1 USING(a) }
  }
} {0 {1 2 3 2 3 4 3 4 5}}
} {1 {a JOIN clause is required before USING}}
do_test vtab6-3.6 {
  catchsql {
    SELECT * FROM t1 JOIN t2 ON t3.a=t2.b;
  }
} {1 {no such column: t3.a}}
do_test vtab6-3.7 {
  catchsql {
490
491
492
493
494
495
496

497
498
499
500
501
502
503
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502







+







  }
} {1 2 3}


do_test vtab6-11.2.0 {
  execsql {
    CREATE INDEX ab_i ON ab_r(b);
    CREATE INDEX bc_i ON bc_r(b);
  }
} {}

unset ::echo_module_cost

do_test vtab6-11.2.1 {
  execsql {
558
559
560
561
562
563
564
565

566
567
568
569
570
571
572
573
574
557
558
559
560
561
562
563

564
565
566
567
568
569
570
571
572
573







-
+









set ::echo_module_ignore_usable 1
db cache flush

do_test vtab6-11.4.1 {
  catchsql {
    SELECT a, b, c FROM ab NATURAL JOIN bc;
  }
} {1 {table ab: xBestIndex returned an invalid plan}}
} {1 {table bc: xBestIndex returned an invalid plan}}
do_test vtab6-11.4.2 {
  catchsql {
    SELECT a, b, c FROM bc NATURAL JOIN ab;
  }
} {1 {table ab: xBestIndex returned an invalid plan}}

unset ::echo_module_ignore_usable

finish_test
Changes to test/vtab_alter.test.
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27







-
+







# command on virtual tables.
#
# $Id: vtab_alter.test,v 1.3 2007/12/13 21:54:11 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !vtab {
ifcapable !vtab||!altertable {
  finish_test
  return
}

# Register the echo module.
#
# This test uses a special feature of the echo module. If the name
Changes to test/vtab_shared.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38

39
40
41
42



43
44
45

46



47
48
49









50
51
52
53


















54
55

























56
57
58
59






































































































































60
61
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25

26












27
28
29
30

31
32
33
34
35

36
37
38
39
40



41
42
43
44
45
46
47
48
49
50



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95




96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231













-
+











-
+
-
-
-
-
-
-
-
-
-
-
-
-
+



-
+
+
+


-
+

+
+
+
-
-
-
+
+
+
+
+
+
+
+
+

-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


# 2007 April 16
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file tests interactions between the virtual table and
# shared-schema functionality.
#
# $Id: vtab_shared.test,v 1.2 2008/03/19 13:03:34 drh Exp $
# $Id: vtab_shared.test,v 1.3 2009/07/24 17:58:53 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !vtab||!shared_cache {
  finish_test
  return
}

db close
sqlite3_enable_shared_cache 1
sqlite3 db test.db
sqlite3 db  test.db

do_test vtab_shared-1.0 {
  register_echo_module [sqlite3_connection_pointer db]
  catchsql {
    CREATE TABLE t0(a, b, c);
    CREATE VIRTUAL TABLE t1 USING echo(t0);
  }
} {1 {Cannot use virtual tables in shared-cache mode}}

db close
sqlite3_enable_shared_cache 0
sqlite3 db test.db
sqlite3 db2 test.db

do_test vtab_shared-1.1 {
  register_echo_module [sqlite3_connection_pointer db]
  catchsql {
  execsql {
    CREATE TABLE t0(a, b, c);
    INSERT INTO t0 VALUES(1, 2, 3);
    CREATE VIRTUAL TABLE t1 USING echo(t0);
  }
} {0 {}}
} {}

do_test vtab_shared-1.2 {
  execsql { SELECT * FROM t1 } db
} {1 2 3}
db close
sqlite3_enable_shared_cache 1
sqlite3 db test.db

# Fails because the 'echo' module has not been registered with connection db2
do_test vtab_shared-1.3 {
  catchsql { SELECT * FROM t1 } db2
} {1 {no such module: echo}}

do_test vtab_shared-1.4 {
  execsql { SELECT * FROM t0 } db2
} {1 2 3}

do_test vtab_shared-1.2 {
  register_echo_module [sqlite3_connection_pointer db]
  catchsql {
do_test vtab_shared-1.5 {
  register_echo_module [sqlite3_connection_pointer db2]
  execsql { SELECT * FROM t1 } db
} {1 2 3}

# Works after the module is registered with db2
do_test vtab_shared-1.6 {
  execsql { SELECT * FROM t1 } db2
} {1 2 3}

# Set a write-lock on table t0 using connection [db]. Then try to read from
# virtual table t1 using [db2]. That this returns an SQLITE_LOCKED error
# shows that the correct sqlite3_vtab is being used.
#
do_test vtab_shared-1.8.1 {
  execsql { 
    BEGIN;
    INSERT INTO t1 VALUES(4, 5, 6);
    SELECT * FROM t1;
  }
} {1 2 3 4 5 6}
do_test vtab_shared-1.8.2 {
  catchsql { SELECT * FROM t1 } db2
} {1 {database table is locked}}
do_test vtab_shared-1.8.3 {
  catchsql { SELECT *  FROM t0 } db2
} {1 {database table is locked: t0}}
do_test vtab_shared-1.8.4 {
  execsql { SELECT * FROM t0 } db
} {1 2 3 4 5 6}
do_test vtab_shared-1.8.5 {
  execsql { COMMIT } db
  execsql { SELECT *  FROM t1 } db2
} {1 2 3 4 5 6}

# While a SELECT is active on virtual table t1 via connection [db], close 
# [db2]. This causes the schema to be reset internally. Verify that this
# does not cause a problem.
#
foreach {iTest dbSelect dbClose} {
  1 db  db2
  2 db  db2
  3 db2 db
} {
  do_test vtab_shared-1.9.$iTest {
} [list 1 \
  {malformed database schema (t1) - Cannot use virtual tables in shared-cache mode}]

db close
    set res [list]
    $dbSelect eval { SELECT * FROM t1 } {
      if {$a == 1} {$dbClose close}
      lappend res $a $b $c
    }
    sqlite3 $dbClose test.db
    register_echo_module [sqlite3_connection_pointer $dbClose]
    set res
  } {1 2 3 4 5 6}
}

# Ensure that it is not possible for one connection to DROP a virtual
# table while a second connection is reading from the database.
#
do_test vtab_shared-1.10 {
  db eval { SELECT * FROM t1 } {
    set error [catchsql { DROP TABLE t1 } db2]
    break
  }
  set error
} {1 {database table is locked: sqlite_master}}

do_test vtab_shared-1.11 {
breakpoint
  execsql {
    CREATE VIRTUAL TABLE t2 USING echo(t0);
    CREATE VIRTUAL TABLE t3 USING echo(t0);
  }
  execsql { SELECT * FROM t3 } db2
} {1 2 3 4 5 6}

do_test vtab_shared-1.12.1 {
  db close
  execsql { 
    SELECT * FROM t1 UNION ALL
    SELECT * FROM t2 UNION ALL
    SELECT * FROM t3 
  } db2
} {1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6}
do_test vtab_shared-1.12.2 {
  sqlite3 db test.db
  register_echo_module [sqlite3_connection_pointer db]
  execsql { 
    SELECT * FROM t1 UNION ALL
    SELECT * FROM t2 UNION ALL
    SELECT * FROM t3 
  } db
} {1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6}

# Try a rename or two.
#
ifcapable altertable {
  do_test vtab_shared-1.13.1 {
    execsql { ALTER TABLE t1 RENAME TO t4 }
    execsql { SELECT * FROM t4 } db
  } {1 2 3 4 5 6}
  do_test vtab_shared-1.13.2 {
    execsql { SELECT * FROM t4 } db2
  } {1 2 3 4 5 6}
  do_test vtab_shared-1.13.3 {
    execsql { ALTER TABLE t2 RENAME TO t5 }
    execsql { SELECT * FROM t4 } db2
  } {1 2 3 4 5 6}
}

# Try an UPDATE/INSERT/DELETE on a shared vtab as the first statement after a
# schema is loaded.
do_test vtab_shared_1.14.1 {
  db2 close
  sqlite3 db2 test.db
  register_echo_module [sqlite3_connection_pointer db2]
  execsql { SELECT * FROM t3 }
} {1 2 3 4 5 6}
do_test vtab_shared_1.14.2 {
  execsql { 
    UPDATE t3 SET c = 'six' WHERE c = 6;
    SELECT * FROM t3;
  } db2
} {1 2 3 4 5 six}
do_test vtab_shared_1.14.3 {
  db2 close
  sqlite3 db2 test.db
  register_echo_module [sqlite3_connection_pointer db2]
  execsql { SELECT * FROM t3 }
} {1 2 3 4 5 six}
do_test vtab_shared_1.14.4 {
  execsql { 
    DELETE FROM t3 WHERE c = 'six';
    SELECT * FROM t3;
  } db2
} {1 2 3}
do_test vtab_shared_1.14.5 {
  db2 close
  sqlite3 db2 test.db
  register_echo_module [sqlite3_connection_pointer db2]
  execsql { SELECT * FROM t3 }
} {1 2 3}
do_test vtab_shared_1.14.6 {
  execsql { 
    INSERT INTO t3 VALUES(4, 5, 6);
    SELECT * FROM t3;
  } db2
} {1 2 3 4 5 6}

do_test vtab_shared_1.15.1 {
  db2 close
  sqlite3 db2 test.db
  register_echo_module [sqlite3_connection_pointer db2]
  execsql { 
    UPDATE t3 SET c = 'six' WHERE c = 6;
    SELECT * FROM t3;
  } db2
} {1 2 3 4 5 six}
do_test vtab_shared_1.15.2 {
  db2 close
  sqlite3 db2 test.db
  register_echo_module [sqlite3_connection_pointer db2]
  execsql { 
    DELETE FROM t3 WHERE c = 'six';
    SELECT * FROM t3;
  } db2
} {1 2 3}
do_test vtab_shared_1.15.3 {
  db2 close
  sqlite3 db2 test.db
  register_echo_module [sqlite3_connection_pointer db2]
  execsql { 
    INSERT INTO t3 VALUES(4, 5, 6);
    SELECT * FROM t3;
  }
} {1 2 3 4 5 6}

db close
db2 close
sqlite3_enable_shared_cache 0
finish_test
Changes to test/where7.test.
86
87
88
89
90
91
92

93
94
95
96

97
98
99
100
101
102
103
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105







+




+







} {2 4 5 scan 0 sort 0}
do_test where7-1.9 {
  count_steps {
    SELECT a FROM t1 WHERE (b=3 OR c>=10 OR c=4)
  }
} {2 4 5 scan 0 sort 0}
do_test where7-1.10 {
breakpoint
  count_steps {
    SELECT a FROM t1 WHERE (b=3 OR c>=10 OR c=4 OR b>10)
  }
} {2 4 5 scan 0 sort 0}
breakpoint
do_test where7-1.11 {
  count_steps {
    SELECT a FROM t1 WHERE (d=5 AND b=3) OR c==100 ORDER BY a;
  }
} {2 5 scan 0 sort 1}
do_test where7-1.12 {
  count_steps {
5408
5409
5410
5411
5412
5413
5414
5415

5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429

5430
5431
5432
5433
5434
5435
5436
5410
5411
5412
5413
5414
5415
5416

5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430

5431
5432
5433
5434
5435
5436
5437
5438







-
+













-
+







         OR ((a BETWEEN 31 AND 33) AND a!=32)
         OR (d>=94.0 AND d<95.0 AND d NOT NULL)
         OR 1000000<b
         OR (f GLOB '?pqrs*' AND f GLOB 'opqr*')
         OR (g='rqponml' AND f GLOB 'lmnop*')
         OR (f GLOB '?ijkl*' AND f GLOB 'hijk*')
  }
} {7 14 18 31 33 37 40 51 53 59 66 85 92 94 98 100 scan 99 sort 0}
} {7 14 18 31 33 37 40 51 53 59 66 85 92 94 98 100 scan 0 sort 0}
do_test where7-2.235.2 {
  count_steps_sort {
     SELECT a FROM t3
      WHERE ((a BETWEEN 98 AND 100) AND a!=99)
         OR ((a BETWEEN 51 AND 53) AND a!=52)
         OR a=18
         OR ((a BETWEEN 31 AND 33) AND a!=32)
         OR (d>=94.0 AND d<95.0 AND d NOT NULL)
         OR 1000000<b
         OR (f GLOB '?pqrs*' AND f GLOB 'opqr*')
         OR (g='rqponml' AND f GLOB 'lmnop*')
         OR (f GLOB '?ijkl*' AND f GLOB 'hijk*')
  }
} {7 14 18 31 33 37 40 51 53 59 66 85 92 94 98 100 scan 99 sort 0}
} {7 14 18 31 33 37 40 51 53 59 66 85 92 94 98 100 scan 0 sort 0}
do_test where7-2.236.1 {
  count_steps_sort {
     SELECT a FROM t2
      WHERE b=1001
         OR b=168
         OR (f GLOB '?ijkl*' AND f GLOB 'hijk*')
         OR (d>=89.0 AND d<90.0 AND d NOT NULL)
6850
6851
6852
6853
6854
6855
6856
6857

6858
6859
6860
6861
6862
6863
6864
6852
6853
6854
6855
6856
6857
6858

6859
6860
6861
6862
6863
6864
6865
6866







-
+







         OR ((a BETWEEN 37 AND 39) AND a!=38)
         OR ((a BETWEEN 56 AND 58) AND a!=57)
         OR ((a BETWEEN 18 AND 20) AND a!=19)
         OR (d>=45.0 AND d<46.0 AND d NOT NULL)
         OR (f GLOB '?ghij*' AND f GLOB 'fghi*')
         OR ((a BETWEEN 53 AND 55) AND a!=54)
  }
} {5 7 18 20 23 25 31 33 37 39 45 53 54 55 56 57 58 59 72 74 83 85 95 scan 99 sort 0}
} {5 7 18 20 23 25 31 33 37 39 45 53 54 55 56 57 58 59 72 74 83 85 95 scan 0 sort 0}
do_test where7-2.297.2 {
  count_steps_sort {
     SELECT a FROM t3
      WHERE a=95
         OR ((a BETWEEN 72 AND 74) AND a!=73)
         OR ((a BETWEEN 23 AND 25) AND a!=24)
         OR b=594
8948
8949
8950
8951
8952
8953
8954
8955

8956
8957
8958
8959
8960
8961
8962
8950
8951
8952
8953
8954
8955
8956

8957
8958
8959
8960
8961
8962
8963
8964







-
+







         OR ((a BETWEEN 32 AND 34) AND a!=33)
         OR (f GLOB '?cdef*' AND f GLOB 'bcde*')
         OR b=300
         OR ((a BETWEEN 24 AND 26) AND a!=25)
         OR (d>=21.0 AND d<22.0 AND d NOT NULL)
         OR ((a BETWEEN 93 AND 95) AND a!=94)
  }
} {1 11 13 21 22 24 26 27 32 34 39 41 53 61 74 76 79 93 95 scan 99 sort 0}
} {1 11 13 21 22 24 26 27 32 34 39 41 53 61 74 76 79 93 95 scan 0 sort 0}
do_test where7-2.385.2 {
  count_steps_sort {
     SELECT a FROM t3
      WHERE (d>=61.0 AND d<62.0 AND d NOT NULL)
         OR ((a BETWEEN 11 AND 13) AND a!=12)
         OR ((a BETWEEN 74 AND 76) AND a!=75)
         OR ((a BETWEEN 39 AND 41) AND a!=40)
Changes to test/where8.test.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The focus
# is testing of where.c. More specifically, the focus is the optimization
# of WHERE clauses that feature the OR operator.
#
# $Id: where8.test,v 1.8 2009/06/07 23:45:11 drh Exp $
# $Id: where8.test,v 1.9 2009/07/31 06:14:52 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Test organization:
#
#   where8-1.*: Tests to demonstrate simple cases work with a single table
283
284
285
286
287
288
289
290

291
292
293
294
295
296
297
283
284
285
286
287
288
289

290
291
292
293
294
295
296
297







-
+








do_test where8-3.15 {
  execsql_status {
    SELECT c FROM t1, t2 WHERE a BETWEEN 1 AND 2 OR a = (
      SELECT sum(e IS NULL) FROM t2 AS inner WHERE t2.d>inner.d
    )
  }
} {I I I I I I I I I I II II II II II II II II II II III III III III III 99 0}
} {I II I II I II I II I II I II III I II III I II III I II III I II III 9 0}

#-----------------------------------------------------------------------
# The following tests - where8-4.* - verify that adding or removing 
# indexes does not change the results returned by various queries.
#
do_test where8-4.1 {
  execsql {
649
650
651
652
653
654
655
656
657
658
659
660













































661
649
650
651
652
653
654
655

656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705







-




+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

      list
    } {}

    do_test where8-4.$A.$B.2 { lsort $R } [lsort $results($B)]
  }
  incr A
}

catch {unset results}
catch {unset A}
catch {unset B}

# At one point the following tests provoked an invalid write error (writing
# to memory that had already been freed). It was not possible to demonstrate
# that this bug could cause a query to return bad data.
# 
do_test where8-5.1 {
  db close
  sqlite3 db test.db
  sqlite3_db_config_lookaside db 0 0 0
  execsql {
    CREATE TABLE tA(
      a, b, c, d, e, f, g, h, 
      i, j, k, l, m, n, o, p
    );
  }
  execsql {
    SELECT * FROM tA WHERE
      a=1 AND b=2 AND c=3 AND d=4 AND e=5 AND f=6 AND g=7 AND h=8 AND
      i=1 AND j=2 AND k=3 AND l=4 AND m=5 AND n=6 AND o=7 AND
      (p = 1 OR p = 2 OR p = 3)
  }
} {}
do_test where8-5.2 {
  execsql {
    SELECT * FROM tA WHERE
      a=1 AND b=2 AND c=3 AND d=4 AND e=5 AND f=6 AND g=7 AND h=8 AND
      i=1 AND j=2 AND k=3 AND l=4 AND m=5 AND
      (p = 1 OR p = 2 OR p = 3) AND n=6 AND o=7
  }
} {}
do_test where8-5.3 {
  execsql {
    INSERT INTO tA VALUES(1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8); 
    CREATE UNIQUE INDEX tAI ON tA(p);
    CREATE TABLE tB(x);
    INSERT INTO tB VALUES('x');
  }
  execsql {
    SELECT a, x FROM tA LEFT JOIN tB ON (
      a=1 AND b=2 AND c=3 AND d=4 AND e=5 AND f=6 AND g=7 AND h=8 AND
      i=1 AND j=2 AND k=3 AND l=4 AND m=5 AND n=6 AND o=7 AND
      (p = 1 OR p = 2 OR p = 3)
    )
  }
} {1 {}}

finish_test
Added test/whereB.test.































































































































































































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 August 13
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is testing WHERE clause conditions with
# subtle affinity issues.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# For this set of tests:
#
#  *   t1.y holds an integer value with affinity NONE
#  *   t2.b holds a text value with affinity TEXT
#
# These values are not equal and because neither affinity is NUMERIC
# no type conversion occurs.
#
do_test whereB-1.1 {
  db eval {
    CREATE TABLE t1(x,y);    -- affinity of t1.y is NONE
    INSERT INTO t1 VALUES(1,99);

    CREATE TABLE t2(a, b TEXT);  -- affinity of t2.b is TEXT
    CREATE INDEX t2b ON t2(b);
    INSERT INTO t2 VALUES(2,99);

    SELECT x, a, y=b FROM t1, t2 ORDER BY +x, +a;
  }
} {1 2 0}
do_test whereB-1.2 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE y=b;
  }
} {}
do_test whereB-1.3 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE b=y;
  }
} {}
do_test whereB-1.4 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
  }
} {}
do_test whereB-1.100 {
  db eval {
    DROP INDEX t2b;
    SELECT x, a, y=b FROM t1, t2 WHERE y=b;
  }
} {}
do_test whereB-1.101 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE b=y;
  }
} {}
do_test whereB-1.102 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
  }
} {}

# For this set of tests:
#
#  *   t1.y holds a text value with affinity TEXT
#  *   t2.b holds an integer value with affinity NONE
#
# These values are not equal and because neither affinity is NUMERIC
# no type conversion occurs.
#
do_test whereB-2.1 {
  db eval {
    DROP TABLE t1;
    DROP TABLE t2;

    CREATE TABLE t1(x, y TEXT);    -- affinity of t1.y is TEXT
    INSERT INTO t1 VALUES(1,99);

    CREATE TABLE t2(a, b BLOB);  -- affinity of t2.b is NONE
    CREATE INDEX t2b ON t2(b);
    INSERT INTO t2 VALUES(2,99);

    SELECT x, a, y=b FROM t1, t2 ORDER BY +x, +a;
  }
} {1 2 0}
do_test whereB-2.2 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE y=b;
  }
} {}
do_test whereB-2.3 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE b=y;
  }
} {}
do_test whereB-2.4 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
  }
} {}
do_test whereB-2.100 {
  db eval {
    DROP INDEX t2b;
    SELECT x, a, y=b FROM t1, t2 WHERE y=b;
  }
} {}
do_test whereB-2.101 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE b=y;
  }
} {}
do_test whereB-2.102 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
  }
} {}

# For this set of tests:
#
#  *   t1.y holds a text value with affinity NONE
#  *   t2.b holds an integer value with affinity NONE
#
# These values are not equal and because neither affinity is NUMERIC
# no type conversion occurs.
#
do_test whereB-3.1 {
  db eval {
    DROP TABLE t1;
    DROP TABLE t2;

    CREATE TABLE t1(x, y BLOB);    -- affinity of t1.y is NONE
    INSERT INTO t1 VALUES(1,99);

    CREATE TABLE t2(a, b BLOB);  -- affinity of t2.b is NONE
    CREATE INDEX t2b ON t2(b);
    INSERT INTO t2 VALUES(2,'99');

    SELECT x, a, y=b FROM t1, t2;
  }
} {1 2 0}
do_test whereB-3.2 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE y=b;
  }
} {}
do_test whereB-3.3 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE b=y;
  }
} {}
do_test whereB-3.4 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
  }
} {}
do_test whereB-3.100 {
  db eval {
    DROP INDEX t2b;
    SELECT x, a, y=b FROM t1, t2 WHERE y=b;
  }
} {}
do_test whereB-3.101 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE b=y;
  }
} {}
do_test whereB-3.102 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
  }
} {}


# For this set of tests:
#
#  *   t1.y holds a text value with affinity NONE
#  *   t2.b holds an integer value with affinity NUMERIC
#
# Because t2.b has a numeric affinity, type conversion should occur
# and the two fields should be equal.
#
do_test whereB-4.1 {
  db eval {
    DROP TABLE t1;
    DROP TABLE t2;

    CREATE TABLE t1(x, y BLOB);    -- affinity of t1.y is NONE
    INSERT INTO t1 VALUES(1,'99');

    CREATE TABLE t2(a, b NUMERIC);  -- affinity of t2.b is NUMERIC
    CREATE INDEX t2b ON t2(b);
    INSERT INTO t2 VALUES(2,99);

    SELECT x, a, y=b FROM t1, t2;
  }
} {1 2 1}
do_test whereB-4.2 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE y=b;
  }
} {1 2 1}
do_test whereB-4.3 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE b=y;
  }
} {1 2 1}
do_test whereB-4.4 {
  # In this case the unary "+" operator removes the column affinity so
  # the columns compare false
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
  }
} {}
do_test whereB-4.100 {
  db eval {
    DROP INDEX t2b;
    SELECT x, a, y=b FROM t1, t2 WHERE y=b;
  }
} {1 2 1}
do_test whereB-4.101 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE b=y;
  }
} {1 2 1}
do_test whereB-4.102 {
  # In this case the unary "+" operator removes the column affinity so
  # the columns compare false
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
  }
} {}



# For this set of tests:
#
#  *   t1.y holds a text value with affinity NONE
#  *   t2.b holds an integer value with affinity INTEGER
#
# Because t2.b has a numeric affinity, type conversion should occur
# and the two fields should be equal.
#
do_test whereB-5.1 {
  db eval {
    DROP TABLE t1;
    DROP TABLE t2;

    CREATE TABLE t1(x, y BLOB);    -- affinity of t1.y is NONE
    INSERT INTO t1 VALUES(1,'99');

    CREATE TABLE t2(a, b INT);  -- affinity of t2.b is INTEGER
    CREATE INDEX t2b ON t2(b);
    INSERT INTO t2 VALUES(2,99);

    SELECT x, a, y=b FROM t1, t2;
  }
} {1 2 1}
do_test whereB-5.2 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE y=b;
  }
} {1 2 1}
do_test whereB-5.3 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE b=y;
  }
} {1 2 1}
do_test whereB-5.4 {
  # In this case the unary "+" operator removes the column affinity so
  # the columns compare false
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
  }
} {}
do_test whereB-5.100 {
  db eval {
    DROP INDEX t2b;
    SELECT x, a, y=b FROM t1, t2 WHERE y=b;
  }
} {1 2 1}
do_test whereB-5.101 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE b=y;
  }
} {1 2 1}
do_test whereB-5.102 {
  # In this case the unary "+" operator removes the column affinity so
  # the columns compare false
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
  }
} {}


# For this set of tests:
#
#  *   t1.y holds a text value with affinity NONE
#  *   t2.b holds an integer value with affinity REAL
#
# Because t2.b has a numeric affinity, type conversion should occur
# and the two fields should be equal.
#
do_test whereB-6.1 {
  db eval {
    DROP TABLE t1;
    DROP TABLE t2;

    CREATE TABLE t1(x, y BLOB);    -- affinity of t1.y is NONE
    INSERT INTO t1 VALUES(1,'99');

    CREATE TABLE t2(a, b REAL);  -- affinity of t2.b is REAL
    CREATE INDEX t2b ON t2(b);
    INSERT INTO t2 VALUES(2,99.0);

    SELECT x, a, y=b FROM t1, t2;
  }
} {1 2 1}
do_test whereB-6.2 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE y=b;
  }
} {1 2 1}
do_test whereB-6.3 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE b=y;
  }
} {1 2 1}
do_test whereB-6.4 {
  # In this case the unary "+" operator removes the column affinity so
  # the columns compare false
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
  }
} {}
do_test whereB-6.100 {
  db eval {
    DROP INDEX t2b;
    SELECT x, a, y=b FROM t1, t2 WHERE y=b;
  }
} {1 2 1}
do_test whereB-6.101 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE b=y;
  }
} {1 2 1}
do_test whereB-6.102 {
  # In this case the unary "+" operator removes the column affinity so
  # the columns compare false
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
  }
} {}


# For this set of tests:
#
#  *   t1.y holds an integer value with affinity NUMERIC
#  *   t2.b holds a text value with affinity NONE
#
# Because t1.y has a numeric affinity, type conversion should occur
# and the two fields should be equal.
#
do_test whereB-7.1 {
  db eval {
    DROP TABLE t1;
    DROP TABLE t2;

    CREATE TABLE t1(x, y NUMERIC);  -- affinity of t1.y is NUMERIC
    INSERT INTO t1 VALUES(1,99);

    CREATE TABLE t2(a, b BLOB);  -- affinity of t2.b is NONE
    CREATE INDEX t2b ON t2(b);
    INSERT INTO t2 VALUES(2,'99');

    SELECT x, a, y=b FROM t1, t2;
  }
} {1 2 1}
do_test whereB-7.2 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE y=b;
  }
} {1 2 1}
do_test whereB-7.3 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE b=y;
  }
} {1 2 1}
do_test whereB-7.4 {
  # In this case the unary "+" operator removes the column affinity so
  # the columns compare false
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
  }
} {}
do_test whereB-7.100 {
  db eval {
    DROP INDEX t2b;
    SELECT x, a, y=b FROM t1, t2 WHERE y=b;
  }
} {1 2 1}
do_test whereB-7.101 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE b=y;
  }
} {1 2 1}
do_test whereB-7.102 {
  # In this case the unary "+" operator removes the column affinity so
  # the columns compare false
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
  }
} {}

# For this set of tests:
#
#  *   t1.y holds an integer value with affinity INTEGER
#  *   t2.b holds a text value with affinity NONE
#
# Because t1.y has a numeric affinity, type conversion should occur
# and the two fields should be equal.
#
do_test whereB-8.1 {
  db eval {
    DROP TABLE t1;
    DROP TABLE t2;

    CREATE TABLE t1(x, y INT);  -- affinity of t1.y is INTEGER
    INSERT INTO t1 VALUES(1,99);

    CREATE TABLE t2(a, b BLOB);  -- affinity of t2.b is NONE
    CREATE INDEX t2b ON t2(b);
    INSERT INTO t2 VALUES(2,'99');

    SELECT x, a, y=b FROM t1, t2;
  }
} {1 2 1}
do_test whereB-8.2 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE y=b;
  }
} {1 2 1}
do_test whereB-8.3 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE b=y;
  }
} {1 2 1}
do_test whereB-8.4 {
  # In this case the unary "+" operator removes the column affinity so
  # the columns compare false
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
  }
} {}
do_test whereB-8.100 {
  db eval {
    DROP INDEX t2b;
    SELECT x, a, y=b FROM t1, t2 WHERE y=b;
  }
} {1 2 1}
do_test whereB-8.101 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE b=y;
  }
} {1 2 1}
do_test whereB-8.102 {
  # In this case the unary "+" operator removes the column affinity so
  # the columns compare false
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
  }
} {}

# For this set of tests:
#
#  *   t1.y holds an integer value with affinity REAL
#  *   t2.b holds a text value with affinity NONE
#
# Because t1.y has a numeric affinity, type conversion should occur
# and the two fields should be equal.
#
do_test whereB-9.1 {
  db eval {
    DROP TABLE t1;
    DROP TABLE t2;

    CREATE TABLE t1(x, y REAL);  -- affinity of t1.y is REAL
    INSERT INTO t1 VALUES(1,99.0);

    CREATE TABLE t2(a, b BLOB);  -- affinity of t2.b is NONE
    CREATE INDEX t2b ON t2(b);
    INSERT INTO t2 VALUES(2,'99');

    SELECT x, a, y=b FROM t1, t2;
  }
} {1 2 1}
do_test whereB-9.2 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE y=b;
  }
} {1 2 1}
do_test whereB-9.3 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE b=y;
  }
} {1 2 1}
do_test whereB-9.4 {
  # In this case the unary "+" operator removes the column affinity so
  # the columns compare false
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
  }
} {}
do_test whereB-9.100 {
  db eval {
    DROP INDEX t2b;
    SELECT x, a, y=b FROM t1, t2 WHERE y=b;
  }
} {1 2 1}
do_test whereB-9.101 {
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE b=y;
  }
} {1 2 1}
do_test whereB-9.102 {
  # In this case the unary "+" operator removes the column affinity so
  # the columns compare false
  db eval {
    SELECT x, a, y=b FROM t1, t2 WHERE +y=+b;
  }
} {}




finish_test
Changes to test/zeroblob.test.
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23







-
+







#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing of the zero-filled blob functionality
# including the sqlite3_bind_zeroblob(), sqlite3_result_zeroblob(),
# and the built-in zeroblob() SQL function.
#
# $Id: zeroblob.test,v 1.13 2008/06/13 18:24:28 drh Exp $
# $Id: zeroblob.test,v 1.14 2009/07/14 02:33:02 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !incrblob {
  finish_test
  return
222
223
224
225
226
227
228
229





























230
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259








+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#
do_test zeroblob-8.1 {
  llength [execsql {
    SELECT 'hello' AS a, zeroblob(10) as b from t1 ORDER BY a, b;
  }]
} {8}


# Ticket #3965
# zeroblobs on either size of an IN operator
#
do_test zeroblob-9.1 {
  db eval {SELECT x'0000' IN (x'000000')}
} {0}
do_test zeroblob-9.2 {
  db eval {SELECT x'0000' IN (x'0000')}
} {1}
do_test zeroblob-9.3 {
  db eval {SELECT zeroblob(2) IN (x'000000')}
} {0}
do_test zeroblob-9.4 {
  db eval {SELECT zeroblob(2) IN (x'0000')}
} {1}
do_test zeroblob-9.5 {
  db eval {SELECT x'0000' IN (zeroblob(3))}
} {0}
do_test zeroblob-9.6 {
  db eval {SELECT x'0000' IN (zeroblob(2))}
} {1}
do_test zeroblob-9.7 {
  db eval {SELECT zeroblob(2) IN (zeroblob(3))}
} {0}
do_test zeroblob-9.8 {
  db eval {SELECT zeroblob(2) IN (zeroblob(2))}
} {1}


finish_test
Changes to tool/genfkey.test.
287
288
289
290
291
292
293




























































294
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

} {1 {constraint failed}}
do_test genfkey-5.5 {
  catchsql { 
    INSERT INTO "t.3" VALUES(1);
    INSERT INTO t13 VALUES(1);
  }
} {0 {}}

# Test also column names that require quoting.
do_test genfkey-6.1 {
  execsql {
    DROP TABLE "t.3";
    DROP TABLE t13;
    CREATE TABLE p(
      "a.1 first", "b.2 second", 
      UNIQUE("a.1 first", "b.2 second")
    );
    CREATE TABLE c(
      "c.1 I", "d.2 II", 
        FOREIGN KEY("c.1 I", "d.2 II") 
        REFERENCES p("a.1 first", "b.2 second")
        ON UPDATE CASCADE ON DELETE CASCADE
    );
  }
} {}
do_test genfkey-6.2 {
  set rc [catch {exec ./sqlite3 test.db .genfkey} msg]
} {0}
do_test genfkey-6.3 {
  execsql $msg
  execsql {
    INSERT INTO p VALUES('A', 'B');
    INSERT INTO p VALUES('C', 'D');
    INSERT INTO c VALUES('A', 'B');
    INSERT INTO c VALUES('C', 'D');
    UPDATE p SET "a.1 first" = 'X' WHERE rowid = 1;
    DELETE FROM p WHERE rowid = 2;
  }
  execsql { SELECT * FROM c }
} {X B}

do_test genfkey-6.4 {
  execsql {
    DROP TABLE p;
    DROP TABLE c;
    CREATE TABLE parent("a.1", PRIMARY KEY("a.1"));
    CREATE TABLE child("b.2", FOREIGN KEY("b.2") REFERENCES parent("a.1"));
  }
  set rc [catch {exec ./sqlite3 test.db .genfkey} msg]
} {0}
do_test genfkey-6.5 {
  execsql $msg
  execsql {
    INSERT INTO parent VALUES(1);
    INSERT INTO child VALUES(1);
  }
  catchsql { UPDATE parent SET "a.1"=0 }
} {1 {constraint failed}}
do_test genfkey-6.6 {
  catchsql { UPDATE child SET "b.2"=7 }
} {1 {constraint failed}}
do_test genfkey-6.7 {
  execsql {
    SELECT * FROM parent;
    SELECT * FROM child;
  }
} {1 1}

Changes to tool/lemon.c.
365
366
367
368
369
370
371



372
373
374
375
376
377
378
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381







+
+
+







  rc = ap1->sp->index - ap2->sp->index;
  if( rc==0 ){
    rc = (int)ap1->type - (int)ap2->type;
  }
  if( rc==0 && ap1->type==REDUCE ){
    rc = ap1->x.rp->index - ap2->x.rp->index;
  }
  if( rc==0 ){
    rc = ap2 - ap1;
  }
  return rc;
}

/* Sort parser actions */
static struct action *Action_sort(
  struct action *ap
){
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532


533
534

535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551



















552
553
554
555
556
557
558
516
517
518
519
520
521
522













523
524


525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568







-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
+

















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







  /* Scan the existing action table looking for an offset where we can
  ** insert the current transaction set.  Fall out of the loop when that
  ** offset is found.  In the worst case, we fall out of the loop when
  ** i reaches p->nAction, which means we append the new transaction set.
  **
  ** i is the index in p->aAction[] where p->mnLookahead is inserted.
  */
  for(i=0; i<p->nAction+p->mnLookahead; i++){
    if( p->aAction[i].lookahead<0 ){
      for(j=0; j<p->nLookahead; j++){
        k = p->aLookahead[j].lookahead - p->mnLookahead + i;
        if( k<0 ) break;
        if( p->aAction[k].lookahead>=0 ) break;
      }
      if( j<p->nLookahead ) continue;
      for(j=0; j<p->nAction; j++){
        if( p->aAction[j].lookahead==j+p->mnLookahead-i ) break;
      }
      if( j==p->nAction ){
        break;  /* Fits in empty slots */
  for(i=p->nAction-1; i>=0; i--){
    /* First look for an existing action table entry that can be reused */
      }
    }else if( p->aAction[i].lookahead==p->mnLookahead ){
    if( p->aAction[i].lookahead==p->mnLookahead ){
      if( p->aAction[i].action!=p->mnAction ) continue;
      for(j=0; j<p->nLookahead; j++){
        k = p->aLookahead[j].lookahead - p->mnLookahead + i;
        if( k<0 || k>=p->nAction ) break;
        if( p->aLookahead[j].lookahead!=p->aAction[k].lookahead ) break;
        if( p->aLookahead[j].action!=p->aAction[k].action ) break;
      }
      if( j<p->nLookahead ) continue;
      n = 0;
      for(j=0; j<p->nAction; j++){
        if( p->aAction[j].lookahead<0 ) continue;
        if( p->aAction[j].lookahead==j+p->mnLookahead-i ) n++;
      }
      if( n==p->nLookahead ){
        break;  /* Same as a prior transaction set */
      }
    }
  }
  if( i<0 ){
    /* If no reusable entry is found, look for an empty slot */
    for(i=0; i<p->nAction; i++){
      if( p->aAction[i].lookahead<0 ){
        for(j=0; j<p->nLookahead; j++){
          k = p->aLookahead[j].lookahead - p->mnLookahead + i;
          if( k<0 ) break;
          if( p->aAction[k].lookahead>=0 ) break;
        }
        if( j<p->nLookahead ) continue;
        for(j=0; j<p->nAction; j++){
          if( p->aAction[j].lookahead==j+p->mnLookahead-i ) break;
        }
        if( j==p->nAction ){
          break;  /* Fits in empty slots */
        }
      }
    }
  }
  /* Insert transaction set at index i. */
  for(j=0; j<p->nLookahead; j++){
    k = p->aLookahead[j].lookahead - p->mnLookahead + i;
    p->aAction[k] = p->aLookahead[j];
    if( k>=p->nAction ) p->nAction = k+1;
  }
1574
1575
1576
1577
1578
1579
1580
1581

1582
1583
1584
1585
1586
1587
1588
1589
1590

1591
1592
1593
1594
1595
1596
1597
1584
1585
1586
1587
1588
1589
1590

1591
1592
1593
1594
1595
1596
1597
1598
1599

1600
1601
1602
1603
1604
1605
1606
1607







-
+








-
+







  char *ptr, *head;

  if( a==0 ){
    head = b;
  }else if( b==0 ){
    head = a;
  }else{
    if( (*cmp)(a,b)<0 ){
    if( (*cmp)(a,b)<=0 ){
      ptr = a;
      a = NEXT(a);
    }else{
      ptr = b;
      b = NEXT(b);
    }
    head = ptr;
    while( a && b ){
      if( (*cmp)(a,b)<0 ){
      if( (*cmp)(a,b)<=0 ){
        NEXT(ptr) = a;
        ptr = a;
        a = NEXT(a);
      }else{
        NEXT(ptr) = b;
        ptr = b;
        b = NEXT(b);
1635
1636
1637
1638
1639
1640
1641
1642

1643
1644
1645
1646
1647
1648
1649
1645
1646
1647
1648
1649
1650
1651

1652
1653
1654
1655
1656
1657
1658
1659







-
+







    for(i=0; i<LISTSIZE-1 && set[i]!=0; i++){
      ep = merge(ep,set[i],cmp,offset);
      set[i] = 0;
    }
    set[i] = ep;
  }
  ep = 0;
  for(i=0; i<LISTSIZE; i++) if( set[i] ) ep = merge(ep,set[i],cmp,offset);
  for(i=0; i<LISTSIZE; i++) if( set[i] ) ep = merge(set[i],ep,cmp,offset);
  return ep;
}
/************************ From the file "option.c" **************************/
static char **argv;
static struct s_options *op;
static FILE *errstream;

3512
3513
3514
3515
3516
3517
3518

3519
3520
3521
3522
3523
3524
3525
3526

3527






3528
3529
3530
3531
3532
3533
3534
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538

3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551







+








+
-
+
+
+
+
+
+







** of the following structure.  An array of these structures is used
** to order the creation of entries in the yy_action[] table.
*/
struct axset {
  struct state *stp;   /* A pointer to a state */
  int isTkn;           /* True to use tokens.  False for non-terminals */
  int nAction;         /* Number of actions */
  int iOrder;          /* Original order of action sets */
};

/*
** Compare to axset structures for sorting purposes
*/
static int axset_compare(const void *a, const void *b){
  struct axset *p1 = (struct axset*)a;
  struct axset *p2 = (struct axset*)b;
  int c;
  return p2->nAction - p1->nAction;
  c = p2->nAction - p1->nAction;
  if( c==0 ){
    c = p2->iOrder - p1->iOrder;
  }
  assert( c!=0 || p1==p2 );
  return c;
}

/*
** Write text on "out" that describes the rule "rp".
*/
static void writeRuleText(FILE *out, struct rule *rp){
  int j;
3554
3555
3556
3557
3558
3559
3560
3561

3562
3563
3564
3565
3566
3567
3568
3571
3572
3573
3574
3575
3576
3577

3578
3579
3580
3581
3582
3583
3584
3585







-
+







  FILE *out, *in;
  char line[LINESIZE];
  int  lineno;
  struct state *stp;
  struct action *ap;
  struct rule *rp;
  struct acttab *pActtab;
  int i, j, n;
  int i, j, k, n;
  char *name;
  int mnTknOfst, mxTknOfst;
  int mnNtOfst, mxNtOfst;
  struct axset *ax;

  in = tplt_open(lemp);
  if( in==0 ) return;
3680
3681
3682
3683
3684
3685
3686

3687
3688
3689
3690
3691
3692
3693
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711







+







  mxTknOfst = mnTknOfst = 0;
  mxNtOfst = mnNtOfst = 0;

  /* Compute the action table.  In order to try to keep the size of the
  ** action table to a minimum, the heuristic of placing the largest action
  ** sets first is used.
  */
  for(i=0; i<lemp->nstate*2; i++) ax[i].iOrder = i;
  qsort(ax, lemp->nstate*2, sizeof(ax[0]), axset_compare);
  pActtab = acttab_alloc();
  for(i=0; i<lemp->nstate*2 && ax[i].nAction>0; i++){
    stp = ax[i].stp;
    if( ax[i].isTkn ){
      for(ap=stp->ap; ap; ap=ap->next){
        int action;
3712
3713
3714
3715
3716
3717
3718
3719
3720


3721
3722
3723
3724
3725
3726
3727
3730
3731
3732
3733
3734
3735
3736

3737
3738
3739
3740
3741
3742
3743
3744
3745
3746







-

+
+







      if( stp->iNtOfst<mnNtOfst ) mnNtOfst = stp->iNtOfst;
      if( stp->iNtOfst>mxNtOfst ) mxNtOfst = stp->iNtOfst;
    }
  }
  free(ax);

  /* Output the yy_action table */
  fprintf(out,"static const YYACTIONTYPE yy_action[] = {\n"); lineno++;
  n = acttab_size(pActtab);
  fprintf(out,"#define YY_ACTTAB_COUNT (%d)\n", n); lineno++;
  fprintf(out,"static const YYACTIONTYPE yy_action[] = {\n"); lineno++;
  for(i=j=0; i<n; i++){
    int action = acttab_yyaction(pActtab, i);
    if( action<0 ) action = lemp->nstate + lemp->nrule + 2;
    if( j==0 ) fprintf(out," /* %5d */ ", i);
    fprintf(out, " %4d,", action);
    if( j==9 || i==n-1 ){
      fprintf(out, "\n"); lineno++;
3748
3749
3750
3751
3752
3753
3754


3755

3756
3757
3758
3759
3760
3761
3762
3767
3768
3769
3770
3771
3772
3773
3774
3775

3776
3777
3778
3779
3780
3781
3782
3783







+
+
-
+







  }
  fprintf(out, "};\n"); lineno++;

  /* Output the yy_shift_ofst[] table */
  fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1); lineno++;
  n = lemp->nstate;
  while( n>0 && lemp->sorted[n-1]->iTknOfst==NO_OFFSET ) n--;
  fprintf(out, "#define YY_SHIFT_COUNT (%d)\n", n-1); lineno++;
  fprintf(out, "#define YY_SHIFT_MIN   (%d)\n", mnTknOfst); lineno++;
  fprintf(out, "#define YY_SHIFT_MAX %d\n", n-1); lineno++;
  fprintf(out, "#define YY_SHIFT_MAX   (%d)\n", mxTknOfst); lineno++;
  fprintf(out, "static const %s yy_shift_ofst[] = {\n", 
          minimum_size_type(mnTknOfst-1, mxTknOfst)); lineno++;
  for(i=j=0; i<n; i++){
    int ofst;
    stp = lemp->sorted[i];
    ofst = stp->iTknOfst;
    if( ofst==NO_OFFSET ) ofst = mnTknOfst - 1;
3771
3772
3773
3774
3775
3776
3777


3778

3779
3780
3781
3782
3783
3784
3785
3792
3793
3794
3795
3796
3797
3798
3799
3800

3801
3802
3803
3804
3805
3806
3807
3808







+
+
-
+







  }
  fprintf(out, "};\n"); lineno++;

  /* Output the yy_reduce_ofst[] table */
  fprintf(out, "#define YY_REDUCE_USE_DFLT (%d)\n", mnNtOfst-1); lineno++;
  n = lemp->nstate;
  while( n>0 && lemp->sorted[n-1]->iNtOfst==NO_OFFSET ) n--;
  fprintf(out, "#define YY_REDUCE_COUNT (%d)\n", n-1); lineno++;
  fprintf(out, "#define YY_REDUCE_MIN   (%d)\n", mnNtOfst); lineno++;
  fprintf(out, "#define YY_REDUCE_MAX %d\n", n-1); lineno++;
  fprintf(out, "#define YY_REDUCE_MAX   (%d)\n", mxNtOfst); lineno++;
  fprintf(out, "static const %s yy_reduce_ofst[] = {\n", 
          minimum_size_type(mnNtOfst-1, mxNtOfst)); lineno++;
  for(i=j=0; i<n; i++){
    int ofst;
    stp = lemp->sorted[i];
    ofst = stp->iNtOfst;
    if( ofst==NO_OFFSET ) ofst = mnNtOfst - 1;
4093
4094
4095
4096
4097
4098
4099


4100



4101
4102
4103
4104
4105
4106
4107
4116
4117
4118
4119
4120
4121
4122
4123
4124

4125
4126
4127
4128
4129
4130
4131
4132
4133
4134







+
+
-
+
+
+







  const struct state *pA = *(const struct state**)a;
  const struct state *pB = *(const struct state**)b;
  int n;

  n = pB->nNtAct - pA->nNtAct;
  if( n==0 ){
    n = pB->nTknAct - pA->nTknAct;
    if( n==0 ){
      n = pB->statenum - pA->statenum;
  }
    }
  }
  assert( n!=0 );
  return n;
}


/*
** Renumber and resort states so that states with fewer choices
** occur at the end.  Except, keep state 0 as the first state.
4397
4398
4399
4400
4401
4402
4403

4404
4405
4406
4407
4408
4409
4410
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438







+







** We find experimentally that leaving the symbols in their original
** order (the order they appeared in the grammar file) gives the
** smallest parser tables in SQLite.
*/
int Symbolcmpp(struct symbol **a, struct symbol **b){
  int i1 = (**a).index + 10000000*((**a).name[0]>'Z');
  int i2 = (**b).index + 10000000*((**b).name[0]>'Z');
  assert( i1!=i2 || strcmp((**a).name,(**b).name)==0 );
  return i1-i2;
}

/* There is one instance of the following structure for each
** associative array of type "x2".
*/
struct s_x2 {
Changes to tool/lempar.c.
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
121
122
123
124
125
126
127

128
129
130
131
132
133
134







-







**  yy_shift_ofst[]    For each state, the offset into yy_action for
**                     shifting terminals.
**  yy_reduce_ofst[]   For each state, the offset into yy_action for
**                     shifting non-terminals after a reduce.
**  yy_default[]       Default action for each state.
*/
%%
#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0]))

/* The next table maps tokens into fallback tokens.  If a construct
** like the following:
** 
**      %fallback ID X Y Z.
**
** appears in the grammar, then ID becomes a fallback token for X, Y,
382
383
384
385
386
387
388

389

390
391
392
393
394

395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411







412


413
414
415
416
417
418
419
381
382
383
384
385
386
387
388

389
390
391
392
393

394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418

419
420
421
422
423
424
425
426
427







+
-
+




-
+

















+
+
+
+
+
+
+
-
+
+







static int yy_find_shift_action(
  yyParser *pParser,        /* The parser */
  YYCODETYPE iLookAhead     /* The look-ahead token */
){
  int i;
  int stateno = pParser->yystack[pParser->yyidx].stateno;
 
  if( stateno>YY_SHIFT_COUNT
  if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
   || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
    return yy_default[stateno];
  }
  assert( iLookAhead!=YYNOCODE );
  i += iLookAhead;
  if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
  if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
    if( iLookAhead>0 ){
#ifdef YYFALLBACK
      YYCODETYPE iFallback;            /* Fallback token */
      if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
             && (iFallback = yyFallback[iLookAhead])!=0 ){
#ifndef NDEBUG
        if( yyTraceFILE ){
          fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
             yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
        }
#endif
        return yy_find_shift_action(pParser, iFallback);
      }
#endif
#ifdef YYWILDCARD
      {
        int j = i - iLookAhead + YYWILDCARD;
        if( 
#if YY_SHIFT_MIN+YYWILDCARD<0
          j>=0 &&
#endif
#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
          j<YY_ACTTAB_COUNT &&
#endif
        if( j>=0 && j<YY_SZ_ACTTAB && yy_lookahead[j]==YYWILDCARD ){
          yy_lookahead[j]==YYWILDCARD
        ){
#ifndef NDEBUG
          if( yyTraceFILE ){
            fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
               yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]);
          }
#endif /* NDEBUG */
          return yy_action[j];
437
438
439
440
441
442
443
444

445
446
447
448

449
450
451
452
453
454
455

456
457
458
459

460
461
462
463
464
465
466
445
446
447
448
449
450
451

452
453
454
455

456
457
458
459
460
461
462

463
464
465
466

467
468
469
470
471
472
473
474







-
+



-
+






-
+



-
+







*/
static int yy_find_reduce_action(
  int stateno,              /* Current state number */
  YYCODETYPE iLookAhead     /* The look-ahead token */
){
  int i;
#ifdef YYERRORSYMBOL
  if( stateno>YY_REDUCE_MAX ){
  if( stateno>YY_REDUCE_COUNT ){
    return yy_default[stateno];
  }
#else
  assert( stateno<=YY_REDUCE_MAX );
  assert( stateno<=YY_REDUCE_COUNT );
#endif
  i = yy_reduce_ofst[stateno];
  assert( i!=YY_REDUCE_USE_DFLT );
  assert( iLookAhead!=YYNOCODE );
  i += iLookAhead;
#ifdef YYERRORSYMBOL
  if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
  if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
    return yy_default[stateno];
  }
#else
  assert( i>=0 && i<YY_SZ_ACTTAB );
  assert( i>=0 && i<YY_ACTTAB_COUNT );
  assert( yy_lookahead[i]==iLookAhead );
#endif
  return yy_action[i];
}

/*
** The following routine is called if the stack overflows.
Changes to tool/mkkeywordhash.c.
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26







-
+







** A header comment placed at the beginning of generated code.
*/
static const char zHdr[] = 
  "/***** This file contains automatically generated code ******\n"
  "**\n"
  "** The code in this file has been automatically generated by\n"
  "**\n"
  "**     $Header: /home/drh/sqlite/trans/cvs/sqlite/sqlite/tool/mkkeywordhash.c,v 1.38 2009/06/09 14:27:41 drh Exp $\n"
  "**   sqlite/tool/mkkeywordhash.c\n"
  "**\n"
  "** The code in this file implements a function that determines whether\n"
  "** or not a given identifier is really an SQL keyword.  The same thing\n"
  "** might be implemented more directly using a hand-written hash table.\n"
  "** But by using this automatically generated code, the size of the code\n"
  "** is substantially reduced.  This is important for embedded applications\n"
  "** on platforms with limited memory.\n"
140
141
142
143
144
145
146

147
148
149
150
151
152
153
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154







+







#endif

/*
** These are the keywords
*/
static Keyword aKeywordTable[] = {
  { "ABORT",            "TK_ABORT",        CONFLICT|TRIGGER       },
  { "ACTION",           "TK_ACTION",       FKEY                   },
  { "ADD",              "TK_ADD",          ALTER                  },
  { "AFTER",            "TK_AFTER",        TRIGGER                },
  { "ALL",              "TK_ALL",          ALWAYS                 },
  { "ALTER",            "TK_ALTER",        ALTER                  },
  { "ANALYZE",          "TK_ANALYZE",      ANALYZE                },
  { "AND",              "TK_AND",          ALWAYS                 },
  { "AS",               "TK_AS",           ALWAYS                 },
214
215
216
217
218
219
220

221
222
223
224
225
226
227
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229







+







  { "JOIN",             "TK_JOIN",         ALWAYS                 },
  { "KEY",              "TK_KEY",          ALWAYS                 },
  { "LEFT",             "TK_JOIN_KW",      ALWAYS                 },
  { "LIKE",             "TK_LIKE_KW",      ALWAYS                 },
  { "LIMIT",            "TK_LIMIT",        ALWAYS                 },
  { "MATCH",            "TK_MATCH",        ALWAYS                 },
  { "NATURAL",          "TK_JOIN_KW",      ALWAYS                 },
  { "NO",               "TK_NO",           FKEY                   },
  { "NOT",              "TK_NOT",          ALWAYS                 },
  { "NOTNULL",          "TK_NOTNULL",      ALWAYS                 },
  { "NULL",             "TK_NULL",         ALWAYS                 },
  { "OF",               "TK_OF",           ALWAYS                 },
  { "OFFSET",           "TK_OFFSET",       ALWAYS                 },
  { "ON",               "TK_ON",           ALWAYS                 },
  { "OR",               "TK_OR",           ALWAYS                 },
295
296
297
298
299
300
301

302
303
304
305
306
307
308
309
310

311
312
313
314
315
316


317
318
319
320
321
322
323
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329







+









+






+
+







static int keywordCompare1(const void *a, const void *b){
  const Keyword *pA = (Keyword*)a;
  const Keyword *pB = (Keyword*)b;
  int n = pA->len - pB->len;
  if( n==0 ){
    n = strcmp(pA->zName, pB->zName);
  }
  assert( n!=0 );
  return n;
}
static int keywordCompare2(const void *a, const void *b){
  const Keyword *pA = (Keyword*)a;
  const Keyword *pB = (Keyword*)b;
  int n = pB->longestSuffix - pA->longestSuffix;
  if( n==0 ){
    n = strcmp(pA->zName, pB->zName);
  }
  assert( n!=0 );
  return n;
}
static int keywordCompare3(const void *a, const void *b){
  const Keyword *pA = (Keyword*)a;
  const Keyword *pB = (Keyword*)b;
  int n = pA->offset - pB->offset;
  if( n==0 ) n = pB->id - pA->id;
  assert( n!=0 );
  return n;
}

/*
** Return a KeywordTable entry with the given id
*/
static Keyword *findById(int id){
Changes to tool/mksqlite3c.tcl.
18
19
20
21
22
23
24
25
26
27



28
29
30
31
32
33
34
18
19
20
21
22
23
24



25
26
27
28
29
30
31
32
33
34







-
-
-
+
+
+







# this script:
#
#      tclsh mksqlite3c.tcl
#
# The amalgamated SQLite code will be written into sqlite3.c
#

# Begin by reading the "sqlite3.h" header file.  Count the number of lines
# in this file and extract the version number.  That information will be
# needed in order to generate the header of the amalgamation.
# Begin by reading the "sqlite3.h" header file.  Extract the version number
# from in this file.  The versioon number is needed to generate the header
# comment of the amalgamation.
#
if {[lsearch $argv --nostatic]>=0} {
  set addstatic 0
} else {
  set addstatic 1
}
set in [open tsrc/sqlite3.h]
56
57
58
59
60
61
62
63
64
65
66
67






68
69
70
71
72
73
74
75
76
77
56
57
58
59
60
61
62





63
64
65
66
67
68



69
70
71
72
73
74
75







-
-
-
-
-
+
+
+
+
+
+
-
-
-







** possible if the files were compiled separately.  Performance improvements
** of 5% are more are commonly seen when SQLite is compiled as a single
** translation unit.
**
** This file is all you need to compile SQLite.  To use SQLite in other
** programs, you need this file and the "sqlite3.h" header file that defines
** the programming interface to the SQLite library.  (If you do not have 
** the "sqlite3.h" header file at hand, you will find a copy in the first
** $cnt lines past this header comment.)  Additional code files may be
** needed if you want a wrapper to interface SQLite with your choice of
** programming language.  The code for the "sqlite3" command-line shell
** is also in a separate file.  This file contains only code for the core
** the "sqlite3.h" header file at hand, you will find a copy embedded within
** the text of this file.  Search for "Begin file sqlite3.h" to find the start
** of the embedded sqlite3.h header file.) Additional code files may be needed
** if you want a wrapper to interface SQLite with your choice of programming
** language. The code for the "sqlite3" command-line shell is also in a
** separate file. This file contains only code for the core SQLite library.
** SQLite library.
**
** This amalgamation was generated on $today.
*/
#define SQLITE_CORE 1
#define SQLITE_AMALGAMATION 1}]
if {$addstatic} {
  puts $out \
{#ifndef SQLITE_PRIVATE
# define SQLITE_PRIVATE static
162
163
164
165
166
167
168

169
170
171
172
173
174
175
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174







+







        puts $out $line
      }
    } elseif {[regexp {^#ifdef __cplusplus} $line]} {
      puts $out "#if 0"
    } elseif {[regexp {^#line} $line]} {
      # Skip #line directives.
    } elseif {$addstatic && ![regexp {^(static|typedef)} $line]} {
      regsub {^SQLITE_API } $line {} line
      if {[regexp $declpattern $line all funcname]} {
        # Add the SQLITE_PRIVATE or SQLITE_API keyword before functions.
        # so that linkage can be modified at compile-time.
        if {[regexp {^sqlite3_} $funcname]} {
          puts $out "SQLITE_API $line"
        } else {
          puts $out "SQLITE_PRIVATE $line"
264
265
266
267
268
269
270

271
272
273
274
275
276
277
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277







+







   analyze.c
   attach.c
   auth.c
   build.c
   callback.c
   delete.c
   func.c
   fkey.c
   insert.c
   legacy.c
   loadext.c
   pragma.c
   prepare.c
   select.c
   table.c
Added tool/mksqlite3h.tcl.
































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#!/usr/bin/tclsh
#
# This script constructs the "sqlite3.h" header file from the following
# sources:
#
#   1) The src/sqlite.h.in source file.  This is the template for sqlite3.h.
#   2) The VERSION file containing the current SQLite version number.
#   3) The manifest file from the fossil SCM.  This gives use the date.
#   4) The manifest.uuid file from the fossil SCM.  This gives the SHA1 hash.
#
# Run this script by specifying the root directory of the source tree
# on the command-line.
# 
# This script performs processing on src/sqlite.h.in. It:
#
#   1) Adds SQLITE_EXTERN in front of the declaration of global variables,
#   2) Adds SQLITE_API in front of the declaration of API functions,
#   3) Replaces the string --VERS-- with the current library version, 
#      formatted as a string (e.g. "3.6.17"), and
#   4) Replaces the string --VERSION-NUMBER-- with current library version,
#      formatted as an integer (e.g. "3006017").
#   5) Replaces the string --SOURCE-ID-- with the date and time and sha1 
#      hash of the fossil-scm manifest for the source tree.
#
# This script outputs to stdout.
#
# Example usage:
#
#   tclsh mksqlite3h.tcl ../sqlite >sqlite3.h
#


# Get the source tree root directory from the command-line
#
set TOP [lindex $argv 0]

# Get the SQLite version number (ex: 3.6.18) from the $TOP/VERSION file.
#
set in [open $TOP/VERSION]
set zVersion [string trim [read $in]]
close $in
set nVersion [eval format "%d%03d%03d" [split $zVersion .]]

# Get the fossil-scm version number from $TOP/manifest.uuid.
#
set in [open $TOP/manifest.uuid]
set zUuid [string trim [read $in]]
close $in

# Get the fossil-scm check-in date from the "D" card of $TOP/manifest.
#
set in [open $TOP/manifest]
set zDate {}
while {![eof $in]} {
  set line [gets $in]
  if {[regexp {^D (2.*[0-9])} $line all date]} {
    set zDate [string map {T { }} $date]
    break
  }
}
close $in

# Set up patterns for recognizing API declarations.
#
set varpattern {^[a-zA-Z][a-zA-Z_0-9 *]+sqlite3_[_a-zA-Z0-9]+(\[|;| =)}
set declpattern {^ *[a-zA-Z][a-zA-Z_0-9 ]+ \**sqlite3_[_a-zA-Z0-9]+\(}

# Process the  src/sqlite.h.in  file.
#
set in [open $TOP/src/sqlite.h.in]
while {![eof $in]} {

  set line [gets $in]

  regsub -- --VERS--           $line $zVersion line
  regsub -- --VERSION-NUMBER-- $line $nVersion line
  regsub -- --SOURCE-ID--      $line "$zDate $zUuid" line

  if {[regexp {define SQLITE_EXTERN extern} $line]} {
    puts $line
    puts [gets $in]
    puts ""
    puts "#ifndef SQLITE_API"
    puts "# define SQLITE_API"
    puts "#endif"
    set line ""
  }

  if {([regexp $varpattern $line] && ![regexp {^ *typedef} $line])
   || ([regexp $declpattern $line])
  } {
    set line "SQLITE_API $line"
  }
  puts $line
}
close $in
Added tool/shell1.test.



































































































































































































































































































































































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 Nov 11
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# The focus of this file is testing the CLI shell tool.
#
# $Id: shell1.test,v 1.7 2009/07/17 16:54:48 shaneh Exp $
#

# Test plan:
#
#   shell1-1.*: Basic command line option handling.
#   shell1-2.*: Basic "dot" command token parsing.
#   shell1-3.*: Basic test that "dot" command can be called.
#

package require sqlite3

set CLI "./sqlite"

proc do_test {name cmd expected} {
  puts -nonewline "$name ..."
  set res [uplevel $cmd]
  if {$res eq $expected} {
    puts Ok
  } else {
    puts Error
    puts "  Got: $res"
    puts "  Expected: $expected"
    exit
  }
}

proc execsql {sql} {
  uplevel [list db eval $sql]
}

proc catchsql {sql} {
  set rc [catch {uplevel [list db eval $sql]} msg]
  list $rc $msg
}

proc catchcmd {db cmd} {
  global CLI
  set out [open cmds.txt w]
  puts $out $cmd
  close $out
  set line "exec $CLI $db < cmds.txt"
  set rc [catch { eval $line } msg]
  list $rc $msg
}

file delete -force test.db test.db.journal
sqlite3 db test.db

#----------------------------------------------------------------------------
# Test cases shell1-1.*: Basic command line option handling.
#

# invalid option
do_test shell1-1.1.1 {
  set res [catchcmd "-bad test.db" ""]
  set rc [lindex $res 0]
  list $rc \
       [regexp {Error: unknown option: -bad} $res]
} {1 1}
# error on extra options
do_test shell1-1.1.2 {
  set res [catchcmd "-bad test.db \"select 3\" \"select 4\"" ""]
  set rc [lindex $res 0]
  list $rc \
       [regexp {Error: too many options: "select 4"} $res]
} {1 1}
# error on extra options
do_test shell1-1.3.2 {
  set res [catchcmd "-bad FOO test.db BAD" ".quit"]
  set rc [lindex $res 0]
  list $rc \
       [regexp {Error: too many options: "BAD"} $res]
} {1 1}

# -help
do_test shell1-1.2.1 {
  set res [catchcmd "-help test.db" ""]
  set rc [lindex $res 0]
  list $rc \
       [regexp {Usage} $res] \
       [regexp {\-init} $res] \
       [regexp {\-version} $res]
} {1 1 1 1}

# -init filename       read/process named file
do_test shell1-1.3.1 {
  catchcmd "-init FOO test.db" "" 
} {0 {}}
do_test shell1-1.3.2 {
  set res [catchcmd "-init FOO test.db .quit BAD" ""]
  set rc [lindex $res 0]
  list $rc \
       [regexp {Error: too many options: "BAD"} $res]
} {1 1}

# -echo                print commands before execution
do_test shell1-1.4.1 {
  catchcmd "-echo test.db" "" 
} {0 {}}

# -[no]header          turn headers on or off
do_test shell1-1.5.1 {
  catchcmd "-header test.db" "" 
} {0 {}}
do_test shell1-1.5.2 {
  catchcmd "-noheader test.db" "" 
} {0 {}}

# -bail                stop after hitting an error
do_test shell1-1.6.1 {
  catchcmd "-bail test.db" "" 
} {0 {}}

# -interactive         force interactive I/O
do_test shell1-1.7.1 {
  set res [catchcmd "-interactive test.db" ".quit"]
  set rc [lindex $res 0]
  list $rc \
       [regexp {SQLite version} $res] \
       [regexp {Enter SQL statements} $res]
} {0 1 1}

# -batch               force batch I/O
do_test shell1-1.8.1 {
  catchcmd "-batch test.db" "" 
} {0 {}}

# -column              set output mode to 'column'
do_test shell1-1.9.1 {
  catchcmd "-column test.db" "" 
} {0 {}}

# -csv                 set output mode to 'csv'
do_test shell1-1.10.1 {
  catchcmd "-csv test.db" "" 
} {0 {}}

# -html                set output mode to HTML
do_test shell1-1.11.1 {
  catchcmd "-html test.db" "" 
} {0 {}}

# -line                set output mode to 'line'
do_test shell1-1.12.1 {
  catchcmd "-line test.db" "" 
} {0 {}}

# -list                set output mode to 'list'
do_test shell1-1.13.1 {
  catchcmd "-list test.db" "" 
} {0 {}}

# -separator 'x'       set output field separator (|)
do_test shell1-1.14.1 {
  catchcmd "-separator 'x' test.db" "" 
} {0 {}}
do_test shell1-1.14.2 {
  catchcmd "-separator x test.db" "" 
} {0 {}}
do_test shell1-1.14.3 {
  set res [catchcmd "-separator" ""]
  set rc [lindex $res 0]
  list $rc \
       [regexp {Error: missing argument for option: -separator} $res]
} {1 1}

# -nullvalue 'text'    set text string for NULL values
do_test shell1-1.15.1 {
  catchcmd "-nullvalue 'x' test.db" ""
} {0 {}}
do_test shell1-1.15.2 {
  catchcmd "-nullvalue x test.db" ""
} {0 {}}
do_test shell1-1.15.3 {
  set res [catchcmd "-nullvalue" ""]
  set rc [lindex $res 0]
  list $rc \
       [regexp {Error: missing argument for option: -nullvalue} $res]
} {1 1}

# -version             show SQLite version
do_test shell1-1.16.1 {
  catchcmd "-version test.db" "" 
} {0 3.6.20}

#----------------------------------------------------------------------------
# Test cases shell1-2.*: Basic "dot" command token parsing.
#

# check first token handling
do_test shell1-2.1.1 {
  catchcmd " test.db" ".foo" 
} {1 {Error: unknown command or invalid arguments:  "foo". Enter ".help" for help}}
do_test shell1-2.1.2 {
  catchcmd " test.db" ".\"foo OFF\""
} {1 {Error: unknown command or invalid arguments:  "foo OFF". Enter ".help" for help}}
do_test shell1-2.1.3 {
  catchcmd " test.db" ".\'foo OFF\'"
} {1 {Error: unknown command or invalid arguments:  "foo OFF". Enter ".help" for help}}

# unbalanced quotes
do_test shell1-2.2.1 {
  catchcmd " test.db" ".\"foo OFF"
} {1 {Error: unknown command or invalid arguments:  "foo OFF". Enter ".help" for help}}
do_test shell1-2.2.2 {
  catchcmd " test.db" ".\'foo OFF"
} {1 {Error: unknown command or invalid arguments:  "foo OFF". Enter ".help" for help}}
do_test shell1-2.2.3 {
  catchcmd " test.db" ".explain \"OFF"
} {0 {}}
do_test shell1-2.2.4 {
  catchcmd " test.db" ".explain \'OFF"
} {0 {}}
do_test shell1-2.2.5 {
  catchcmd " test.db" ".mode \"insert FOO"
} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}}
do_test shell1-2.2.6 {
  catchcmd " test.db" ".mode \'insert FOO"
} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}}

# check multiple tokens, and quoted tokens
do_test shell1-2.3.1 {
  catchcmd " test.db" ".explain 1"
} {0 {}}
do_test shell1-2.3.2 {
  catchcmd " test.db" ".explain on"
} {0 {}}
do_test shell1-2.3.3 {
  catchcmd " test.db" ".explain \"1 2 3\""
} {0 {}}
do_test shell1-2.3.4 {
  catchcmd " test.db" ".explain \"OFF\""
} {0 {}}
do_test shell1-2.3.5 {
  catchcmd " test.db" ".\'explain\' \'OFF\'"
} {0 {}}
do_test shell1-2.3.6 {
  catchcmd " test.db" ".explain \'OFF\'"
} {0 {}}
do_test shell1-2.3.7 {
  catchcmd " test.db" ".\'explain\' \'OFF\'"
} {0 {}}

# check quoted args are unquoted
do_test shell1-2.4.1 {
  catchcmd " test.db" ".mode FOO"
} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}}
do_test shell1-2.4.2 {
  catchcmd " test.db" ".mode csv"
} {0 {}}
do_test shell1-2.4.2 {
  catchcmd " test.db" ".mode \"csv\""
} {0 {}}


#----------------------------------------------------------------------------
# Test cases shell1-3.*: Basic test that "dot" command can be called.
#

# .backup ?DB? FILE      Backup DB (default "main") to FILE
do_test shell1-3.1.1 {
  catchcmd " test.db" ".backup"
} {1 {Error: unknown command or invalid arguments:  "backup". Enter ".help" for help}}
do_test shell1-3.1.2 {
  # catchcmd " test.db" ".backup FOO"
  #TBD!!! this asserts currently
} {}
do_test shell1-3.1.3 {
  catchcmd " test.db" ".backup FOO BAR"
} {1 {Error: unknown database FOO}}
do_test shell1-3.1.4 {
  # too many arguments
  catchcmd " test.db" ".backup FOO BAR BAD"
} {1 {Error: unknown command or invalid arguments:  "backup". Enter ".help" for help}}

# .bail ON|OFF           Stop after hitting an error.  Default OFF
do_test shell1-3.2.1 {
  catchcmd " test.db" ".bail"
} {1 {Error: unknown command or invalid arguments:  "bail". Enter ".help" for help}}
do_test shell1-3.2.2 {
  catchcmd " test.db" ".bail ON"
} {0 {}}
do_test shell1-3.2.3 {
  catchcmd " test.db" ".bail OFF"
} {0 {}}
do_test shell1-3.2.4 {
  # too many arguments
  catchcmd " test.db" ".bail OFF BAD"
} {1 {Error: unknown command or invalid arguments:  "bail". Enter ".help" for help}}

# .databases             List names and files of attached databases
do_test shell1-3.3.1 {
  set res [catchcmd " test.db" ".databases"]
  regexp {0.*main.*test\.db} $res
} {1}
do_test shell1-3.3.2 {
  # too many arguments
  catchcmd " test.db" ".databases BAD"
} {1 {Error: unknown command or invalid arguments:  "databases". Enter ".help" for help}}

# .dump ?TABLE? ...      Dump the database in an SQL text format
#                          If TABLE specified, only dump tables matching
#                          LIKE pattern TABLE.
do_test shell1-3.4.1 {
  set res [catchcmd " test.db" ".dump"]
  list [regexp {BEGIN TRANSACTION;} $res] \
       [regexp {COMMIT;} $res]
} {1 1}
do_test shell1-3.4.2 {
  set res [catchcmd " test.db" ".dump FOO"]
  list [regexp {BEGIN TRANSACTION;} $res] \
       [regexp {COMMIT;} $res]
} {1 1}
do_test shell1-3.4.3 {
  # too many arguments
  catchcmd " test.db" ".dump FOO BAD"
} {1 {Error: unknown command or invalid arguments:  "dump". Enter ".help" for help}}

# .echo ON|OFF           Turn command echo on or off
do_test shell1-3.5.1 {
  catchcmd " test.db" ".echo"
} {1 {Error: unknown command or invalid arguments:  "echo". Enter ".help" for help}}
do_test shell1-3.5.2 {
  catchcmd " test.db" ".echo ON"
} {0 {}}
do_test shell1-3.5.3 {
  catchcmd " test.db" ".echo OFF"
} {0 {}}
do_test shell1-3.5.4 {
  # too many arguments
  catchcmd " test.db" ".echo OFF BAD"
} {1 {Error: unknown command or invalid arguments:  "echo". Enter ".help" for help}}

# .exit                  Exit this program
do_test shell1-3.6.1 {
  catchcmd " test.db" ".exit"
} {0 {}}
do_test shell1-3.6.2 {
  # too many arguments
  catchcmd " test.db" ".exit BAD"
} {1 {Error: unknown command or invalid arguments:  "exit". Enter ".help" for help}}

# .explain ON|OFF        Turn output mode suitable for EXPLAIN on or off.
do_test shell1-3.7.1 {
  catchcmd " test.db" ".explain"
  # explain is the exception to the booleans.  without an option, it turns it on.
} {0 {}}
do_test shell1-3.7.2 {
  catchcmd " test.db" ".explain ON"
} {0 {}}
do_test shell1-3.7.3 {
  catchcmd " test.db" ".explain OFF"
} {0 {}}
do_test shell1-3.7.4 {
  # too many arguments
  catchcmd " test.db" ".explain OFF BAD"
} {1 {Error: unknown command or invalid arguments:  "explain". Enter ".help" for help}}

# .genfkey ?OPTIONS?     Options are:
#                          --no-drop: Do not drop old fkey triggers.
#                          --ignore-errors: Ignore tables with fkey errors
#                          --exec: Execute generated SQL immediately
#                        See file tool/genfkey.README in the source
#                        distribution for further information.
do_test shell1-3.8.1 {
  catchcmd " test.db" ".genfkey"
} {0 {}}
do_test shell1-3.8.2 {
  catchcmd " test.db" ".genfkey FOO"
} {1 {unknown option: FOO}}

# .header(s) ON|OFF      Turn display of headers on or off
do_test shell1-3.9.1 {
  catchcmd " test.db" ".header"
} {1 {Error: unknown command or invalid arguments:  "header". Enter ".help" for help}}
do_test shell1-3.9.2 {
  catchcmd " test.db" ".header ON"
} {0 {}}
do_test shell1-3.9.3 {
  catchcmd " test.db" ".header OFF"
} {0 {}}
do_test shell1-3.9.4 {
  # too many arguments
  catchcmd " test.db" ".header OFF BAD"
} {1 {Error: unknown command or invalid arguments:  "header". Enter ".help" for help}}

do_test shell1-3.9.5 {
  catchcmd " test.db" ".headers"
} {1 {Error: unknown command or invalid arguments:  "headers". Enter ".help" for help}}
do_test shell1-3.9.6 {
  catchcmd " test.db" ".headers ON"
} {0 {}}
do_test shell1-3.9.7 {
  catchcmd " test.db" ".headers OFF"
} {0 {}}
do_test shell1-3.9.8 {
  # too many arguments
  catchcmd " test.db" ".headers OFF BAD"
} {1 {Error: unknown command or invalid arguments:  "headers". Enter ".help" for help}}

# .help                  Show this message
do_test shell1-3.10.1 {
  set res [catchcmd " test.db" ".help"]
  # look for a few of the possible help commands
  list [regexp {.help} $res] \
       [regexp {.quit} $res] \
       [regexp {.show} $res]
} {1 1 1}
do_test shell1-3.10.2 {
  # we allow .help to take extra args (it is help after all)
  set res [catchcmd " test.db" ".help BAD"]
  # look for a few of the possible help commands
  list [regexp {.help} $res] \
       [regexp {.quit} $res] \
       [regexp {.show} $res]
} {1 1 1}

# .import FILE TABLE     Import data from FILE into TABLE
do_test shell1-3.11.1 {
  catchcmd " test.db" ".import"
} {1 {Error: unknown command or invalid arguments:  "import". Enter ".help" for help}}
do_test shell1-3.11.2 {
  catchcmd " test.db" ".import FOO"
} {1 {Error: unknown command or invalid arguments:  "import". Enter ".help" for help}}
do_test shell1-3.11.2 {
  catchcmd " test.db" ".import FOO BAR"
} {1 {Error: no such table: BAR}}
do_test shell1-3.11.3 {
  # too many arguments
  catchcmd " test.db" ".import FOO BAR BAD"
} {1 {Error: unknown command or invalid arguments:  "import". Enter ".help" for help}}

# .indices ?TABLE?       Show names of all indices
#                          If TABLE specified, only show indices for tables
#                          matching LIKE pattern TABLE.
do_test shell1-3.12.1 {
  catchcmd " test.db" ".indices"
} {0 {}}
do_test shell1-3.12.2 {
  catchcmd " test.db" ".indices FOO"
} {0 {}}
do_test shell1-3.12.3 {
  # too many arguments
  catchcmd " test.db" ".indices FOO BAD"
} {1 {Error: unknown command or invalid arguments:  "indices". Enter ".help" for help}}

# .mode MODE ?TABLE?     Set output mode where MODE is one of:
#                          csv      Comma-separated values
#                          column   Left-aligned columns.  (See .width)
#                          html     HTML <table> code
#                          insert   SQL insert statements for TABLE
#                          line     One value per line
#                          list     Values delimited by .separator string
#                          tabs     Tab-separated values
#                          tcl      TCL list elements
do_test shell1-3.13.1 {
  catchcmd " test.db" ".mode"
} {1 {Error: unknown command or invalid arguments:  "mode". Enter ".help" for help}}
do_test shell1-3.13.2 {
  catchcmd " test.db" ".mode FOO"
} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}}
do_test shell1-3.13.3 {
  catchcmd " test.db" ".mode csv"
} {0 {}}
do_test shell1-3.13.4 {
  catchcmd " test.db" ".mode column"
} {0 {}}
do_test shell1-3.13.5 {
  catchcmd " test.db" ".mode html"
} {0 {}}
do_test shell1-3.13.6 {
  catchcmd " test.db" ".mode insert"
} {0 {}}
do_test shell1-3.13.7 {
  catchcmd " test.db" ".mode line"
} {0 {}}
do_test shell1-3.13.8 {
  catchcmd " test.db" ".mode list"
} {0 {}}
do_test shell1-3.13.9 {
  catchcmd " test.db" ".mode tabs"
} {0 {}}
do_test shell1-3.13.10 {
  catchcmd " test.db" ".mode tcl"
} {0 {}}
do_test shell1-3.13.11 {
  # too many arguments
  catchcmd " test.db" ".mode tcl BAD"
} {1 {Error: invalid arguments:  "BAD". Enter ".help" for help}}

# don't allow partial mode type matches
do_test shell1-3.13.12 {
  catchcmd " test.db" ".mode l"
} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}}
do_test shell1-3.13.13 {
  catchcmd " test.db" ".mode li"
} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}}
do_test shell1-3.13.14 {
  catchcmd " test.db" ".mode lin"
} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}}

# .nullvalue STRING      Print STRING in place of NULL values
do_test shell1-3.14.1 {
  catchcmd " test.db" ".nullvalue"
} {1 {Error: unknown command or invalid arguments:  "nullvalue". Enter ".help" for help}}
do_test shell1-3.14.2 {
  catchcmd " test.db" ".nullvalue FOO"
} {0 {}}
do_test shell1-3.14.3 {
  # too many arguments
  catchcmd " test.db" ".nullvalue FOO BAD"
} {1 {Error: unknown command or invalid arguments:  "nullvalue". Enter ".help" for help}}

# .output FILENAME       Send output to FILENAME
do_test shell1-3.15.1 {
  catchcmd " test.db" ".output"
} {1 {Error: unknown command or invalid arguments:  "output". Enter ".help" for help}}
do_test shell1-3.15.2 {
  catchcmd " test.db" ".output FOO"
} {0 {}}
do_test shell1-3.15.3 {
  # too many arguments
  catchcmd " test.db" ".output FOO BAD"
} {1 {Error: unknown command or invalid arguments:  "output". Enter ".help" for help}}

# .output stdout         Send output to the screen
do_test shell1-3.16.1 {
  catchcmd " test.db" ".output stdout"
} {0 {}}
do_test shell1-3.16.2 {
  # too many arguments
  catchcmd " test.db" ".output stdout BAD"
} {1 {Error: unknown command or invalid arguments:  "output". Enter ".help" for help}}

# .prompt MAIN CONTINUE  Replace the standard prompts
do_test shell1-3.17.1 {
  catchcmd " test.db" ".prompt"
} {1 {Error: unknown command or invalid arguments:  "prompt". Enter ".help" for help}}
do_test shell1-3.17.2 {
  catchcmd " test.db" ".prompt FOO"
} {0 {}}
do_test shell1-3.17.3 {
  catchcmd " test.db" ".prompt FOO BAR"
} {0 {}}
do_test shell1-3.17.4 {
  # too many arguments
  catchcmd " test.db" ".prompt FOO BAR BAD"
} {1 {Error: unknown command or invalid arguments:  "prompt". Enter ".help" for help}}

# .quit                  Exit this program
do_test shell1-3.18.1 {
  catchcmd " test.db" ".quit"
} {0 {}}
do_test shell1-3.18.2 {
  # too many arguments
  catchcmd " test.db" ".quit BAD"
} {1 {Error: unknown command or invalid arguments:  "quit". Enter ".help" for help}}

# .read FILENAME         Execute SQL in FILENAME
do_test shell1-3.19.1 {
  catchcmd " test.db" ".read"
} {1 {Error: unknown command or invalid arguments:  "read". Enter ".help" for help}}
do_test shell1-3.19.2 {
  file delete -force FOO
  catchcmd " test.db" ".read FOO"
} {1 {Error: cannot open "FOO"}}
do_test shell1-3.19.3 {
  # too many arguments
  catchcmd " test.db" ".read FOO BAD"
} {1 {Error: unknown command or invalid arguments:  "read". Enter ".help" for help}}

# .restore ?DB? FILE     Restore content of DB (default "main") from FILE
do_test shell1-3.20.1 {
  catchcmd " test.db" ".restore"
} {1 {Error: unknown command or invalid arguments:  "restore". Enter ".help" for help}}
do_test shell1-3.20.2 {
  # catchcmd " test.db" ".restore FOO"
  #TBD!!! this asserts currently
} {}
do_test shell1-3.20.3 {
  catchcmd " test.db" ".restore FOO BAR"
} {1 {Error: unknown database FOO}}
do_test shell1-3.20.4 {
  # too many arguments
  catchcmd " test.db" ".restore FOO BAR BAD"
} {1 {Error: unknown command or invalid arguments:  "restore". Enter ".help" for help}}

# .schema ?TABLE?        Show the CREATE statements
#                          If TABLE specified, only show tables matching
#                          LIKE pattern TABLE.
do_test shell1-3.21.1 {
  catchcmd " test.db" ".schema"
} {0 {}}
do_test shell1-3.21.2 {
  catchcmd " test.db" ".schema FOO"
} {0 {}}
do_test shell1-3.21.3 {
  # too many arguments
  catchcmd " test.db" ".schema FOO BAD"
} {1 {Error: unknown command or invalid arguments:  "schema". Enter ".help" for help}}

# .separator STRING      Change separator used by output mode and .import
do_test shell1-3.22.1 {
  catchcmd " test.db" ".separator"
} {1 {Error: unknown command or invalid arguments:  "separator". Enter ".help" for help}}
do_test shell1-3.22.2 {
  catchcmd " test.db" ".separator FOO"
} {0 {}}
do_test shell1-3.22.3 {
  # too many arguments
  catchcmd " test.db" ".separator FOO BAD"
} {1 {Error: unknown command or invalid arguments:  "separator". Enter ".help" for help}}

# .show                  Show the current values for various settings
do_test shell1-3.23.1 {
  set res [catchcmd " test.db" ".show"]
  list [regexp {echo:} $res] \
       [regexp {explain:} $res] \
       [regexp {headers:} $res] \
       [regexp {mode:} $res] \
       [regexp {nullvalue:} $res] \
       [regexp {output:} $res] \
       [regexp {separator:} $res] \
       [regexp {width:} $res]
} {1 1 1 1 1 1 1 1}
do_test shell1-3.23.2 {
  # too many arguments
  catchcmd " test.db" ".show BAD"
} {1 {Error: unknown command or invalid arguments:  "show". Enter ".help" for help}}

# .tables ?TABLE?        List names of tables
#                          If TABLE specified, only list tables matching
#                          LIKE pattern TABLE.
do_test shell1-3.24.1 {
  catchcmd " test.db" ".tables"
} {0 {}}
do_test shell1-3.24.2 {
  catchcmd " test.db" ".tables FOO"
} {0 {}}
do_test shell1-3.24.3 {
  # too many arguments
  catchcmd " test.db" ".tables FOO BAD"
} {1 {Error: unknown command or invalid arguments:  "tables". Enter ".help" for help}}

# .timeout MS            Try opening locked tables for MS milliseconds
do_test shell1-3.25.1 {
  catchcmd " test.db" ".timeout"
} {1 {Error: unknown command or invalid arguments:  "timeout". Enter ".help" for help}}
do_test shell1-3.25.2 {
  catchcmd " test.db" ".timeout zzz"
  # this should be treated the same as a '0' timeout
} {0 {}}
do_test shell1-3.25.3 {
  catchcmd " test.db" ".timeout 1"
} {0 {}}
do_test shell1-3.25.4 {
  # too many arguments
  catchcmd " test.db" ".timeout 1 BAD"
} {1 {Error: unknown command or invalid arguments:  "timeout". Enter ".help" for help}}

# .width NUM NUM ...     Set column widths for "column" mode
do_test shell1-3.26.1 {
  catchcmd " test.db" ".width"
} {1 {Error: unknown command or invalid arguments:  "width". Enter ".help" for help}}
do_test shell1-3.26.2 {
  catchcmd " test.db" ".width xxx"
  # this should be treated the same as a '0' width for col 1
} {0 {}}
do_test shell1-3.26.3 {
  catchcmd " test.db" ".width xxx yyy"
  # this should be treated the same as a '0' width for col 1 and 2
} {0 {}}
do_test shell1-3.26.4 {
  catchcmd " test.db" ".width 1 1"
  # this should be treated the same as a '1' width for col 1 and 2
} {0 {}}

# .timer ON|OFF          Turn the CPU timer measurement on or off
do_test shell1-3.27.1 {
  catchcmd " test.db" ".timer"
} {1 {Error: unknown command or invalid arguments:  "timer". Enter ".help" for help}}
do_test shell1-3.27.2 {
  catchcmd " test.db" ".timer ON"
} {0 {}}
do_test shell1-3.27.3 {
  catchcmd " test.db" ".timer OFF"
} {0 {}}
do_test shell1-3.27.4 {
  # too many arguments
  catchcmd " test.db" ".timer OFF BAD"
} {1 {Error: unknown command or invalid arguments:  "timer". Enter ".help" for help}}

# 
Added tool/shell2.test.





















































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# 2009 Nov 11
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# The focus of this file is testing the CLI shell tool.
#
# $Id: shell2.test,v 1.7 2009/07/17 16:54:48 shaneh Exp $
#

# Test plan:
#
#   shell2-1.*: Misc. test of various tickets and reported errors.
#

package require sqlite3

set CLI "./sqlite"

proc do_test {name cmd expected} {
  puts -nonewline "$name ..."
  set res [uplevel $cmd]
  if {$res eq $expected} {
    puts Ok
  } else {
    puts Error
    puts "  Got: $res"
    puts "  Expected: $expected"
    exit
  }
}

proc execsql {sql} {
  uplevel [list db eval $sql]
}

proc catchsql {sql} {
  set rc [catch {uplevel [list db eval $sql]} msg]
  list $rc $msg
}

proc catchcmd {db cmd} {
  global CLI
  set out [open cmds.txt w]
  puts $out $cmd
  close $out
  set line "exec $CLI $db < cmds.txt"
  set rc [catch { eval $line } msg]
  list $rc $msg
}

file delete -force test.db test.db.journal
sqlite3 db test.db


#----------------------------------------------------------------------------
#   shell2-1.*: Misc. test of various tickets and reported errors.
#

# Batch mode not creating databases.  
# Reported on mailing list by Ken Zalewski.
# Ticket [aeff892c57].
do_test shell2-1.1.1 {
  file delete -force foo.db
  set rc [ catchcmd "-batch foo.db" "CREATE TABLE t1(a);" ]
  set fexist [file exist foo.db]
  list $rc $fexist
} {{0 {}} 1}

# Shell silently ignores extra parameters.
# Ticket [f5cb008a65].
do_test shell2-1.2.1 {
  set rc [catch { eval exec $CLI \":memory:\" \"select 3\" \"select 4\" } msg]
  list $rc \
       [regexp {Error: too many options: "select 4"} $msg]
} {1 1}



Changes to tool/vdbe-compress.tcl.
91
92
93
94
95
96
97

98
99
100
101
102
103
104
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105







+







  }
  if {[regexp "^\175" $line]} {
    append afterUnion $line\n
    set vlist {}
  } elseif {[llength $vlist]>0} {
    append line " "
    foreach v $vlist {
      regsub -all "(\[^a-zA-Z0-9>.\])${v}(\\W)" $line "\\1u.$sname.$v\\2" line
      regsub -all "(\[^a-zA-Z0-9>.\])${v}(\\W)" $line "\\1u.$sname.$v\\2" line
    }
    append afterUnion [string trimright $line]\n
  } elseif {$line=="" && [eof stdin]} {
    # no-op
  } else {
    append afterUnion $line\n