SQLite

Check-in [6994a2d8af]
Login

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

Overview
Comment:Merge latest changes from begin-concurrent-pnu into this branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | begin-concurrent-report
Files: files | file ages | folders
SHA3-256: 6994a2d8af30e5f5a9ce7735c3d1b2b66c1adc8f6fff37c894e2b827fe714f91
User & Date: dan 2021-03-11 19:26:42.089
Context
2021-03-12
16:50
Merge the 3.35.0 release into the begin-concurrent-report branch. (check-in: 27f8f56b98 user: drh tags: begin-concurrent-report)
2021-03-11
19:26
Merge latest changes from begin-concurrent-pnu into this branch. (check-in: 6994a2d8af user: dan tags: begin-concurrent-report)
19:08
Merge latest trunk changes with this branch. (check-in: eb3101364f user: dan tags: begin-concurrent-pnu)
2020-11-26
17:54
Merge latest changes from begin-concurrent-pnu into this branch. (check-in: d2de81a24f user: dan tags: begin-concurrent-report)
Changes
Unified Diff Ignore Whitespace Patch
Changes to Makefile.in.
436
437
438
439
440
441
442

443
444
445
446
447
448
449

# Statically linked extensions
#
TESTSRC += \
  $(TOP)/ext/expert/sqlite3expert.c \
  $(TOP)/ext/expert/test_expert.c \
  $(TOP)/ext/misc/amatch.c \

  $(TOP)/ext/misc/carray.c \
  $(TOP)/ext/misc/cksumvfs.c \
  $(TOP)/ext/misc/closure.c \
  $(TOP)/ext/misc/csv.c \
  $(TOP)/ext/misc/decimal.c \
  $(TOP)/ext/misc/eval.c \
  $(TOP)/ext/misc/explain.c \







>







436
437
438
439
440
441
442
443
444
445
446
447
448
449
450

# Statically linked extensions
#
TESTSRC += \
  $(TOP)/ext/expert/sqlite3expert.c \
  $(TOP)/ext/expert/test_expert.c \
  $(TOP)/ext/misc/amatch.c \
  $(TOP)/ext/misc/appendvfs.c \
  $(TOP)/ext/misc/carray.c \
  $(TOP)/ext/misc/cksumvfs.c \
  $(TOP)/ext/misc/closure.c \
  $(TOP)/ext/misc/csv.c \
  $(TOP)/ext/misc/decimal.c \
  $(TOP)/ext/misc/eval.c \
  $(TOP)/ext/misc/explain.c \
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277

# Fuzz testing
fuzztest:	fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db
	./fuzzcheck$(TEXE) $(FUZZDATA)
	./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db

valgrindfuzz:	fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db
	valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA)
	valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db

# The veryquick.test TCL tests.
#
tcltest:	./testfixture$(TEXE)
	./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS)








|







1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278

# Fuzz testing
fuzztest:	fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db
	./fuzzcheck$(TEXE) $(FUZZDATA)
	./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db

valgrindfuzz:	fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db
	valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M $(FUZZDATA)
	valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db

# The veryquick.test TCL tests.
#
tcltest:	./testfixture$(TEXE)
	./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS)

1374
1375
1376
1377
1378
1379
1380



1381
1382
1383
1384
1385
1386
1387

wordcount$(TEXE):	$(TOP)/test/wordcount.c sqlite3.lo
	$(LTLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.lo $(TLIBS)

speedtest1$(TEXE):	$(TOP)/test/speedtest1.c sqlite3.c
	$(LTLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(TLIBS)




KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ

kvtest$(TEXE):	$(TOP)/test/kvtest.c sqlite3.c
	$(LTLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(TLIBS)

rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.lo
	$(LTLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.lo $(TLIBS)







>
>
>







1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391

wordcount$(TEXE):	$(TOP)/test/wordcount.c sqlite3.lo
	$(LTLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.lo $(TLIBS)

speedtest1$(TEXE):	$(TOP)/test/speedtest1.c sqlite3.c
	$(LTLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(TLIBS)

startup$(TEXE):	$(TOP)/test/startup.c sqlite3.c
	$(CC) -Os -g -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(TLIBS)

KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ

kvtest$(TEXE):	$(TOP)/test/kvtest.c sqlite3.c
	$(LTLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(TLIBS)

rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.lo
	$(LTLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.lo $(TLIBS)
Changes to Makefile.msc.
376
377
378
379
380
381
382



383
384
385
386
387
388
389
# to enable it.
#
!IF $(SESSION)!=0
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1
!ENDIF




# Should the rbu extension be enabled?  If so, add compilation options
# to enable it.
#
!IF $(RBU)!=0
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RBU=1
!ENDIF








>
>
>







376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
# to enable it.
#
!IF $(SESSION)!=0
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1
!ENDIF

# Always enable math functions on Windows
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_MATH_FUNCTIONS

# Should the rbu extension be enabled?  If so, add compilation options
# to enable it.
#
!IF $(RBU)!=0
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RBU=1
!ENDIF

1553
1554
1555
1556
1557
1558
1559

1560
1561
1562
1563
1564
1565
1566

# Statically linked extensions.
#
TESTEXT = \
  $(TOP)\ext\expert\sqlite3expert.c \
  $(TOP)\ext\expert\test_expert.c \
  $(TOP)\ext\misc\amatch.c \

  $(TOP)\ext\misc\carray.c \
  $(TOP)\ext\misc\cksumvfs.c \
  $(TOP)\ext\misc\closure.c \
  $(TOP)\ext\misc\csv.c \
  $(TOP)\ext\misc\decimal.c \
  $(TOP)\ext\misc\eval.c \
  $(TOP)\ext\misc\explain.c \







>







1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570

# Statically linked extensions.
#
TESTEXT = \
  $(TOP)\ext\expert\sqlite3expert.c \
  $(TOP)\ext\expert\test_expert.c \
  $(TOP)\ext\misc\amatch.c \
  $(TOP)\ext\misc\appendvfs.c \
  $(TOP)\ext\misc\carray.c \
  $(TOP)\ext\misc\cksumvfs.c \
  $(TOP)\ext\misc\closure.c \
  $(TOP)\ext\misc\csv.c \
  $(TOP)\ext\misc\decimal.c \
  $(TOP)\ext\misc\eval.c \
  $(TOP)\ext\misc\explain.c \
Changes to VERSION.
1
3.34.0
|
1
3.35.0
Changes to autoconf/configure.ac.
83
84
85
86
87
88
89
90


91
92
93
94
95
96
97

#-----------------------------------------------------------------------
#   --enable-threadsafe
#
AC_ARG_ENABLE(threadsafe, [AS_HELP_STRING(
  [--enable-threadsafe], [build a thread-safe library [default=yes]])], 
  [], [enable_threadsafe=yes])
if test x"$enable_threadsafe" != "xno"; then


  BUILD_CFLAGS="$BUILD_CFLAGS -D_REENTRANT=1 -DSQLITE_THREADSAFE=1"
  AC_SEARCH_LIBS(pthread_create, pthread)
  AC_SEARCH_LIBS(pthread_mutexattr_init, pthread)
fi
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------







|
>
>







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

#-----------------------------------------------------------------------
#   --enable-threadsafe
#
AC_ARG_ENABLE(threadsafe, [AS_HELP_STRING(
  [--enable-threadsafe], [build a thread-safe library [default=yes]])], 
  [], [enable_threadsafe=yes])
if test x"$enable_threadsafe" == "xno"; then
  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_THREADSAFE=0"
else
  BUILD_CFLAGS="$BUILD_CFLAGS -D_REENTRANT=1 -DSQLITE_THREADSAFE=1"
  AC_SEARCH_LIBS(pthread_create, pthread)
  AC_SEARCH_LIBS(pthread_mutexattr_init, pthread)
fi
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
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
else
  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_OMIT_LOAD_EXTENSION=1"
fi
AC_MSG_CHECKING([for whether to support dynamic extensions])
AC_MSG_RESULT($enable_dynamic_extensions)
#-----------------------------------------------------------------------

















#-----------------------------------------------------------------------
#   --enable-fts4
#
AC_ARG_ENABLE(fts4, [AS_HELP_STRING(
  [--enable-fts4], [include fts4 support [default=yes]])], 
  [], [enable_fts4=yes])

if test x"$enable_fts4" = "xyes"; then
  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS4"



fi
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
#   --enable-fts3
#
AC_ARG_ENABLE(fts3, [AS_HELP_STRING(
  [--enable-fts3], [include fts3 support [default=no]])], 
  [], [])

if test x"$enable_fts3" = "xyes" -a x"$enable_fts4" = "xno"; then
  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS3"



fi
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
#   --enable-fts5
#
AC_ARG_ENABLE(fts5, [AS_HELP_STRING(
  [--enable-fts5], [include fts5 support [default=yes]])], 
  [], [enable_fts5=yes])

if test x"$enable_fts5" = "xyes"; then

  AC_SEARCH_LIBS(log, m)
  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS5"


fi
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
#   --enable-json1
#
AC_ARG_ENABLE(json1, [AS_HELP_STRING(
  [--enable-json1], [include json1 support [default=yes]])], 
  [],[enable_json1=yes])

if test x"$enable_json1" = "xyes"; then
  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_JSON1"



fi
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
#   --enable-rtree
#
AC_ARG_ENABLE(rtree, [AS_HELP_STRING(
  [--enable-rtree], [include rtree support [default=yes]])], 
  [], [enable_rtree=yes])

if test x"$enable_rtree" = "xyes"; then
  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_GEOPOLY"



fi
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
#   --enable-session
#
AC_ARG_ENABLE(session, [AS_HELP_STRING(
  [--enable-session], [enable the session extension [default=no]])], 
  [], [])

if test x"$enable_session" = "xyes"; then
  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK"



fi
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
#   --enable-debug
#
AC_ARG_ENABLE(debug, [AS_HELP_STRING(
  [--enable-debug], [build with debugging features enabled [default=no]])], 
  [], [])

if test x"$enable_debug" = "xyes"; then
  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_DEBUG -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE"
  CFLAGS="-g -O0"



fi
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
#   --enable-static-shell
#
AC_ARG_ENABLE(static-shell, [AS_HELP_STRING(







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






>


>
>
>









>


>
>
>









>

>


>
>









>


>
>
>









>


>
>
>









>


>
>
>









>



>
>
>







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
else
  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_OMIT_LOAD_EXTENSION=1"
fi
AC_MSG_CHECKING([for whether to support dynamic extensions])
AC_MSG_RESULT($enable_dynamic_extensions)
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
#   --enable-math
#
AC_ARG_ENABLE(math, [AS_HELP_STRING(
  [--enable-math], [SQL math functions [default=yes]])],
  [], [enable_math=yes])
AC_MSG_CHECKING([SQL math functions])
if test x"$enable_math" = "xyes"; then
  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_MATH_FUNCTIONS"
  AC_MSG_RESULT([enabled])
  AC_SEARCH_LIBS(ceil, m)
else
  AC_MSG_RESULT([disabled])
fi
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
#   --enable-fts4
#
AC_ARG_ENABLE(fts4, [AS_HELP_STRING(
  [--enable-fts4], [include fts4 support [default=yes]])], 
  [], [enable_fts4=yes])
AC_MSG_CHECKING([FTS4 extension])
if test x"$enable_fts4" = "xyes"; then
  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS4"
  AC_MSG_RESULT([enabled])
else
  AC_MSG_RESULT([disabled])
fi
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
#   --enable-fts3
#
AC_ARG_ENABLE(fts3, [AS_HELP_STRING(
  [--enable-fts3], [include fts3 support [default=no]])], 
  [], [])
AC_MSG_CHECKING([FTS3 extension])
if test x"$enable_fts3" = "xyes" -a x"$enable_fts4" = "xno"; then
  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS3"
  AC_MSG_RESULT([enabled])
else
  AC_MSG_RESULT([disabled])
fi
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
#   --enable-fts5
#
AC_ARG_ENABLE(fts5, [AS_HELP_STRING(
  [--enable-fts5], [include fts5 support [default=yes]])], 
  [], [enable_fts5=yes])
AC_MSG_CHECKING([FTS5 extension])
if test x"$enable_fts5" = "xyes"; then
  AC_MSG_RESULT([enabled])
  AC_SEARCH_LIBS(log, m)
  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS5"
else
  AC_MSG_RESULT([disabled])
fi
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
#   --enable-json1
#
AC_ARG_ENABLE(json1, [AS_HELP_STRING(
  [--enable-json1], [include json1 support [default=yes]])], 
  [],[enable_json1=yes])
AC_MSG_CHECKING([JSON functions])
if test x"$enable_json1" = "xyes"; then
  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_JSON1"
  AC_MSG_RESULT([enabled])
else
  AC_MSG_RESULT([disabled])
fi
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
#   --enable-rtree
#
AC_ARG_ENABLE(rtree, [AS_HELP_STRING(
  [--enable-rtree], [include rtree support [default=yes]])], 
  [], [enable_rtree=yes])
AC_MSG_CHECKING([RTREE extension])
if test x"$enable_rtree" = "xyes"; then
  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_GEOPOLY"
  AC_MSG_RESULT([enabled])
else
  AC_MSG_RESULT([disabled])
fi
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
#   --enable-session
#
AC_ARG_ENABLE(session, [AS_HELP_STRING(
  [--enable-session], [enable the session extension [default=no]])], 
  [], [])
AC_MSG_CHECKING([Session extension])
if test x"$enable_session" = "xyes"; then
  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK"
  AC_MSG_RESULT([enabled])
else
  AC_MSG_RESULT([disabled])
fi
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
#   --enable-debug
#
AC_ARG_ENABLE(debug, [AS_HELP_STRING(
  [--enable-debug], [build with debugging features enabled [default=no]])], 
  [], [])
AC_MSG_CHECKING([Build type])
if test x"$enable_debug" = "xyes"; then
  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_DEBUG -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE"
  CFLAGS="-g -O0"
  AC_MSG_RESULT([debug])
else
  AC_MSG_RESULT([release])
fi
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
#   --enable-static-shell
#
AC_ARG_ENABLE(static-shell, [AS_HELP_STRING(
Changes to autoconf/tea/win/makefile.vc.
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# would install it into $(INSTALLDIR)\lib\sample04
#
# You need to specify the object files that need to be linked into your
# binary here.
#
#-------------------------------------------------------------------------

PROJECT = tclsqlite3
!include "rules.vc"

# nmakehelp -V <file> <tag> will search the file for tag, skips until a
#	number and returns all character until a character not in [0-9.ab]
#	is read.

!if [echo REM = This file is generated from Makefile.vc > versions.vc]







|







149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# would install it into $(INSTALLDIR)\lib\sample04
#
# You need to specify the object files that need to be linked into your
# binary here.
#
#-------------------------------------------------------------------------

PROJECT = sqlite3
!include "rules.vc"

# nmakehelp -V <file> <tag> will search the file for tag, skips until a
#	number and returns all character until a character not in [0-9.ab]
#	is read.

!if [echo REM = This file is generated from Makefile.vc > versions.vc]
Changes to configure.
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.69 for sqlite 3.34.0.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.


|







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.69 for sqlite 3.35.0.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
subdirs=
MFLAGS=
MAKEFLAGS=

# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.34.0'
PACKAGE_STRING='sqlite 3.34.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''

# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H







|
|







722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
subdirs=
MFLAGS=
MAKEFLAGS=

# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.35.0'
PACKAGE_STRING='sqlite 3.35.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''

# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
899
900
901
902
903
904
905
906

907
908
909
910
911
912
913
914
915
enable_editline
enable_readline
with_readline_lib
with_readline_inc
enable_debug
enable_amalgamation
enable_load_extension
enable_memsys5

enable_memsys3
enable_all
enable_fts3
enable_fts4
enable_fts5
enable_json1
enable_update_limit
enable_geopoly
enable_rtree







|
>
|
|







899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
enable_editline
enable_readline
with_readline_lib
with_readline_inc
enable_debug
enable_amalgamation
enable_load_extension
enable_math
enable_all
enable_memsys5
enable_memsys3
enable_fts3
enable_fts4
enable_fts5
enable_json1
enable_update_limit
enable_geopoly
enable_rtree
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
#
# 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.34.0 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.







|







1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
#
# 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.35.0 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.
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
  --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.34.0:";;
   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]







|







1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
  --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.35.0:";;
   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]
1553
1554
1555
1556
1557
1558
1559


1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
  --enable-editline       enable BSD editline support
  --disable-readline      disable readline support
  --enable-debug          enable debugging & verbose explain
  --disable-amalgamation  Disable the amalgamation and instead build all files
                          separately
  --disable-load-extension
                          Disable loading of external extensions


  --enable-memsys5        Enable MEMSYS5
  --enable-memsys3        Enable MEMSYS3
  --enable-all            Enable FTS4, FTS5, Geopoly, JSON, RTree, Sessions
  --enable-fts3           Enable the FTS3 extension
  --enable-fts4           Enable the FTS4 extension
  --enable-fts5           Enable the FTS5 extension
  --enable-json1          Enable the JSON1 extension
  --enable-update-limit   Enable the UPDATE/DELETE LIMIT clause
  --enable-geopoly        Enable the GEOPOLY extension
  --enable-rtree          Enable the RTREE extension







>
>


<







1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564

1565
1566
1567
1568
1569
1570
1571
  --enable-editline       enable BSD editline support
  --disable-readline      disable readline support
  --enable-debug          enable debugging & verbose explain
  --disable-amalgamation  Disable the amalgamation and instead build all files
                          separately
  --disable-load-extension
                          Disable loading of external extensions
  --disable-math          Disable math functions
  --enable-all            Enable FTS4, FTS5, Geopoly, JSON, RTree, Sessions
  --enable-memsys5        Enable MEMSYS5
  --enable-memsys3        Enable MEMSYS3

  --enable-fts3           Enable the FTS3 extension
  --enable-fts4           Enable the FTS4 extension
  --enable-fts5           Enable the FTS5 extension
  --enable-json1          Enable the JSON1 extension
  --enable-update-limit   Enable the UPDATE/DELETE LIMIT clause
  --enable-geopoly        Enable the GEOPOLY extension
  --enable-rtree          Enable the RTREE extension
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
    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.34.0
generated by GNU Autoconf 2.69

Copyright (C) 2012 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







|







1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
    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.35.0
generated by GNU Autoconf 2.69

Copyright (C) 2012 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
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

} # ac_fn_c_check_header_mongrel
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.34.0, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  $ $0 $@

_ACEOF
exec 5>>config.log
{







|







2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

} # ac_fn_c_check_header_mongrel
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.35.0, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  $ $0 $@

_ACEOF
exec 5>>config.log
{
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
$as_echo_n "checking the name lister ($NM) interface... " >&6; }
if ${lt_cv_nm_interface+:} false; then :
  $as_echo_n "(cached) " >&6
else
  lt_cv_nm_interface="BSD nm"
  echo "int some_variable = 0;" > conftest.$ac_ext
  (eval echo "\"\$as_me:3938: $ac_compile\"" >&5)
  (eval "$ac_compile" 2>conftest.err)
  cat conftest.err >&5
  (eval echo "\"\$as_me:3941: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
  cat conftest.err >&5
  (eval echo "\"\$as_me:3944: output\"" >&5)
  cat conftest.out >&5
  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
    lt_cv_nm_interface="MS dumpbin"
  fi
  rm -f conftest*
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5







|


|


|







3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
$as_echo_n "checking the name lister ($NM) interface... " >&6; }
if ${lt_cv_nm_interface+:} false; then :
  $as_echo_n "(cached) " >&6
else
  lt_cv_nm_interface="BSD nm"
  echo "int some_variable = 0;" > conftest.$ac_ext
  (eval echo "\"\$as_me:3940: $ac_compile\"" >&5)
  (eval "$ac_compile" 2>conftest.err)
  cat conftest.err >&5
  (eval echo "\"\$as_me:3943: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
  cat conftest.err >&5
  (eval echo "\"\$as_me:3946: output\"" >&5)
  cat conftest.out >&5
  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
    lt_cv_nm_interface="MS dumpbin"
  fi
  rm -f conftest*
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
	;;
    esac
  fi
  rm -rf conftest*
  ;;
*-*-irix6*)
  # Find out which ABI we are using.
  echo '#line 5150 "configure"' > conftest.$ac_ext
  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
  (eval $ac_compile) 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then
    if test "$lt_cv_prog_gnu_ld" = yes; then
      case `/usr/bin/file conftest.$ac_objext` in







|







5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
	;;
    esac
  fi
  rm -rf conftest*
  ;;
*-*-irix6*)
  # Find out which ABI we are using.
  echo '#line 5152 "configure"' > conftest.$ac_ext
  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
  (eval $ac_compile) 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then
    if test "$lt_cv_prog_gnu_ld" = yes; then
      case `/usr/bin/file conftest.$ac_objext` in
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
   # Note that $ac_compile itself does not contain backslashes and begins
   # with a dollar sign (not a hyphen), so the echo should work correctly.
   # The option is referenced via a variable to avoid confusing sed.
   lt_compile=`echo "$ac_compile" | $SED \
   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
   -e 's:$: $lt_compiler_flag:'`
   (eval echo "\"\$as_me:6675: $lt_compile\"" >&5)
   (eval "$lt_compile" 2>conftest.err)
   ac_status=$?
   cat conftest.err >&5
   echo "$as_me:6679: \$? = $ac_status" >&5
   if (exit $ac_status) && test -s "$ac_outfile"; then
     # The compiler can only warn and ignore the option if not recognized
     # So say no if there are warnings other than the usual output.
     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
       lt_cv_prog_compiler_rtti_exceptions=yes







|



|







6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
   # Note that $ac_compile itself does not contain backslashes and begins
   # with a dollar sign (not a hyphen), so the echo should work correctly.
   # The option is referenced via a variable to avoid confusing sed.
   lt_compile=`echo "$ac_compile" | $SED \
   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
   -e 's:$: $lt_compiler_flag:'`
   (eval echo "\"\$as_me:6677: $lt_compile\"" >&5)
   (eval "$lt_compile" 2>conftest.err)
   ac_status=$?
   cat conftest.err >&5
   echo "$as_me:6681: \$? = $ac_status" >&5
   if (exit $ac_status) && test -s "$ac_outfile"; then
     # The compiler can only warn and ignore the option if not recognized
     # So say no if there are warnings other than the usual output.
     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
       lt_cv_prog_compiler_rtti_exceptions=yes
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
   # Note that $ac_compile itself does not contain backslashes and begins
   # with a dollar sign (not a hyphen), so the echo should work correctly.
   # The option is referenced via a variable to avoid confusing sed.
   lt_compile=`echo "$ac_compile" | $SED \
   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
   -e 's:$: $lt_compiler_flag:'`
   (eval echo "\"\$as_me:7014: $lt_compile\"" >&5)
   (eval "$lt_compile" 2>conftest.err)
   ac_status=$?
   cat conftest.err >&5
   echo "$as_me:7018: \$? = $ac_status" >&5
   if (exit $ac_status) && test -s "$ac_outfile"; then
     # The compiler can only warn and ignore the option if not recognized
     # So say no if there are warnings other than the usual output.
     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
       lt_cv_prog_compiler_pic_works=yes







|



|







7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
   # Note that $ac_compile itself does not contain backslashes and begins
   # with a dollar sign (not a hyphen), so the echo should work correctly.
   # The option is referenced via a variable to avoid confusing sed.
   lt_compile=`echo "$ac_compile" | $SED \
   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
   -e 's:$: $lt_compiler_flag:'`
   (eval echo "\"\$as_me:7016: $lt_compile\"" >&5)
   (eval "$lt_compile" 2>conftest.err)
   ac_status=$?
   cat conftest.err >&5
   echo "$as_me:7020: \$? = $ac_status" >&5
   if (exit $ac_status) && test -s "$ac_outfile"; then
     # The compiler can only warn and ignore the option if not recognized
     # So say no if there are warnings other than the usual output.
     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
       lt_cv_prog_compiler_pic_works=yes
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
   # (2) before a word containing "conftest.", or (3) at the end.
   # Note that $ac_compile itself does not contain backslashes and begins
   # with a dollar sign (not a hyphen), so the echo should work correctly.
   lt_compile=`echo "$ac_compile" | $SED \
   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
   -e 's:$: $lt_compiler_flag:'`
   (eval echo "\"\$as_me:7119: $lt_compile\"" >&5)
   (eval "$lt_compile" 2>out/conftest.err)
   ac_status=$?
   cat out/conftest.err >&5
   echo "$as_me:7123: \$? = $ac_status" >&5
   if (exit $ac_status) && test -s out/conftest2.$ac_objext
   then
     # The compiler can only warn and ignore the option if not recognized
     # So say no if there are warnings
     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then







|



|







7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
   # (2) before a word containing "conftest.", or (3) at the end.
   # Note that $ac_compile itself does not contain backslashes and begins
   # with a dollar sign (not a hyphen), so the echo should work correctly.
   lt_compile=`echo "$ac_compile" | $SED \
   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
   -e 's:$: $lt_compiler_flag:'`
   (eval echo "\"\$as_me:7121: $lt_compile\"" >&5)
   (eval "$lt_compile" 2>out/conftest.err)
   ac_status=$?
   cat out/conftest.err >&5
   echo "$as_me:7125: \$? = $ac_status" >&5
   if (exit $ac_status) && test -s out/conftest2.$ac_objext
   then
     # The compiler can only warn and ignore the option if not recognized
     # So say no if there are warnings
     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
   # (2) before a word containing "conftest.", or (3) at the end.
   # Note that $ac_compile itself does not contain backslashes and begins
   # with a dollar sign (not a hyphen), so the echo should work correctly.
   lt_compile=`echo "$ac_compile" | $SED \
   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
   -e 's:$: $lt_compiler_flag:'`
   (eval echo "\"\$as_me:7174: $lt_compile\"" >&5)
   (eval "$lt_compile" 2>out/conftest.err)
   ac_status=$?
   cat out/conftest.err >&5
   echo "$as_me:7178: \$? = $ac_status" >&5
   if (exit $ac_status) && test -s out/conftest2.$ac_objext
   then
     # The compiler can only warn and ignore the option if not recognized
     # So say no if there are warnings
     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then







|



|







7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
   # (2) before a word containing "conftest.", or (3) at the end.
   # Note that $ac_compile itself does not contain backslashes and begins
   # with a dollar sign (not a hyphen), so the echo should work correctly.
   lt_compile=`echo "$ac_compile" | $SED \
   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
   -e 's:$: $lt_compiler_flag:'`
   (eval echo "\"\$as_me:7176: $lt_compile\"" >&5)
   (eval "$lt_compile" 2>out/conftest.err)
   ac_status=$?
   cat out/conftest.err >&5
   echo "$as_me:7180: \$? = $ac_status" >&5
   if (exit $ac_status) && test -s out/conftest2.$ac_objext
   then
     # The compiler can only warn and ignore the option if not recognized
     # So say no if there are warnings
     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
9547
9548
9549
9550
9551
9552
9553
9554
9555
9556
9557
9558
9559
9560
9561
else
  	  if test "$cross_compiling" = yes; then :
  lt_cv_dlopen_self=cross
else
  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
  lt_status=$lt_dlunknown
  cat > conftest.$ac_ext <<_LT_EOF
#line 9554 "configure"
#include "confdefs.h"

#if HAVE_DLFCN_H
#include <dlfcn.h>
#endif

#include <stdio.h>







|







9549
9550
9551
9552
9553
9554
9555
9556
9557
9558
9559
9560
9561
9562
9563
else
  	  if test "$cross_compiling" = yes; then :
  lt_cv_dlopen_self=cross
else
  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
  lt_status=$lt_dlunknown
  cat > conftest.$ac_ext <<_LT_EOF
#line 9556 "configure"
#include "confdefs.h"

#if HAVE_DLFCN_H
#include <dlfcn.h>
#endif

#include <stdio.h>
9643
9644
9645
9646
9647
9648
9649
9650
9651
9652
9653
9654
9655
9656
9657
else
  	  if test "$cross_compiling" = yes; then :
  lt_cv_dlopen_self_static=cross
else
  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
  lt_status=$lt_dlunknown
  cat > conftest.$ac_ext <<_LT_EOF
#line 9650 "configure"
#include "confdefs.h"

#if HAVE_DLFCN_H
#include <dlfcn.h>
#endif

#include <stdio.h>







|







9645
9646
9647
9648
9649
9650
9651
9652
9653
9654
9655
9656
9657
9658
9659
else
  	  if test "$cross_compiling" = yes; then :
  lt_cv_dlopen_self_static=cross
else
  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
  lt_status=$lt_dlunknown
  cat > conftest.$ac_ext <<_LT_EOF
#line 9652 "configure"
#include "confdefs.h"

#if HAVE_DLFCN_H
#include <dlfcn.h>
#endif

#include <stdio.h>
10360
10361
10362
10363
10364
10365
10366

10367
10368

10369
10370
10371
10372
10373
10374
10375
fi



if test "x${TCLLIBDIR+set}" != "xset" ; then
  TCLLIBDIR='$(libdir)'
  for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do

    TCLLIBDIR=$i
    break

  done
  TCLLIBDIR="${TCLLIBDIR}/sqlite3"
fi


#########
# Set up an appropriate program prefix







>
|
|
>







10362
10363
10364
10365
10366
10367
10368
10369
10370
10371
10372
10373
10374
10375
10376
10377
10378
10379
fi



if test "x${TCLLIBDIR+set}" != "xset" ; then
  TCLLIBDIR='$(libdir)'
  for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do
    if test -d $i ; then
      TCLLIBDIR=$i
      break
    fi
  done
  TCLLIBDIR="${TCLLIBDIR}/sqlite3"
fi


#########
# Set up an appropriate program prefix
11243
11244
11245
11246
11247
11248
11249


11250
11251


11252
11253


11254
11255
11256
11257
11258
11259
11260
#########
# check for debug enabled
# Check whether --enable-debug was given.
if test "${enable_debug+set}" = set; then :
  enableval=$enable_debug;
fi



if test "${enable_debug}" = "yes" ; then
  TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0"


else
  TARGET_DEBUG="-DNDEBUG"


fi


#########
# See whether we should use the amalgamation to build
# Check whether --enable-amalgamation was given.
if test "${enable_amalgamation+set}" = set; then :







>
>


>
>


>
>







11247
11248
11249
11250
11251
11252
11253
11254
11255
11256
11257
11258
11259
11260
11261
11262
11263
11264
11265
11266
11267
11268
11269
11270
#########
# check for debug enabled
# Check whether --enable-debug was given.
if test "${enable_debug+set}" = set; then :
  enableval=$enable_debug;
fi

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build type" >&5
$as_echo_n "checking build type... " >&6; }
if test "${enable_debug}" = "yes" ; then
  TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0"
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: debug" >&5
$as_echo "debug" >&6; }
else
  TARGET_DEBUG="-DNDEBUG"
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: release" >&5
$as_echo "release" >&6; }
fi


#########
# See whether we should use the amalgamation to build
# Check whether --enable-amalgamation was given.
if test "${enable_amalgamation+set}" = set; then :
11406
11407
11408
11409
11410
11411
11412





















































































11413
11414
11415
11416
11417
11418
11419
  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"

fi

else
  OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1"
fi






















































































##########
# Do we want to support memsys3 and/or memsys5
#
# Check whether --enable-memsys5 was given.
if test "${enable_memsys5+set}" = set; then :
  enableval=$enable_memsys5;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







11416
11417
11418
11419
11420
11421
11422
11423
11424
11425
11426
11427
11428
11429
11430
11431
11432
11433
11434
11435
11436
11437
11438
11439
11440
11441
11442
11443
11444
11445
11446
11447
11448
11449
11450
11451
11452
11453
11454
11455
11456
11457
11458
11459
11460
11461
11462
11463
11464
11465
11466
11467
11468
11469
11470
11471
11472
11473
11474
11475
11476
11477
11478
11479
11480
11481
11482
11483
11484
11485
11486
11487
11488
11489
11490
11491
11492
11493
11494
11495
11496
11497
11498
11499
11500
11501
11502
11503
11504
11505
11506
11507
11508
11509
11510
11511
11512
11513
11514
  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"

fi

else
  OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1"
fi

##########
# Do we want to support math functions
#
# Check whether --enable-math was given.
if test "${enable_math+set}" = set; then :
  enableval=$enable_math;
fi

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support math functions" >&5
$as_echo_n "checking whether to support math functions... " >&6; }
if test "$enable_math" = "no"; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MATH_FUNCTIONS"
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ceil" >&5
$as_echo_n "checking for library containing ceil... " >&6; }
if ${ac_cv_search_ceil+:} false; then :
  $as_echo_n "(cached) " >&6
else
  ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

/* Override any GCC internal prototype to avoid an error.
   Use char because int might match the return type of a GCC
   builtin and then its argument prototype would still apply.  */
#ifdef __cplusplus
extern "C"
#endif
char ceil ();
int
main ()
{
return ceil ();
  ;
  return 0;
}
_ACEOF
for ac_lib in '' m; do
  if test -z "$ac_lib"; then
    ac_res="none required"
  else
    ac_res=-l$ac_lib
    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
  fi
  if ac_fn_c_try_link "$LINENO"; then :
  ac_cv_search_ceil=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
    conftest$ac_exeext
  if ${ac_cv_search_ceil+:} false; then :
  break
fi
done
if ${ac_cv_search_ceil+:} false; then :

else
  ac_cv_search_ceil=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ceil" >&5
$as_echo "$ac_cv_search_ceil" >&6; }
ac_res=$ac_cv_search_ceil
if test "$ac_res" != no; then :
  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"

fi

fi


########
# The --enable-all argument is short-hand to enable
# multiple extensions.
# Check whether --enable-all was given.
if test "${enable_all+set}" = set; then :
  enableval=$enable_all;
fi


##########
# Do we want to support memsys3 and/or memsys5
#
# Check whether --enable-memsys5 was given.
if test "${enable_memsys5+set}" = set; then :
  enableval=$enable_memsys5;
11440
11441
11442
11443
11444
11445
11446
11447
11448
11449
11450
11451
11452
11453
11454
11455
11456
11457
11458
11459
11460
11461
11462
11463


11464
11465





11466
11467
11468
11469
11470
11471


11472


11473
11474
11475
11476
11477
11478
11479
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS3"
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi

########
# The --enable-extensions argument is short-hand to enable
# multiple extensions.
# Check whether --enable-all was given.
if test "${enable_all+set}" = set; then :
  enableval=$enable_all;
fi


#########
# See whether we should enable Full Text Search extensions
# Check whether --enable-fts3 was given.
if test "${enable_fts3+set}" = set; then :
  enableval=$enable_fts3;
fi



if test "${enable_fts3}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3"





fi
# Check whether --enable-fts4 was given.
if test "${enable_fts4+set}" = set; then :
  enableval=$enable_fts4;
fi



if test "${enable_fts4}" = "yes" -o "${enable_all}" = "yes" ; then


  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4"
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5
$as_echo_n "checking for library containing log... " >&6; }
if ${ac_cv_search_log+:} false; then :
  $as_echo_n "(cached) " >&6
else
  ac_func_search_save_LIBS=$LIBS







<
<
<
<
<
<
<
<
<








>
>


>
>
>
>
>






>
>

>
>







11535
11536
11537
11538
11539
11540
11541









11542
11543
11544
11545
11546
11547
11548
11549
11550
11551
11552
11553
11554
11555
11556
11557
11558
11559
11560
11561
11562
11563
11564
11565
11566
11567
11568
11569
11570
11571
11572
11573
11574
11575
11576
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS3"
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi










#########
# See whether we should enable Full Text Search extensions
# Check whether --enable-fts3 was given.
if test "${enable_fts3+set}" = set; then :
  enableval=$enable_fts3;
fi

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support FTS3" >&5
$as_echo_n "checking whether to support FTS3... " >&6; }
if test "${enable_fts3}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3"
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
# Check whether --enable-fts4 was given.
if test "${enable_fts4+set}" = set; then :
  enableval=$enable_fts4;
fi

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support FTS4" >&5
$as_echo_n "checking whether to support FTS4... " >&6; }
if test "${enable_fts4}" = "yes" -o "${enable_all}" = "yes" ; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4"
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5
$as_echo_n "checking for library containing log... " >&6; }
if ${ac_cv_search_log+:} false; then :
  $as_echo_n "(cached) " >&6
else
  ac_func_search_save_LIBS=$LIBS
11523
11524
11525
11526
11527
11528
11529



11530
11531
11532
11533
11534
11535


11536


11537
11538
11539
11540
11541
11542
11543
$as_echo "$ac_cv_search_log" >&6; }
ac_res=$ac_cv_search_log
if test "$ac_res" != no; then :
  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"

fi




fi
# Check whether --enable-fts5 was given.
if test "${enable_fts5+set}" = set; then :
  enableval=$enable_fts5;
fi



if test "${enable_fts5}" = "yes" -o "${enable_all}" = "yes" ; then


  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5"
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5
$as_echo_n "checking for library containing log... " >&6; }
if ${ac_cv_search_log+:} false; then :
  $as_echo_n "(cached) " >&6
else
  ac_func_search_save_LIBS=$LIBS







>
>
>






>
>

>
>







11620
11621
11622
11623
11624
11625
11626
11627
11628
11629
11630
11631
11632
11633
11634
11635
11636
11637
11638
11639
11640
11641
11642
11643
11644
11645
11646
11647
$as_echo "$ac_cv_search_log" >&6; }
ac_res=$ac_cv_search_log
if test "$ac_res" != no; then :
  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"

fi

else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
# Check whether --enable-fts5 was given.
if test "${enable_fts5+set}" = set; then :
  enableval=$enable_fts5;
fi

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support FTS5" >&5
$as_echo_n "checking whether to support FTS5... " >&6; }
if test "${enable_fts5}" = "yes" -o "${enable_all}" = "yes" ; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5"
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5
$as_echo_n "checking for library containing log... " >&6; }
if ${ac_cv_search_log+:} false; then :
  $as_echo_n "(cached) " >&6
else
  ac_func_search_save_LIBS=$LIBS
11587
11588
11589
11590
11591
11592
11593



11594
11595
11596
11597
11598
11599
11600
11601
11602


11603
11604





11605
11606
11607
11608
11609
11610
11611
11612
11613
11614


11615
11616





11617
11618
11619
11620
11621
11622
11623
11624
11625
11626
11627


11628
11629
11630





11631
11632
11633
11634
11635
11636
11637
11638
11639


11640
11641





11642
11643
11644
11645
11646
11647
11648
11649
11650


11651
11652
11653





11654
11655
11656
11657
11658
11659
11660
$as_echo "$ac_cv_search_log" >&6; }
ac_res=$ac_cv_search_log
if test "$ac_res" != no; then :
  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"

fi




fi

#########
# See whether we should enable JSON1
# Check whether --enable-json1 was given.
if test "${enable_json1+set}" = set; then :
  enableval=$enable_json1;
fi



if test "${enable_json1}" = "yes" -o "${enable_all}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1"





fi

#########
# See whether we should enable the LIMIT clause on UPDATE and DELETE
# statements.
# Check whether --enable-update-limit was given.
if test "${enable_update_limit+set}" = set; then :
  enableval=$enable_update_limit;
fi



if test "${enable_update_limit}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT"





fi

#########
# See whether we should enable GEOPOLY
# Check whether --enable-geopoly was given.
if test "${enable_geopoly+set}" = set; then :
  enableval=$enable_geopoly; enable_geopoly=yes
else
  enable_geopoly=no
fi



if test "${enable_geopoly}" = "yes" -o "${enable_all}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY"
  enable_rtree=yes





fi

#########
# See whether we should enable RTREE
# Check whether --enable-rtree was given.
if test "${enable_rtree+set}" = set; then :
  enableval=$enable_rtree;
fi



if test "${enable_rtree}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE"





fi

#########
# See whether we should enable the SESSION extension
# Check whether --enable-session was given.
if test "${enable_session+set}" = set; then :
  enableval=$enable_session;
fi



if test "${enable_session}" = "yes" -o "${enable_all}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION"
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK"





fi

#########
# attempt to duplicate any OMITS and ENABLES into the ${OPT_FEATURE_FLAGS} parameter
for option in $CFLAGS $CPPFLAGS
do
  case $option in







>
>
>









>
>


>
>
>
>
>










>
>


>
>
>
>
>











>
>



>
>
>
>
>









>
>


>
>
>
>
>









>
>



>
>
>
>
>







11691
11692
11693
11694
11695
11696
11697
11698
11699
11700
11701
11702
11703
11704
11705
11706
11707
11708
11709
11710
11711
11712
11713
11714
11715
11716
11717
11718
11719
11720
11721
11722
11723
11724
11725
11726
11727
11728
11729
11730
11731
11732
11733
11734
11735
11736
11737
11738
11739
11740
11741
11742
11743
11744
11745
11746
11747
11748
11749
11750
11751
11752
11753
11754
11755
11756
11757
11758
11759
11760
11761
11762
11763
11764
11765
11766
11767
11768
11769
11770
11771
11772
11773
11774
11775
11776
11777
11778
11779
11780
11781
11782
11783
11784
11785
11786
11787
11788
11789
11790
11791
11792
11793
11794
11795
11796
11797
11798
11799
11800
11801
11802
$as_echo "$ac_cv_search_log" >&6; }
ac_res=$ac_cv_search_log
if test "$ac_res" != no; then :
  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"

fi

else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi

#########
# See whether we should enable JSON1
# Check whether --enable-json1 was given.
if test "${enable_json1+set}" = set; then :
  enableval=$enable_json1;
fi

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support JSON" >&5
$as_echo_n "checking whether to support JSON... " >&6; }
if test "${enable_json1}" = "yes" -o "${enable_all}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1"
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi

#########
# See whether we should enable the LIMIT clause on UPDATE and DELETE
# statements.
# Check whether --enable-update-limit was given.
if test "${enable_update_limit+set}" = set; then :
  enableval=$enable_update_limit;
fi

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support LIMIT on UPDATE and DELETE statements" >&5
$as_echo_n "checking whether to support LIMIT on UPDATE and DELETE statements... " >&6; }
if test "${enable_update_limit}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT"
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi

#########
# See whether we should enable GEOPOLY
# Check whether --enable-geopoly was given.
if test "${enable_geopoly+set}" = set; then :
  enableval=$enable_geopoly; enable_geopoly=yes
else
  enable_geopoly=no
fi

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support GEOPOLY" >&5
$as_echo_n "checking whether to support GEOPOLY... " >&6; }
if test "${enable_geopoly}" = "yes" -o "${enable_all}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY"
  enable_rtree=yes
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi

#########
# See whether we should enable RTREE
# Check whether --enable-rtree was given.
if test "${enable_rtree+set}" = set; then :
  enableval=$enable_rtree;
fi

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support RTREE" >&5
$as_echo_n "checking whether to support RTREE... " >&6; }
if test "${enable_rtree}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE"
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi

#########
# See whether we should enable the SESSION extension
# Check whether --enable-session was given.
if test "${enable_session+set}" = set; then :
  enableval=$enable_session;
fi

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support SESSION" >&5
$as_echo_n "checking whether to support SESSION... " >&6; }
if test "${enable_session}" = "yes" -o "${enable_all}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION"
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK"
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi

#########
# attempt to duplicate any OMITS and ENABLES into the ${OPT_FEATURE_FLAGS} parameter
for option in $CFLAGS $CPPFLAGS
do
  case $option in
12232
12233
12234
12235
12236
12237
12238
12239
12240
12241
12242
12243
12244
12245
12246
test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=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.34.0, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@







|







12374
12375
12376
12377
12378
12379
12380
12381
12382
12383
12384
12385
12386
12387
12388
test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=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.35.0, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@
12298
12299
12300
12301
12302
12303
12304
12305
12306
12307
12308
12309
12310
12311
12312

Report bugs to the package provider."

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

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








|







12440
12441
12442
12443
12444
12445
12446
12447
12448
12449
12450
12451
12452
12453
12454

Report bugs to the package provider."

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

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

Changes to configure.ac.
130
131
132
133
134
135
136

137
138

139
140
141
142
143
144
145
fi
AC_SUBST(TCLSH_CMD)

AC_ARG_VAR([TCLLIBDIR], [Where to install tcl plugin])
if test "x${TCLLIBDIR+set}" != "xset" ; then
  TCLLIBDIR='$(libdir)'
  for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do

    TCLLIBDIR=$i
    break

  done
  TCLLIBDIR="${TCLLIBDIR}/sqlite3"
fi


#########
# Set up an appropriate program prefix







>
|
|
>







130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
fi
AC_SUBST(TCLSH_CMD)

AC_ARG_VAR([TCLLIBDIR], [Where to install tcl plugin])
if test "x${TCLLIBDIR+set}" != "xset" ; then
  TCLLIBDIR='$(libdir)'
  for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do
    if test -d $i ; then
      TCLLIBDIR=$i
      break
    fi
  done
  TCLLIBDIR="${TCLLIBDIR}/sqlite3"
fi


#########
# Set up an appropriate program prefix
549
550
551
552
553
554
555

556
557

558
559

560
561
562
563
564
565
566
# that use "fdatasync()" function.
#
AC_SEARCH_LIBS(fdatasync, [rt])

#########
# check for debug enabled
AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],[enable debugging & verbose explain]))

if test "${enable_debug}" = "yes" ; then
  TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0"

else
  TARGET_DEBUG="-DNDEBUG"

fi
AC_SUBST(TARGET_DEBUG)

#########
# See whether we should use the amalgamation to build
AC_ARG_ENABLE(amalgamation, AC_HELP_STRING([--disable-amalgamation],
      [Disable the amalgamation and instead build all files separately]))







>


>


>







551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
# that use "fdatasync()" function.
#
AC_SEARCH_LIBS(fdatasync, [rt])

#########
# check for debug enabled
AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],[enable debugging & verbose explain]))
AC_MSG_CHECKING([build type])
if test "${enable_debug}" = "yes" ; then
  TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0"
  AC_MSG_RESULT([debug])
else
  TARGET_DEBUG="-DNDEBUG"
  AC_MSG_RESULT([release])
fi
AC_SUBST(TARGET_DEBUG)

#########
# See whether we should use the amalgamation to build
AC_ARG_ENABLE(amalgamation, AC_HELP_STRING([--disable-amalgamation],
      [Disable the amalgamation and instead build all files separately]))
582
583
584
585
586
587
588





















589
590
591
592
593
594
595
if test "${enable_load_extension}" = "yes" ; then
  OPT_FEATURE_FLAGS=""
  AC_SEARCH_LIBS(dlopen, dl)
else
  OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1"
fi






















##########
# Do we want to support memsys3 and/or memsys5
#
AC_ARG_ENABLE(memsys5, 
  AC_HELP_STRING([--enable-memsys5],[Enable MEMSYS5]))
AC_MSG_CHECKING([whether to support MEMSYS5])
if test "${enable_memsys5}" = "yes"; then







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
if test "${enable_load_extension}" = "yes" ; then
  OPT_FEATURE_FLAGS=""
  AC_SEARCH_LIBS(dlopen, dl)
else
  OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1"
fi

##########
# Do we want to support math functions
#
AC_ARG_ENABLE(math, 
AC_HELP_STRING([--disable-math],[Disable math functions]))
AC_MSG_CHECKING([whether to support math functions])
if test "$enable_math" = "no"; then
  AC_MSG_RESULT([no])
else
  AC_MSG_RESULT([yes])
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MATH_FUNCTIONS"
  AC_SEARCH_LIBS(ceil, m)
fi


########
# The --enable-all argument is short-hand to enable
# multiple extensions.
AC_ARG_ENABLE(all, AC_HELP_STRING([--enable-all],
      [Enable FTS4, FTS5, Geopoly, JSON, RTree, Sessions]))

##########
# Do we want to support memsys3 and/or memsys5
#
AC_ARG_ENABLE(memsys5, 
  AC_HELP_STRING([--enable-memsys5],[Enable MEMSYS5]))
AC_MSG_CHECKING([whether to support MEMSYS5])
if test "${enable_memsys5}" = "yes"; then
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
if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS3"
  AC_MSG_RESULT([yes])
else
  AC_MSG_RESULT([no])
fi

########
# The --enable-extensions argument is short-hand to enable
# multiple extensions.
AC_ARG_ENABLE(all, AC_HELP_STRING([--enable-all],
      [Enable FTS4, FTS5, Geopoly, JSON, RTree, Sessions]))

#########
# See whether we should enable Full Text Search extensions
AC_ARG_ENABLE(fts3, AC_HELP_STRING([--enable-fts3],
      [Enable the FTS3 extension]))

if test "${enable_fts3}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3"



fi
AC_ARG_ENABLE(fts4, AC_HELP_STRING([--enable-fts4],
      [Enable the FTS4 extension]))

if test "${enable_fts4}" = "yes" -o "${enable_all}" = "yes" ; then

  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4"
  AC_SEARCH_LIBS([log],[m])


fi
AC_ARG_ENABLE(fts5, AC_HELP_STRING([--enable-fts5],
      [Enable the FTS5 extension]))

if test "${enable_fts5}" = "yes" -o "${enable_all}" = "yes" ; then

  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5"
  AC_SEARCH_LIBS([log],[m])


fi

#########
# See whether we should enable JSON1
AC_ARG_ENABLE(json1, AC_HELP_STRING([--enable-json1],[Enable the JSON1 extension]))

if test "${enable_json1}" = "yes" -o "${enable_all}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1"



fi

#########
# See whether we should enable the LIMIT clause on UPDATE and DELETE
# statements.
AC_ARG_ENABLE(update-limit, AC_HELP_STRING([--enable-update-limit],
      [Enable the UPDATE/DELETE LIMIT clause]))

if test "${enable_update_limit}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT"



fi

#########
# See whether we should enable GEOPOLY
AC_ARG_ENABLE(geopoly, AC_HELP_STRING([--enable-geopoly],
      [Enable the GEOPOLY extension]),
      [enable_geopoly=yes],[enable_geopoly=no])

if test "${enable_geopoly}" = "yes" -o "${enable_all}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY"
  enable_rtree=yes



fi

#########
# See whether we should enable RTREE
AC_ARG_ENABLE(rtree, AC_HELP_STRING([--enable-rtree],
      [Enable the RTREE extension]))

if test "${enable_rtree}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE"



fi

#########
# See whether we should enable the SESSION extension
AC_ARG_ENABLE(session, AC_HELP_STRING([--enable-session],
      [Enable the SESSION extension]))

if test "${enable_session}" = "yes" -o "${enable_all}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION"
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK"



fi

#########
# attempt to duplicate any OMITS and ENABLES into the ${OPT_FEATURE_FLAGS} parameter
for option in $CFLAGS $CPPFLAGS
do
  case $option in







<
<
<
<
<
<




>


>
>
>



>

>


>
>



>

>


>
>





>


>
>
>







>


>
>
>







>



>
>
>






>


>
>
>






>



>
>
>







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
if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS3"
  AC_MSG_RESULT([yes])
else
  AC_MSG_RESULT([no])
fi







#########
# See whether we should enable Full Text Search extensions
AC_ARG_ENABLE(fts3, AC_HELP_STRING([--enable-fts3],
      [Enable the FTS3 extension]))
AC_MSG_CHECKING([whether to support FTS3])
if test "${enable_fts3}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3"
  AC_MSG_RESULT([yes])
else
  AC_MSG_RESULT([no])
fi
AC_ARG_ENABLE(fts4, AC_HELP_STRING([--enable-fts4],
      [Enable the FTS4 extension]))
AC_MSG_CHECKING([whether to support FTS4])
if test "${enable_fts4}" = "yes" -o "${enable_all}" = "yes" ; then
  AC_MSG_RESULT([yes])
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4"
  AC_SEARCH_LIBS([log],[m])
else
  AC_MSG_RESULT([no])
fi
AC_ARG_ENABLE(fts5, AC_HELP_STRING([--enable-fts5],
      [Enable the FTS5 extension]))
AC_MSG_CHECKING([whether to support FTS5])
if test "${enable_fts5}" = "yes" -o "${enable_all}" = "yes" ; then
  AC_MSG_RESULT([yes])
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5"
  AC_SEARCH_LIBS([log],[m])
else
  AC_MSG_RESULT([no])
fi

#########
# See whether we should enable JSON1
AC_ARG_ENABLE(json1, AC_HELP_STRING([--enable-json1],[Enable the JSON1 extension]))
AC_MSG_CHECKING([whether to support JSON])
if test "${enable_json1}" = "yes" -o "${enable_all}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1"
  AC_MSG_RESULT([yes])
else
  AC_MSG_RESULT([no])
fi

#########
# See whether we should enable the LIMIT clause on UPDATE and DELETE
# statements.
AC_ARG_ENABLE(update-limit, AC_HELP_STRING([--enable-update-limit],
      [Enable the UPDATE/DELETE LIMIT clause]))
AC_MSG_CHECKING([whether to support LIMIT on UPDATE and DELETE statements])
if test "${enable_update_limit}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT"
  AC_MSG_RESULT([yes])
else
  AC_MSG_RESULT([no])
fi

#########
# See whether we should enable GEOPOLY
AC_ARG_ENABLE(geopoly, AC_HELP_STRING([--enable-geopoly],
      [Enable the GEOPOLY extension]),
      [enable_geopoly=yes],[enable_geopoly=no])
AC_MSG_CHECKING([whether to support GEOPOLY])
if test "${enable_geopoly}" = "yes" -o "${enable_all}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY"
  enable_rtree=yes
  AC_MSG_RESULT([yes])
else
  AC_MSG_RESULT([no])
fi

#########
# See whether we should enable RTREE
AC_ARG_ENABLE(rtree, AC_HELP_STRING([--enable-rtree],
      [Enable the RTREE extension]))
AC_MSG_CHECKING([whether to support RTREE])
if test "${enable_rtree}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE"
  AC_MSG_RESULT([yes])
else
  AC_MSG_RESULT([no])
fi

#########
# See whether we should enable the SESSION extension
AC_ARG_ENABLE(session, AC_HELP_STRING([--enable-session],
      [Enable the SESSION extension]))
AC_MSG_CHECKING([whether to support SESSION])
if test "${enable_session}" = "yes" -o "${enable_all}" = "yes" ; then
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION"
  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK"
  AC_MSG_RESULT([yes])
else
  AC_MSG_RESULT([no])
fi

#########
# attempt to duplicate any OMITS and ENABLES into the ${OPT_FEATURE_FLAGS} parameter
for option in $CFLAGS $CPPFLAGS
do
  case $option in
Changes to doc/lemon.html.
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
<pre>
   %start_symbol  prog
</pre>

<a id='syntax_error'></a>
<h4>4.4.19 The <tt>%syntax_error</tt> directive</h4>

<p>See <a href='#error_processing'>Error Processing</a>.</p>

<a id='token_class'></a>
<h4>4.4.20 The <tt>%token_class</tt> directive</h4>

<p>Undocumented.  Appears to be related to the MULTITERMINAL concept.
<a href='http://sqlite.org/src/fdiff?v1=796930d5fc2036c7&v2=624b24c5dc048e09&sbs=0'>Implementation</a>.</p>








|







1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
<pre>
   %start_symbol  prog
</pre>

<a id='syntax_error'></a>
<h4>4.4.19 The <tt>%syntax_error</tt> directive</h4>

<p>See <a href='#errors'>Error Processing</a>.</p>

<a id='token_class'></a>
<h4>4.4.20 The <tt>%token_class</tt> directive</h4>

<p>Undocumented.  Appears to be related to the MULTITERMINAL concept.
<a href='http://sqlite.org/src/fdiff?v1=796930d5fc2036c7&v2=624b24c5dc048e09&sbs=0'>Implementation</a>.</p>

1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
period.  This directive specifies that the identified token should
match any input token.</p>

<p>When the generated parser has the choice of matching an input against
the wildcard token and some other token, the other token is always used.
The wildcard token is only matched if there are no alternatives.</p>

<a id='error_processing'></a>
<h2>5.0 Error Processing</h2>

<p>After extensive experimentation over several years, it has been
discovered that the error recovery strategy used by yacc is about
as good as it gets.  And so that is what Lemon uses.</p>

<p>When a Lemon-generated parser encounters a syntax error, it







|







1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
period.  This directive specifies that the identified token should
match any input token.</p>

<p>When the generated parser has the choice of matching an input against
the wildcard token and some other token, the other token is always used.
The wildcard token is only matched if there are no alternatives.</p>

<a id='errors'></a>
<h2>5.0 Error Processing</h2>

<p>After extensive experimentation over several years, it has been
discovered that the error recovery strategy used by yacc is about
as good as it gets.  And so that is what Lemon uses.</p>

<p>When a Lemon-generated parser encounters a syntax error, it
Changes to ext/expert/expert1.test.
23
24
25
26
27
28
29

30
31
32
33
34
35
36
source $testdir/tester.tcl
set testprefix expert1

if {[info commands sqlite3_expert_new]==""} {
  finish_test
  return
}


set CLI [test_binary_name sqlite3]
set CMD [test_binary_name sqlite3_expert]

proc squish {txt} {
  regsub -all {[[:space:]]+} $txt { }
}







>







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
source $testdir/tester.tcl
set testprefix expert1

if {[info commands sqlite3_expert_new]==""} {
  finish_test
  return
}


set CLI [test_binary_name sqlite3]
set CMD [test_binary_name sqlite3_expert]

proc squish {txt} {
  regsub -all {[[:space:]]+} $txt { }
}
363
364
365
366
367
368
369























370
371
372
373
374
375
376
} {
  SELECT * FROM example WHERE a>? AND b=?
} {
  CREATE INDEX example_idx_0000cb3f ON example(B, A);
  SEARCH TABLE example USING INDEX example_idx_0000cb3f (B=? AND A>?)
}
























}

proc do_candidates_test {tn sql res} {
  set res [squish [string trim $res]]

  set expert [sqlite3_expert_new db]
  $expert sql $sql







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
} {
  SELECT * FROM example WHERE a>? AND b=?
} {
  CREATE INDEX example_idx_0000cb3f ON example(B, A);
  SEARCH TABLE example USING INDEX example_idx_0000cb3f (B=? AND A>?)
}

do_setup_rec_test $tn.18.0 {
  CREATE TABLE SomeObject (
     a INTEGER PRIMARY KEY,
     x TEXT GENERATED ALWAYS AS(HEX(a)) VIRTUAL
  );
} {
  SELECT x FROM SomeObject;
} {
  (no new indexes)
  SCAN TABLE SomeObject
}
do_setup_rec_test $tn.18.1 {
  CREATE TABLE SomeObject (
     a INTEGER PRIMARY KEY,
     x TEXT GENERATED ALWAYS AS(HEX(a)) VIRTUAL
  );
} {
  SELECT * FROM SomeObject WHERE x=?;
} {
  CREATE INDEX SomeObject_idx_00000078 ON SomeObject(x);
  SEARCH TABLE SomeObject USING COVERING INDEX SomeObject_idx_00000078 (x=?)
}

}

proc do_candidates_test {tn sql res} {
  set res [squish [string trim $res]]

  set expert [sqlite3_expert_new db]
  $expert sql $sql
426
427
428
429
430
431
432
433
434

  t1 t1_idx_00000062 {100 20}
  t1 t1_idx_000123a7 {100 50 17}
  t2 t2_idx_00000063 {100 20} 
  t2 t2_idx_00000064 {100 5} 
  t2 t2_idx_0001295b {100 20 5}
}


finish_test








<

>
450
451
452
453
454
455
456

457
458
  t1 t1_idx_00000062 {100 20}
  t1 t1_idx_000123a7 {100 50 17}
  t2 t2_idx_00000063 {100 20} 
  t2 t2_idx_00000064 {100 5} 
  t2 t2_idx_0001295b {100 20 5}
}


finish_test

Changes to ext/expert/sqlite3expert.c.
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
  int nTab = STRLEN(zTab);
  int nByte = sizeof(IdxTable) + nTab + 1;
  IdxTable *pNew = 0;
  int rc, rc2;
  char *pCsr = 0;
  int nPk = 0;

  rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q", zTab);
  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
    const char *zCol = (const char*)sqlite3_column_text(p1, 1);
    nByte += 1 + STRLEN(zCol);
    rc = sqlite3_table_column_metadata(
        db, "main", zTab, zCol, 0, &zCol, 0, 0, 0
    );
    nByte += 1 + STRLEN(zCol);







|







683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
  int nTab = STRLEN(zTab);
  int nByte = sizeof(IdxTable) + nTab + 1;
  IdxTable *pNew = 0;
  int rc, rc2;
  char *pCsr = 0;
  int nPk = 0;

  rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_xinfo=%Q", zTab);
  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
    const char *zCol = (const char*)sqlite3_column_text(p1, 1);
    nByte += 1 + STRLEN(zCol);
    rc = sqlite3_table_column_metadata(
        db, "main", zTab, zCol, 0, &zCol, 0, 0, 0
    );
    nByte += 1 + STRLEN(zCol);
1717
1718
1719
1720
1721
1722
1723

1724
1725
1726
1727

1728
1729
1730
1731
1732
1733
1734
    );
  }

  idxFinalize(&rc, pAllIndex);
  idxFinalize(&rc, pIndexXInfo);
  idxFinalize(&rc, pWrite);


  for(i=0; i<pCtx->nSlot; i++){
    sqlite3_free(pCtx->aSlot[i].z);
  }
  sqlite3_free(pCtx);


  if( rc==SQLITE_OK ){
    rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0);
  }

  sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0);
  return rc;







>
|
|
|
|
>







1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
    );
  }

  idxFinalize(&rc, pAllIndex);
  idxFinalize(&rc, pIndexXInfo);
  idxFinalize(&rc, pWrite);

  if( pCtx ){
    for(i=0; i<pCtx->nSlot; i++){
      sqlite3_free(pCtx->aSlot[i].z);
    }
    sqlite3_free(pCtx);
  }

  if( rc==SQLITE_OK ){
    rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0);
  }

  sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0);
  return rc;
Changes to ext/fts3/fts3.c.
5208
5209
5210
5211
5212
5213
5214

5215
5216
5217
5218
5219
5220
5221
5222
5223
5224

  p2 = pOut = pPhrase->doclist.pList;
  res = fts3PoslistNearMerge(
    &pOut, aTmp, nParam1, nParam2, paPoslist, &p2
  );
  if( res ){
    nNew = (int)(pOut - pPhrase->doclist.pList) - 1;

    if( nNew>=0 ){
      assert( pPhrase->doclist.pList[nNew]=='\0' );
      assert( nNew<=pPhrase->doclist.nList && nNew>0 );
      memset(&pPhrase->doclist.pList[nNew], 0, pPhrase->doclist.nList - nNew);
      pPhrase->doclist.nList = nNew;
    }
    *paPoslist = pPhrase->doclist.pList;
    *pnToken = pPhrase->nToken;
  }








>
|

<







5208
5209
5210
5211
5212
5213
5214
5215
5216
5217

5218
5219
5220
5221
5222
5223
5224

  p2 = pOut = pPhrase->doclist.pList;
  res = fts3PoslistNearMerge(
    &pOut, aTmp, nParam1, nParam2, paPoslist, &p2
  );
  if( res ){
    nNew = (int)(pOut - pPhrase->doclist.pList) - 1;
    assert_fts3_nc( nNew<=pPhrase->doclist.nList && nNew>0 );
    if( nNew>=0 && nNew<=pPhrase->doclist.nList ){
      assert( pPhrase->doclist.pList[nNew]=='\0' );

      memset(&pPhrase->doclist.pList[nNew], 0, pPhrase->doclist.nList - nNew);
      pPhrase->doclist.nList = nNew;
    }
    *paPoslist = pPhrase->doclist.pList;
    *pnToken = pPhrase->nToken;
  }

Changes to ext/fts3/fts3_expr.c.
489
490
491
492
493
494
495





496
497
498
499
500
501
502
    return getNextString(pParse, &zInput[1], ii-1, ppExpr);
  }

  if( sqlite3_fts3_enable_parentheses ){
    if( *zInput=='(' ){
      int nConsumed = 0;
      pParse->nNest++;





      rc = fts3ExprParse(pParse, zInput+1, nInput-1, ppExpr, &nConsumed);
      *pnConsumed = (int)(zInput - z) + 1 + nConsumed;
      return rc;
    }else if( *zInput==')' ){
      pParse->nNest--;
      *pnConsumed = (int)((zInput - z) + 1);
      *ppExpr = 0;







>
>
>
>
>







489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
    return getNextString(pParse, &zInput[1], ii-1, ppExpr);
  }

  if( sqlite3_fts3_enable_parentheses ){
    if( *zInput=='(' ){
      int nConsumed = 0;
      pParse->nNest++;
#if !defined(SQLITE_MAX_EXPR_DEPTH)
      if( pParse->nNest>1000 ) return SQLITE_ERROR;
#elif SQLITE_MAX_EXPR_DEPTH>0
      if( pParse->nNest>SQLITE_MAX_EXPR_DEPTH ) return SQLITE_ERROR;
#endif
      rc = fts3ExprParse(pParse, zInput+1, nInput-1, ppExpr, &nConsumed);
      *pnConsumed = (int)(zInput - z) + 1 + nConsumed;
      return rc;
    }else if( *zInput==')' ){
      pParse->nNest--;
      *pnConsumed = (int)((zInput - z) + 1);
      *ppExpr = 0;
Changes to ext/fts3/fts3_unicode.c.
281
282
283
284
285
286
287

288
289
290
291
292
293
294
    return SQLITE_NOMEM;
  }
  memset(pCsr, 0, sizeof(unicode_cursor));

  pCsr->aInput = (const unsigned char *)aInput;
  if( aInput==0 ){
    pCsr->nInput = 0;

  }else if( nInput<0 ){
    pCsr->nInput = (int)strlen(aInput);
  }else{
    pCsr->nInput = nInput;
  }

  *pp = &pCsr->base;







>







281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
    return SQLITE_NOMEM;
  }
  memset(pCsr, 0, sizeof(unicode_cursor));

  pCsr->aInput = (const unsigned char *)aInput;
  if( aInput==0 ){
    pCsr->nInput = 0;
    pCsr->aInput = (const unsigned char*)"";
  }else if( nInput<0 ){
    pCsr->nInput = (int)strlen(aInput);
  }else{
    pCsr->nInput = nInput;
  }

  *pp = &pCsr->base;
Changes to ext/fts3/fts3_write.c.
4331
4332
4333
4334
4335
4336
4337


4338

4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
        pNode = &pWriter->aNodeWriter[i];

        if( pNode->block.a){
          rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n);
          while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader);
          blobGrowBuffer(&pNode->key, reader.term.n, &rc);
          if( rc==SQLITE_OK ){


            memcpy(pNode->key.a, reader.term.a, reader.term.n);

            pNode->key.n = reader.term.n;
            if( i>0 ){
              char *aBlock = 0;
              int nBlock = 0;
              pNode = &pWriter->aNodeWriter[i-1];
              pNode->iBlock = reader.iChild;
              rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock, 0);
              blobGrowBuffer(&pNode->block, 
                  MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc
              );
              if( rc==SQLITE_OK ){
                memcpy(pNode->block.a, aBlock, nBlock);
                pNode->block.n = nBlock;
                memset(&pNode->block.a[nBlock], 0, FTS3_NODE_PADDING);
              }
              sqlite3_free(aBlock);
            }







>
>
|
>






|


|







4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
        pNode = &pWriter->aNodeWriter[i];

        if( pNode->block.a){
          rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n);
          while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader);
          blobGrowBuffer(&pNode->key, reader.term.n, &rc);
          if( rc==SQLITE_OK ){
            assert_fts3_nc( reader.term.n>0 || reader.aNode==0 );
            if( reader.term.n>0 ){
              memcpy(pNode->key.a, reader.term.a, reader.term.n);
            }
            pNode->key.n = reader.term.n;
            if( i>0 ){
              char *aBlock = 0;
              int nBlock = 0;
              pNode = &pWriter->aNodeWriter[i-1];
              pNode->iBlock = reader.iChild;
              rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock,0);
              blobGrowBuffer(&pNode->block, 
                  MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc
                  );
              if( rc==SQLITE_OK ){
                memcpy(pNode->block.a, aBlock, nBlock);
                pNode->block.n = nBlock;
                memset(&pNode->block.a[nBlock], 0, FTS3_NODE_PADDING);
              }
              sqlite3_free(aBlock);
            }
Changes to ext/fts3/unicode/mkunicode.tcl.
738
739
740
741
742
743
744

745
746
747
748
749
750
751
        int bToken = aArray[ aFts5UnicodeData[iTbl] & 0x1F ];
        int n = (aFts5UnicodeData[iTbl] >> 5) + i;
        for(; i<128 && i<n; i++){
          aAscii[i] = (u8)bToken;
        }
        iTbl++;
      }

    }
  }]
}

proc print_test_categories {lMap} {

  set lCP [list]







>







738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
        int bToken = aArray[ aFts5UnicodeData[iTbl] & 0x1F ];
        int n = (aFts5UnicodeData[iTbl] >> 5) + i;
        for(; i<128 && i<n; i++){
          aAscii[i] = (u8)bToken;
        }
        iTbl++;
      }
      aAscii[0] = 0;                  /* 0x00 is never a token character */
    }
  }]
}

proc print_test_categories {lMap} {

  set lCP [list]
Changes to ext/fts5/fts5_aux.c.
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
  const Fts5ExtensionApi *pApi, 
  Fts5Context *pFts,
  Fts5Bm25Data **ppData           /* OUT: bm25-data object for this query */
){
  int rc = SQLITE_OK;             /* Return code */
  Fts5Bm25Data *p;                /* Object to return */

  p = pApi->xGetAuxdata(pFts, 0);
  if( p==0 ){
    int nPhrase;                  /* Number of phrases in query */
    sqlite3_int64 nRow = 0;       /* Number of rows in table */
    sqlite3_int64 nToken = 0;     /* Number of tokens in table */
    sqlite3_int64 nByte;          /* Bytes of space to allocate */
    int i;








|







562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
  const Fts5ExtensionApi *pApi, 
  Fts5Context *pFts,
  Fts5Bm25Data **ppData           /* OUT: bm25-data object for this query */
){
  int rc = SQLITE_OK;             /* Return code */
  Fts5Bm25Data *p;                /* Object to return */

  p = (Fts5Bm25Data*)pApi->xGetAuxdata(pFts, 0);
  if( p==0 ){
    int nPhrase;                  /* Number of phrases in query */
    sqlite3_int64 nRow = 0;       /* Number of rows in table */
    sqlite3_int64 nToken = 0;     /* Number of tokens in table */
    sqlite3_int64 nByte;          /* Bytes of space to allocate */
    int i;

636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
  Fts5Context *pFts,              /* First arg to pass to pApi functions */
  sqlite3_context *pCtx,          /* Context for returning result/error */
  int nVal,                       /* Number of values in apVal[] array */
  sqlite3_value **apVal           /* Array of trailing arguments */
){
  const double k1 = 1.2;          /* Constant "k1" from BM25 formula */
  const double b = 0.75;          /* Constant "b" from BM25 formula */
  int rc = SQLITE_OK;             /* Error code */
  double score = 0.0;             /* SQL function return value */
  Fts5Bm25Data *pData;            /* Values allocated/calculated once only */
  int i;                          /* Iterator variable */
  int nInst = 0;                  /* Value returned by xInstCount() */
  double D = 0.0;                 /* Total number of tokens in row */
  double *aFreq = 0;              /* Array of phrase freq. for current row */








|







636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
  Fts5Context *pFts,              /* First arg to pass to pApi functions */
  sqlite3_context *pCtx,          /* Context for returning result/error */
  int nVal,                       /* Number of values in apVal[] array */
  sqlite3_value **apVal           /* Array of trailing arguments */
){
  const double k1 = 1.2;          /* Constant "k1" from BM25 formula */
  const double b = 0.75;          /* Constant "b" from BM25 formula */
  int rc;                         /* Error code */
  double score = 0.0;             /* SQL function return value */
  Fts5Bm25Data *pData;            /* Values allocated/calculated once only */
  int i;                          /* Iterator variable */
  int nInst = 0;                  /* Value returned by xInstCount() */
  double D = 0.0;                 /* Total number of tokens in row */
  double *aFreq = 0;              /* Array of phrase freq. for current row */

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
  /* Figure out the total size of the current row in tokens. */
  if( rc==SQLITE_OK ){
    int nTok;
    rc = pApi->xColumnSize(pFts, -1, &nTok);
    D = (double)nTok;
  }

  /* Determine the BM25 score for the current row. */


  for(i=0; rc==SQLITE_OK && i<pData->nPhrase; i++){
    score += pData->aIDF[i] * (
      ( aFreq[i] * (k1 + 1.0) ) / 
      ( aFreq[i] + k1 * (1 - b + b * D / pData->avgdl) )
    );
  }
  
  /* If no error has occurred, return the calculated score. Otherwise,
  ** throw an SQL exception.  */
  if( rc==SQLITE_OK ){
    sqlite3_result_double(pCtx, -1.0 * score);
  }else{
    sqlite3_result_error_code(pCtx, rc);
  }
}

int sqlite3Fts5AuxInit(fts5_api *pApi){







|
>
>
|
|
|
|
|
|
<
<
<
<







668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683




684
685
686
687
688
689
690
  /* Figure out the total size of the current row in tokens. */
  if( rc==SQLITE_OK ){
    int nTok;
    rc = pApi->xColumnSize(pFts, -1, &nTok);
    D = (double)nTok;
  }

  /* Determine and return the BM25 score for the current row. Or, if an
  ** error has occurred, throw an exception. */
  if( rc==SQLITE_OK ){
    for(i=0; i<pData->nPhrase; i++){
      score += pData->aIDF[i] * (
          ( aFreq[i] * (k1 + 1.0) ) / 
          ( aFreq[i] + k1 * (1 - b + b * D / pData->avgdl) )
      );
    }




    sqlite3_result_double(pCtx, -1.0 * score);
  }else{
    sqlite3_result_error_code(pCtx, rc);
  }
}

int sqlite3Fts5AuxInit(fts5_api *pApi){
Changes to ext/fts5/fts5_expr.c.
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
   && 0==pRoot->bEof 
   && fts5RowidCmp(p, pRoot->iRowid, iFirst)<0 
  ){
    rc = fts5ExprNodeNext(p, pRoot, 1, iFirst);
  }

  /* If the iterator is not at a real match, skip forward until it is. */
  while( pRoot->bNomatch ){
    assert( pRoot->bEof==0 && rc==SQLITE_OK );
    rc = fts5ExprNodeNext(p, pRoot, 0, 0);
  }
  return rc;
}

/*
** Move to the next document 







|
|







1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
   && 0==pRoot->bEof 
   && fts5RowidCmp(p, pRoot->iRowid, iFirst)<0 
  ){
    rc = fts5ExprNodeNext(p, pRoot, 1, iFirst);
  }

  /* If the iterator is not at a real match, skip forward until it is. */
  while( pRoot->bNomatch && rc==SQLITE_OK ){
    assert( pRoot->bEof==0 );
    rc = fts5ExprNodeNext(p, pRoot, 0, 0);
  }
  return rc;
}

/*
** Move to the next document 
Changes to ext/fts5/fts5_index.c.
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
        fts5SegIterLoadTerm(p, pIter, nKeep);
        fts5SegIterLoadNPos(p, pIter);
        if( pbNewTerm ) *pbNewTerm = 1;
      }
    }else{
      /* The following could be done by calling fts5SegIterLoadNPos(). But
      ** this block is particularly performance critical, so equivalent
      ** code is inlined. 
      **
      ** Later: Switched back to fts5SegIterLoadNPos() because it supports
      ** detail=none mode. Not ideal.
      */
      int nSz;
      assert( p->rc==SQLITE_OK );
      assert( pIter->iLeafOffset<=pIter->pLeaf->nn );
      fts5FastGetVarint32(pIter->pLeaf->p, pIter->iLeafOffset, nSz);
      pIter->bDel = (nSz & 0x0001);
      pIter->nPos = nSz>>1;
      assert_nc( pIter->nPos>=0 );
    }
  }
}







|
<
<
<
<


|







2066
2067
2068
2069
2070
2071
2072
2073




2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
        fts5SegIterLoadTerm(p, pIter, nKeep);
        fts5SegIterLoadNPos(p, pIter);
        if( pbNewTerm ) *pbNewTerm = 1;
      }
    }else{
      /* The following could be done by calling fts5SegIterLoadNPos(). But
      ** this block is particularly performance critical, so equivalent
      ** code is inlined.  */




      int nSz;
      assert( p->rc==SQLITE_OK );
      assert_nc( pIter->iLeafOffset<=pIter->pLeaf->nn );
      fts5FastGetVarint32(pIter->pLeaf->p, pIter->iLeafOffset, nSz);
      pIter->bDel = (nSz & 0x0001);
      pIter->nPos = nSz>>1;
      assert_nc( pIter->nPos>=0 );
    }
  }
}
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
  int nRem = pSeg->nPos;          /* Number of bytes still to come */
  Fts5Data *pData = 0;
  u8 *pChunk = &pSeg->pLeaf->p[pSeg->iLeafOffset];
  int nChunk = MIN(nRem, pSeg->pLeaf->szLeaf - pSeg->iLeafOffset);
  int pgno = pSeg->iLeafPgno;
  int pgnoSave = 0;

  /* This function does notmwork with detail=none databases. */
  assert( p->pConfig->eDetail!=FTS5_DETAIL_NONE );

  if( (pSeg->flags & FTS5_SEGITER_REVERSE)==0 ){
    pgnoSave = pgno+1;
  }

  while( 1 ){
    xChunk(p, pCtx, pChunk, nChunk);
    nRem -= nChunk;
    fts5DataRelease(pData);
    if( nRem<=0 ){
      break;



    }else{
      pgno++;
      pData = fts5LeafRead(p, FTS5_SEGMENT_ROWID(pSeg->pSeg->iSegid, pgno));
      if( pData==0 ) break;
      pChunk = &pData->p[4];
      nChunk = MIN(nRem, pData->szLeaf - 4);
      if( pgno==pgnoSave ){







|












>
>
>







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
  int nRem = pSeg->nPos;          /* Number of bytes still to come */
  Fts5Data *pData = 0;
  u8 *pChunk = &pSeg->pLeaf->p[pSeg->iLeafOffset];
  int nChunk = MIN(nRem, pSeg->pLeaf->szLeaf - pSeg->iLeafOffset);
  int pgno = pSeg->iLeafPgno;
  int pgnoSave = 0;

  /* This function does not work with detail=none databases. */
  assert( p->pConfig->eDetail!=FTS5_DETAIL_NONE );

  if( (pSeg->flags & FTS5_SEGITER_REVERSE)==0 ){
    pgnoSave = pgno+1;
  }

  while( 1 ){
    xChunk(p, pCtx, pChunk, nChunk);
    nRem -= nChunk;
    fts5DataRelease(pData);
    if( nRem<=0 ){
      break;
    }else if( pSeg->pSeg==0 ){
      p->rc = FTS5_CORRUPT;
      return;
    }else{
      pgno++;
      pData = fts5LeafRead(p, FTS5_SEGMENT_ROWID(pSeg->pSeg->iSegid, pgno));
      if( pData==0 ) break;
      pChunk = &pData->p[4];
      nChunk = MIN(nRem, pData->szLeaf - 4);
      if( pgno==pgnoSave ){
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
        fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistOffsetsCallback);
      }
    }
  }
}

/*
** IN/OUT parameter (*pa) points to a position list n bytes in size. If
** the position list contains entries for column iCol, then (*pa) is set
** to point to the sub-position-list for that column and the number of
** bytes in it returned. Or, if the argument position list does not
** contain any entries for column iCol, return 0.
*/
static int fts5IndexExtractCol(
  const u8 **pa,                  /* IN/OUT: Pointer to poslist */
  int n,                          /* IN: Size of poslist in bytes */
  int iCol                        /* Column to extract from poslist */
){
  int iCurrent = 0;               /* Anything before the first 0x01 is col 0 */
  const u8 *p = *pa;
  const u8 *pEnd = &p[n];         /* One byte past end of position list */

  while( iCol>iCurrent ){
    /* Advance pointer p until it points to pEnd or an 0x01 byte that is
    ** not part of a varint. Note that it is not possible for a negative
    ** or extremely large varint to occur within an uncorrupted position 
    ** list. So the last byte of each varint may be assumed to have a clear
    ** 0x80 bit.  */
    while( *p!=0x01 ){
      while( *p++ & 0x80 );
      if( p>=pEnd ) return 0;
    }
    *pa = p++;
    iCurrent = *p++;
    if( iCurrent & 0x80 ){
      p--;
      p += fts5GetVarint32(p, iCurrent);
    }
  }
  if( iCol!=iCurrent ) return 0;

  /* Advance pointer p until it points to pEnd or an 0x01 byte that is
  ** not part of a varint */
  while( p<pEnd && *p!=0x01 ){
    while( *p++ & 0x80 );
  }

  return p - (*pa);
}

static void fts5IndexExtractColset(
  int *pRc,
  Fts5Colset *pColset,            /* Colset to filter on */
  const u8 *pPos, int nPos,       /* Position list */
  Fts5Buffer *pBuf                /* Output buffer */
){
  if( *pRc==SQLITE_OK ){



    int i;

    fts5BufferZero(pBuf);







    for(i=0; i<pColset->nCol; i++){





      const u8 *pSub = pPos;






      int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
      if( nSub ){




        fts5BufferAppendBlob(pRc, pBuf, nSub, pSub);
      }




    }





  }



}

/*
** xSetOutputs callback used by detail=none tables.
*/
static void fts5IterSetOutputs_None(Fts5Iter *pIter, Fts5SegIter *pSeg){
  assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_NONE );







|
|
|
|
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
|
<
|




|


>
>
>
|
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
|
|
>
>
>
>
|

>
>
>
>
|
>
>
>
>
>
|
>
>
>







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
        fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistOffsetsCallback);
      }
    }
  }
}

/*
** Parameter pPos points to a buffer containing a position list, size nPos.
** This function filters it according to pColset (which must be non-NULL)
** and sets pIter->base.pData/nData to point to the new position list.
** If memory is required for the new position list, use buffer pIter->poslist.









** Or, if the new position list is a contiguous subset of the input, set
** pIter->base.pData/nData to point directly to it.





**












** This function is a no-op if *pRc is other than SQLITE_OK when it is





** called. If an OOM error is encountered, *pRc is set to SQLITE_NOMEM
** before returning.

*/
static void fts5IndexExtractColset(
  int *pRc,
  Fts5Colset *pColset,            /* Colset to filter on */
  const u8 *pPos, int nPos,       /* Position list */
  Fts5Iter *pIter
){
  if( *pRc==SQLITE_OK ){
    const u8 *p = pPos;
    const u8 *aCopy = p;
    const u8 *pEnd = &p[nPos];    /* One byte past end of position list */
    int i = 0;
    int iCurrent = 0;

    if( pColset->nCol>1 && sqlite3Fts5BufferSize(pRc, &pIter->poslist, nPos) ){
      return;
    }

    while( 1 ){
      while( pColset->aiCol[i]<iCurrent ){
        i++;
        if( i==pColset->nCol ){
          pIter->base.pData = pIter->poslist.p;
          pIter->base.nData = pIter->poslist.n;
          return;
        }
      }

      /* Advance pointer p until it points to pEnd or an 0x01 byte that is
      ** not part of a varint */
      while( p<pEnd && *p!=0x01 ){
        while( *p++ & 0x80 );
      }

      if( pColset->aiCol[i]==iCurrent ){
        if( pColset->nCol==1 ){
          pIter->base.pData = aCopy;
          pIter->base.nData = p-aCopy;
          return;
        }
        fts5BufferSafeAppendBlob(&pIter->poslist, aCopy, p-aCopy);
      }
      if( p==pEnd ){
        pIter->base.pData = pIter->poslist.p;
        pIter->base.nData = pIter->poslist.n;
        return;
      }
      aCopy = p++;
      iCurrent = *p++;
      if( iCurrent & 0x80 ){
        p--;
        p += fts5GetVarint32(p, iCurrent);
      }
    }
  }

}

/*
** xSetOutputs callback used by detail=none tables.
*/
static void fts5IterSetOutputs_None(Fts5Iter *pIter, Fts5SegIter *pSeg){
  assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_NONE );
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
  assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_FULL );
  assert( pColset );

  if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){
    /* All data is stored on the current page. Populate the output 
    ** variables to point into the body of the page object. */
    const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset];
    if( pColset->nCol==1 ){
      pIter->base.nData = fts5IndexExtractCol(&a, pSeg->nPos,pColset->aiCol[0]);
      pIter->base.pData = a;
    }else{
      int *pRc = &pIter->pIndex->rc;
      fts5BufferZero(&pIter->poslist);
      fts5IndexExtractColset(pRc, pColset, a, pSeg->nPos, &pIter->poslist);
      pIter->base.pData = pIter->poslist.p;
      pIter->base.nData = pIter->poslist.n;
    }
  }else{
    /* The data is distributed over two or more pages. Copy it into the
    ** Fts5Iter.poslist buffer and then set the output pointer to point
    ** to this buffer.  */
    fts5BufferZero(&pIter->poslist);
    fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist);
    pIter->base.pData = pIter->poslist.p;







<
<
<
<
|
|
|
<
<
<







3313
3314
3315
3316
3317
3318
3319




3320
3321
3322



3323
3324
3325
3326
3327
3328
3329
  assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_FULL );
  assert( pColset );

  if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){
    /* All data is stored on the current page. Populate the output 
    ** variables to point into the body of the page object. */
    const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset];




    int *pRc = &pIter->pIndex->rc;
    fts5BufferZero(&pIter->poslist);
    fts5IndexExtractColset(pRc, pColset, a, pSeg->nPos, pIter);



  }else{
    /* The data is distributed over two or more pages. Copy it into the
    ** Fts5Iter.poslist buffer and then set the output pointer to point
    ** to this buffer.  */
    fts5BufferZero(&pIter->poslist);
    fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist);
    pIter->base.pData = pIter->poslist.p;
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
  }
}


static void fts5DoclistIterNext(Fts5DoclistIter *pIter){
  u8 *p = pIter->aPoslist + pIter->nSize + pIter->nPoslist;

  assert( pIter->aPoslist );
  if( p>=pIter->aEof ){
    pIter->aPoslist = 0;
  }else{
    i64 iDelta;

    p += fts5GetVarint(p, (u64*)&iDelta);
    pIter->iRowid += iDelta;

    /* Read position list size */
    if( p[0] & 0x80 ){
      int nPos;
      pIter->nSize = fts5GetVarint32(p, nPos);
      pIter->nPoslist = (nPos>>1);
    }else{
      pIter->nPoslist = ((int)(p[0])) >> 1;
      pIter->nSize = 1;
    }

    pIter->aPoslist = p;



  }
}

static void fts5DoclistIterInit(
  Fts5Buffer *pBuf, 
  Fts5DoclistIter *pIter
){
  memset(pIter, 0, sizeof(*pIter));

  pIter->aPoslist = pBuf->p;
  pIter->aEof = &pBuf->p[pBuf->n];
  fts5DoclistIterNext(pIter);

}

#if 0
/*
** Append a doclist to buffer pBuf.
**
** This function assumes that space within the buffer has already been







|



















>
>
>








>
|
|
|
>







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
  }
}


static void fts5DoclistIterNext(Fts5DoclistIter *pIter){
  u8 *p = pIter->aPoslist + pIter->nSize + pIter->nPoslist;

  assert( pIter->aPoslist || (p==0 && pIter->aPoslist==0) );
  if( p>=pIter->aEof ){
    pIter->aPoslist = 0;
  }else{
    i64 iDelta;

    p += fts5GetVarint(p, (u64*)&iDelta);
    pIter->iRowid += iDelta;

    /* Read position list size */
    if( p[0] & 0x80 ){
      int nPos;
      pIter->nSize = fts5GetVarint32(p, nPos);
      pIter->nPoslist = (nPos>>1);
    }else{
      pIter->nPoslist = ((int)(p[0])) >> 1;
      pIter->nSize = 1;
    }

    pIter->aPoslist = p;
    if( &pIter->aPoslist[pIter->nPoslist]>pIter->aEof ){
      pIter->aPoslist = 0;
    }
  }
}

static void fts5DoclistIterInit(
  Fts5Buffer *pBuf, 
  Fts5DoclistIter *pIter
){
  memset(pIter, 0, sizeof(*pIter));
  if( pBuf->n>0 ){
    pIter->aPoslist = pBuf->p;
    pIter->aEof = &pBuf->p[pBuf->n];
    fts5DoclistIterNext(pIter);
  }
}

#if 0
/*
** Append a doclist to buffer pBuf.
**
** This function assumes that space within the buffer has already been
4884
4885
4886
4887
4888
4889
4890

4891
4892
4893
4894
4895
4896
4897
4898
4899


4900

4901
4902
4903
4904
4905
4906
4907
/*
** This is the equivalent of fts5MergePrefixLists() for detail=none mode.
** In this case the buffers consist of a delta-encoded list of rowids only.
*/
static void fts5MergeRowidLists(
  Fts5Index *p,                   /* FTS5 backend object */
  Fts5Buffer *p1,                 /* First list to merge */

  Fts5Buffer *p2                  /* Second list to merge */
){
  int i1 = 0;
  int i2 = 0;
  i64 iRowid1 = 0;
  i64 iRowid2 = 0;
  i64 iOut = 0;

  Fts5Buffer out;


  memset(&out, 0, sizeof(out));

  sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n);
  if( p->rc ) return;

  fts5NextRowid(p1, &i1, &iRowid1);
  fts5NextRowid(p2, &i2, &iRowid2);
  while( i1>=0 || i2>=0 ){
    if( i1>=0 && (i2<0 || iRowid1<iRowid2) ){







>
|






|

>
>

>







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
/*
** This is the equivalent of fts5MergePrefixLists() for detail=none mode.
** In this case the buffers consist of a delta-encoded list of rowids only.
*/
static void fts5MergeRowidLists(
  Fts5Index *p,                   /* FTS5 backend object */
  Fts5Buffer *p1,                 /* First list to merge */
  int nBuf,                       /* Number of entries in apBuf[] */
  Fts5Buffer *aBuf                /* Array of other lists to merge into p1 */
){
  int i1 = 0;
  int i2 = 0;
  i64 iRowid1 = 0;
  i64 iRowid2 = 0;
  i64 iOut = 0;
  Fts5Buffer *p2 = &aBuf[0];
  Fts5Buffer out;

  (void)nBuf;
  memset(&out, 0, sizeof(out));
  assert( nBuf==1 );
  sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n);
  if( p->rc ) return;

  fts5NextRowid(p1, &i1, &iRowid1);
  fts5NextRowid(p2, &i2, &iRowid2);
  while( i1>=0 || i2>=0 ){
    if( i1>=0 && (i2<0 || iRowid1<iRowid2) ){
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
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
5077
5078
5079
5080
5081
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
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
5144



5145

5146

5147
5148
5149
5150
5151
5152
5153
5154
5155

5156

5157
5158
5159

5160

5161
5162
5163
5164
5165
5166
5167
      fts5NextRowid(p2, &i2, &iRowid2);
    }
  }

  fts5BufferSwap(&out, p1);
  fts5BufferFree(&out);
}






/*


** Buffers p1 and p2 contain doclists. This function merges the content













** of the two doclists together and sets buffer p1 to the result before


** returning.







**


** If an error occurs, an error code is left in p->rc. If an error has
** already occurred, this function is a no-op.



*/
static void fts5MergePrefixLists(
  Fts5Index *p,                   /* FTS5 backend object */
  Fts5Buffer *p1,                 /* First list to merge */

  Fts5Buffer *p2                  /* Second list to merge */
){
  if( p2->n ){




    i64 iLastRowid = 0;
    Fts5DoclistIter i1;
    Fts5DoclistIter i2;

    Fts5Buffer out = {0, 0, 0};
    Fts5Buffer tmp = {0, 0, 0};

















    /* The maximum size of the output is equal to the sum of the two 
    ** input sizes + 1 varint (9 bytes). The extra varint is because if the
    ** first rowid in one input is a large negative number, and the first in
    ** the other a non-negative number, the delta for the non-negative
    ** number will be larger on disk than the literal integer value
    ** was.  
    **
    ** Or, if the input position-lists are corrupt, then the output might
    ** include up to 2 extra 10-byte positions created by interpreting -1
    ** (the value PoslistNext64() uses for EOF) as a position and appending
    ** it to the output. This can happen at most once for each input 
    ** position-list, hence two 10 byte paddings.  */
    if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9+10+10) ) return;
    fts5DoclistIterInit(p1, &i1);
    fts5DoclistIterInit(p2, &i2);

    while( 1 ){
      if( i1.iRowid<i2.iRowid ){
        /* Copy entry from i1 */
        fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid);
        fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.nPoslist+i1.nSize);
        fts5DoclistIterNext(&i1);
        if( i1.aPoslist==0 ) break;
        assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) );
      }
      else if( i2.iRowid!=i1.iRowid ){
        /* Copy entry from i2 */
        fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
        fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.nPoslist+i2.nSize);
        fts5DoclistIterNext(&i2);
        if( i2.aPoslist==0 ) break;
        assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) );
      }
      else{

        /* Merge the two position lists. */ 

        i64 iPos1 = 0;
        i64 iPos2 = 0;
        int iOff1 = 0;
        int iOff2 = 0;




        u8 *a1 = &i1.aPoslist[i1.nSize];

        u8 *a2 = &i2.aPoslist[i2.nSize];




        int nCopy;


        u8 *aCopy;

        i64 iPrev = 0;
        Fts5PoslistWriter writer;
        memset(&writer, 0, sizeof(writer));

        /* See the earlier comment in this function for an explanation of why
        ** corrupt input position lists might cause the output to consume
        ** at most 20 bytes of unexpected space. */
        fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
        fts5BufferZero(&tmp);
        sqlite3Fts5BufferSize(&p->rc, &tmp, 
            i1.nPoslist + i2.nPoslist + 10 + 10 + FTS5_DATA_ZERO_PADDING
        );
        if( p->rc ) break;

        sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
        sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
        assert_nc( iPos1>=0 && iPos2>=0 );


        if( iPos1<iPos2 ){
          sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1);
          sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
        }else{
          sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);
          sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);

        }
        if( iPos1>=0 && iPos2>=0 ){
          while( 1 ){
            if( iPos1<iPos2 ){

              if( iPos1!=iPrev ){
                sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1);
              }
              sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
              if( iPos1<0 ) break;
            }else{

              assert_nc( iPos2!=iPrev );
              sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);
              sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
              if( iPos2<0 ) break;
            }
          }
        }

        if( iPos1>=0 ){
          if( iPos1!=iPrev ){
            sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1);
          }
          aCopy = &a1[iOff1];
          nCopy = i1.nPoslist - iOff1;
        }else{

          assert_nc( iPos2>=0 && iPos2!=iPrev );
          sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);

          aCopy = &a2[iOff2];
          nCopy = i2.nPoslist - iOff2;

        }


        if( nCopy>0 ){
          fts5BufferSafeAppendBlob(&tmp, aCopy, nCopy);
        }

        /* WRITEPOSLISTSIZE */
        assert_nc( tmp.n<=i1.nPoslist+i2.nPoslist );
        assert( tmp.n<=i1.nPoslist+i2.nPoslist+10+10 );
        if( tmp.n>i1.nPoslist+i2.nPoslist ){
          if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT;
          break;
        }
        fts5BufferSafeAppendVarint(&out, tmp.n * 2);
        fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n);
        fts5DoclistIterNext(&i1);
        fts5DoclistIterNext(&i2);
        assert_nc( out.n<=(p1->n+p2->n+9) );
        if( i1.aPoslist==0 || i2.aPoslist==0 ) break;
        assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) );
      }
    }


    if( i1.aPoslist ){
      fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid);

      fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.aEof - i1.aPoslist);



    }
    else if( i2.aPoslist ){
      fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
      fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist);
    }
    assert_nc( out.n<=(p1->n+p2->n+9) );

    fts5BufferFree(p1);
    fts5BufferFree(&tmp);
    memset(&out.p[out.n], 0, FTS5_DATA_ZERO_PADDING);
    *p1 = out;
  }
}

static void fts5SetupPrefixIter(
  Fts5Index *p,                   /* Index to read from */
  int bDesc,                      /* True for "ORDER BY rowid DESC" */

  const u8 *pToken,               /* Buffer containing prefix to match */
  int nToken,                     /* Size of buffer pToken in bytes */
  Fts5Colset *pColset,            /* Restrict matches to these columns */
  Fts5Iter **ppIter          /* OUT: New iterator */
){
  Fts5Structure *pStruct;
  Fts5Buffer *aBuf;
  const int nBuf = 32;


  void (*xMerge)(Fts5Index*, Fts5Buffer*, Fts5Buffer*);
  void (*xAppend)(Fts5Index*, i64, Fts5Iter*, Fts5Buffer*);
  if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
    xMerge = fts5MergeRowidLists;
    xAppend = fts5AppendRowid;
  }else{


    xMerge = fts5MergePrefixLists;
    xAppend = fts5AppendPoslist;
  }

  aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf);
  pStruct = fts5StructureRead(p);

  if( aBuf && pStruct ){
    const int flags = FTS5INDEX_QUERY_SCAN 
                    | FTS5INDEX_QUERY_SKIPEMPTY 
                    | FTS5INDEX_QUERY_NOOUTPUT;
    int i;
    i64 iLastRowid = 0;
    Fts5Iter *p1 = 0;     /* Iterator used to gather data from index */
    Fts5Data *pData;
    Fts5Buffer doclist;
    int bNewTerm = 1;

    memset(&doclist, 0, sizeof(doclist));





















    fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1);
    fts5IterSetOutputCb(&p->rc, p1);
    for( /* no-op */ ;
        fts5MultiIterEof(p, p1)==0;
        fts5MultiIterNext2(p, p1, &bNewTerm)
    ){
      Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
      int nTerm = pSeg->term.n;
      const u8 *pTerm = pSeg->term.p;
      p1->xSetOutputs(p1, pSeg);

      assert_nc( memcmp(pToken, pTerm, MIN(nToken, nTerm))<=0 );
      if( bNewTerm ){
        if( nTerm<nToken || memcmp(pToken, pTerm, nToken) ) break;
      }

      if( p1->base.nData==0 ) continue;

      if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){
        for(i=0; p->rc==SQLITE_OK && doclist.n; i++){


          assert( i<nBuf );

          if( aBuf[i].n==0 ){
            fts5BufferSwap(&doclist, &aBuf[i]);
            fts5BufferZero(&doclist);
          }else{



            xMerge(p, &doclist, &aBuf[i]);

            fts5BufferZero(&aBuf[i]);

          }
        }
        iLastRowid = 0;
      }

      xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist);
      iLastRowid = p1->base.iRowid;
    }


    for(i=0; i<nBuf; i++){

      if( p->rc==SQLITE_OK ){
        xMerge(p, &doclist, &aBuf[i]);
      }

      fts5BufferFree(&aBuf[i]);

    }
    fts5MultiIterFree(p1);

    pData = fts5IdxMalloc(p, sizeof(Fts5Data)+doclist.n+FTS5_DATA_ZERO_PADDING);
    if( pData ){
      pData->p = (u8*)&pData[1];
      pData->nn = pData->szLeaf = doclist.n;








>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
|
>
>
|
|
>
>
>




>
|

<
>
>
>
>
|
|
<
>
|
|
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<

|
<
<
|
<
<
<
<
|
|
<
<
<
<
|
<
<
|
>
|
>
|
|
|
|
>
>
>
>
|
>
|
>
>
>
>
|
>
>
|
|
<
<
<

|
|
|
<
<
|
<
<
|
|
<
<
<
>

<
<
|
|
|
|
>
|
<
|
<
>
|
|
|
<
|
<
>
|
<
<
<
|
|
<
<
<
|
|
|
<
|
|
>
|
<
>
|
<
>
|
>
>
|
|
|

|
|
|
|
<
<
<
<
<
|
|
<
<
<
|
|

>
|
|
>
|
>
>
>

<
<
<
|
<

|
|
|
|
<





>
|






|
>

|





>
>



















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




















>
>
|
>
|
|
|
|
>
>
>
|
>
|
>









>
|
>

|

>
|
>







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
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
5077
5078

5079
5080
5081
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
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
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
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
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
      fts5NextRowid(p2, &i2, &iRowid2);
    }
  }

  fts5BufferSwap(&out, p1);
  fts5BufferFree(&out);
}

typedef struct PrefixMerger PrefixMerger;
struct PrefixMerger {
  Fts5DoclistIter iter;           /* Doclist iterator */
  i64 iPos;                       /* For iterating through a position list */
  int iOff;
  u8 *aPos;
  PrefixMerger *pNext;            /* Next in docid/poslist order */
};

static void fts5PrefixMergerInsertByRowid(
  PrefixMerger **ppHead, 
  PrefixMerger *p
){
  if( p->iter.aPoslist ){
    PrefixMerger **pp = ppHead;
    while( *pp && p->iter.iRowid>(*pp)->iter.iRowid ){
      pp = &(*pp)->pNext;
    }
    p->pNext = *pp;
    *pp = p;
  }
}

static void fts5PrefixMergerInsertByPosition(
  PrefixMerger **ppHead, 
  PrefixMerger *p
){
  if( p->iPos>=0 ){
    PrefixMerger **pp = ppHead;
    while( *pp && p->iPos>(*pp)->iPos ){
      pp = &(*pp)->pNext;
    }
    p->pNext = *pp;
    *pp = p;
  }
}


/*
** Array aBuf[] contains nBuf doclists. These are all merged in with the
** doclist in buffer p1.
*/
static void fts5MergePrefixLists(
  Fts5Index *p,                   /* FTS5 backend object */
  Fts5Buffer *p1,                 /* First list to merge */
  int nBuf,                       /* Number of buffers in array aBuf[] */
  Fts5Buffer *aBuf                /* Other lists to merge in */ 
){

#define fts5PrefixMergerNextPosition(p) \
  sqlite3Fts5PoslistNext64((p)->aPos,(p)->iter.nPoslist,&(p)->iOff,&(p)->iPos);
#define FTS5_MERGE_NLIST 16
  PrefixMerger aMerger[FTS5_MERGE_NLIST];
  PrefixMerger *pHead = 0;
  int i;

  int nOut = 0;
  Fts5Buffer out = {0, 0, 0};
  Fts5Buffer tmp = {0, 0, 0};
  i64 iLastRowid = 0;

  /* Initialize a doclist-iterator for each input buffer. Arrange them in
  ** a linked-list starting at pHead in ascending order of rowid. Avoid
  ** linking any iterators already at EOF into the linked list at all. */ 
  assert( nBuf+1<=sizeof(aMerger)/sizeof(aMerger[0]) );
  memset(aMerger, 0, sizeof(PrefixMerger)*(nBuf+1));
  pHead = &aMerger[nBuf];
  fts5DoclistIterInit(p1, &pHead->iter);
  for(i=0; i<nBuf; i++){
    fts5DoclistIterInit(&aBuf[i], &aMerger[i].iter);
    fts5PrefixMergerInsertByRowid(&pHead, &aMerger[i]);
    nOut += aBuf[i].n;
  }
  if( nOut==0 ) return;
  nOut += p1->n + 9 + 10*nBuf;

  /* The maximum size of the output is equal to the sum of the
  ** input sizes + 1 varint (9 bytes). The extra varint is because if the
  ** first rowid in one input is a large negative number, and the first in
  ** the other a non-negative number, the delta for the non-negative
  ** number will be larger on disk than the literal integer value
  ** was.  
  **
  ** Or, if the input position-lists are corrupt, then the output might
  ** include up to (nBuf+1) extra 10-byte positions created by interpreting -1
  ** (the value PoslistNext64() uses for EOF) as a position and appending
  ** it to the output. This can happen at most once for each input 
  ** position-list, hence (nBuf+1) 10 byte paddings.  */
  if( sqlite3Fts5BufferSize(&p->rc, &out, nOut) ) return;



  while( pHead ){


    fts5MergeAppendDocid(&out, iLastRowid, pHead->iter.iRowid);





    if( pHead->pNext && iLastRowid==pHead->pNext->iter.iRowid ){




      /* Merge data from two or more poslists */


      i64 iPrev = 0;
      int nTmp = FTS5_DATA_ZERO_PADDING;
      int nMerge = 0;
      PrefixMerger *pSave = pHead;
      PrefixMerger *pThis = 0;
      int nTail = 0;

      pHead = 0;
      while( pSave && pSave->iter.iRowid==iLastRowid ){
        PrefixMerger *pNext = pSave->pNext;
        pSave->iOff = 0;
        pSave->iPos = 0;
        pSave->aPos = &pSave->iter.aPoslist[pSave->iter.nSize];
        fts5PrefixMergerNextPosition(pSave);
        nTmp += pSave->iter.nPoslist + 10;
        nMerge++;
        fts5PrefixMergerInsertByPosition(&pHead, pSave);
        pSave = pNext;
      }

      if( pHead==0 || pHead->pNext==0 ){
        p->rc = FTS5_CORRUPT;
        break;
      }




      /* See the earlier comment in this function for an explanation of why
      ** corrupt input position lists might cause the output to consume
      ** at most nMerge*10 bytes of unexpected space. */


      if( sqlite3Fts5BufferSize(&p->rc, &tmp, nTmp+nMerge*10) ){


        break;
      }



      fts5BufferZero(&tmp);



      pThis = pHead;
      pHead = pThis->pNext;
      sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pThis->iPos);
      fts5PrefixMergerNextPosition(pThis);
      fts5PrefixMergerInsertByPosition(&pHead, pThis);


      while( pHead->pNext ){

        pThis = pHead;
        if( pThis->iPos!=iPrev ){
          sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pThis->iPos);
        }

        fts5PrefixMergerNextPosition(pThis);

        pHead = pThis->pNext;
        fts5PrefixMergerInsertByPosition(&pHead, pThis);



      }




      if( pHead->iPos!=iPrev ){
        sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pHead->iPos);
      }

      nTail = pHead->iter.nPoslist - pHead->iOff;

      /* WRITEPOSLISTSIZE */
      assert( tmp.n+nTail<=nTmp );

      if( tmp.n+nTail>nTmp-FTS5_DATA_ZERO_PADDING ){
        if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT;

        break;
      }
      fts5BufferSafeAppendVarint(&out, (tmp.n+nTail) * 2);
      fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n);
      if( nTail>0 ){
        fts5BufferSafeAppendBlob(&out, &pHead->aPos[pHead->iOff], nTail);
      }

      pHead = pSave;
      for(i=0; i<nBuf+1; i++){
        PrefixMerger *pX = &aMerger[i];
        if( pX->iter.aPoslist && pX->iter.iRowid==iLastRowid ){





          fts5DoclistIterNext(&pX->iter);
          fts5PrefixMergerInsertByRowid(&pHead, pX);



        }
      }

    }else{
      /* Copy poslist from pHead to output */
      PrefixMerger *pThis = pHead;
      Fts5DoclistIter *pI = &pThis->iter;
      fts5BufferSafeAppendBlob(&out, pI->aPoslist, pI->nPoslist+pI->nSize);
      fts5DoclistIterNext(pI);
      pHead = pThis->pNext;
      fts5PrefixMergerInsertByRowid(&pHead, pThis);
    }



  }


  fts5BufferFree(p1);
  fts5BufferFree(&tmp);
  memset(&out.p[out.n], 0, FTS5_DATA_ZERO_PADDING);
  *p1 = out;

}

static void fts5SetupPrefixIter(
  Fts5Index *p,                   /* Index to read from */
  int bDesc,                      /* True for "ORDER BY rowid DESC" */
  int iIdx,                       /* Index to scan for data */
  u8 *pToken,                     /* Buffer containing prefix to match */
  int nToken,                     /* Size of buffer pToken in bytes */
  Fts5Colset *pColset,            /* Restrict matches to these columns */
  Fts5Iter **ppIter          /* OUT: New iterator */
){
  Fts5Structure *pStruct;
  Fts5Buffer *aBuf;
  int nBuf = 32;
  int nMerge = 1;

  void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*);
  void (*xAppend)(Fts5Index*, i64, Fts5Iter*, Fts5Buffer*);
  if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
    xMerge = fts5MergeRowidLists;
    xAppend = fts5AppendRowid;
  }else{
    nMerge = FTS5_MERGE_NLIST-1;
    nBuf = nMerge*8;   /* Sufficient to merge (16^8)==(2^32) lists */
    xMerge = fts5MergePrefixLists;
    xAppend = fts5AppendPoslist;
  }

  aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf);
  pStruct = fts5StructureRead(p);

  if( aBuf && pStruct ){
    const int flags = FTS5INDEX_QUERY_SCAN 
                    | FTS5INDEX_QUERY_SKIPEMPTY 
                    | FTS5INDEX_QUERY_NOOUTPUT;
    int i;
    i64 iLastRowid = 0;
    Fts5Iter *p1 = 0;     /* Iterator used to gather data from index */
    Fts5Data *pData;
    Fts5Buffer doclist;
    int bNewTerm = 1;

    memset(&doclist, 0, sizeof(doclist));
    if( iIdx!=0 ){
      int dummy = 0;
      const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT;
      pToken[0] = FTS5_MAIN_PREFIX;
      fts5MultiIterNew(p, pStruct, f2, pColset, pToken, nToken, -1, 0, &p1);
      fts5IterSetOutputCb(&p->rc, p1);
      for(;
        fts5MultiIterEof(p, p1)==0;
        fts5MultiIterNext2(p, p1, &dummy)
      ){
        Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
        p1->xSetOutputs(p1, pSeg);
        if( p1->base.nData ){
          xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist);
          iLastRowid = p1->base.iRowid;
        }
      }
      fts5MultiIterFree(p1);
    }

    pToken[0] = FTS5_MAIN_PREFIX + iIdx;
    fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1);
    fts5IterSetOutputCb(&p->rc, p1);
    for( /* no-op */ ;
        fts5MultiIterEof(p, p1)==0;
        fts5MultiIterNext2(p, p1, &bNewTerm)
    ){
      Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
      int nTerm = pSeg->term.n;
      const u8 *pTerm = pSeg->term.p;
      p1->xSetOutputs(p1, pSeg);

      assert_nc( memcmp(pToken, pTerm, MIN(nToken, nTerm))<=0 );
      if( bNewTerm ){
        if( nTerm<nToken || memcmp(pToken, pTerm, nToken) ) break;
      }

      if( p1->base.nData==0 ) continue;

      if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){
        for(i=0; p->rc==SQLITE_OK && doclist.n; i++){
          int i1 = i*nMerge;
          int iStore;
          assert( i1+nMerge<=nBuf );
          for(iStore=i1; iStore<i1+nMerge; iStore++){
            if( aBuf[iStore].n==0 ){
              fts5BufferSwap(&doclist, &aBuf[iStore]);
              fts5BufferZero(&doclist);
              break;
            }
          }
          if( iStore==i1+nMerge ){
            xMerge(p, &doclist, nMerge, &aBuf[i1]);
            for(iStore=i1; iStore<i1+nMerge; iStore++){
              fts5BufferZero(&aBuf[iStore]);
            }
          }
        }
        iLastRowid = 0;
      }

      xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist);
      iLastRowid = p1->base.iRowid;
    }

    assert( (nBuf%nMerge)==0 );
    for(i=0; i<nBuf; i+=nMerge){
      int iFree;
      if( p->rc==SQLITE_OK ){
        xMerge(p, &doclist, nMerge, &aBuf[i]);
      }
      for(iFree=i; iFree<i+nMerge; iFree++){
        fts5BufferFree(&aBuf[iFree]);
      }
    }
    fts5MultiIterFree(p1);

    pData = fts5IdxMalloc(p, sizeof(Fts5Data)+doclist.n+FTS5_DATA_ZERO_PADDING);
    if( pData ){
      pData->p = (u8*)&pData[1];
      pData->nn = pData->szLeaf = doclist.n;
5408
5409
5410
5411
5412
5413
5414

5415
5416
5417
5418
5419
5420
5421
  Fts5Buffer buf = {0, 0, 0};

  /* If the QUERY_SCAN flag is set, all other flags must be clear. */
  assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN );

  if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
    int iIdx = 0;                 /* Index to search */

    if( nToken ) memcpy(&buf.p[1], pToken, nToken);

    /* Figure out which index to search and set iIdx accordingly. If this
    ** is a prefix query for which there is no prefix index, set iIdx to
    ** greater than pConfig->nPrefix to indicate that the query will be
    ** satisfied by scanning multiple terms in the main index.
    **







>







5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
  Fts5Buffer buf = {0, 0, 0};

  /* If the QUERY_SCAN flag is set, all other flags must be clear. */
  assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN );

  if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
    int iIdx = 0;                 /* Index to search */
    int iPrefixIdx = 0;           /* +1 prefix index */
    if( nToken ) memcpy(&buf.p[1], pToken, nToken);

    /* Figure out which index to search and set iIdx accordingly. If this
    ** is a prefix query for which there is no prefix index, set iIdx to
    ** greater than pConfig->nPrefix to indicate that the query will be
    ** satisfied by scanning multiple terms in the main index.
    **
5429
5430
5431
5432
5433
5434
5435
5436


5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
      assert( flags & FTS5INDEX_QUERY_PREFIX );
      iIdx = 1+pConfig->nPrefix;
    }else
#endif
    if( flags & FTS5INDEX_QUERY_PREFIX ){
      int nChar = fts5IndexCharlen(pToken, nToken);
      for(iIdx=1; iIdx<=pConfig->nPrefix; iIdx++){
        if( pConfig->aPrefix[iIdx-1]==nChar ) break;


      }
    }

    if( iIdx<=pConfig->nPrefix ){
      /* Straight index lookup */
      Fts5Structure *pStruct = fts5StructureRead(p);
      buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx);
      if( pStruct ){
        fts5MultiIterNew(p, pStruct, flags | FTS5INDEX_QUERY_SKIPEMPTY, 
            pColset, buf.p, nToken+1, -1, 0, &pRet
        );
        fts5StructureRelease(pStruct);
      }
    }else{
      /* Scan multiple terms in the main index */
      int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
      buf.p[0] = FTS5_MAIN_PREFIX;
      fts5SetupPrefixIter(p, bDesc, buf.p, nToken+1, pColset, &pRet);
      assert( p->rc!=SQLITE_OK || pRet->pColset==0 );
      fts5IterSetOutputCb(&p->rc, pRet);
      if( p->rc==SQLITE_OK ){
        Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst];
        if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg);
      }
    }







|
>
>
















<
|







5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528

5529
5530
5531
5532
5533
5534
5535
5536
      assert( flags & FTS5INDEX_QUERY_PREFIX );
      iIdx = 1+pConfig->nPrefix;
    }else
#endif
    if( flags & FTS5INDEX_QUERY_PREFIX ){
      int nChar = fts5IndexCharlen(pToken, nToken);
      for(iIdx=1; iIdx<=pConfig->nPrefix; iIdx++){
        int nIdxChar = pConfig->aPrefix[iIdx-1];
        if( nIdxChar==nChar ) break;
        if( nIdxChar==nChar+1 ) iPrefixIdx = iIdx;
      }
    }

    if( iIdx<=pConfig->nPrefix ){
      /* Straight index lookup */
      Fts5Structure *pStruct = fts5StructureRead(p);
      buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx);
      if( pStruct ){
        fts5MultiIterNew(p, pStruct, flags | FTS5INDEX_QUERY_SKIPEMPTY, 
            pColset, buf.p, nToken+1, -1, 0, &pRet
        );
        fts5StructureRelease(pStruct);
      }
    }else{
      /* Scan multiple terms in the main index */
      int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;

      fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet);
      assert( p->rc!=SQLITE_OK || pRet->pColset==0 );
      fts5IterSetOutputCb(&p->rc, pRet);
      if( p->rc==SQLITE_OK ){
        Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst];
        if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg);
      }
    }
5520
5521
5522
5523
5524
5525
5526

5527
5528
5529
5530
5531
5532
5533
5534
5535

/*
** Return the current term.
*/
const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){
  int n;
  const char *z = (const char*)fts5MultiIterTerm((Fts5Iter*)pIndexIter, &n);

  *pn = n-1;
  return &z[1];
}

/*
** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
*/
void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
  if( pIndexIter ){







>

|







5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611

/*
** Return the current term.
*/
const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){
  int n;
  const char *z = (const char*)fts5MultiIterTerm((Fts5Iter*)pIndexIter, &n);
  assert_nc( z || n<=1 );
  *pn = n-1;
  return (z ? &z[1] : 0);
}

/*
** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
*/
void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
  if( pIndexIter ){
6119
6120
6121
6122
6123
6124
6125

6126
6127
6128
6129
6130
6131
6132
    if( eDetail==FTS5_DETAIL_NONE ){
      if( 0==fts5MultiIterIsEmpty(p, pIter) ){
        cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, 0, 0, -1, z, n);
      }
    }else{
      poslist.n = 0;
      fts5SegiterPoslist(p, &pIter->aSeg[pIter->aFirst[1].iFirst], 0, &poslist);

      while( 0==sqlite3Fts5PoslistNext64(poslist.p, poslist.n, &iOff, &iPos) ){
        int iCol = FTS5_POS2COLUMN(iPos);
        int iTokOff = FTS5_POS2OFFSET(iPos);
        cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, iCol, iTokOff, -1, z, n);
      }
    }
  }







>







6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
    if( eDetail==FTS5_DETAIL_NONE ){
      if( 0==fts5MultiIterIsEmpty(p, pIter) ){
        cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, 0, 0, -1, z, n);
      }
    }else{
      poslist.n = 0;
      fts5SegiterPoslist(p, &pIter->aSeg[pIter->aFirst[1].iFirst], 0, &poslist);
      fts5BufferAppendBlob(&p->rc, &poslist, 4, (const u8*)"\0\0\0\0");
      while( 0==sqlite3Fts5PoslistNext64(poslist.p, poslist.n, &iOff, &iPos) ){
        int iCol = FTS5_POS2COLUMN(iPos);
        int iTokOff = FTS5_POS2OFFSET(iPos);
        cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, iCol, iTokOff, -1, z, n);
      }
    }
  }
Changes to ext/fts5/fts5_main.c.
2173
2174
2175
2176
2177
2178
2179

2180
2181
2182
2183
2184
2185
2186
2187
  Fts5PhraseIter *pIter, 
  int *piCol, int *piOff
){
  Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  int n;
  int rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n);
  if( rc==SQLITE_OK ){

    pIter->b = &pIter->a[n];
    *piCol = 0;
    *piOff = 0;
    fts5ApiPhraseNext(pCtx, pIter, piCol, piOff);
  }
  return rc;
}








>
|







2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
  Fts5PhraseIter *pIter, 
  int *piCol, int *piOff
){
  Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  int n;
  int rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n);
  if( rc==SQLITE_OK ){
    assert( pIter->a || n==0 );
    pIter->b = (pIter->a ? &pIter->a[n] : 0);
    *piCol = 0;
    *piOff = 0;
    fts5ApiPhraseNext(pCtx, pIter, piCol, piOff);
  }
  return rc;
}

2232
2233
2234
2235
2236
2237
2238

2239
2240
2241
2242
2243
2244
2245
2246

2247
2248
2249
2250
2251
2252
2253
2254
      int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
      n = pSorter->aIdx[iPhrase] - i1;
      pIter->a = &pSorter->aPoslist[i1];
    }else{
      rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n);
    }
    if( rc==SQLITE_OK ){

      pIter->b = &pIter->a[n];
      *piCol = 0;
      fts5ApiPhraseNextColumn(pCtx, pIter, piCol);
    }
  }else{
    int n;
    rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n);
    if( rc==SQLITE_OK ){

      pIter->b = &pIter->a[n];
      if( n<=0 ){
        *piCol = -1;
      }else if( pIter->a[0]==0x01 ){
        pIter->a += 1 + fts5GetVarint32(&pIter->a[1], *piCol);
      }else{
        *piCol = 0;
      }







>
|







>
|







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
      int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
      n = pSorter->aIdx[iPhrase] - i1;
      pIter->a = &pSorter->aPoslist[i1];
    }else{
      rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n);
    }
    if( rc==SQLITE_OK ){
      assert( pIter->a || n==0 );
      pIter->b = (pIter->a ? &pIter->a[n] : 0);
      *piCol = 0;
      fts5ApiPhraseNextColumn(pCtx, pIter, piCol);
    }
  }else{
    int n;
    rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n);
    if( rc==SQLITE_OK ){
      assert( pIter->a || n==0 );
      pIter->b = (pIter->a ? &pIter->a[n] : 0);
      if( n<=0 ){
        *piCol = -1;
      }else if( pIter->a[0]==0x01 ){
        pIter->a += 1 + fts5GetVarint32(&pIter->a[1], *piCol);
      }else{
        *piCol = 0;
      }
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
  pMod = fts5LocateTokenizer(pGlobal, nArg==0 ? 0 : azArg[0]);
  if( pMod==0 ){
    assert( nArg>0 );
    rc = SQLITE_ERROR;
    *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]);
  }else{
    rc = pMod->x.xCreate(
        pMod->pUserData, &azArg[1], (nArg?nArg-1:0), &pConfig->pTok
    );
    pConfig->pTokApi = &pMod->x;
    if( rc!=SQLITE_OK ){
      if( pzErr ) *pzErr = sqlite3_mprintf("error in tokenizer constructor");
    }else{
      pConfig->ePattern = sqlite3Fts5TokenizerPattern(
          pMod->x.xCreate, pConfig->pTok







|







2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
  pMod = fts5LocateTokenizer(pGlobal, nArg==0 ? 0 : azArg[0]);
  if( pMod==0 ){
    assert( nArg>0 );
    rc = SQLITE_ERROR;
    *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]);
  }else{
    rc = pMod->x.xCreate(
        pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->pTok
    );
    pConfig->pTokApi = &pMod->x;
    if( rc!=SQLITE_OK ){
      if( pzErr ) *pzErr = sqlite3_mprintf("error in tokenizer constructor");
    }else{
      pConfig->ePattern = sqlite3Fts5TokenizerPattern(
          pMod->x.xCreate, pConfig->pTok
Changes to ext/fts5/fts5_test_tok.c.
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
    const char *zModule = 0;
    if( nDequote>0 ){
      zModule = azDequote[0];
    }

    rc = pApi->xFindTokenizer(pApi, zModule, &pTokCtx, &pTab->tok);
    if( rc==SQLITE_OK ){
      const char **azArg = (const char **)&azDequote[1];
      int nArg = nDequote>0 ? nDequote-1 : 0;
      rc = pTab->tok.xCreate(pTokCtx, azArg, nArg, &pTab->pTok);
    }
  }

  if( rc!=SQLITE_OK ){
    sqlite3_free(pTab);







|







207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
    const char *zModule = 0;
    if( nDequote>0 ){
      zModule = azDequote[0];
    }

    rc = pApi->xFindTokenizer(pApi, zModule, &pTokCtx, &pTab->tok);
    if( rc==SQLITE_OK ){
      const char **azArg = (nDequote>1 ? (const char **)&azDequote[1] : 0);
      int nArg = nDequote>0 ? nDequote-1 : 0;
      rc = pTab->tok.xCreate(pTokCtx, azArg, nArg, &pTab->pTok);
    }
  }

  if( rc!=SQLITE_OK ){
    sqlite3_free(pTab);
Changes to ext/fts5/fts5_unicode2.c.
771
772
773
774
775
776
777

    for(; i<128 && i<n; i++){
      aAscii[i] = (u8)bToken;
    }
    iTbl++;
  }
  aAscii[0] = 0;                  /* 0x00 is never a token character */
}








>
771
772
773
774
775
776
777
778
    for(; i<128 && i<n; i++){
      aAscii[i] = (u8)bToken;
    }
    iTbl++;
  }
  aAscii[0] = 0;                  /* 0x00 is never a token character */
}

Changes to ext/fts5/test/fts5corrupt3.test.
8342
8343
8344
8345
8346
8347
8348

8349
8350
8351
8352
8353
8354
8355
do_catchsql_test 58.1 {
  SELECT * FROM t1('t*');
} {/*malformed database schema*/}

#-------------------------------------------------------------------------
do_test 59.0 {
  sqlite3 db {}

  db deserialize [decode_hexdb {
.open --hexdb
| size 32768 pagesize 4096 filename crash-96b136358d01ec.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00   .....@  ........
|     96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36   ...............6







>







8342
8343
8344
8345
8346
8347
8348
8349
8350
8351
8352
8353
8354
8355
8356
do_catchsql_test 58.1 {
  SELECT * FROM t1('t*');
} {/*malformed database schema*/}

#-------------------------------------------------------------------------
do_test 59.0 {
  sqlite3 db {}
  sqlite3_fts5_register_matchinfo db
  db deserialize [decode_hexdb {
.open --hexdb
| size 32768 pagesize 4096 filename crash-96b136358d01ec.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00   .....@  ........
|     96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36   ...............6
8540
8541
8542
8543
8544
8545
8546
8547
8548
8549
8550
8551

8552
8553
8554
8555
8556
8557
8558
| page 8 offset 28672
|   4048: 00 00 00 00 00 00 5d 03 02 2b 69 6e 74 00 00 00   ......]..+int...
| end crash-96b136358d01ec.db
}]} {}

do_catchsql_test 59.1 {
  SELECT (matchinfo(591,t1)) FROM t1 WHERE t1 MATCH 'e*eŸ'
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
do_test 60.0 {
  sqlite3 db {}

  db deserialize [decode_hexdb {
.open --hexdb
| size 32768 pagesize 4096 filename crash-c77b90b929dc92.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00   .....@  ........
|     96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36   ...............6







|




>







8541
8542
8543
8544
8545
8546
8547
8548
8549
8550
8551
8552
8553
8554
8555
8556
8557
8558
8559
8560
| page 8 offset 28672
|   4048: 00 00 00 00 00 00 5d 03 02 2b 69 6e 74 00 00 00   ......]..+int...
| end crash-96b136358d01ec.db
}]} {}

do_catchsql_test 59.1 {
  SELECT (matchinfo(591,t1)) FROM t1 WHERE t1 MATCH 'e*eŸ'
} {0 {}}

#-------------------------------------------------------------------------
do_test 60.0 {
  sqlite3 db {}
  sqlite3_fts5_register_matchinfo db
  db deserialize [decode_hexdb {
.open --hexdb
| size 32768 pagesize 4096 filename crash-c77b90b929dc92.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00   .....@  ........
|     96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36   ...............6
10422
10423
10424
10425
10426
10427
10428




































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































10429
10430
10431
10432
do_catchsql_test 70.1 {
  SELECT snippet(ttt, -1, '', '','','>')FROM ttt('e* NOT ee*e* NOT ee*');
} {1 {database disk image is malformed}}

do_catchsql_test 70.2 {
  SELECT snippet(ttt, -1, '', '','',13)FROM ttt('e* NOT ee*e* NOT ee*')
} {1 {database disk image is malformed}}





































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































sqlite3_fts5_may_be_corrupt 0
finish_test








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




10424
10425
10426
10427
10428
10429
10430
10431
10432
10433
10434
10435
10436
10437
10438
10439
10440
10441
10442
10443
10444
10445
10446
10447
10448
10449
10450
10451
10452
10453
10454
10455
10456
10457
10458
10459
10460
10461
10462
10463
10464
10465
10466
10467
10468
10469
10470
10471
10472
10473
10474
10475
10476
10477
10478
10479
10480
10481
10482
10483
10484
10485
10486
10487
10488
10489
10490
10491
10492
10493
10494
10495
10496
10497
10498
10499
10500
10501
10502
10503
10504
10505
10506
10507
10508
10509
10510
10511
10512
10513
10514
10515
10516
10517
10518
10519
10520
10521
10522
10523
10524
10525
10526
10527
10528
10529
10530
10531
10532
10533
10534
10535
10536
10537
10538
10539
10540
10541
10542
10543
10544
10545
10546
10547
10548
10549
10550
10551
10552
10553
10554
10555
10556
10557
10558
10559
10560
10561
10562
10563
10564
10565
10566
10567
10568
10569
10570
10571
10572
10573
10574
10575
10576
10577
10578
10579
10580
10581
10582
10583
10584
10585
10586
10587
10588
10589
10590
10591
10592
10593
10594
10595
10596
10597
10598
10599
10600
10601
10602
10603
10604
10605
10606
10607
10608
10609
10610
10611
10612
10613
10614
10615
10616
10617
10618
10619
10620
10621
10622
10623
10624
10625
10626
10627
10628
10629
10630
10631
10632
10633
10634
10635
10636
10637
10638
10639
10640
10641
10642
10643
10644
10645
10646
10647
10648
10649
10650
10651
10652
10653
10654
10655
10656
10657
10658
10659
10660
10661
10662
10663
10664
10665
10666
10667
10668
10669
10670
10671
10672
10673
10674
10675
10676
10677
10678
10679
10680
10681
10682
10683
10684
10685
10686
10687
10688
10689
10690
10691
10692
10693
10694
10695
10696
10697
10698
10699
10700
10701
10702
10703
10704
10705
10706
10707
10708
10709
10710
10711
10712
10713
10714
10715
10716
10717
10718
10719
10720
10721
10722
10723
10724
10725
10726
10727
10728
10729
10730
10731
10732
10733
10734
10735
10736
10737
10738
10739
10740
10741
10742
10743
10744
10745
10746
10747
10748
10749
10750
10751
10752
10753
10754
10755
10756
10757
10758
10759
10760
10761
10762
10763
10764
10765
10766
10767
10768
10769
10770
10771
10772
10773
10774
10775
10776
10777
10778
10779
10780
10781
10782
10783
10784
10785
10786
10787
10788
10789
10790
10791
10792
10793
10794
10795
10796
10797
10798
10799
10800
10801
10802
10803
10804
10805
10806
10807
10808
10809
10810
10811
10812
10813
10814
10815
10816
10817
10818
10819
10820
10821
10822
10823
10824
10825
10826
10827
10828
10829
10830
10831
10832
10833
10834
10835
10836
10837
10838
10839
10840
10841
10842
10843
10844
10845
10846
10847
10848
10849
10850
10851
10852
10853
10854
10855
10856
10857
10858
10859
10860
10861
10862
10863
10864
10865
10866
10867
10868
10869
10870
10871
10872
10873
10874
10875
10876
10877
10878
10879
10880
10881
10882
10883
10884
10885
10886
10887
10888
10889
10890
10891
10892
10893
10894
10895
10896
10897
10898
10899
10900
10901
10902
10903
10904
10905
10906
10907
10908
10909
10910
10911
10912
10913
10914
10915
10916
10917
10918
10919
10920
10921
10922
10923
10924
10925
10926
10927
10928
10929
10930
10931
10932
10933
10934
10935
10936
10937
10938
10939
10940
10941
10942
10943
10944
10945
10946
10947
10948
10949
10950
10951
10952
10953
10954
10955
10956
10957
10958
10959
10960
10961
10962
10963
10964
10965
10966
10967
10968
10969
10970
10971
10972
10973
10974
10975
10976
10977
10978
10979
10980
10981
10982
10983
10984
10985
10986
10987
10988
10989
10990
10991
10992
10993
10994
10995
10996
10997
10998
10999
11000
11001
11002
11003
11004
11005
11006
11007
11008
11009
11010
11011
11012
11013
11014
11015
11016
11017
11018
11019
11020
11021
11022
11023
11024
11025
11026
11027
11028
11029
11030
11031
11032
11033
11034
11035
11036
11037
11038
11039
11040
11041
11042
11043
11044
11045
11046
11047
11048
11049
11050
11051
11052
11053
11054
11055
11056
11057
11058
11059
11060
11061
11062
11063
11064
11065
11066
11067
11068
11069
11070
11071
11072
11073
11074
11075
11076
11077
11078
11079
11080
11081
11082
11083
11084
11085
11086
11087
11088
11089
11090
11091
11092
11093
11094
11095
11096
11097
11098
11099
11100
11101
11102
11103
11104
11105
11106
11107
11108
11109
11110
11111
11112
11113
11114
11115
11116
11117
11118
11119
11120
11121
11122
11123
11124
11125
11126
11127
11128
11129
11130
11131
11132
11133
11134
11135
11136
11137
11138
11139
11140
11141
11142
11143
11144
11145
11146
11147
11148
11149
11150
11151
11152
11153
11154
11155
11156
11157
11158
11159
11160
11161
11162
11163
11164
11165
11166
11167
11168
11169
11170
11171
11172
11173
11174
11175
11176
11177
11178
11179
11180
11181
11182
11183
11184
11185
11186
11187
11188
11189
11190
11191
11192
11193
11194
11195
11196
11197
11198
11199
11200
11201
11202
11203
11204
11205
11206
11207
11208
11209
11210
11211
11212
11213
11214
11215
11216
11217
11218
11219
11220
11221
11222
11223
11224
11225
11226
11227
11228
11229
11230
11231
11232
11233
11234
11235
11236
11237
11238
11239
11240
11241
11242
11243
11244
11245
11246
11247
11248
11249
11250
11251
11252
11253
11254
11255
11256
11257
11258
11259
11260
11261
11262
11263
11264
11265
11266
11267
11268
11269
11270
11271
11272
11273
11274
11275
11276
11277
11278
11279
11280
11281
11282
11283
11284
11285
11286
11287
11288
11289
11290
11291
11292
11293
11294
11295
11296
11297
11298
11299
11300
11301
11302
11303
11304
11305
11306
11307
11308
11309
11310
11311
11312
11313
11314
11315
11316
11317
11318
11319
11320
11321
11322
11323
11324
11325
11326
11327
11328
11329
11330
11331
11332
11333
11334
11335
11336
11337
11338
11339
11340
11341
11342
11343
11344
11345
11346
11347
11348
11349
11350
11351
11352
11353
11354
11355
11356
11357
11358
11359
11360
11361
11362
11363
11364
11365
11366
11367
11368
11369
11370
11371
11372
11373
11374
11375
11376
11377
11378
11379
11380
11381
11382
11383
11384
11385
11386
11387
11388
11389
11390
11391
11392
11393
11394
11395
11396
11397
11398
11399
11400
11401
11402
11403
11404
11405
11406
11407
11408
11409
11410
11411
11412
11413
11414
11415
11416
11417
11418
11419
11420
11421
11422
11423
11424
11425
11426
11427
11428
11429
11430
11431
11432
11433
11434
11435
11436
11437
11438
11439
11440
11441
11442
11443
11444
11445
11446
11447
11448
11449
11450
11451
11452
11453
11454
11455
11456
11457
11458
11459
11460
11461
11462
11463
11464
11465
11466
11467
11468
11469
11470
11471
11472
11473
11474
11475
11476
11477
11478
11479
11480
11481
11482
11483
11484
11485
11486
11487
11488
11489
11490
11491
11492
11493
11494
11495
11496
11497
11498
11499
11500
11501
11502
11503
11504
11505
11506
11507
11508
11509
11510
11511
11512
11513
11514
11515
11516
11517
11518
11519
11520
11521
11522
11523
11524
11525
11526
11527
11528
11529
11530
11531
11532
11533
11534
11535
11536
11537
11538
11539
11540
11541
11542
11543
11544
11545
11546
11547
11548
11549
11550
11551
11552
11553
11554
11555
11556
11557
11558
11559
11560
11561
11562
11563
11564
11565
11566
11567
11568
11569
11570
11571
11572
11573
11574
11575
11576
11577
11578
11579
11580
11581
11582
11583
11584
11585
11586
11587
11588
11589
11590
11591
11592
11593
11594
11595
11596
11597
11598
11599
11600
11601
11602
11603
11604
11605
11606
11607
11608
11609
11610
11611
11612
11613
11614
11615
11616
11617
11618
11619
11620
11621
11622
11623
11624
11625
11626
11627
11628
11629
11630
11631
11632
11633
11634
11635
11636
11637
11638
11639
11640
11641
11642
11643
11644
11645
11646
11647
11648
11649
11650
11651
11652
11653
11654
11655
11656
11657
11658
11659
11660
11661
11662
11663
11664
11665
11666
11667
11668
11669
11670
11671
11672
11673
11674
11675
11676
11677
11678
11679
11680
11681
11682
11683
11684
11685
11686
11687
11688
11689
11690
11691
11692
11693
11694
11695
11696
11697
11698
11699
11700
11701
11702
11703
11704
11705
11706
11707
11708
11709
11710
11711
11712
11713
11714
11715
11716
11717
11718
11719
11720
11721
11722
11723
11724
11725
11726
11727
11728
11729
11730
11731
11732
11733
11734
11735
11736
11737
11738
11739
11740
11741
11742
11743
11744
11745
11746
11747
11748
11749
11750
11751
11752
11753
11754
11755
11756
11757
11758
11759
11760
11761
11762
11763
11764
11765
11766
11767
11768
11769
11770
11771
11772
11773
11774
11775
11776
11777
11778
11779
11780
11781
11782
11783
11784
11785
11786
11787
11788
11789
11790
11791
11792
11793
11794
11795
11796
11797
11798
11799
11800
11801
11802
11803
11804
11805
11806
11807
11808
11809
11810
11811
11812
11813
11814
11815
11816
11817
11818
11819
11820
11821
11822
11823
11824
11825
11826
11827
11828
11829
11830
11831
11832
11833
11834
11835
11836
11837
11838
11839
11840
11841
11842
11843
11844
11845
11846
11847
11848
11849
11850
11851
11852
11853
11854
11855
11856
11857
11858
11859
11860
11861
11862
11863
11864
11865
11866
11867
11868
11869
11870
11871
11872
11873
11874
11875
11876
11877
11878
11879
11880
11881
11882
11883
11884
11885
11886
11887
11888
11889
11890
11891
11892
11893
11894
11895
11896
11897
11898
11899
11900
11901
11902
11903
11904
11905
11906
11907
11908
11909
11910
11911
11912
11913
11914
11915
11916
11917
11918
11919
11920
11921
11922
11923
11924
11925
11926
11927
11928
11929
11930
11931
11932
11933
11934
11935
11936
11937
11938
11939
11940
11941
11942
11943
11944
11945
11946
11947
11948
11949
11950
11951
11952
11953
11954
11955
11956
11957
11958
11959
11960
11961
11962
11963
11964
11965
11966
11967
11968
11969
11970
11971
11972
11973
11974
11975
11976
11977
11978
11979
11980
11981
11982
11983
11984
11985
11986
11987
11988
11989
11990
11991
11992
11993
11994
11995
11996
11997
11998
11999
12000
12001
12002
12003
12004
12005
12006
12007
12008
12009
12010
12011
12012
12013
12014
12015
12016
12017
12018
12019
12020
12021
12022
12023
12024
12025
12026
12027
12028
12029
12030
12031
12032
12033
12034
12035
12036
12037
12038
12039
12040
12041
12042
12043
12044
12045
12046
12047
12048
12049
12050
12051
12052
12053
12054
12055
12056
12057
12058
12059
12060
12061
12062
12063
12064
12065
12066
12067
12068
12069
12070
12071
12072
12073
12074
12075
12076
12077
12078
12079
12080
12081
12082
12083
12084
12085
12086
12087
12088
12089
12090
12091
12092
12093
12094
12095
12096
12097
12098
12099
12100
12101
12102
12103
12104
12105
12106
12107
12108
12109
12110
12111
12112
12113
12114
12115
12116
12117
12118
12119
12120
12121
12122
12123
12124
12125
12126
12127
12128
12129
12130
12131
12132
12133
12134
12135
12136
12137
12138
12139
12140
12141
12142
12143
12144
12145
12146
12147
12148
12149
12150
12151
12152
12153
12154
12155
12156
12157
12158
12159
12160
12161
12162
12163
12164
12165
12166
12167
12168
12169
12170
12171
12172
12173
12174
12175
12176
12177
12178
12179
12180
12181
12182
12183
12184
12185
12186
12187
12188
12189
12190
12191
12192
12193
12194
12195
12196
12197
12198
12199
12200
12201
12202
12203
12204
12205
12206
12207
12208
12209
12210
12211
12212
12213
12214
12215
12216
12217
12218
12219
12220
12221
12222
12223
12224
12225
12226
12227
12228
12229
12230
12231
12232
12233
12234
12235
12236
12237
12238
12239
12240
12241
12242
12243
12244
12245
12246
12247
12248
12249
12250
12251
12252
12253
12254
12255
12256
12257
12258
12259
12260
12261
12262
12263
12264
12265
12266
12267
12268
12269
12270
12271
12272
12273
12274
12275
12276
12277
12278
12279
12280
12281
12282
12283
12284
12285
12286
12287
12288
12289
12290
12291
12292
12293
12294
12295
12296
12297
12298
12299
12300
12301
12302
12303
12304
12305
12306
12307
12308
12309
12310
12311
12312
12313
12314
12315
12316
12317
12318
12319
12320
12321
12322
12323
12324
12325
12326
12327
12328
12329
12330
12331
12332
12333
12334
12335
12336
12337
12338
12339
12340
12341
12342
12343
12344
12345
12346
12347
12348
12349
12350
12351
12352
12353
12354
12355
12356
12357
12358
12359
12360
12361
12362
12363
12364
12365
12366
12367
12368
12369
12370
12371
12372
12373
12374
12375
12376
12377
12378
12379
12380
12381
12382
12383
12384
12385
12386
12387
12388
12389
12390
12391
12392
12393
12394
12395
12396
12397
12398
12399
12400
12401
12402
12403
12404
12405
12406
12407
12408
12409
12410
12411
12412
12413
12414
12415
12416
12417
12418
12419
12420
12421
12422
12423
12424
12425
12426
12427
12428
12429
12430
12431
12432
12433
12434
12435
12436
12437
12438
12439
12440
12441
12442
12443
12444
12445
12446
12447
12448
12449
12450
12451
12452
12453
12454
12455
12456
12457
12458
12459
12460
12461
12462
12463
12464
12465
12466
12467
12468
12469
12470
12471
12472
12473
12474
12475
12476
12477
12478
12479
12480
12481
12482
12483
12484
12485
12486
12487
12488
12489
12490
12491
12492
12493
12494
12495
12496
12497
12498
12499
12500
12501
12502
12503
12504
12505
12506
12507
12508
12509
12510
12511
12512
12513
12514
12515
12516
12517
12518
12519
12520
12521
12522
12523
12524
12525
12526
12527
12528
12529
12530
12531
12532
12533
12534
12535
12536
12537
12538
12539
12540
12541
12542
12543
12544
12545
12546
12547
12548
12549
12550
12551
12552
12553
12554
12555
12556
12557
12558
12559
12560
12561
12562
12563
12564
12565
12566
12567
12568
12569
12570
12571
12572
12573
12574
12575
12576
12577
12578
12579
12580
12581
12582
12583
12584
12585
12586
12587
12588
12589
12590
12591
12592
12593
12594
12595
12596
12597
12598
12599
12600
12601
12602
12603
12604
12605
12606
12607
12608
12609
12610
12611
12612
12613
12614
12615
12616
12617
12618
12619
12620
12621
12622
12623
12624
12625
12626
12627
12628
12629
12630
12631
12632
12633
12634
12635
12636
12637
12638
12639
12640
12641
12642
12643
12644
12645
12646
12647
12648
12649
12650
12651
12652
12653
12654
12655
12656
12657
12658
12659
12660
12661
12662
12663
12664
12665
12666
12667
12668
12669
12670
12671
12672
12673
12674
12675
12676
12677
12678
12679
12680
12681
12682
12683
12684
12685
12686
12687
12688
12689
12690
12691
12692
12693
12694
12695
12696
12697
12698
12699
12700
12701
12702
12703
12704
12705
12706
12707
12708
12709
12710
12711
12712
12713
12714
12715
12716
12717
12718
12719
12720
12721
12722
12723
12724
12725
12726
12727
12728
12729
12730
12731
12732
12733
12734
12735
12736
12737
12738
12739
12740
12741
12742
12743
12744
12745
12746
12747
12748
12749
12750
12751
12752
12753
12754
12755
12756
12757
12758
12759
12760
12761
12762
12763
12764
12765
12766
12767
12768
12769
12770
12771
12772
12773
12774
12775
12776
12777
12778
12779
12780
12781
12782
12783
12784
12785
12786
12787
12788
12789
12790
12791
12792
12793
12794
12795
12796
12797
12798
12799
12800
12801
12802
12803
12804
12805
12806
12807
12808
12809
12810
12811
12812
12813
12814
12815
12816
12817
12818
12819
12820
12821
12822
12823
12824
12825
12826
12827
12828
12829
12830
12831
12832
12833
12834
12835
12836
12837
12838
12839
12840
12841
12842
12843
12844
12845
12846
12847
12848
12849
12850
12851
12852
12853
12854
12855
12856
12857
12858
12859
12860
12861
12862
12863
12864
12865
12866
12867
12868
12869
12870
12871
12872
12873
12874
12875
12876
12877
12878
12879
12880
12881
12882
12883
12884
12885
12886
12887
12888
12889
12890
12891
12892
12893
12894
12895
12896
12897
12898
12899
12900
12901
12902
12903
12904
12905
12906
12907
12908
12909
12910
12911
12912
12913
12914
12915
12916
12917
12918
12919
12920
12921
12922
12923
12924
12925
12926
12927
12928
12929
12930
12931
12932
12933
12934
12935
12936
12937
12938
12939
12940
12941
12942
12943
12944
12945
12946
12947
12948
12949
12950
12951
12952
12953
12954
12955
12956
12957
12958
12959
12960
12961
12962
12963
12964
12965
12966
12967
12968
12969
12970
12971
12972
12973
12974
12975
12976
12977
12978
12979
12980
12981
12982
12983
12984
12985
12986
12987
12988
12989
12990
12991
12992
12993
12994
12995
12996
12997
12998
12999
13000
13001
13002
13003
13004
13005
13006
13007
13008
13009
13010
13011
13012
13013
13014
13015
13016
13017
13018
13019
13020
13021
13022
13023
13024
13025
13026
13027
13028
13029
13030
13031
13032
13033
13034
13035
13036
13037
13038
13039
13040
13041
13042
13043
13044
13045
13046
13047
13048
13049
13050
13051
13052
13053
13054
13055
13056
13057
13058
13059
13060
13061
13062
13063
13064
13065
13066
13067
13068
13069
13070
13071
13072
13073
13074
13075
13076
13077
13078
13079
13080
13081
13082
13083
13084
13085
13086
13087
13088
13089
13090
13091
13092
13093
13094
13095
13096
13097
13098
13099
13100
13101
13102
13103
13104
13105
13106
13107
13108
13109
13110
13111
13112
13113
13114
13115
13116
13117
13118
13119
13120
13121
13122
13123
13124
13125
13126
13127
13128
13129
13130
13131
13132
13133
13134
13135
13136
13137
13138
13139
13140
13141
13142
13143
13144
13145
13146
13147
13148
13149
13150
13151
13152
13153
13154
13155
13156
13157
13158
13159
13160
13161
13162
13163
13164
13165
13166
13167
13168
13169
13170
13171
13172
13173
13174
13175
13176
13177
13178
13179
13180
13181
13182
13183
13184
13185
13186
13187
13188
13189
13190
13191
13192
13193
13194
13195
13196
13197
13198
13199
13200
13201
13202
13203
13204
13205
13206
13207
13208
13209
13210
13211
13212
13213
13214
13215
13216
13217
13218
13219
13220
13221
13222
13223
13224
13225
13226
13227
13228
13229
13230
13231
13232
13233
13234
13235
13236
13237
13238
13239
13240
13241
13242
13243
13244
13245
13246
13247
13248
13249
13250
13251
13252
13253
13254
13255
13256
13257
13258
13259
13260
13261
13262
13263
13264
13265
13266
13267
13268
13269
13270
13271
13272
13273
13274
13275
13276
13277
13278
13279
13280
13281
13282
13283
13284
13285
13286
13287
13288
13289
13290
13291
13292
13293
13294
13295
13296
13297
13298
13299
13300
13301
13302
13303
13304
13305
13306
13307
13308
13309
13310
13311
13312
13313
13314
13315
13316
13317
13318
13319
13320
13321
13322
13323
13324
13325
13326
13327
13328
13329
13330
13331
13332
13333
13334
13335
13336
13337
13338
13339
13340
13341
13342
13343
13344
13345
13346
13347
13348
13349
13350
13351
13352
13353
13354
13355
13356
13357
13358
13359
13360
13361
13362
13363
13364
13365
13366
13367
13368
13369
13370
13371
13372
13373
13374
13375
13376
13377
13378
13379
13380
13381
13382
13383
13384
13385
13386
13387
13388
13389
13390
13391
13392
13393
13394
13395
13396
13397
13398
13399
13400
13401
13402
13403
13404
13405
13406
13407
13408
13409
13410
13411
13412
13413
13414
13415
13416
13417
13418
13419
13420
13421
13422
13423
13424
13425
13426
13427
13428
13429
13430
13431
13432
13433
13434
13435
13436
13437
13438
13439
13440
13441
13442
13443
13444
13445
13446
13447
13448
13449
13450
13451
13452
13453
13454
13455
13456
13457
13458
13459
13460
13461
13462
13463
13464
13465
13466
13467
13468
13469
13470
13471
13472
13473
13474
13475
13476
13477
13478
13479
13480
13481
13482
13483
13484
13485
13486
13487
13488
13489
13490
13491
13492
13493
13494
13495
13496
13497
13498
13499
13500
13501
13502
13503
13504
13505
13506
13507
13508
13509
13510
13511
13512
13513
13514
13515
13516
13517
13518
13519
13520
13521
13522
13523
13524
13525
13526
13527
13528
13529
13530
13531
13532
13533
13534
13535
13536
13537
13538
13539
13540
13541
13542
13543
13544
13545
13546
13547
13548
13549
13550
13551
13552
13553
13554
13555
13556
13557
13558
13559
13560
13561
13562
13563
13564
13565
13566
13567
13568
13569
13570
13571
13572
13573
13574
13575
13576
13577
13578
13579
13580
13581
13582
13583
13584
13585
13586
13587
13588
13589
13590
13591
13592
13593
13594
13595
13596
13597
13598
13599
13600
13601
13602
13603
13604
13605
13606
13607
13608
13609
13610
13611
13612
13613
13614
13615
13616
13617
13618
13619
13620
13621
13622
13623
13624
13625
13626
13627
13628
13629
13630
13631
13632
13633
13634
13635
13636
13637
13638
13639
13640
13641
13642
13643
13644
13645
13646
13647
13648
13649
13650
13651
13652
13653
13654
13655
13656
13657
13658
13659
13660
13661
13662
13663
13664
13665
13666
13667
13668
13669
13670
13671
13672
13673
13674
13675
13676
13677
13678
13679
13680
13681
13682
13683
13684
13685
13686
13687
13688
13689
13690
13691
13692
13693
13694
13695
13696
13697
13698
13699
13700
13701
13702
13703
13704
13705
13706
13707
13708
13709
13710
13711
13712
13713
13714
13715
13716
13717
13718
13719
13720
13721
13722
13723
13724
13725
13726
13727
13728
13729
13730
13731
13732
13733
13734
13735
13736
13737
13738
13739
13740
13741
13742
13743
13744
13745
13746
13747
13748
13749
13750
13751
13752
13753
13754
13755
13756
13757
13758
13759
13760
13761
13762
13763
13764
13765
13766
13767
13768
13769
13770
13771
13772
13773
13774
13775
13776
13777
13778
13779
13780
13781
13782
13783
13784
13785
13786
13787
13788
13789
13790
13791
13792
13793
13794
13795
13796
13797
13798
13799
13800
13801
13802
13803
13804
13805
13806
13807
13808
13809
13810
13811
13812
13813
13814
13815
13816
13817
13818
13819
13820
13821
13822
13823
13824
13825
13826
13827
13828
13829
13830
13831
13832
13833
13834
13835
13836
13837
13838
13839
13840
13841
13842
13843
13844
13845
13846
13847
13848
13849
13850
13851
13852
13853
13854
13855
13856
13857
13858
13859
13860
13861
13862
13863
13864
13865
13866
13867
13868
13869
13870
13871
13872
13873
13874
13875
13876
13877
13878
13879
13880
13881
13882
13883
13884
13885
13886
13887
13888
13889
13890
13891
13892
13893
13894
13895
13896
13897
13898
13899
13900
13901
13902
13903
13904
13905
13906
13907
13908
13909
13910
13911
13912
13913
13914
13915
13916
13917
13918
13919
13920
13921
13922
13923
13924
13925
13926
13927
13928
13929
13930
13931
13932
13933
13934
13935
13936
13937
13938
13939
13940
13941
13942
13943
13944
13945
13946
13947
13948
13949
13950
13951
13952
13953
13954
13955
13956
13957
13958
13959
13960
13961
13962
13963
13964
13965
13966
13967
13968
13969
13970
13971
13972
13973
13974
13975
13976
13977
13978
13979
13980
13981
13982
13983
13984
13985
13986
13987
13988
13989
13990
13991
13992
13993
13994
13995
13996
13997
13998
13999
14000
14001
14002
14003
14004
14005
14006
14007
14008
14009
14010
14011
14012
14013
14014
14015
14016
14017
14018
14019
14020
14021
14022
14023
14024
14025
14026
14027
14028
14029
14030
14031
14032
14033
14034
14035
14036
14037
14038
14039
14040
14041
14042
14043
14044
14045
14046
14047
14048
14049
14050
14051
14052
14053
14054
14055
14056
14057
14058
14059
14060
14061
14062
14063
14064
14065
14066
14067
14068
14069
14070
14071
14072
14073
14074
14075
14076
14077
14078
14079
14080
14081
14082
14083
14084
14085
14086
14087
14088
14089
14090
14091
14092
14093
14094
14095
14096
14097
14098
14099
14100
14101
14102
14103
14104
14105
14106
14107
14108
14109
14110
14111
14112
14113
14114
14115
14116
14117
14118
14119
14120
14121
14122
14123
14124
14125
14126
14127
14128
14129
14130
14131
14132
14133
14134
14135
14136
14137
14138
14139
14140
14141
14142
14143
14144
14145
14146
14147
14148
14149
14150
14151
14152
14153
14154
14155
14156
14157
14158
14159
14160
14161
14162
14163
14164
14165
14166
14167
14168
14169
14170
14171
14172
14173
14174
14175
14176
14177
14178
14179
14180
14181
14182
14183
14184
14185
14186
14187
14188
14189
14190
14191
14192
14193
14194
14195
14196
14197
14198
14199
14200
14201
14202
14203
14204
14205
14206
14207
14208
14209
14210
14211
14212
14213
14214
14215
14216
14217
14218
14219
14220
14221
14222
14223
14224
14225
14226
14227
14228
14229
14230
14231
14232
14233
14234
14235
14236
14237
14238
14239
14240
14241
14242
14243
14244
14245
14246
14247
14248
14249
14250
14251
14252
14253
14254
14255
14256
14257
14258
14259
14260
14261
14262
14263
14264
14265
14266
14267
14268
14269
14270
14271
14272
14273
14274
14275
14276
14277
14278
14279
14280
14281
14282
14283
14284
14285
14286
14287
14288
14289
14290
14291
14292
14293
14294
14295
14296
14297
14298
14299
14300
14301
14302
14303
14304
14305
14306
14307
14308
14309
14310
14311
14312
14313
14314
14315
14316
14317
14318
14319
14320
14321
14322
14323
14324
14325
14326
14327
14328
14329
14330
14331
14332
14333
14334
14335
14336
14337
14338
14339
14340
14341
14342
14343
14344
14345
14346
14347
14348
14349
14350
14351
14352
14353
14354
14355
14356
14357
14358
14359
14360
14361
14362
14363
14364
14365
14366
14367
14368
14369
14370
14371
14372
14373
14374
14375
14376
14377
14378
14379
14380
14381
14382
14383
14384
14385
14386
14387
14388
14389
14390
14391
14392
14393
14394
14395
14396
14397
14398
14399
14400
14401
14402
14403
14404
14405
14406
14407
14408
14409
14410
14411
14412
14413
14414
14415
14416
14417
14418
14419
14420
14421
14422
14423
14424
14425
14426
14427
14428
14429
14430
14431
14432
14433
14434
14435
14436
14437
14438
14439
14440
14441
14442
14443
14444
14445
14446
14447
14448
14449
14450
14451
14452
14453
14454
14455
14456
14457
14458
14459
14460
14461
14462
14463
14464
14465
14466
14467
14468
14469
14470
14471
14472
14473
14474
14475
14476
14477
14478
14479
14480
14481
14482
14483
14484
14485
14486
14487
14488
14489
14490
14491
14492
14493
14494
14495
14496
14497
14498
14499
14500
14501
14502
14503
14504
14505
14506
14507
14508
14509
14510
14511
14512
14513
14514
14515
14516
14517
14518
14519
14520
14521
14522
14523
14524
14525
14526
14527
14528
14529
14530
14531
14532
14533
14534
14535
14536
14537
14538
14539
14540
14541
14542
14543
14544
14545
14546
14547
14548
14549
14550
14551
14552
14553
14554
14555
14556
14557
14558
14559
14560
14561
14562
14563
14564
14565
14566
14567
14568
14569
14570
14571
14572
14573
14574
14575
14576
14577
14578
14579
14580
14581
14582
14583
14584
14585
14586
14587
14588
14589
14590
14591
14592
14593
14594
14595
14596
14597
14598
do_catchsql_test 70.1 {
  SELECT snippet(ttt, -1, '', '','','>')FROM ttt('e* NOT ee*e* NOT ee*');
} {1 {database disk image is malformed}}

do_catchsql_test 70.2 {
  SELECT snippet(ttt, -1, '', '','',13)FROM ttt('e* NOT ee*e* NOT ee*')
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 71.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 28672 pagesize 4096 filename sql025294.txt.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 00 01 00 40 20 20 00 00 00 00 00 00 00 07   .....@  ........
|     96: 00 00 00 00 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ...............m
|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
|   3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
|   3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
|   4016: 41 52 58 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARX KEY, block B
|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
| page 2 offset 4096
|      0: 0d 00 00 00 03 0f bd 00 0f e8 0f ef 0f bd 00 00   ................
|   4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 24 84 80   .............$..
|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
|   4048: 60 eb 01 02 02 04 01 66 74 02 02 02 04 04 6e 64   `......ft.....nd
|   4064: 6f 6e 03 01 f2 04 1a 07 05 01 03 00 10 03 03 0f   on..............
|   4080: 0a 03 00 24 00 00 00 00 01 01 4b 00 01 01 01 01   ...$......K.....
| page 3 offset 8192
|      0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02   ................
| page 4 offset 12288
|      0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00   ................
|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
| page 5 offset 16384
|      0: 0d 00 00 00 03 0f ee 00 0f fa 0f f4 0f ee 00 00   ................
|   4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 03   ................
|   4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
| page 6 offset 20480
|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| page 7 offset 24576
|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 00 00 00 00   ................
|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
| end sql025294.txt.db
}]} {}

do_catchsql_test 71.2 {
  INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 72.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 24576 pagesize 4096 filename crash-77b86d070d0ac6.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 06   .....@  ........
|     32: 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 04   ................
|     96: 00 00 00 00 0d 00 00 00 06 0d e2 00 0f c4 0f 6a   ...............j
|    112: 0e fc 0e 9d 0e 3d 0d e2 00 00 00 00 00 00 00 00   .....=..........
|   3552: 00 00 59 06 06 17 21 21 01 7f 74 61 62 6c 65 74   ..Y...!!..tablet
|   3568: 74 74 5f 63 6f 6e 66 69 67 74 74 74 5f 63 6f 6e   tt_configttt_con
|   3584: 66 69 67 06 43 52 45 41 54 45 20 54 41 42 4c 45   fig.CREATE TABLE
|   3600: 20 27 74 74 74 5f 63 6f 6e 66 69 67 27 28 6b 20    'ttt_config'(k 
|   3616: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20   PRIMARY KEY, v) 
|   3632: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5e 05 07   WITHOUT ROWID^..
|   3648: 17 23 23 01 81 03 74 61 62 6c 65 74 74 74 5f 64   .##...tablettt_d
|   3664: 6f 63 73 69 7a 65 74 74 74 5f 64 6f 63 73 69 7a   ocsizettt_docsiz
|   3680: 65 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27   e.CREATE TABLE '
|   3696: 74 74 74 5f 64 6f 63 73 69 7a 65 27 28 69 64 20   ttt_docsize'(id 
|   3712: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20   INTEGER PRIMARY 
|   3728: 4b 45 59 2c 20 73 7a 20 42 4c 4f 42 29 5d 04 07   KEY, sz BLOB)]..
|   3744: 17 23 23 01 81 01 74 61 62 6c 65 74 74 74 5f 63   .##...tablettt_c
|   3760: 6f 6e 74 65 6e 74 74 74 74 5f 63 6f 6e 74 65 6e   ontentttt_conten
|   3776: 74 04 43 52 45 41 54 45 20 54 41 42 4c 45 20 27   t.CREATE TABLE '
|   3792: 74 74 74 5f 63 6f 6e 74 65 6e 74 27 28 69 64 20   ttt_content'(id 
|   3808: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20   INTEGER PRIMARY 
|   3824: 4b 45 59 2c 20 63 30 2c 20 63 31 29 6c 03 07 17   KEY, c0, c1)l...
|   3840: 1b 1b 01 81 2f 74 61 62 6c 65 74 74 74 5f 69 64   ..../tablettt_id
|   3856: 78 74 74 74 5f 69 64 78 03 43 52 45 41 54 45 20   xttt_idx.CREATE 
|   3872: 54 41 42 4c 45 20 27 74 74 74 5f 69 64 78 27 28   TABLE 'ttt_idx'(
|   3888: 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 70 67 6e   segid, term, pgn
|   3904: 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 73   o, PRIMARY KEY(s
|   3920: 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 49 54   egid, term)) WIT
|   3936: 48 4f 55 54 20 52 4f 57 49 44 58 02 07 17 1d 1d   HOUT ROWIDX.....
|   3952: 01 81 03 74 61 62 6c 65 74 74 74 5f 64 61 74 61   ...tablettt_data
|   3968: 74 74 74 5f 64 61 74 61 02 43 52 45 41 54 45 20   ttt_data.CREATE 
|   3984: 54 41 42 4c 45 20 27 74 74 74 5f 64 61 74 61 27   TABLE 'ttt_data'
|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
|   4032: 4c 4f 42 29 3a 01 06 17 13 13 08 5f 74 61 62 6c   LOB):......_tabl
|   4048: 65 74 74 74 74 74 74 43 52 45 41 54 45 20 56 49   ettttttCREATE VI
|   4064: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 74 74 20   RTUAL TABLE ttt 
|   4080: 55 53 49 4e 47 20 66 74 73 35 28 61 2c 20 62 29   USING fts5(a, b)
| page 2 offset 4096
|      0: 0d 0f 44 00 05 0e 81 00 0f e7 0e 81 0f af 0f 58   ..D............X
|     16: 0e 98 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   3712: 00 15 0a 03 00 30 00 00 00 00 01 03 03 00 03 01   .....0..........
|   3728: 01 01 02 01 01 03 01 01 81 24 8c 80 80 80 80 01   .........$......
|   3744: 04 00 82 4c 00 00 00 9b 02 30 65 03 1a 02 05 05   ...L.....0e.....
|   3760: 07 05 01 01 04 03 03 08 03 03 01 2e 02 05 05 07   ................
|   3776: 05 07 05 07 05 01 01 04 03 03 08 03 03 08 03 03   ................
|   3792: 08 03 03 02 01 65 03 1e 03 05 05 04 05 05 01 01   .....e..........
|   3808: 03 06 04 04 06 04 03 01 36 03 05 05 04 05 05 04   ........6.......
|   3824: 05 05 04 05 05 01 01 03 06 04 04 06 04 04 06 04   ................
|   3840: 04 06 04 03 03 01 65 03 14 04 05 07 05 05 01 01   ......e.........
|   3856: 02 08 0a 01 20 04 05 07 05 07 05 07 05 05 01 01   .... ...........
|   3872: 02 08 0a 09 fa 04 01 65 03 02 0a 01 06 0a 1a 0a   .......e........
|   3888: 05 01 65 03 06 01 01 0a 01 0a 01 01 0a 0a 0a 04   ..e.............
|   3904: 2b 31 21 0b 0f ef 00 14 2a 00 00 00 00 01 02 02   +1!.....*.......
|   3920: 00 02 01 01 01 02 01 01 50 88 80 80 80 80 01 04   ........P.......
|   3936: 00 81 24 00 00 00 47 02 30 65 02 1a 02 05 05 07   ..$...G.0e......
|   3952: 05 01 01 04 03 03 08 03 03 02 01 65 02 1e 03 05   ...........e....
|   3968: 05 04 05 05 01 01 03 06 04 04 06 04 03 03 01 65   ...............e
|   3984: 02 14 04 05 07 05 05 01 01 02 08 0a 04 01 65 02   ..............e.
|   4000: 02 0a 05 01 65 02 06 01 01 0a 04 12 14 0f 06 31   ....e..........1
|   4016: 84 80 80 80 80 01 03 00 68 00 00 00 2b 02 30 65   ........h...+.0e
|   4032: 01 10 02 05 05 01 01 04 03 9f 02 01 65 01 12 03   ............e...
|   4048: 05 05 01 01 03 06 04 03 03 01 65 01 0e 14 05 05   ..........e.....
|   4064: 01 01 02 08 04 0d 0e 06 01 03 00 12 04 4c 4c 00   .............LL.
|   4080: 00 00 11 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
| page 3 offset 8192
|      0: 0a 00 00 00 03 0f 00 00 00 00 00 00 00 00 00 00   ................
|   4064: 00 00 00 00 00 00 00 00 00 00 00 00 06 04 01 0c   ................
|   4080: 01 03 02 06 04 01 0c 01 02 02 05 04 09 0c 01 02   ................
| page 4 offset 12288
|      0: 0d 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00   ................
|   3600: 00 00 00 00 00 00 00 00 00 00 81 52 04 06 00 81   ...........R....
|   3616: 5d 81 55 65 20 65 65 20 65 65 65 20 65 20 65 65   ].Ue ee eee e ee
|   3632: 20 65 65 65 20 65 20 65 65 20 65 65 65 65 20 65    eee e ee eeee e
|   3648: 65 20 65 65 65 20 65 20 65 65 20 65 65 65 20 65   e eee e ee eee e
|   3664: 20 65 65 20 65 65 55 65 20 65 65 20 65 65 65 20    ee eeUe ee eee 
|   3680: 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 65   e ee eee e ee ee
|   3696: 65 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65   ee ee eee e ee e
|   3712: 65 65 20 65 20 65 65 20 65 65 65 65 65 65 20 65   ee e ee eeeeee e
|   3728: 65 20 65 20 65 20 65 20 65 65 20 65 85 65 20 65   e e e e ee e.e e
|   3744: 65 20 65 65 65 65 65 20 65 65 20 65 20 65 20 65   e eeeee ee e e e
|   3760: 20 65 65 20 65 65 65 20 65 65 20 65 65 65 65 65    ee eee ee eeeee
|   3776: 20 65 65 20 65 20 65 20 65 20 65 65 20 65 65 65    ee e e e ee eee
|   3792: 20 65 65 20 65 65 65 65 65 20 65 65 20 65 20 65    ee eeeee ee e e
|   3808: 20 65 20 65 65 20 65 65 65 20 65 65 20 65 65 6a    e ee eee ee eej
|   3824: 03 04 00 75 71 65 20 65 65 20 65 65 65 20 65 20   ...uqe ee eee e 
|   3840: 65 65 20 65 65 65 20 65 20 65 65 20 65 65 65 65   ee eee e ee eeee
|   3856: 20 65 65 20 65 65 65 20 65 20 65 65 20 65 65 65    ee eee e ee eee
|   3872: 20 65 20 65 65 20 65 65 65 65 65 65 20 65 65 20    e ee eeeeee ee 
|   3888: 65 20 65 20 65 20 65 64 20 65 65 65 20 65 65 20   e e e ed eee ee 
|   3904: 65 65 65 65 65 20 65 65 20 65 20 65 20 65 10 65   eeeee ee e e e.e
|   3920: 65 20 65 65 65 10 65 65 20 65 65 6a 02 04 00 75   e eee.ee eej...u
|   3936: 71 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65   qe ee eee e ee e
|   3952: 65 65 20 65 20 65 65 20 65 65 65 65 20 65 65 20   ee e ee eeee ee 
|   3968: 65 65 65 20 65 20 65 65 20 65 65 65 20 65 20 65   eee e ee eee e e
|   3984: 65 20 65 65 65 66 65 65 20 65 65 20 65 20 65 20   e eeefee ee e e 
|   4000: 65 88 65 65 20 65 65 65 30 65 65 20 65 65 65 65   e.ee eee0ee eeee
|   4016: 65 20 65 65 20 65 20 65 20 65 20 65 65 20 65 65   e ee e e e ee ee
|   4032: 65 20 65 65 20 65 65 37 01 04 00 41 3f 65 20 65   e ee ee7...A?e e
|   4048: 65 20 65 65 65 20 65 20 65 65 20 65 65 65 20 65   e eee e ee eee e
|   4064: 20 65 65 20 65 65 65 65 65 65 20 65 65 20 65 20    ee eeeeee ee e 
|   4080: 65 20 65 20 65 65 20 65 65 65 20 65 65 20 65 65   e e ee eee ee ee
| page 5 offset 16384
|      0: 0d 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00   ................
|   4064: 00 00 00 00 05 04 03 00 10 21 21 05 03 03 00 10   .........!!.....
|   4080: 11 11 05 02 03 00 10 11 11 05 01 03 00 10 09 09   ................
| page 6 offset 20480
|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| end crash-77b86d070d0ac6.db
}]} {}

do_catchsql_test 72.1 {
  INSERT INTO ttt(ttt) VALUES('integrity-check');
} {1 {database disk image is malformed}}

do_catchsql_test 72.1 {
  SELECT 1 FROM ttt('e* NOT ee*');
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 73.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 24576 pagesize 4096 filename crash-b02ca2cc4d7dda.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 06   .....@  ........
|     32: 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 04   ................
|     96: 00 00 00 00 0d 00 00 00 06 0d e2 00 0f c4 0f 6a   ...............j
|    112: 0e fc 0e 9d 0e 3d 0d e2 00 00 00 00 00 00 00 00   .....=..........
|   3552: 00 00 59 06 06 17 21 21 01 7f 74 61 62 6c 65 74   ..Y...!!..tablet
|   3568: 74 74 5f 63 6f 6e 66 69 67 74 74 74 5f 63 6f 6e   tt_configttt_con
|   3584: 66 69 67 06 43 52 45 41 54 45 20 54 41 42 4c 45   fig.CREATE TABLE
|   3600: 20 27 74 74 74 5f 63 6f 6e 66 69 67 27 28 6b 20    'ttt_config'(k 
|   3616: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20   PRIMARY KEY, v) 
|   3632: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5e 05 07   WITHOUT ROWID^..
|   3648: 17 23 23 01 81 03 74 61 62 6c 65 74 74 74 5f 64   .##...tablettt_d
|   3664: 6f 63 73 69 7a 65 74 74 74 5f 64 6f 63 73 69 7a   ocsizettt_docsiz
|   3680: 65 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27   e.CREATE TABLE '
|   3696: 74 74 74 5f 64 6f 63 73 69 7a 65 27 28 69 64 20   ttt_docsize'(id 
|   3712: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20   INTEGER PRIMARY 
|   3728: 4b 45 59 2c 20 73 7a 20 42 4c 4f 42 29 5d 04 07   KEY, sz BLOB)]..
|   3744: 17 23 23 01 81 01 74 61 62 6c 65 74 74 74 5f 63   .##...tablettt_c
|   3760: 6f 6e 74 65 6e 74 74 74 74 5f 63 6f 6e 74 65 6e   ontentttt_conten
|   3776: 74 04 43 52 45 41 54 45 20 54 41 42 4c 45 20 27   t.CREATE TABLE '
|   3792: 74 74 74 5f 63 6f 6e 74 65 6e 74 27 28 69 64 20   ttt_content'(id 
|   3808: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20   INTEGER PRIMARY 
|   3824: 4b 45 59 2c 20 63 30 2c 20 63 31 29 6c 03 07 17   KEY, c0, c1)l...
|   3840: 1b 1b 01 81 2f 74 61 62 6c 65 74 74 74 5f 69 64   ..../tablettt_id
|   3856: 78 74 74 74 5f 69 64 78 03 43 52 45 41 54 45 20   xttt_idx.CREATE 
|   3872: 54 41 42 4c 45 20 27 74 74 74 5f 69 64 78 27 28   TABLE 'ttt_idx'(
|   3888: 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 70 67 6e   segid, term, pgn
|   3904: 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 73   o, PRIMARY KEY(s
|   3920: 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 49 54   egid, term)) WIT
|   3936: 48 4f 55 54 20 52 4f 57 49 44 58 02 07 17 1d 1d   HOUT ROWIDX.....
|   3952: 01 81 03 74 61 62 6c 65 74 74 74 5f 64 61 74 61   ...tablettt_data
|   3968: 74 74 74 5f 64 61 74 61 02 43 52 45 41 54 45 20   ttt_data.CREATE 
|   3984: 54 41 42 4c 45 20 27 74 74 74 5f 64 61 74 61 27   TABLE 'ttt_data'
|   4000: 28 69 65 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (ie INTEGER PRIM
|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
|   4032: 4c 4f 42 29 3a 01 06 17 13 13 08 5f 74 61 62 6c   LOB):......_tabl
|   4048: 65 74 74 74 74 74 74 43 52 45 41 54 45 20 56 49   ettttttCREATE VI
|   4064: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 74 74 20   RTUAL TABLE ttt 
|   4080: 55 53 49 4e 47 20 66 74 73 35 28 61 2c 20 62 29   USING fts5(a, b)
| page 2 offset 4096
|      0: 0d 0f 44 00 05 0e 81 00 0f e7 0e 81 0f af 0f 58   ..D............X
|     16: 0e 98 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   3712: 00 15 0a 03 00 30 00 00 00 00 01 03 03 00 03 01   .....0..........
|   3728: 01 01 02 01 01 03 01 01 81 24 8c 80 80 80 80 01   .........$......
|   3744: 04 00 82 4c 00 00 00 9b 02 30 65 03 1a 02 05 05   ...L.....0e.....
|   3760: 07 05 01 01 04 03 03 08 03 03 01 2e 02 05 05 07   ................
|   3776: 05 07 05 07 05 01 01 04 03 03 08 03 03 08 03 03   ................
|   3792: 08 03 03 02 01 65 03 1e 03 05 05 04 05 05 01 01   .....e..........
|   3808: 03 06 04 04 06 04 03 01 36 03 05 05 04 05 05 04   ........6.......
|   3824: 05 04 f4 04 05 01 01 03 06 04 04 06 04 04 06 04   ................
|   3840: 04 06 04 db 03 01 65 03 14 04 05 07 05 05 01 01   ......e.........
|   3856: 02 08 0a 01 20 04 05 07 05 07 05 07 05 05 01 01   .... ...........
|   3872: 02 08 0a 0a 0a 04 01 65 03 02 0a 01 06 0a 0a 0a   .......e........
|   3888: 05 01 65 03 06 01 01 0a 01 0a 01 01 0a 0a 0a 04   ..e.............
|   3904: 2b 31 21 0b 0f ef 00 14 2a 00 00 00 00 01 02 02   +1!.....*.......
|   3920: 00 02 01 01 01 02 01 01 50 88 80 80 80 80 01 04   ........P.......
|   3936: 00 81 24 00 00 00 47 02 30 65 02 1a 02 05 05 07   ..$...G.0e......
|   3952: 05 01 01 04 03 03 08 03 03 02 01 65 02 1e 03 05   ...........e....
|   3968: 05 04 05 05 01 01 03 06 09 14 06 04 03 03 01 65   ...............e
|   3984: 02 14 04 05 07 05 05 01 01 02 08 ed 04 01 65 02   ..............e.
|   4000: 02 0a 05 01 65 02 06 01 01 0a 04 12 14 0f 06 31   ....e..........1
|   4016: 84 80 80 80 80 01 03 00 68 00 00 00 2b 02 30 65   ........h...+.0e
|   4032: 01 10 02 05 05 01 01 04 03 03 02 01 55 01 12 03   ............U...
|   4048: 05 05 01 01 03 06 05 03 03 01 65 01 0e 04 05 05   ..........e.....
|   4064: 01 01 02 08 04 0d 0e 06 01 03 00 12 04 4c 4c 00   .............LL.
|   4080: 00 00 11 24 00 00 00 00 01 0f c1 00 01 01 01 01   ...$............
| page 3 offset 8192
|      0: 0a 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00   ................
|   4064: 00 00 00 00 00 00 00 00 00 00 00 00 06 04 01 0c   ................
|   4080: 01 03 02 06 04 01 0c 01 02 02 05 04 09 0c 01 02   ................
| page 4 offset 12288
|      0: 0d 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00   ................
|   3600: 00 00 00 00 00 00 00 00 00 00 81 52 04 06 00 81   ...........R....
|   3616: 5d 81 55 65 20 65 65 20 65 65 65 20 65 20 65 65   ].Ue ee eee e ee
|   3632: 20 65 65 65 20 65 20 65 65 20 65 65 65 65 20 65    eee e ee eeee e
|   3648: 65 20 65 65 65 20 65 20 65 65 20 65 65 65 20 65   e eee e ee eee e
|   3664: 20 65 65 20 65 65 65 65 20 65 65 20 65 65 65 20    ee eeee ee eee 
|   3680: 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 65   e ee eee e ee ee
|   3696: 65 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65   ee ee eee e ee e
|   3712: 65 65 20 65 20 65 65 20 65 65 65 65 65 65 20 65   ee e ee eeeeee e
|   3728: 65 20 65 20 65 20 65 20 65 65 20 65 65 65 20 65   e e e e ee eee e
|   3744: 65 20 65 65 65 65 65 20 65 65 20 65 20 65 20 65   e eeeee ee e e e
|   3760: 20 65 65 20 65 62 d5 20 65 65 20 65 65 65 65 65    ee eb. ee eeeee
|   3776: 20 65 65 20 65 20 65 20 65 20 65 65 20 65 65 65    ee e e e ee eee
|   3792: 20 65 65 20 65 65 65 65 65 20 65 65 20 65 21 65    ee eeeee ee e!e
|   3808: 20 65 20 65 65 20 65 65 65 20 65 65 20 65 65 6a    e ee eee ee eej
|   3824: 03 04 00 75 71 65 20 65 65 10 65 65 65 20 65 20   ...uqe ee.eee e 
|   3840: 65 65 20 65 65 65 20 65 20 65 65 20 65 65 65 65   ee eee e ee eeee
|   3856: 20 65 65 20 65 65 65 20 65 20 65 65 20 65 65 65    ee eee e ee eee
|   3872: 20 65 20 65 65 20 65 65 65 65 65 65 20 65 65 20    e ee eeeeee ee 
|   3888: 65 20 65 20 65 20 65 65 20 65 65 65 20 62 55 20   e e e ee eee bU 
|   3904: 65 65 65 65 65 20 65 65 20 65 20 65 20 65 20 65   eeeee ee e e e e
|   3920: 65 20 65 65 65 20 55 65 20 65 65 6a 02 04 00 75   e eee Ue eej...u
|   3936: 71 65 20 65 65 20 65 65 65 20 65 10 65 65 20 65   qe ee eee e.ee e
|   3952: 65 65 20 65 20 65 65 20 65 65 65 65 20 65 65 20   ee e ee eeee ee 
|   3968: 65 65 65 20 65 20 65 65 20 65 65 65 20 65 20 65   eee e ee eee e e
|   3984: 65 20 65 65 65 65 65 65 20 65 65 20 65 20 65 20   e eeeeee ee e e 
|   4000: 65 20 65 65 20 65 65 65 20 65 65 20 65 65 65 65   e ee eee ee eeee
|   4016: 65 20 65 65 20 65 20 65 20 65 20 65 65 20 65 65   e ee e e e ee ee
|   4032: 65 20 65 65 21 65 65 37 0a 04 00 41 3f 65 20 65   e ee!ee7...A?e e
|   4048: 65 20 65 65 65 20 65 20 65 65 20 65 65 65 20 65   e eee e ee eee e
|   4064: 20 65 65 20 65 65 65 65 65 65 20 65 65 20 65 20    ee eeeeee ee e 
|   4080: 65 20 65 20 65 65 20 65 65 65 20 65 65 20 65 65   e e ee eee ee ee
| page 5 offset 16384
|      0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   4064: 00 00 00 00 05 04 03 00 10 21 21 05 13 03 00 10   .........!!.....
|   4080: 11 11 05 02 03 00 10 11 11 05 01 03 00 10 09 09   ................
| page 6 offset 20480
|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| end crash-b02ca2cc4d7dda.db
}]} {}

do_catchsql_test 73.1 {
  SELECT snippet(ttt,ttt, NOT 54 ), 
  * FROM ttt('e* NOT ee*e* NOT ee* NOT ee*e* NOT e*') ;
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 74.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 106496 pagesize 4096 filename x.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 01 00 00 00 1a   .....@  ........
|     32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04   ................
|     80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01   ................
|     96: 00 2e 4f 78 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36   ..Ox...........6
|    112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 0d 92 00 00 00 00   ...k............
|   3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
|   3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
|   3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
|   3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
|   3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
|   3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
|   3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
|   3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06    WITHOUT ROWID[.
|   3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
|   3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
|   3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
|   3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
|   3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
|   3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21   Y, sz BLOB)^...!
|   3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74   !...tablet1_cont
|   3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52   entt1_content.CR
|   3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63   EATE TABLE 't1_c
|   3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47   ontent'(id INTEG
|   3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20   ER PRIMARY KEY, 
|   3776: 63 30 2c 20 63 31 2c d6 63 32 29 69 04 07 17 19   c0, c1,.c2)i....
|   3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74   ...-tablet1_idxt
|   3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42   1_idx.CREATE TAB
|   3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69   LE 't1_idx'(segi
|   3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50   d, term, pgno, P
|   3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64   RIMARY KEY(segid
|   3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54   , term)) WITHOUT
|   3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74    ROWIDU........t
|   3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61   ablet1_datat1_da
|   3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20   ta.CREATE TABLE 
|   3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54   't1_data'(id INT
|   3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59   EGER PRIMARY KEY
|   3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06   , block BLOB)8..
|   3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52   ...._tablet1t1CR
|   4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42   EATE VIRTUAL TAB
|   4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35   LE t1 USING fts5
|   4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00   (a,b,c).........
| page 2 offset 4096
|      0: 0d 00 00 00 24 0c 0a 00 0f d8 0f af 0f 86 0f 74   ....$..........t
|     16: 0f 61 0f 4e 0f 2f 0f 0f 0e ef 0e d7 0e be 0e a5   .a.N./..........
|     32: 0e 8d 0e 74 0e 5b 0e 40 0e 24 0e 08 01 2f 0d d5   ...t.[.@.$.../..
|     48: 0d bb 0d a0 0d 84 0d 68 0d 4f 0d 35 0d 1b 0c fb   .......h.O.5....
|     64: 0c da 0c b9 0c 99 0c 78 0c 57 0c 00 00 00 00 00   .......x.W......
|   3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f   ...........$..%.
|   3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49   .THREADSAFE=0XBI
|   3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41   NARY.#..%..THREA
|   3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 8f   DSAFE=0XNOCASE..
|   3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 45 3d   ..%..THREADSAFE=
|   3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d   0XRTRIM.!..3..OM
|   3168: 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 4f   IT LOAD EXTENSIO
|   3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f   NXBINARY. ..3..O
|   3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49   MIT LOAD EXTENSI
|   3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17   ONXNOCASE....3..
|   3232: 4f 4d 59 54 20 4c 4f 41 44 20 45 58 54 45 4e 53   OMYT LOAD EXTENS
|   3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 05 00 33 0f 19   IONXRTRIM....3..
|   3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30   MAX MEMORY=50000
|   3280: 30 30 30 57 42 49 4e 41 52 59 1f 1d 05 00 33 0f   000WBINARY....3.
|   3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30   .MAX MEMORY=5000
|   3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 33   0000XNOCASE....3
|   3328: 0f 17 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30   ..MAX MEMORY=500
|   3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25   00000XRTRIM....%
|   3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42   ..ENABLE RTREEXB
|   3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42   INARY....%..ENAB
|   3392: 4c 45 20 52 54 52 45 45 59 4e 4f 43 41 53 45 17   LE RTREEYNOCASE.
|   3408: 19 05 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52   ...%..ENABLE RTR
|   3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45   EEXRTRIM....)..E
|   3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49   NABLE MEMSYS5XBI
|   3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c   NARY....)..ENABL
|   3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45   E MEMSYS5XNOCASE
|   3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45   ....)..ENABLE ME
|   3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 00 25   MSYS5XRTRIM....%
|   3520: 0f 19 45 4e 41 42 4c 45 20 4a 53 4f 4e 31 58 42   ..ENABLE JSON1XB
|   3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42   INARY....%..ENAB
|   3552: 4c 45 20 4a 53 4f 4e 31 58 4e 4f 43 41 53 45 17   LE JSON1XNOCASE.
|   3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f   ...%..ENABLE JSO
|   3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45   N1XRTRIM....)..E
|   3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49   NABLE GEOPOLYXBI
|   3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4f 41 42 4c   NARY....)..EOABL
|   3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 51 53 45   E GEOPOLYXNOCQSE
|   3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45   ....)..ENABLE GE
|   3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23   OPOLYXRTRIM....#
|   3680: 0f 19 45 4e 41 42 4c 45 20 46 54 53 35 58 42 49   ..ENABLE FTS5XBI
|   3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c   NARY....#..ENABL
|   3712: 45 20 46 54 53 35 58 4e 4f 43 41 53 45 16 1d 05   E FTS5XNOCASE...
|   3728: 00 23 0f a4 45 4e 41 42 4c 45 20 46 54 53 35 58   .#..ENABLE FTS5X
|   3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42   RTRIM....#..ENAB
|   3760: 4c 45 20 46 55 53 34 58 42 49 4e 41 52 59 17 0b   LE FUS4XBINARY..
|   3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34   ..#..ENABLE FTS4
|   3792: 58 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e   XNOCASE....#..EN
|   3808: 41 42 4c 45 20 46 54 53 34 58 52 54 52 49 4d 1e   ABLE FTS4XRTRIM.
|   3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53   ...1..ENABLE DBS
|   3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e   TAT VTABXBINARY.
|   3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53   ...1..ENABLE DBS
|   3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d   TAT VTABXNOCASE.
|   3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53   ...1..ENABLE DBS
|   3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 11 06   TAT VTABXRTRIM..
|   3920: 05 00 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52   .....DEBUGXBINAR
|   3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f   Y.......DEBUGXNO
|   3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47   CASE.......DEBUG
|   3968: 58 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d   XRTRIM'...C..COM
|   3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20   PILER=gcc-5.4.0 
|   4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27   20160609XBINARY'
|   4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3d 67   ...C..COMPILER=g
|   4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30   cc-5.4.0 2016060
|   4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 43   9XNOCASE&...C..C
|   4064: 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e   OMPILER=gcc-5.4.
|   4080: 30 20 32 30 31 36 30 36 30 39 58 52 54 53 49 4d   0 20160609XRTSIM
| page 3 offset 8192
|      0: 05 00 00 00 07 0f ba 00 00 00 00 1a 0f f6 0f ec   ................
|     16: 0f e2 0f d8 0f ce 0f c4 0f ba 00 00 00 00 00 00   ................
|   3200: 00 00 00 00 00 00 00 00 00 00 08 01 03 00 16 2e   ................
|   3216: b1 7d 24 24 86 4a 84 80 80 80 80 01 04 00 8d 18   ..$$.J..........
|   3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06   ...+.00.........
|   3248: 1f 02 03 01 02 03 01 02 03 01 08 32 30 31 36 30   ...........20160
|   3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 34 00   609...........4.
|   3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 04 01 02   ..........5.....
|   3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 3d   ......0000000..=
|   3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06   ........binary..
|   3328: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01   ................
|   3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02   ................
|   3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02   ................
|   3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70   ............comp
|   3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64   iler...........d
|   3408: 62 73 74 61 74 07 02 03 01 02 03 01 02 03 02 04   bstat...........
|   3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 07 65   ebug...........e
|   3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 d3 02 01 02   nable...........
|   3456: 02 01 02 02 02 02 02 01 02 02 01 02 02 01 02 02   ................
|   3472: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01   ................
|   3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02   ................
|   3504: 02 01 02 02 02 08 78 74 65 6e 73 69 6f 6e 1f 02   ......xtension..
|   3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03   .........fts4...
|   3536: 01 02 03 01 02 03 04 01 35 0d 02 03 01 02 03 01   ........5.......
|   3552: 02 03 01 03 67 63 63 01 02 54 01 02 03 01 02 03   ....gcc..T......
|   3568: 02 06 65 6f 70 6f 6c 79 10 02 03 01 02 03 01 02   ..eopoly........
|   3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02   ...json1........
|   3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03   ...load.........
|   3616: 01 03 6d 61 78 1c 02 02 01 02 02 01 02 02 02 05   ..max...........
|   3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04   emory...........
|   3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e   sys5...........n
|   3664: 6f 63 61 73 65 02 06 01 02 02 03 06 01 02 02 03   ocase...........
|   3680: 06 01 02 02 13 06 01 02 02 03 06 01 02 02 03 06   ................
|   3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01   ................
|   3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02   ................
|   3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 02   ...omit.........
|   3744: 01 05 72 74 72 65 65 19 02 03 01 02 03 01 02 03   ..rtree.........
|   3760: 04 02 69 6d 01 06 01 02 02 03 06 01 02 02 03 06   ..im............
|   3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01   ................
|   3792: 02 01 f3 06 01 02 02 03 06 01 02 02 03 06 01 02   ................
|   3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 08   ................
|   3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01   ..threadsafe....
|   3840: 02 02 01 02 02 01 04 76 74 61 62 07 02 04 01 02   .......vtab.....
|   3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01   ......x.........
|   3872: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02   ................
|   3888: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01   ................
|   3904: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06   ................
|   3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01   ................
|   3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01   ................
|   3952: 02 01 06 01 01 02 01 06 01 01 02 ad 06 01 01 02   ................
|   3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01   ................
|   3984: 06 01 01 01 01 06 01 01 02 01 06 01 01 02 01 06   ................
|   4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01   ................
|   4016: 01 02 01 06 01 01 02 01 06 01 00 00 00 19 88 80   ................
|   4032: 80 80 80 06 00 00 00 18 88 80 80 80 80 05 00 00   ................
|   4048: 00 17 88 80 80 80 80 04 00 00 00 16 88 80 80 80   ................
|   4064: 80 03 00 00 00 15 88 80 80 80 80 02 00 00 00 14   ................
|   4080: 88 80 80 80 80 01 00 00 00 13 84 80 80 80 80 01   ................
| page 4 offset 12288
|      0: 0a 00 00 00 08 0e bd 00 00 00 0e f9 0e ef 0e e5   ................
|     16: 0e db 0e d1 0e c7 0e bd 00 00 00 00 00 00 00 00   ................
|   3760: 00 00 00 00 00 00 00 00 00 00 00 00 00 09 04 01   ................
|   3776: 12 01 02 30 f4 a3 0e 09 04 01 12 01 02 30 cf 8c   ...0.........0..
|   3792: 0c 09 04 01 12 01 02 30 7a 34 0a 09 04 01 12 01   .......0z4......
|   3808: 02 30 72 64 08 09 04 01 12 01 02 30 6b 30 06 09   .0rd.......0k0..
|   3824: 04 01 12 01 02 30 63 33 04 06 04 01 0c 01 02 02   .....0c3........
|   4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02   ................
| page 5 offset 16384
|      0: 05 00 00 00 0a 0f ce 00 00 00 00 12 0f fb 0f f6   ................
|     16: 0f f1 0f ec 0f e7 0f e2 0f dd 0f d8 0f d3 0f ce   ................
|     32: 0e 8d 0e 74 0e 5b 0e 40 0e 24 0e 08 01 2f 0d d5   ...t.[.@.$.../..
|     48: 0d bb 0d a0 0d 84 0d 68 0d 4f 0d 35 0d 1b 0c fb   .......h.O.5....
|     64: 0c da 0c b9 0c 99 0c 78 0c 57 0c 00 00 00 00 00   .......x.W......
|   3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f   ...........$..%.
|   3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49   .THREADSAFE=0XBI
|   3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41   NARY.#..%..THREA
|   3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 8f   DSAFE=0XNOCASE..
|   3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 45 3d   ..%..THREADSAFE=
|   3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d   0XRTRIM.!..3..OM
|   3168: 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 4f   IT LOAD EXTENSIO
|   3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f   NXBINARY. ..3..O
|   3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49   MIT LOAD EXTENSI
|   3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17   ONXNOCASE....3..
|   3232: 4f 4d 59 54 20 4c 4f 41 44 20 45 58 54 45 4e 53   OMYT LOAD EXTENS
|   3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 05 00 33 0f 19   IONXRTRIM....3..
|   3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30   MAX MEMORY=50000
|   3280: 30 30 30 57 42 49 4e 41 52 59 1f 1d 05 00 33 0f   000WBINARY....3.
|   3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30   .MAX MEMORY=5000
|   3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 33   0000XNOCASE....3
|   3328: 0f 17 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30   ..MAX MEMORY=500
|   3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25   00000XRTRIM....%
|   3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42   ..ENABLE RTREEXB
|   3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42   INARY....%..ENAB
|   3392: 4c 45 20 52 54 52 45 45 59 4e 4f 43 41 53 45 17   LE RTREEYNOCASE.
|   3408: 19 05 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52   ...%..ENABLE RTR
|   3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45   EEXRTRIM....)..E
|   3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49   NABLE MEMSYS5XBI
|   3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c   NARY....)..ENABL
|   3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45   E MEMSYS5XNOCASE
|   3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45   ....)..ENABLE ME
|   3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 00 25   MSYS5XRTRIM....%
|   3520: 0f 19 45 4e 41 42 4c 45 20 4a 53 4f 4e 31 58 42   ..ENABLE JSON1XB
|   3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42   INARY....%..ENAB
|   3552: 4c 45 20 4a 53 4f 4e 31 58 4e 4f 43 41 53 45 17   LE JSON1XNOCASE.
|   3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f   ...%..ENABLE JSO
|   3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45   N1XRTRIM....)..E
|   3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49   NABLE GEOPOLYXBI
|   3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4f 41 42 4c   NARY....)..EOABL
|   3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 51 53 45   E GEOPOLYXNOCQSE
|   3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45   ....)..ENABLE GE
|   3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23   OPOLYXRTRIM....#
|   3680: 0f 19 45 4e 41 42 4c 45 20 46 54 53 35 58 42 49   ..ENABLE FTS5XBI
|   3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c   NARY....#..ENABL
|   3712: 45 20 46 54 53 35 58 4e 4f 43 41 53 45 16 1d 05   E FTS5XNOCASE...
|   3728: 00 23 0f a4 45 4e 41 42 4c 45 20 46 54 53 35 58   .#..ENABLE FTS5X
|   3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42   RTRIM....#..ENAB
|   3760: 4c 45 20 46 55 53 34 58 42 49 4e 41 52 59 17 0b   LE FUS4XBINARY..
|   3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34   ..#..ENABLE FTS4
|   3792: 58 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e   XNOCASE....#..EN
|   3808: 41 42 4c 45 20 46 54 53 34 58 52 54 52 49 4d 1e   ABLE FTS4XRTRIM.
|   3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53   ...1..ENABLE DBS
|   3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e   TAT VTABXBINARY.
|   3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53   ...1..ENABLE DBS
|   3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d   TAT VTABXNOCASE.
|   3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53   ...1..ENABLE DBS
|   3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 11 06   TAT VTABXRTRIM..
|   3920: 05 00 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52   .....DEBUGXBINAR
|   3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f   Y.......DEBUGXNO
|   3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47   CASE.......DEBUG
|   3968: 58 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d   XRTRIM'...C..COM
|   3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20   PILER=gcc-5.4.0 
|   4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27   20160609XBINARY'
|   4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3d 67   ...C..COMPILER=g
|   4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 00 00   cc-5.4.0 20160..
|   4048: 00 11 09 00 00 00 10 08 00 00 00 0f 07 00 00 00   ................
|   4064: 0e 06 00 00 00 0d 05 00 00 00 0c 04 00 00 00 0b   ................
|   4080: 03 00 00 00 0a 02 00 00 00 09 01 00 00 00 02 00   ................
| page 6 offset 20480
|      0: 0d 0f b0 00 25 0e bc 03 0e d7 0e ce 0f f0 0e c5   ....%...........
|     16: 0f e7 0f de 0f d5 0f cc 0f c3 0e bc 0f b7 0f a8   ................
|     32: 0f a0 0f 98 0f 90 0f 88 0f 80 0f 78 0f 70 0f 68   ...........x.p.h
|     48: 0f 60 0f 58 0f 50 0f 48 0f 40 0f 38 0f 30 0f 28   .`.X.P.H.@.8.0.(
|     64: 0f 20 0f 18 0f 10 0f 08 0f 00 0e f8 0e 00 00 00   . ..............
|   3760: 00 00 00 00 00 00 00 00 00 00 00 00 07 09 03 00   ................
|   3776: 14 84 6b 00 00 07 03 03 00 14 84 5b 00 00 07 02   ..k........[....
|   3792: 03 00 14 84 63 00 00 07 01 03 00 14 85 07 00 00   ....c...........
|   3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01   .$.......#......
|   3824: 06 22 03 00 12 02 01 01 06 21 03 00 12 03 01 01   .........!......
|   3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 01 01   . ..............
|   3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01   ................
|   3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01   ................
|   3888: 06 1a 03 00 12 02 01 01 06 19 03 00 12 02 01 01   ................
|   3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01   ................
|   3920: 06 16 03 00 12 02 01 01 06 15 03 00 12 02 01 01   ................
|   3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01   ................
|   3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01   ................
|   3968: 06 00 03 00 12 02 01 01 06 0f 03 00 12 02 01 01   ................
|   3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01   ................
|   4000: 06 0c 03 00 12 02 01 01 06 0b 03 00 12 02 01 01   ................
|   4016: 0f f8 00 07 12 02 01 07 0a 03 00 14 85 05 00 00   ................
|   4032: 0f f8 00 07 08 03 00 14 84 73 00 00 07 07 03 00   .........s......
|   4048: 14 85 0b 00 00 07 06 03 00 14 85 02 00 00 07 05   ................
|   4064: 03 00 14 84 70 00 00 07 04 03 00 14 84 7e 00 00   ....p........~..
|   4080: 06 de 03 00 12 06 01 01 00 00 00 08 12 06 01 01   ................
| page 7 offset 24576
|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| page 8 offset 28672
|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e9 0f d6 00 01   ................
|   4048: 00 00 00 00 00 00 11 03 02 2b 69 6e 74 65 67 72   .........+integr
|   4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62   ity-check....reb
|   4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 00 00 00 00   uild....opti....
| page 9 offset 32768
|      0: 0d 00 00 00 01 04 3f 00 04 3f 00 00 00 00 00 00   ......?..?......
|   1072: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97   ................
|   1088: 3e 01 06 00 ae 7c 00 00 ee a4 ad af cf 26 bc c7   >....|.......&..
|   1104: a8 a1 59 d7 43 c2 93 4f ad 82 19 2e 25 e1 97 f9   ..Y.C..O....%...
|   1120: 21 59 34 ce e8 b2 e2 3c 4b f2 b4 ee 6b 35 84 c3   !Y4....<K...k5..
|   1136: d7 a0 6c e4 36 57 6f 0b d4 6d d9 cb b4 42 69 b6   ..l.6Wo..m...Bi.
|   1152: c4 a6 c8 53 85 27 5f ee 81 66 da 94 e8 ee af 44   ...S.'_..f.....D
|   1168: ef 8d 32 9c a7 2b 79 73 fe 68 c0 d0 0f 49 48 82   ..2..+ys.h...IH.
|   1184: 6f 6e 0d 23 9c c1 38 27 61 94 31 e5 2d 04 ad 20   on.#..8'a.1.-.. 
|   1200: d1 db 69 b9 b2 4a 09 71 0a 98 82 28 0d 11 82 6e   ..i..J.q...(...n
|   1216: dd b1 ca b2 50 7b 04 0a f0 01 f6 c5 3c 31 43 d7   ....P.......<1C.
|   1232: 1b 7a 13 b9 9b 03 02 98 ca 31 6c f1 a4 03 71 1e   .z.......1l...q.
|   1248: 37 38 b4 19 d5 ee bd 6e 6c 22 44 10 19 b4 80 b7   78.....nl.D.....
|   1264: 87 68 cb 1d 67 d8 b9 1d 59 5b 78 c0 d5 3c 55 2c   .h..g...Y[x..<U,
|   1280: 98 8e e1 73 0f 33 2f 46 f0 4c b5 ed 2f ba 23 92   ...s.3/F.L../.#.
|   1296: 74 f2 80 14 7c ec 00 54 e5 0b a6 5f 2a 31 00 8c   t...|..T..._*1..
|   1312: ce 19 8d 97 28 24 6b b3 ec b3 fc 25 1c 13 98 f7   ....($k....%....
|   1328: 18 dd 8a 9a 6a 8e d2 c1 4a 75 9e 85 dd a0 79 c9   ....j...Ju....y.
|   1344: a8 75 b4 f0 75 01 6f 53 c5 2b 9d f7 49 f1 0f f5   .u..u.oS.+..I...
|   1360: 95 89 08 0a 9d 73 2e 9e 2e c0 be e9 80 7f c3 ff   .....s..........
|   1376: 43 f4 60 08 e5 8d 57 64 e5 42 73 ab b2 8f 05 74   C.`...Wd.Bs....t
|   1392: 22 53 26 52 1e 35 6e b6 22 d5 d6 ae 5d 5b ad bf   .S&R.5n.....][..
|   1408: 89 00 25 26 d8 65 26 4b 52 11 c0 19 a3 92 f1 45   ..%&.e&KR......E
|   1424: 78 c8 70 af 1f 34 73 12 51 be ca cd c5 d6 09 13   x.p..4s.Q.......
|   1440: dc ec 57 80 9a de 2c 74 b7 cb e1 63 fd e5 0d 9b   ..W...,t...c....
|   1456: 17 93 41 74 18 b5 cd 87 69 d5 b1 30 d1 bb 6e ce   ..At....i..0..n.
|   1472: 54 75 8f 00 44 bb 97 6d b0 04 db a6 18 8c 8a 39   Tu..D..m.......9
|   1488: 3a d9 79 14 36 8b 4e c9 76 6a 11 00 bd f6 6e d0   :.y.6.N.vj....n.
|   1504: b2 b2 4c c0 8d 79 b8 27 2c 34 c3 bc f9 b0 52 a3   ..L..y.',4....R.
|   1520: 7a 24 31 e7 db db 7d ee 2a 51 d0 c7 51 4e 5d dc   z$1.....*Q..QN].
|   1536: 52 c4 8d ac 38 b8 84 d5 bc fe 96 c4 80 bb 5c e1   R...8...........
|   1552: 57 95 e8 7b 94 94 a1 0a e1 df c7 41 c5 29 c1 46   W..........A.).F
|   1568: 94 53 cb 26 fa 3d ee 2a 93 64 89 33 41 33 fb 95   .S.&.=.*.d.3A3..
|   1584: 42 9c dc 8e ee 15 19 7a 7b a6 92 0b aa 66 dc 0e   B......z.....f..
|   1600: b6 ef ad 5d 4f 93 ef cc ac a9 59 55 f9 ea 1e 45   ...]O.....YU...E
|   1616: bc 4f 92 d2 35 41 34 91 21 14 73 b0 3a 4e 36 2a   .O..5A4.!.s.:N6*
|   1632: 11 06 e1 23 ef 13 30 05 20 ae 45 0d b4 75 df ed   ...#..0. .E..u..
|   1648: 95 73 2f c7 a1 a8 ee eb 7d ad 41 ff 8b 2b 08 4e   .s/.......A..+.N
|   1664: ca e9 6f 1d 11 43 d4 a7 e0 85 75 ae 07 21 af 07   ..o..C....u..!..
|   1680: 58 42 1b 7e 02 85 95 16 76 c2 f5 9d 6f 90 c0 d7   XB.~....v...o...
|   1696: ab cb 49 cd 3f 20 43 07 7c 9e b3 be b9 fa 62 64   ..I.? C.|.....bd
|   1712: 2a 7c dc f6 d2 0e 01 ec 99 d3 00 1a 63 7d 4a a3   *|..........c.J.
|   1728: 16 fd c1 fa f8 c9 59 71 eb 15 09 41 2b 72 4a 67   ......Yq...A+rJg
|   1744: c5 65 14 70 ba fc 4c 30 d6 1c 6c 41 c1 8d 93 49   .e.p..L0..lA...I
|   1760: c5 26 be 91 81 e8 ad f3 34 58 c3 f2 51 aa 4a 88   .&......4X..Q.J.
|   1776: ee e5 86 a9 bd 11 5f 3e fe 40 e4 ed 72 18 8b 83   ......_>.@..r...
|   1792: 8d 30 50 e6 54 9d 62 0d 11 b0 80 ad 64 44 7f 82   .0P.T.b.....dD..
|   1808: 9a 61 c7 d5 f1 6b 34 2b ec bf 1a ee 5f bf 10 fe   .a...k4+...._...
|   1824: 0f 9e 42 3d 34 1e ff 00 82 db 52 e0 65 d1 d7 0d   ..B=4.....R.e...
|   1840: 77 fb 84 5c ec c3 b7 72 cf 21 26 40 85 20 f4 78   w......r.!&@. .x
|   1856: 6a f2 f4 52 8a c8 cd d9 99 73 8f 65 f5 f5 a8 af   j..R.....s.e....
|   1872: 75 bd a0 c6 ff 1a bf 64 53 01 4e ed be 22 95 1a   u......dS.N.....
|   1888: 57 06 21 1d f3 f3 97 4f c7 de 83 ab 80 40 c4 02   W.!....O.....@..
|   1904: 12 65 0d d5 55 87 6f 33 a1 b9 45 86 56 aa df fc   .e..U.o3..E.V...
|   1920: 24 e6 70 37 c3 e8 bc b6 b6 e1 02 29 dc ba 7e 16   $.p7.......)..~.
|   1936: e9 52 3b 9d e7 f8 d9 d1 5c b2 db 4c 18 29 56 80   .R;........L.)V.
|   1952: f0 f1 b4 07 34 30 2c 2f ee f6 a5 80 f7 a0 b6 7c   ....40,/.......|
|   1968: 43 e7 6f e2 a9 87 21 a2 96 82 d7 17 55 4d 33 ff   C.o...!.....UM3.
|   1984: 78 75 40 fe db de 63 c3 b5 45 c8 37 40 97 f8 68   xu@...c..E.7@..h
|   2000: b3 03 46 2d 50 1e 2b b0 90 23 09 47 f5 05 db 9c   ..F-P.+..#.G....
|   2016: 23 71 b1 12 e4 b2 ff 41 b4 1f e3 bb 3c 50 d2 ab   #q.....A....<P..
|   2032: ab cc 8c 8d ea 81 3b 9f 05 58 30 2b 27 23 8b 02   ......;..X0+'#..
|   2048: c2 c2 7a 00 a4 a8 56 ea 20 a7 9d 06 7b 36 e8 71   ..z...V. ....6.q
|   2064: 60 5c 75 98 22 1b 4b 04 b7 ef a0 a1 bb c6 11 12   `.u...K.........
|   2080: 52 10 ee 98 be 78 23 ab 07 60 c8 fe 9f 3e fd a4   R....x#..`...>..
|   2096: 24 2d b9 ba ec 3d e0 88 60 b2 9d 02 07 86 97 13   $-...=..`.......
|   2112: e9 c5 64 c8 0f 03 e1 1b 12 0b ff 39 e1 49 95 fa   ..d........9.I..
|   2128: 6f c3 63 4a 7c 86 38 66 95 b3 57 0b 95 96 c5 e5   o.cJ|.8f..W.....
|   2144: 55 3b 4b 58 d2 59 89 fa 70 40 b5 59 a1 b9 9e 46   U;KX.Y..p@.Y...F
|   2160: ec 3a 5a c8 6d fb ac da d0 62 f6 fb 8c 26 ff 3e   .:Z.m....b...&.>
|   2176: fb 54 69 ca 27 4b b5 a3 d1 27 f4 f5 2e d4 26 5a   .Ti.'K...'....&Z
|   2192: 0b 3e d6 f4 11 b9 ae fd 42 65 08 6f c1 83 51 1a   .>......Be.o..Q.
|   2208: 98 bc ad a9 77 8c da ef 70 dd 9b 6e e6 89 a0 75   ....w...p..n...u
|   2224: 5b c5 14 70 9c 3c 8d 99 b5 83 59 1e 77 0f 16 5e   [..p.<....Y.w..^
|   2240: 38 44 b9 da 9c c0 f0 61 23 5a 67 0e 43 48 81 ff   8D.....a#Zg.CH..
|   2256: 50 9b 2a 36 d1 18 7e bb d2 4e 83 45 07 f8 35 5f   P.*6..~..N.E..5_
|   2272: a4 8a af 12 ab 91 3e 4f 4f 40 32 3f 7e fc 06 6a   ......>OO@2?~..j
|   2288: c4 de 5e aa 2a a5 21 ba 14 51 28 65 c9 9e ef 7c   ..^.*.!..Q(e...|
|   2304: 6a 65 67 fc 11 23 1d 76 e3 be e3 10 7a 34 b8 ef   jeg..#.v....z4..
|   2320: 37 b8 ba 9c 1a 13 c7 e1 91 c9 06 ad 98 3c 4b ea   7............<K.
|   2336: 86 b3 bb ca 72 14 06 52 1e 3c ff 5e 6a fd 63 f9   ....r..R.<.^j.c.
|   2352: dc 03 ee 42 75 32 c7 09 cd b8 03 d9 a7 4a 61 5c   ...Bu2.......Ja.
|   2368: 04 50 25 45 05 dc 55 57 bf 6e 48 19 e1 c3 bd f8   .P%E..UW.nH.....
|   2384: 0e fa 7f 4b 6d 6a da e6 94 2b f3 bc 7b e6 cc 2e   ...Kmj...+......
|   2400: 6d 57 b8 e2 bc 05 05 68 16 af 37 12 5e 79 e3 05   mW.....h..7.^y..
|   2416: bd 32 ce d4 0c 25 c3 ab aa e6 ef c1 8c d0 c8 76   .2...%.........v
|   2432: 58 76 76 d2 4e db 37 d4 09 c3 21 53 3c 90 27 60   Xvv.N.7...!S<.'`
|   2448: ff a9 f2 18 fe 46 5c 29 4b 43 df f2 7e 06 15 28   .....F.)KC..~..(
|   2464: 4b 4f e4 aa 52 33 fd 11 f5 f1 8a 0b 3d 59 7e 88   KO..R3......=Y~.
|   2480: 0c 62 5e ad df f9 f1 31 d6 b2 d4 5f 9d 44 6b 8e   .b^....1..._.Dk.
|   2496: b6 02 b4 70 70 e1 9b 7e 7e 49 f5 20 a8 ad 83 04   ...pp..~~I. ....
|   2512: 1c 08 d0 2f 1e df 36 b0 b5 95 e2 4c 55 cd a2 e4   .../..6....LU...
|   2528: 2e 68 fb b8 66 70 85 de 89 8c a8 61 e9 53 05 86   .h..fp.....a.S..
|   2544: b0 4c 27 8b 43 4b c2 cb a1 6a ea 28 37 82 30 b7   .L'.CK...j.(7.0.
|   2560: 72 d7 e3 9a d3 cd fd 9a a0 5f 30 3e fe a4 c0 0f   r........_0>....
|   2576: 93 1b 7c 28 fb 53 bc b2 13 2d 8e 22 50 97 4c cf   ..|(.S...-..P.L.
|   2592: 06 f1 ac 55 9d c8 ce cd 59 74 9c af 7b bd 6f 7c   ...U....Yt....o|
|   2608: a5 b3 a4 87 6a 67 22 f1 82 5b 3e 9e 76 b0 2f d6   ....jg...[>.v./.
|   2624: f6 6d 7a c0 f5 8f 06 c2 5b 09 0f b5 df b9 d7 c2   .mz.....[.......
|   2640: be 51 e0 5e 5a 0a 79 62 3a 3c c8 a1 50 0d a3 36   .Q.^Z.yb:<..P..6
|   2656: e1 7d 61 4a 1b af f0 42 20 dc 10 a9 13 3d 2b 46   ..aJ...B ....=+F
|   2672: 16 98 d1 24 a8 a1 1a c8 88 0d 63 23 2b 23 b3 8d   ...$......c#+#..
|   2688: 19 13 f9 4c 76 0b 48 40 bb 02 db 1a 54 e8 ea f4   ...Lv.H@....T...
|   2704: f4 57 25 0d 50 1d 31 af 74 00 d8 f4 22 d9 53 e8   .W%.P.1.t.....S.
|   2720: 35 ae 1c c6 82 18 06 4f b6 f3 e8 2c 15 1c 38 1c   5......O...,..8.
|   2736: 5c 47 24 f4 49 44 ef a6 cc de 85 0d 61 aa f6 4f   .G$.ID......a..O
|   2752: 18 4b 23 7e ca dd 04 7a 7f 6c d0 70 59 05 0f 31   .K#~...z.l.pY..1
|   2768: de 19 71 96 7a 1b 93 a2 20 18 d6 a6 f2 8d 28 1d   ..q.z... .....(.
|   2784: c0 f3 a9 20 87 f7 dc 10 eb bf bc 1e cf 7a 54 a2   ... .........zT.
|   2800: 7f 96 0d 32 a9 30 30 5c 6d 31 3c 76 4d 65 1f d0   ...2.00.m1<vMe..
|   2816: 7a 9e db 78 60 bd b6 87 a2 1b 57 7c 2c f2 8e fa   z..x`.....W|,...
|   2832: a1 62 dd f2 16 9f a9 1d 39 5f 57 5d d1 01 4e 11   .b......9_W]..N.
|   2848: 83 53 88 b6 9c 02 f6 36 e9 c7 f7 e8 c3 35 a8 f6   .S.....6.....5..
|   2864: 56 10 62 a6 0e 91 0e be 95 65 87 c8 3d 98 1b 0c   V.b......e..=...
|   2880: 1f 4f 0c ef f9 0e 50 b7 6a 8b a0 07 02 f2 04 1a   .O....P.j.......
|   2896: e0 e2 d9 61 41 96 af 60 78 68 b8 4d 4e 8d 90 26   ...aA..`xh.MN..&
|   2912: 6f b7 24 3e 22 18 3d e4 94 cf bd da de 55 53 4a   o.$>..=......USJ
|   2928: 53 80 b1 9e 23 83 49 1a e0 22 9f 5c f3 df 87 d8   S...#.I.........
|   2944: 6f 45 ff 9b 8a 69 80 95 f8 ca bc 5c 0c b1 46 04   oE...i........F.
|   2960: 7e d7 61 72 d8 bf a1 b6 bc b3 48 c7 c2 b3 9d 7c   ~.ar......H....|
|   2976: de fb a4 0a 04 2f 97 99 eb ca 8c b5 39 fc 2b 45   ...../......9.+E
|   2992: 69 7f a9 70 c6 73 a1 22 71 b0 0d 53 0c f4 c7 68   i..p.s..q..S...h
|   3008: 85 ec 11 44 0b f9 b7 3b ff b7 91 1b fb bd bf e1   ...D...;........
|   3024: 01 90 4c 74 35 f3 ac 5a 70 bd e1 4e bb fd a8 dc   ..Lt5..Zp..N....
|   3040: 4d 38 c4 68 a8 e1 8f d1 69 b8 7a 20 b6 5c ed 2b   M8.h....i.z ...+
|   3056: e8 20 dc 0f 7e 29 3e 5f 83 76 e2 d9 b1 c0 07 66   . ..~)>_.v.....f
|   3072: cd a2 d4 57 bc 27 ff 1d 16 7a 11 d6 3d df 04 89   ...W.'...z..=...
|   3088: 45 91 e5 37 62 51 5a e6 0f 0d b8 e9 1a 43 e4 c3   E..7bQZ......C..
|   3104: 47 94 bf 16 fb 8c e2 f7 b8 c8 7f 7f 34 3b a3 fa   G...........4;..
|   3120: 4f 39 b3 89 ee 7a 1b 80 a6 04 46 24 7f 0c d2 48   O9...z....F$...H
|   3136: b4 cb a2 df 5c af 55 11 a5 c6 f6 de 6a a4 0f dc   ......U.....j...
|   3152: ae 12 98 11 9e 95 e2 b1 a6 c2 67 bb 37 ea e8 8e   ..........g.7...
|   3168: d1 6f 6c 7a 3a 13 5e 1c 31 92 7e 24 72 b0 f5 b6   .olz:.^.1.~$r...
|   3184: f5 db 3e b9 3b 2a 18 da 93 29 da 2c be 4a de c6   ..>.;*...).,.J..
|   3200: 6c 55 a0 3e 47 25 76 5c 73 08 99 17 87 e9 30 0e   lU.>G%v.s.....0.
|   3216: 91 a8 cd da 9a cd 90 8b 2d 5f 0e 88 7c a7 00 42   ........-_..|..B
|   3232: 84 bd 59 1b ce fa 76 27 33 78 c1 a4 0d 29 98 45   ..Y...v'3x...).E
|   3248: d1 7f b6 7d 56 f6 67 fe 78 ae 83 03 39 66 ce 5a   ....V.g.x...9f.Z
|   3264: 62 a1 e3 c5 fd 29 53 06 6e cd ff 0e 5a 95 ca 91   b....)S.n...Z...
|   3280: 1b 24 0d 42 ec e2 24 8a 01 ff 12 0b bf b1 18 74   .$.B..$........t
|   3296: 77 2d f5 9e 0a 74 e6 d4 7d 1c c1 53 d9 f5 65 9c   w-...t.....S..e.
|   3312: 40 6d 8f a9 f6 7b b0 96 37 71 c2 96 8c 90 f8 29   @m......7q.....)
|   3328: 07 10 c7 2d f5 1d 80 dc 96 b7 25 65 a6 a2 ff ba   ...-......%e....
|   3344: 5d 1e c1 0d ed b1 6a 83 20 6d 06 28 6d 54 8c 88   ].....j. m.(mT..
|   3360: 08 02 3d cf f6 79 81 f1 36 3b f0 6e e6 80 39 43   ..=..y..6;.n..9C
|   3376: 64 d6 4a 24 8b 3d 21 41 a9 48 d2 36 65 2f 5a 71   d.J$.=!A.H.6e/Zq
|   3392: eb 6f 2b 47 78 2d 8c 28 91 60 25 3c 35 81 5b 1d   .o+Gx-.(.`%<5.[.
|   3408: b7 36 34 71 4c 38 f2 29 7e f5 a8 45 71 95 78 19   .64qL8.)~..Eq.x.
|   3424: 00 e8 87 4d da 50 78 5e f7 dc aa 2d 15 92 49 d8   ...M.Px^...-..I.
|   3440: 4e af 77 30 bd ad 22 1b 6a 84 ff 78 6d 37 cf 1b   N.w0....j..xm7..
|   3456: 8a d9 81 dd 34 15 a7 3a c0 53 d6 ab 5a 38 ec 69   ....4..:.S..Z8.i
|   3472: 6a 88 64 8c a6 ce 50 12 45 a1 7f a2 aa 3a a8 cf   j.d...P.E....:..
|   3488: d6 a0 80 4e d6 7a b6 50 90 64 c0 52 30 51 04 6f   ...N.z.P.d.R0Q.o
|   3504: 89 25 02 b3 54 0b fb 24 89 cf f7 98 bd 8e fc 9f   .%..T..$........
|   3520: 62 0c cd fd 57 fd ac 64 b9 2a 94 62 94 38 c6 01   b...W..d.*.b.8..
|   3536: 0c f1 b9 75 f4 3c 5d 0e d4 1f 96 b3 74 3f 96 03   ...u.<].....t?..
|   3552: 13 b6 76 32 07 e0 1f 82 d8 27 f3 e7 2e f4 60 d0   ..v2.....'....`.
|   3568: 56 a5 8f 04 37 bd 5c 17 1e 33 94 75 d8 30 59 0d   V...7....3.u.0Y.
|   3584: e5 90 f5 09 ee 5c 01 88 14 ca 69 27 08 fa e7 3c   ..........i'...<
|   3600: a2 69 df e2 be 35 44 96 b5 06 69 5c 01 3f 52 67   .i...5D...i..?Rg
|   3616: 18 d2 c9 64 a7 ba 0b 59 d8 b8 53 21 74 de 2b 21   ...d...Y..S!t.+!
|   3632: 8a 53 3d 97 14 92 77 ed 51 21 4b f0 2d 69 93 09   .S=...w.Q!K.-i..
|   3648: 57 3e 92 9f 3e 20 6c 4d bf 8b fd 4f 75 4b 19 5d   W>..> lM...OuK.]
|   3664: 48 ef 23 1e 53 11 ee 76 b7 04 08 5a c4 9a 1f 6c   H.#.S..v...Z...l
|   3680: 24 cb 15 7f 0b f7 86 8e 60 a4 8d 3c 2a fe 14 13   $.......`..<*...
|   3696: 03 28 80 fa 6b d7 1b 02 a7 0d 9e 88 4d 1f b2 a4   .(..k.......M...
|   3712: 63 c7 65 56 14 df 51 7e d3 d4 3b e3 45 e1 7a 49   c.eV..Q~..;.E.zI
|   3728: 1e 71 40 fe b7 ae 65 10 b1 27 3a 02 31 21 47 11   .q@...e..':.1!G.
|   3744: d9 fc 9c 32 e5 c8 40 0d b6 4b 02 ed bc da 4c 98   ...2..@..K....L.
|   3760: 35 2c d5 9e 6f b3 42 c7 8e 0a c7 fa ae ff 36 5b   5,..o.B.......6[
|   3776: 76 08 69 3e 3c cd 4d eb 6f 0c a0 f6 23 93 a6 bb   v.i><.M.o...#...
|   3792: 2f ed 44 64 22 df e8 6b 21 68 5b 35 d6 8f 68 c5   /.Dd...k!h[5..h.
|   3808: 15 1f 46 fd 12 bc b5 b5 3e a7 e4 9b b2 83 f4 12   ..F.....>.......
|   3824: ea bb 50 84 f4 40 96 c4 64 30 d8 fe 74 5b f2 ba   ..P..@..d0..t[..
|   3840: 9a 64 23 67 4a 3d 7e 54 da 8f 39 18 df 31 88 23   .d#gJ=~T..9..1.#
|   3856: d6 80 5f e9 10 9f 37 22 6f 4a 21 13 20 13 fc 66   .._...7.oJ!. ..f
|   3872: fc 4b db a8 d9 aa 55 01 48 3e 8c ac bf 16 fc 62   .K....U.H>.....b
|   3888: 95 2c 44 1f 27 bf 7b 45 7d 28 55 14 1f ed 56 ed   .,D.'..E.(U...V.
|   3904: 24 5b 11 ff be a0 7a 20 3b 3e 9c 2c e6 d6 b0 ef   $[....z ;>.,....
|   3920: b4 df 16 73 f2 d3 a9 90 2b 54 c7 7a fa 25 e7 ee   ...s....+T.z.%..
|   3936: da 99 8d d7 b5 7d 0f 72 c7 61 75 d1 d7 23 dd 41   .......r.au..#.A
|   3952: 1e 46 ee ef 41 86 00 9f 1c 47 36 75 95 f6 1d 89   .F..A....G6u....
|   3968: 13 c0 75 f8 cc 5e 08 93 e4 de a8 ee d2 ce c2 32   ..u..^.........2
|   3984: e4 16 b0 c8 82 c1 2a 74 ed 5c 5f c1 99 f7 07 a7   ......*t.._.....
|   4000: b3 50 21 87 a1 43 dc 17 4f 2d 47 e0 be 53 ad 17   .P!..C..O-G..S..
|   4016: f9 09 67 d1 4f 1f 72 17 62 b7 03 fa cd de 3e a7   ..g.O.r.b.....>.
|   4032: 25 a9 e7 a0 e2 3d a3 6b 2b 34 3f 55 46 18 df ef   %....=.k+4?UF...
|   4048: 16 0a ce c8 67 58 eb 64 eb 7e a3 5b 4e 85 49 64   ....gX.d.~.[N.Id
|   4064: d7 f9 ec 0d 4d b6 1d 49 bb 93 e9 79 3d e1 f9 ad   ....M..I...y=...
|   4080: 6d c0 45 9c 46 26 21 41 10 dd 4a 12 fc 28 f4 cc   m.E.F&!A..J..(..
| page 10 offset 36864
|      0: 0d 00 00 00 01 04 3f 00 04 3f 00 00 00 00 00 00   ......?..?......
|   1072: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97   ................
|   1088: 3e 02 06 00 ae 7c 00 00 9a 84 85 31 87 79 cc e4   >....|.....1.y..
|   1104: 12 98 6f 2c 46 b6 5d 4e d9 5c ba 21 2f cf 51 9d   ..o,F.]N...!/.Q.
|   1120: 9f 8c 48 7d 5a 15 ae 1c 54 d7 f0 7f a2 e6 cc fd   ..H.Z...T.......
|   1136: ad e6 3c d5 e5 98 5d f2 64 82 5b 9e 6c d6 05 8f   ..<...].d.[.l...
|   1152: de fb 33 3a 37 b3 1d 58 04 47 13 cd d9 39 17 a9   ..3:7..X.G...9..
|   1168: a7 14 f1 fe c8 3b 21 40 a8 22 f5 3b 64 74 14 dc   .....;!@...;dt..
|   1184: c5 9e 99 8b f3 d4 5f 1a e8 1d 93 98 9e 00 7d ee   ......_.........
|   1200: 9f 0f 49 b5 af 12 7e 47 8e fe 5f 70 a1 9c 32 ae   ..I...~G.._p..2.
|   1216: d1 23 33 d1 c0 65 b6 8e 5a 4a 03 2f 74 27 0f 3d   .#3..e..ZJ./t'.=
|   1232: 3f 42 0d 03 5f 6c ef 2c 54 6a bd ec 88 eb cd 1f   ?B.._l.,Tj......
|   1248: dd 03 9c 06 18 8e a4 c1 a5 3c ec 9d 68 da d9 d3   .........<..h...
|   1264: d8 8f ba 16 95 fd 94 ed 19 2b 2f 5e 0e a5 fa de   .........+/^....
|   1280: dc c5 a0 a2 d4 31 0f dc f5 8b 4a 28 4f 6f 9f ff   .....1....J(Oo..
|   1296: 7f e6 d4 d0 08 7e 5c 76 9a 3a ea 0e ea b4 9d 45   .....~.v.:.....E
|   1312: 4b db 96 ed 27 ad a8 09 63 3c d0 1d d9 b1 dc 94   K...'...c<......
|   1328: 6a 8e e7 6a 9b 6e d1 8b f7 c8 60 1c 85 e9 a2 3e   j..j.n....`....>
|   1344: 0c b6 2f 40 b0 2e b6 53 8f 94 74 6b 39 13 fd c9   ../@...S..tk9...
|   1360: 44 77 64 7c 62 e0 51 2e 04 0f 6a 99 5e 68 6f 72   Dwd|b.Q...j.^hor
|   1376: 08 92 02 bf 36 78 0c 98 c3 3f 3d e3 ac a4 2d 3b   ....6x...?=...-;
|   1392: d7 51 cf f9 25 72 59 36 b0 ea 51 a1 9c bf 13 f1   .Q..%rY6..Q.....
|   1408: dc f5 36 f0 d9 83 fe 0a ff b5 00 ab 5b 4e 0b 33   ..6.........[N.3
|   1424: 0a a1 fa c1 02 c8 7a af 00 30 54 d3 6e a8 37 b4   ......z..0T.n.7.
|   1440: 02 88 16 41 95 86 1f 36 e0 98 43 d5 55 57 c6 5e   ...A...6..C.UW.^
|   1456: 0d 10 40 fd 3d 85 a1 5f 19 3f 18 87 11 d9 6a ca   ..@.=.._.?....j.
|   1472: 8b 5c 14 cc 64 48 b9 42 71 61 30 ca 0d 2c a5 67   ....dH.Bqa0..,.g
|   1488: 6b 4f 5b 34 1b f3 7b a1 1f ed e4 3b ef 68 27 00   kO[4.......;.h'.
|   1504: f3 8a 27 ff de 2e 07 ab 03 b1 5b b9 c3 84 53 f1   ..'.......[...S.
|   1520: d0 c5 8c 65 50 4b 7a 35 06 0c d5 2a ce 4c b9 02   ...ePKz5...*.L..
|   1536: 7f cf 2a d9 0d 2a 1c c1 5f 94 cb 5c 05 4d 3a 7a   ..*..*.._....M:z
|   1552: aa c5 3e 4e 26 93 8a 4d 1d fc 75 23 9f b5 27 87   ..>N&..M..u#..'.
|   1568: fc f7 3d aa a6 3e 5d c3 55 63 e2 a8 2a 7b 2e 26   ..=..>].Uc..*..&
|   1584: e9 64 59 1f 2a e7 ff 7c d4 69 a6 34 bb d9 23 81   .dY.*..|.i.4..#.
|   1600: de 4b ba f3 91 cd 9a 8b 98 56 f0 b8 73 7b 83 f1   .K.......V..s...
|   1616: fc e9 5c 01 7e 74 66 d0 0c 01 79 c0 b2 49 0f 78   ....~tf...y..I.x
|   1632: 79 ef 20 96 ec cb 63 67 fe 43 a7 ea 5d af 68 12   y. ...cg.C..].h.
|   1648: 84 dc 0c 5c 31 6a 1d d6 a1 1e d4 25 a3 f0 7c 19   ....1j.....%..|.
|   1664: dc 84 4f 7b e4 5a e5 40 23 07 b3 5b 92 92 4b 3a   ..O..Z.@#..[..K:
|   1680: 0e 11 9c b4 ba d4 d1 ff 22 af cd 7d e8 86 c3 0a   ................
|   1696: 14 eb 01 13 f8 99 56 8c c6 26 55 8d a7 cc cc 00   ......V..&U.....
|   1712: 4c 16 7a 07 de 6c 69 02 e2 a1 e6 e1 d5 ff 12 f5   L.z..li.........
|   1728: ee d7 8f 90 e1 78 99 09 de 27 b8 b3 e1 7a df 8a   .....x...'...z..
|   1744: 08 cb c0 67 ff d4 48 bd 0b 4c 65 56 5a ed 02 47   ...g..H..LeVZ..G
|   1760: 1c de b7 58 7c cf 68 a4 7f e6 db 74 26 55 9c 14   ...X|.h....t&U..
|   1776: 76 5a bf f3 e1 79 23 5e 33 f8 65 13 bb 36 cc ed   vZ...y#^3.e..6..
|   1792: 9e 12 63 b2 c2 14 3f 6a 4d e3 a4 63 bf 30 0f cb   ..c...?jM..c.0..
|   1808: f2 f0 d1 81 a7 26 d7 c0 92 9f 06 79 bd a7 a0 8d   .....&.....y....
|   1824: 74 21 7b c6 46 49 5c fd 01 a6 92 56 3b eb e6 d5   t!..FI.....V;...
|   1840: b4 4d 76 2a e8 00 98 3b a3 67 a9 7d 02 25 96 3b   .Mv*...;.g...%.;
|   1856: 45 19 a0 d4 b5 67 88 cf 48 eb 1a b6 0e f3 2d 62   E....g..H.....-b
|   1872: 3e 0c fa b3 e7 a4 f1 76 d4 d7 f5 19 6f b2 9e e8   >......v....o...
|   1888: e1 a1 b7 be 3a ff 69 db eb 75 1c 0c 91 7f 02 4f   ....:.i..u.....O
|   1904: df 15 af 09 48 2c d0 86 bd b0 80 82 e7 7b 1d a6   ....H,..........
|   1920: 38 f1 24 79 d0 8e 4c 07 9f ed 9f fb 90 a1 7e fd   8.$y..L.......~.
|   1936: 50 c6 fe d3 61 04 a1 03 34 30 bd 98 db 5c 18 e3   P...a...40......
|   1952: 94 d9 ba 8f 64 f8 6b c1 21 3b 22 b7 3e 71 5a 66   ....d.k.!;..>qZf
|   1968: cf 9f 51 c4 a2 36 c8 ba c3 2a 95 2e 67 e4 87 3e   ..Q..6...*..g..>
|   1984: 07 ae 66 ad ec af c6 17 62 11 be 5f 15 fc 61 53   ..f.....b.._..aS
|   2000: 76 eb f5 78 da 32 8c fa 4e d3 cc 27 19 dc 89 fc   v..x.2..N..'....
|   2016: 37 4f 74 61 f7 5e 97 0f fe fc af aa 12 ee ea f2   7Ota.^..........
|   2032: 68 36 36 cd 7e 57 41 75 48 be cd 46 e3 cd 3a 99   h66.~WAuH..F..:.
|   2048: 31 33 9a 84 8a 83 a2 fc 85 85 3c bc cf 07 b4 6d   13........<....m
|   2064: 57 d2 c9 63 a2 9d 42 07 4e cd 65 2e 65 0a af 03   W..c..B.N.e.e...
|   2080: dc a9 98 57 b6 7f da 1d b7 3c e0 ef aa 18 eb 3f   ...W.....<.....?
|   2096: 78 f1 34 e6 bf c7 28 34 11 a7 bc b3 34 79 f2 85   x.4...(4....4y..
|   2112: ed 7d fe 38 a5 48 b3 b4 8a 0d 75 12 65 04 f8 88   ...8.H....u.e...
|   2128: 71 b9 d4 86 48 c7 ea 2f af 4d 50 b9 50 a7 17 f6   q...H../.MP.P...
|   2144: 1f a2 e1 b8 aa ed 6d 85 3a e2 91 be 94 c8 fc db   ......m.:.......
|   2160: 93 50 0e 50 7c cf 52 f7 55 81 3e 1a 59 4d a8 36   .P.P|.R.U.>.YM.6
|   2176: ee 07 f1 9e 26 4a 1e d3 0b 7d 52 e3 bc 7c 91 78   ....&J....R..|.x
|   2192: 02 48 7e b5 4c 32 1e a3 ba db 93 61 94 3b d7 22   .H~.L2.....a.;..
|   2208: 7b cb 46 5b c0 a5 1e e6 5a ed c9 82 07 48 17 d6   ..F[....Z....H..
|   2224: de 85 ca 47 e1 16 5c c8 dc 30 5e 27 65 60 a5 41   ...G.....0^'e`.A
|   2240: 46 0a 12 0e 97 63 3f 05 5f 62 83 e0 cb 72 b6 61   F....c?._b...r.a
|   2256: 6a 4c 1d 7b 09 28 75 54 1c cd 29 bc f8 71 34 56   jL...(uT..)..q4V
|   2272: d6 ac 77 34 44 0d 5f c3 0e f1 d7 b3 dc 0d 1f 85   ..w4D._.........
|   2288: e3 db 45 88 fd db ab bf a6 ff bc 08 f3 3c 00 f0   ..E..........<..
|   2304: 9f 3b 07 36 cc 37 f0 6d 14 a8 6b 69 d6 e4 3a ab   .;.6.7.m..ki..:.
|   2320: 4f 5a b5 ad 3a e5 e3 d6 1c e1 6b 15 97 69 b0 41   OZ..:.....k..i.A
|   2336: 91 09 50 02 6a 5c c1 9e fe e7 38 7e 19 8a 36 44   ..P.j.....8~..6D
|   2352: 51 04 8d 61 d9 a3 12 34 00 b2 b1 60 f3 35 eb 8a   Q..a...4...`.5..
|   2368: dc bb a1 67 48 b6 95 81 91 fe 20 dd 03 74 bb 3b   ...gH..... ..t.;
|   2384: 8c 33 58 b2 d8 55 7e 04 ea 42 6c 02 e8 26 18 19   .3X..U~..Bl..&..
|   2400: 23 15 21 a5 73 ca 08 7b dd db fb b2 12 df 6a 5a   #.!.s.........jZ
|   2416: d7 ac e4 57 61 ac 3f 81 77 df f6 a3 97 5c 69 47   ...Wa.?.w.....iG
|   2432: 5a b7 75 23 6c 60 be 97 ee b5 5d a0 c3 60 15 4a   Z.u#l`....]..`.J
|   2448: 79 eb 81 9f 2a 74 22 13 7e ca 4d 3b 19 13 62 58   y...*t..~.M;..bX
|   2464: 78 25 ca 21 c3 10 1e 96 34 82 37 6b 08 b5 9b f6   x%.!....4.7k....
|   2480: 7b 87 97 cd bf 64 67 b4 10 f6 84 16 62 74 a5 b0   .....dg.....bt..
|   2496: 1f d4 c7 1d 8c 2d b5 10 36 5b fb 06 80 fe 97 59   .....-..6[.....Y
|   2512: b6 5a 08 0f 1e ff 0f 5f bf 28 46 4b d8 84 6c ad   .Z....._.(FK..l.
|   2528: 05 c0 25 89 a9 cd 6a be a3 59 84 f0 17 1c 37 8a   ..%...j..Y....7.
|   2544: 8d 09 17 bf 7d fe 47 b4 d6 d6 56 1f d8 04 66 59   ......G...V...fY
|   2560: 2c c4 b4 91 a9 ff da 4a 9c b1 29 ff 92 db 6f 19   ,......J..)...o.
|   2576: ef eb 99 ba 6e 65 2f 6a 7f 1a cf ad a3 96 8c 1d   ....ne/j........
|   2592: 62 86 42 3e a3 64 fc e0 40 4c 7c 60 77 b5 42 68   b.B>.d..@L|`w.Bh
|   2608: 3f 09 37 68 02 75 2c 22 83 d5 04 17 eb a7 e2 71   ?.7h.u,........q
|   2624: 29 36 b7 1b c5 1f 11 ce 8d 91 5a 25 39 50 16 2b   )6........Z%9P.+
|   2640: 60 29 50 9f 17 55 b0 9b a5 92 92 f8 1b e3 9c a3   `)P..U..........
|   2656: e2 a4 cd 90 1e 21 ac 30 ac 35 de 25 30 88 6c 2c   .....!.0.5.%0.l,
|   2672: 79 ea b5 0d 58 a5 37 2b ac af 7d 1f af 32 ca 58   y...X.7+.....2.X
|   2688: 27 17 68 f2 a3 ca a6 cc b2 be 12 c1 a0 43 1e 7d   '.h..........C..
|   2704: 11 ec 8e 23 22 0a ca cd 70 d1 05 fd c0 68 92 e9   ...#....p....h..
|   2720: 1c 55 85 48 10 37 7c 02 69 bf 3f 86 cf d6 40 38   .U.H.7|.i.?...@8
|   2736: a3 9c 83 40 b8 4b 83 51 50 0d d2 b9 c3 32 09 f8   ...@.K.QP....2..
|   2752: bc 7b 9b b8 d7 2e 4f a0 96 48 a7 5a 1b c9 71 fb   ......O..H.Z..q.
|   2768: f4 2b ff 05 54 89 26 b9 6f 25 4a b9 e2 2b e8 86   .+..T.&.o%J..+..
|   2784: 43 22 f6 20 28 a9 39 d9 09 a2 dc 60 14 09 d6 0d   C.. (.9....`....
|   2800: 61 7c 15 5a 8f 3f cc 00 12 f5 e0 45 fe 14 1a cc   a|.Z.?.....E....
|   2816: 98 c4 de 48 75 12 02 2b 79 a1 4a 33 a5 7c 3d cd   ...Hu..+y.J3.|=.
|   2832: b0 5c dd 77 15 5f d9 24 b7 6b 62 80 cb 35 5c e6   ...w._.$.kb..5..
|   2848: a6 57 2e e9 00 9e 20 a9 c6 f0 63 a2 0e eb 9d f3   .W.... ...c.....
|   2864: bb 2c 56 03 68 35 53 5a fb 4f 44 8e 0f a4 9c 9a   .,V.h5SZ.OD.....
|   2880: 0d b7 2c a9 03 14 8c 51 23 21 fb fd 46 07 68 a7   ..,....Q#!..F.h.
|   2896: f3 09 25 e4 98 55 24 da 72 ee 50 00 95 04 7c 74   ..%..U$.r.P...|t
|   2912: d0 07 8b 92 f9 27 11 3e 41 b4 3e 6c aa 56 ed 54   .....'.>A.>l.V.T
|   2928: e3 40 4d 67 8b 7b 63 cd 62 37 ec e2 1b b4 f9 eb   .@Mg..c.b7......
|   2944: ca c7 6e 8a d3 7e f5 e9 e1 33 84 31 05 cb f8 e4   ..n..~...3.1....
|   2960: 02 76 c2 2c b9 00 32 5f be b5 f1 c8 78 e8 cf 22   .v.,..2_....x...
|   2976: 65 d8 2b 43 2c 2e 5d fb 2e 58 92 d2 3e 9b 7e 67   e.+C,.]..X..>.~g
|   2992: a7 3b 59 18 84 5d 61 92 ec 57 97 b6 bd e3 7b f2   .;Y..]a..W......
|   3008: ff 3b 9f 48 39 ad 10 81 51 85 7c 6b 5c b0 53 10   .;.H9...Q.|k..S.
|   3024: 60 9b 4e 0d 86 c0 31 b9 a1 95 05 f4 54 13 52 6a   `.N...1.....T.Rj
|   3040: 96 50 1b e5 f5 54 98 63 8f 07 28 cf b4 ba 9c 3b   .P...T.c..(....;
|   3056: dd 85 3c a6 15 a6 31 f6 aa 1c 3b 31 3e d9 6e c3   ..<...1...;1>.n.
|   3072: 09 74 b9 8e 59 a1 50 10 e0 f0 48 a9 f1 dd a1 ab   .t..Y.P...H.....
|   3088: b6 fc 53 9f bb 38 69 78 07 50 8c 77 cb d1 89 e2   ..S..8ix.P.w....
|   3104: cb b9 51 dc c7 2e 8a 56 47 14 67 80 eb 7a 16 f8   ..Q....VG.g..z..
|   3120: 87 89 58 d1 55 58 c5 bd 62 24 4d ef 46 9f 68 94   ..X.UX..b$M.F.h.
|   3136: 61 9a 08 81 dd dd f1 51 c6 40 63 9b a1 3c 3e 5a   a......Q.@c..<>Z
|   3152: 78 b2 10 7c a2 47 45 57 ef 98 85 82 7e 21 3b 77   x..|.GEW....~!;w
|   3168: 1e d2 fd 0d bf a5 41 6f f5 ee 4c ed 82 f3 15 ea   ......Ao..L.....
|   3184: 2e 57 5e 78 7c 22 2e a4 a6 9c 3f 50 e9 4b 02 11   .W^x|.....?P.K..
|   3200: a0 7c 5a 19 82 9b 34 13 39 32 07 f1 46 4c ad fa   .|Z...4.92..FL..
|   3216: a7 5a fa 22 5c 84 4d 8d 07 1f 17 1f 1a 49 5f fa   .Z....M......I_.
|   3232: df 22 56 ac ce 27 4d 00 a9 b0 c0 77 d8 10 56 cb   ..V..'M....w..V.
|   3248: 76 e0 c8 4a 8a d1 37 c1 cc b8 74 d3 e9 61 1b 0c   v..J..7...t..a..
|   3264: 81 7b be 3d e3 17 43 75 5c ba 6f 61 74 d4 a4 e9   ...=..Cu..oat...
|   3280: d7 0f 2f d2 bc 7d 0b 6e 32 ae fc 20 db 08 39 b5   ../....n2.. ..9.
|   3296: 8f 78 1f d6 4e 84 46 05 a3 a1 15 e8 9d 36 b1 96   .x..N.F......6..
|   3312: 3e e3 12 1b 72 28 28 e8 a5 0f e1 16 a2 31 22 48   >...r((......1.H
|   3328: 4b 77 c6 e5 3f b8 f5 bb 29 13 e1 c1 da 79 81 72   Kw..?...)....y.r
|   3344: fa 12 ab 62 da 63 ac 95 2a 1b 4a a4 4f 96 95 c0   ...b.c..*.J.O...
|   3360: 30 38 3b af 2d c5 cd aa 56 ef e4 35 1d 97 9c 3f   08;.-...V..5...?
|   3376: 57 30 2a 7a 1a 0f 4d 9e be 82 a6 fc 5e a7 9d 0d   W0*z..M.....^...
|   3392: a8 11 12 39 b5 e7 5f 8d 18 1d bb a0 2b 02 10 d3   ...9.._.....+...
|   3408: 08 3a 47 de a1 93 f3 7b b7 07 21 c2 62 22 f2 b3   .:G.......!.b...
|   3424: dd 67 9c 8c 87 59 7d 87 75 46 0c 85 64 f3 09 7f   .g...Y..uF..d...
|   3440: e2 7f ee ca c8 d2 2e 96 14 50 30 89 86 f6 ed 07   .........P0.....
|   3456: ee 9d 78 0c 84 c8 80 ee 2f d4 59 22 12 92 e9 80   ..x...../.Y.....
|   3472: 04 f5 ed aa 7a f5 cd 53 d7 de 45 a5 c3 e1 4e 9d   ....z..S..E...N.
|   3488: fb 78 98 4d cb 5b 0b bf 1b 6a bc 50 ba 45 e5 ff   .x.M.[...j.P.E..
|   3504: d7 d0 7b 39 3d 5b eb 92 46 7f bb 21 7f 81 8b da   ...9=[..F..!....
|   3520: e7 c1 e2 12 41 82 19 7a bd 78 de bc e0 51 cf a7   ....A..z.x...Q..
|   3536: 0e 20 0b 74 cb c8 fe e9 26 64 6e c4 e1 cc 3f b8   . .t....&dn...?.
|   3552: 62 a1 9b 79 bd 9f 05 21 b1 d6 93 66 6f 38 e5 df   b..y...!...fo8..
|   3568: 56 0c 57 c3 3b 57 04 79 f7 f4 b5 20 16 65 18 dc   V.W.;W.y... .e..
|   3584: a8 88 ce 1c bd 7f 40 c8 05 46 17 d7 99 a7 8e 07   ......@..F......
|   3600: b7 02 2f 8c a6 49 5a 1f ce 63 3a 66 31 c2 3b 78   ../..IZ..c:f1.;x
|   3616: 84 00 80 8e 81 43 07 3a 43 ef e4 df 33 4b 18 33   .....C.:C...3K.3
|   3632: 45 27 cc 2e e8 cf e8 be 1a 90 97 ed 99 9b b2 6f   E'.............o
|   3648: 65 ff 53 ad df f8 58 47 d9 5d 71 6a 38 e4 e8 17   e.S...XG.]qj8...
|   3664: e1 1d 4c 03 cc c1 33 18 96 3e 9c 11 98 55 8e 62   ..L...3..>...U.b
|   3680: 1a af a0 33 36 f7 0c 87 0a 0c f0 43 ff e4 71 19   ...36......C..q.
|   3696: 5a 38 f8 9d 9a 53 d4 48 ff e3 40 89 e2 18 d5 3c   Z8...S.H..@....<
|   3712: fb 2c 67 2c b9 f3 e5 d7 5c 97 e9 8f fb 3e 3e a2   .,g,.........>>.
|   3728: 22 63 47 fb d0 65 ed 87 b0 93 e4 28 e5 85 87 68   .cG..e.....(...h
|   3744: fc 0b 64 4c 5b 3c 5f 9f 40 96 d7 34 5b cb d0 a9   ..dL[<_.@..4[...
|   3760: 63 f5 f7 80 f4 67 49 1d 20 0d 84 f9 39 85 28 8b   c....gI. ...9.(.
|   3776: 78 52 fc 86 fb f8 33 cd d6 ef ef ca 32 51 98 2c   xR....3.....2Q.,
|   3792: 54 d4 2e b9 78 0c 2a 5e c0 e6 2c 58 83 60 85 ea   T...x.*^..,X.`..
|   3808: 0b 33 de 33 40 a4 05 80 0d 21 b5 0e 4f 87 a1 a2   .3.3@....!..O...
|   3824: 3a 20 d6 ee 63 7a 31 93 5c 64 f4 f4 57 43 8a 65   : ..cz1..d..WC.e
|   3840: 53 e0 6e 84 c0 ee f6 44 ce 46 ea 97 fc af ec 4b   S.n....D.F.....K
|   3856: ff af da 33 b8 69 e5 08 bd 36 17 aa be 1b 99 5f   ...3.i...6....._
|   3872: 80 c2 8c 27 56 1c f4 99 fa c3 1c 54 01 b7 3e 96   ...'V......T..>.
|   3888: 67 b7 f0 31 f7 20 63 51 17 61 f1 b7 06 23 24 35   g..1. cQ.a...#$5
|   3904: f3 84 c9 01 ec 59 ba 00 83 b8 6c f9 4b 94 01 53   .....Y....l.K..S
|   3920: d4 06 ef b7 a9 08 3c 29 7d ab 8a 88 12 e2 3f a6   ......<)......?.
|   3936: a1 27 be 2e 09 aa d4 15 bc 43 2a 10 ff 2a 2d 89   .'.......C*..*-.
|   3952: fd a0 73 e7 91 14 a3 e2 2c 00 e8 c8 a7 bf 7c c3   ..s.....,.....|.
|   3968: 4c a0 89 bb 70 da 99 1a 39 5f 81 77 af 17 8d af   L...p...9_.w....
|   3984: e8 b0 e0 27 fb f0 b2 39 45 4a 82 97 93 00 a5 54   ...'...9EJ.....T
|   4000: 44 07 b7 1d ce 52 5f bd cd 07 6f ba 6f 8d 6d d7   D....R_...o.o.m.
|   4016: 2b 4f f5 4b 7b 23 45 74 d9 d8 aa e0 15 14 f6 be   +O.K.#Et........
|   4032: 74 f2 b8 38 f9 ba 64 58 93 b2 b6 0c e7 62 10 81   t..8..dX.....b..
|   4048: ad ce 6f 23 0e cd 1c 3c 1e 30 62 64 95 d6 48 55   ..o#...<.0bd..HU
|   4064: fc 63 67 73 85 40 16 2b ab 0b 96 c4 90 8e ea 04   .cgs.@.+........
|   4080: 64 13 bb 60 63 d8 6c d3 73 ed a9 10 03 bf 20 04   d..`c.l.s..... .
| page 11 offset 40960
|      0: 0d 00 00 00 01 04 3f 00 04 3f 00 00 00 00 00 00   ......?..?......
|   1072: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97   ................
|   1088: 3e 03 06 00 ae 7c 00 00 68 95 7f 98 0f 98 e0 e6   >....|..h.......
|   1104: fd 92 02 0f 0f 29 aa bd bc 40 56 6c 5e fa 3f 54   .....)...@Vl^.?T
|   1120: 10 24 70 48 b1 c5 fe e5 0b 21 21 65 1e a4 f1 2a   .$pH.....!!e...*
|   1136: fa 3e 9a a1 b8 67 92 ab cd 27 a2 0f f3 b1 77 9b   .>...g...'....w.
|   1152: 97 e6 c0 f2 c4 db a4 5c d8 f1 01 bd 3c f4 fd 0f   ............<...
|   1168: 00 ca 6d 75 11 fd 56 e2 12 96 e1 f7 18 99 f3 78   ..mu..V........x
|   1184: 9b b7 ef 8c 50 1f dc c5 fa f5 92 fb 91 70 cc d3   ....P........p..
|   1200: ca 0a c6 9b 42 d4 2f cc ce 98 48 a6 ab cd d1 d8   ....B./...H.....
|   1216: 4c 8a 98 2f 2d dc 48 d9 84 52 8f 86 57 04 b8 14   L../-.H..R..W...
|   1232: ec 33 d4 5e 69 da c5 45 8e 2c 4f d6 fc a3 ee f1   .3.^i..E.,O.....
|   1248: 7c 47 c1 5c 8d 48 1b c2 be f1 ca b8 f4 91 d8 bd   |G...H..........
|   1264: d6 41 f6 40 ee 41 90 51 14 09 a8 c5 cf 38 16 21   .A.@.A.Q.....8.!
|   1280: b5 84 48 6c 8e eb e7 b0 62 69 dd 04 c4 4a 75 f6   ..Hl....bi...Ju.
|   1296: 6f 92 af 16 33 94 81 eb 26 00 9f dd d4 01 73 32   o...3...&.....s2
|   1312: ec ee 9d 23 bf 82 8f e0 c8 eb 8f aa 4f 69 4b 68   ...#........OiKh
|   1328: a8 4e 3d 6e d8 2c 99 49 fb 96 d1 77 f6 a0 c3 97   .N=n.,.I...w....
|   1344: 7e c6 7d ff 90 fc 12 97 e7 71 7b 20 ea dd ba 47   ~........q. ...G
|   1360: 3f bc bf 89 2e 26 82 91 71 97 6c 5e 2e ba 8d b9   ?....&..q.l^....
|   1376: c6 ff 51 b3 17 7d e6 ca 99 75 53 73 99 9f 5a b8   ..Q......uSs..Z.
|   1392: 11 db 5a fb b3 73 55 bd 61 0c 2c e5 03 b2 d5 1c   ..Z..sU.a.,.....
|   1408: ce ea ef b4 2e 2c dd d4 55 df cc 7b 13 c9 ba 87   .....,..U.......
|   1424: 25 38 2d d7 fc 7b 47 c1 da 56 42 fe 50 8e 12 a8   %8-...G..VB.P...
|   1440: fd 9d 90 e3 ae e1 f2 5d fa 1e c5 e2 d9 74 b9 55   .......].....t.U
|   1456: d0 5b 90 1d 31 f0 fb 36 d6 e5 df 91 72 4b 69 41   .[..1..6....rKiA
|   1472: 06 33 4e 77 cc 1c a7 d1 3e 49 7f 76 8d d3 73 88   .3Nw....>I.v..s.
|   1488: 27 53 13 95 87 9a 99 cc b2 54 46 34 7f 96 98 1e   'S.......TF4....
|   1504: fb 60 06 85 93 37 0a 90 30 4b 8a ca 7f e8 a6 6a   .`...7..0K.....j
|   1520: a1 94 da ac 1f 47 80 1a 81 8f dd 19 9d 70 88 73   .....G.......p.s
|   1536: b7 4c 22 f7 fe 8b c1 05 5a ea e0 20 5d 01 55 c4   .L......Z.. ].U.
|   1552: 7c 3d 99 f7 8a 1a 15 23 1a a6 5a 02 52 35 2f 14   |=.....#..Z.R5/.
|   1568: ea 01 d4 2b 97 3f 7c e3 4f 7b 58 ea 83 2f 1f 03   ...+.?|.O.X../..
|   1584: c3 64 4f e8 81 f2 ec 19 92 5f c7 b1 27 5a 74 12   .dO......_..'Zt.
|   1600: fd f3 d1 48 0c eb fd 57 9d 28 1e 44 28 3d 69 aa   ...H...W.(.D(=i.
|   1616: 94 66 23 55 11 3b 01 52 76 0b 3b e0 fe 67 e0 fe   .f#U.;.Rv.;..g..
|   1632: f1 e5 18 2b 19 ec 22 a0 33 94 e2 33 3f 59 fc 04   ...+....3..3?Y..
|   1648: 15 c3 ee a0 f8 18 7d 07 39 04 04 e5 df ee 0c 38   ........9......8
|   1664: 31 94 76 b0 ec 42 89 fe 3a d9 d2 1a 4d ee b0 67   1.v..B..:...M..g
|   1680: 10 f4 e6 d1 dd 96 9c d8 ec 10 f0 4b 8c 02 37 54   ...........K..7T
|   1696: 5b b8 e6 d6 d2 d3 ad cd cc 84 02 bd 1f bf 36 de   [.............6.
|   1712: fe d3 8f 68 94 5d c7 19 18 d0 91 e5 be c2 e6 40   ...h.].........@
|   1728: b6 21 ec 29 08 49 08 96 97 a1 14 3a 32 cb 0b 24   .!.).I.....:2..$
|   1744: d4 8c 77 f9 f8 4b 78 8c cf de 90 27 b8 a1 5b dd   ..w..Kx....'..[.
|   1760: 84 c5 88 21 39 fe 1e 88 c0 1c 9b d7 46 44 4f a7   ...!9.......FDO.
|   1776: 13 49 c0 49 d6 c4 c2 06 ab 24 9b 8d 80 83 32 32   .I.I.....$....22
|   1792: b0 ff e5 47 db 08 c0 17 c5 98 67 12 fa 2f 86 39   ...G......g../.9
|   1808: a5 f6 13 03 4d 25 af dc 2c 52 e2 5e f0 36 b3 a2   ....M%..,R.^.6..
|   1824: 13 5b d4 47 14 5e 26 66 f5 a8 48 b3 1a 9e c5 03   .[.G.^&f..H.....
|   1840: 39 66 f3 34 fc c2 ff a8 0f a5 66 a7 7a 6b ad dc   9f.4......f.zk..
|   1856: 77 e2 c7 fb 10 c6 fe a6 2a 64 fc e3 84 8c 12 0e   w.......*d......
|   1872: 5d 96 80 c8 d2 0d d9 e4 f1 bd 96 51 a0 ad a2 cb   ]..........Q....
|   1888: 99 d9 13 4b de c3 f6 ab 20 d8 ad 61 23 fd be 39   ...K.... ..a#..9
|   1904: 97 0b 90 22 49 08 e2 38 3e 43 e6 91 9a ef e5 d7   ....I..8>C......
|   1920: 9e d3 ff 82 51 99 6d 12 f5 74 0d 84 6e f8 ed 63   ....Q.m..t..n..c
|   1936: b8 ff 4d dd ea ae a3 0c 55 13 a1 03 4c 8b 3f 0e   ..M.....U...L.?.
|   1952: 54 b7 02 3e 01 5a 77 ad 6f fc 92 bd b3 6f 3e 89   T..>.Zw.o....o>.
|   1968: 8e fe e1 2e 1c d4 56 c8 5f 4c 57 73 99 95 d6 be   ......V._LWs....
|   1984: f8 f5 17 22 5f 3f 13 5d 98 c9 b5 74 b2 17 7c c8   ...._?.]...t..|.
|   2000: dd d0 a8 d1 fa da 22 5a e8 34 f9 83 93 1b 7f e7   .......Z.4......
|   2016: ba 48 ab e4 cd 3d 54 ec a2 9b 4b ca cf 84 0a d3   .H...=T...K.....
|   2032: 4d 8c bc 0d 73 1a 29 05 0c 60 0a 4a 6e 54 d3 0f   M...s.)..`.JnT..
|   2048: 84 00 df c0 f3 0b 73 2b 3b f0 60 68 91 ae cd 60   ......s+;.`h...`
|   2064: 59 0b ee b7 dc 7c eb b1 cc 70 f3 bb 6a 27 3b bb   Y....|...p..j';.
|   2080: 20 41 3c 84 9d 3d 06 94 0c 53 eb 9c 31 e3 8a a0    A<..=...S..1...
|   2096: 1e c1 65 ef a6 78 92 ae 2e f9 64 49 58 b7 c0 23   ..e..x....dIX..#
|   2112: 2b 4c ab 93 2c 78 c2 86 32 09 d0 8e bf 34 b4 9e   +L..,x..2....4..
|   2128: 59 5c 6f 69 bb 85 5d a6 02 b2 01 85 89 23 40 7f   Y.oi..]......#@.
|   2144: 23 3f c7 67 da 35 cf 2e d0 36 1e 71 fa 78 da c5   #?.g.5...6.q.x..
|   2160: 41 db 9a 14 b1 48 d4 02 36 2f ed 6a 85 4a f4 f6   A....H..6/.j.J..
|   2176: f4 3f 46 81 2d fa 92 47 21 16 14 84 f8 c9 18 86   .?F.-..G!.......
|   2192: 74 45 16 8d b3 cd 58 93 40 62 9b 24 6b af d3 44   tE....X.@b.$k..D
|   2208: 67 f9 0a 7f e5 25 01 b9 76 3f 8e 4d 82 b8 04 ae   g....%..v?.M....
|   2224: ef ed 12 c3 9f c6 a9 54 03 8a 78 0d f4 7e bf 7d   .......T..x..~..
|   2240: c1 f5 be 24 33 54 77 e3 7f c4 c9 fd 5c 79 6d 54   ...$3Tw......ymT
|   2256: 67 2f 83 a3 04 8b 16 09 71 ff 47 67 14 6a 84 71   g/......q.Gg.j.q
|   2272: 39 54 18 0b 7d 7e ac ef 62 0f 4b dd 9c d0 0d 20   9T...~..b.K.... 
|   2288: 9e 62 98 79 11 53 de 73 a9 9d 44 5e f5 5a 23 62   .b.y.S.s..D^.Z#b
|   2304: 08 01 fb de 39 57 24 ac c6 b5 5f e2 6b 07 18 2e   ....9W$..._.k...
|   2320: 27 24 42 96 d8 31 68 d3 0e bb 65 9c 01 f8 93 ba   '$B..1h...e.....
|   2336: 4a 2a 60 3a b3 c2 9c 17 66 1d 34 4c 0f 90 38 5e   J*`:....f.4L..8^
|   2352: a4 9c 72 9c 16 d7 c4 98 33 ed c1 95 a2 d7 cc a1   ..r.....3.......
|   2368: 3b 36 28 1c 44 1c 8f c9 f7 bc eb ed 5a d3 2d 69   ;6(.D.......Z.-i
|   2384: 6f 86 9a 2f 15 91 aa 63 0d 19 f9 bb 07 6b 87 f5   o../...c.....k..
|   2400: 0a 48 7e db b6 9a c3 97 01 d1 91 44 37 7c ce 5c   .H~........D7|..
|   2416: 63 43 c0 92 20 31 b4 5c 36 98 01 50 05 ec 1d ac   cC.. 1..6..P....
|   2432: 73 10 66 97 48 60 c2 2b 46 3e 2b fc 52 1d 42 87   s.f.H`.+F>+.R.B.
|   2448: d3 af 2c 42 7f c4 a2 0b 2b d6 09 64 0a f9 9d f5   ..,B....+..d....
|   2464: 54 b8 1d 96 23 1f 22 0e 56 de dc 0a f8 97 55 41   T...#...V.....UA
|   2480: 56 ff 72 20 73 2b 50 fe 0d 79 c2 d3 61 73 22 da   V.r s+P..y..as..
|   2496: 68 8e 77 23 19 ca f9 7c a6 9c 91 27 ed eb f8 9c   h.w#...|...'....
|   2512: b6 bb 72 dc 3a 62 23 17 fb 04 98 bb ce 1a fb 1f   ..r.:b#.........
|   2528: 17 ab aa 46 46 5a 8b 98 c6 7e 0e 18 74 8a 62 9e   ...FFZ...~..t.b.
|   2544: 1f 7f f4 dd 8c 1d 68 8d 54 3d 0c 06 95 f9 9f 06   ......h.T=......
|   2560: 3f 97 71 00 21 d5 e9 c0 44 7b 98 27 16 ba d2 fa   ?.q.!...D..'....
|   2576: c2 33 1d 4a 34 ec ae 4d a7 6c 68 77 9b f6 7b 2c   .3.J4..M.lhw...,
|   2592: 6e d3 f6 1b b6 35 6f 47 69 be 5f 96 66 13 c3 8e   n....5oGi._.f...
|   2608: 2f f1 4a 5e cb 26 00 73 33 a9 05 12 7b 6d 5b 96   /.J^.&.s3....m[.
|   2624: b7 3d 7e bc 62 aa c7 fe d2 fb 11 d5 7c a3 bf 90   .=~.b.......|...
|   2640: 09 fa ba 2b 2e 8d 65 c6 3f 21 41 fa 3d 71 f8 8d   ...+..e.?!A.=q..
|   2656: e5 77 34 b2 ea 4d 28 d1 48 fc 4c 1f 2e db 9c 58   .w4..M(.H.L....X
|   2672: b1 04 54 ce 4b 68 a3 7b b6 28 16 19 22 d7 fe d3   ..T.Kh...(......
|   2688: f9 88 dd ca f6 26 43 88 28 bb 0f 62 3b d5 d4 cf   .....&C.(..b;...
|   2704: af 90 27 ca 8e 40 62 f6 50 a8 2b 23 d4 3e 6d 32   ..'..@b.P.+#.>m2
|   2720: e0 62 79 28 29 ab fe 77 21 ad 98 62 11 8a d2 90   .by()..w!..b....
|   2736: 9a 83 73 c5 44 45 cb dd 71 7e 45 b7 79 d8 ab 3f   ..s.DE..q~E.y..?
|   2752: ea 53 89 0b 8c 18 b3 95 1b 45 d5 dd 45 5b 79 b0   .S.......E..E[y.
|   2768: e8 c2 a9 58 77 cf c2 5b 43 a2 81 0e 43 9c c2 6d   ...Xw..[C...C..m
|   2784: 5b a3 7a ef ed e1 24 56 54 a4 e1 ef 07 e7 9b 0e   [.z...$VT.......
|   2800: 1f 32 78 3d a4 0f c2 52 ee 7d 4e 4d 80 4d ff 00   .2x=...R..NM.M..
|   2816: 6c 8f da b7 ff aa fd a6 05 c1 31 e1 03 5c a4 e1   l.........1.....
|   2832: 92 39 d9 be 7a 16 9a c2 4b c7 01 eb ef 54 f8 2a   .9..z...K....T.*
|   2848: 60 82 bb f6 4c 86 d5 8b 23 ce 88 52 a5 35 a7 ba   `...L...#..R.5..
|   2864: b6 31 e5 ec fe 30 f9 06 98 e7 bd eb 83 08 33 e5   .1...0........3.
|   2880: c5 a2 12 68 ca cb 97 77 db 60 94 4a 43 fb c1 04   ...h...w.`.JC...
|   2896: f1 8d 16 af 2e 8d bf 61 2a ff b5 4b 80 65 8a 07   .......a*..K.e..
|   2912: 91 17 7f b7 ee c0 57 ce 40 82 c7 c8 57 89 62 61   ......W.@...W.ba
|   2928: b8 63 fe eb c2 97 30 ed 71 84 23 b3 48 e9 d9 ba   .c....0.q.#.H...
|   2944: 71 c3 66 f5 6a 66 5a ee e6 bf 72 fe 80 a1 40 24   q.f.jfZ...r...@$
|   2960: 75 0e 01 f9 1d 18 c3 fd 73 1c 21 92 5c 2b 07 a0   u.......s.!..+..
|   2976: 83 80 5c 0f 20 fe e9 55 d6 f4 4c 96 d8 ab 7a 5c   .... ..U..L...z.
|   2992: d6 d1 1e 44 60 ee 0a 30 7e 92 cf af a3 41 20 d5   ...D`..0~....A .
|   3008: 0b de fb 9c f4 81 76 5c d6 58 5d 86 1e 14 10 c5   ......v..X].....
|   3024: 12 b5 f1 2d 73 09 0b ad 33 2c 49 5f 59 a7 08 80   ...-s...3,I_Y...
|   3040: 30 bf 50 61 b4 0b b2 3c 53 f3 de 2f e0 87 59 58   0.Pa...<S../..YX
|   3056: b8 2f 36 56 90 74 35 2b ab c6 b1 e3 7c ae 8f ee   ./6V.t5+....|...
|   3072: 52 41 4a e8 f2 03 26 36 18 6d 04 ff 10 75 df ec   RAJ...&6.m...u..
|   3088: ff c8 fc 2d 1e f1 5f 60 8a 29 44 f2 48 39 eb be   ...-.._`.)D.H9..
|   3104: 75 29 d6 8c fc d4 09 1d 8d 40 5b 6a 52 1e 63 0b   u).......@[jR.c.
|   3120: af a0 f4 5c 05 da 78 cf 7c 4e 54 e7 c6 b3 b2 f9   ......x.|NT.....
|   3136: b8 ef 06 47 4b ea 4f c1 d5 ab 09 e4 cc 2d 18 94   ...GK.O......-..
|   3152: 0b 1e 48 96 4e ae d0 3c af 24 31 6e 07 a0 5a 56   ..H.N..<.$1n..ZV
|   3168: 4c d4 c6 10 b2 da 6b f2 47 5b 7e e8 e2 ed e2 c6   L.....k.G[~.....
|   3184: 7b 8d 6b 39 ce 6f 1b 3e 4d 43 be c9 12 f1 75 a4   ..k9.o.>MC....u.
|   3200: 36 53 ad 19 cc d1 3c 57 45 64 fc e4 19 89 42 81   6S....<WEd....B.
|   3216: ee 16 a7 5d 6a 36 64 ba 8e c3 ca e7 3f 29 94 27   ...]j6d.....?).'
|   3232: 23 7c a6 da 5d 0b 54 21 7f 2f 1c a6 6a 29 c0 99   #|..].T!./..j)..
|   3248: 7d fa fc cb 67 43 75 e5 7b 22 b6 e0 5d b6 73 9a   ....gCu.....].s.
|   3264: db e9 36 6a fa 27 51 64 50 8b e5 fd 8c 6b 5a 51   ..6j.'QdP....kZQ
|   3280: 4b e0 ac 57 f6 97 db 4d 94 25 95 b5 f8 83 de 8f   K..W...M.%......
|   3296: f9 28 80 06 d6 a5 ad dd 2f 2f 70 bf ff 73 1b 51   .(......//p..s.Q
|   3312: c7 3c 5e 4c 53 7e 46 58 1d 1b 38 88 0f 7d 48 25   .<^LS~FX..8...H%
|   3328: ca e4 6f c9 d9 60 60 98 e8 bc 31 bb b3 b1 01 e9   ..o..``...1.....
|   3344: a8 0a 2f 23 cc 53 40 9a 27 00 65 19 6f 02 8b fa   ../#.S@.'.e.o...
|   3360: 6c b7 8e af cd 67 54 58 a8 77 4e 79 48 31 25 f4   l....gTX.wNyH1%.
|   3376: a2 76 16 18 ec 1a 98 f8 8e 03 f6 41 25 ef 8a 55   .v.........A%..U
|   3392: 6a 5b 97 d7 bd e4 98 a5 6c c9 2f ca 5f b5 67 9a   j[......l./._.g.
|   3408: 35 c5 f1 98 56 4e d9 a0 3e 13 e6 e3 22 02 e0 b4   5...VN..>.......
|   3424: 65 16 ad c6 c4 a3 75 78 94 b2 ce b5 9c 50 df 02   e.....ux.....P..
|   3440: f3 c2 91 11 5a 81 de eb 31 24 16 50 16 d8 5f c5   ....Z...1$.P.._.
|   3456: df 62 1b 24 37 bb cd 5d a8 a7 93 d0 6a 5e d8 55   .b.$7..]....j^.U
|   3472: 74 cf 69 a2 4a 05 07 2e 61 09 0e fa 1e 12 ab 62   t.i.J...a......b
|   3488: d9 ca ff ab 2b b0 3b 16 16 b0 95 15 27 26 89 46   ....+.;.....'&.F
|   3504: d3 67 fb 0f 33 00 18 44 c3 a1 92 de 6e 6d b0 67   .g..3..D....nm.g
|   3520: b0 65 97 fa b9 10 1d 39 15 10 95 f1 b3 cc a3 d4   .e.....9........
|   3536: 28 06 9f b7 00 be a1 06 8f 61 34 66 92 fa 58 0b   (........a4f..X.
|   3552: 4f 91 6d 93 31 32 cb a1 97 a5 18 b2 f1 bc fc 70   O.m.12.........p
|   3568: c0 86 62 24 4b 82 ce b3 71 30 53 ac 42 c7 32 2d   ..b$K...q0S.B.2-
|   3584: 3a 0e 3f 8a 91 89 0b 46 55 f3 5d 73 b1 74 a2 9e   :.?....FU.]s.t..
|   3600: 97 6e 85 b6 f0 3e 56 6d 31 50 96 87 3d 18 cf 5f   .n...>Vm1P..=.._
|   3616: 74 57 1a 65 b4 d2 4e 96 1c 6e 3f 5b a9 a0 47 2d   tW.e..N..n?[..G-
|   3632: 22 5b 16 ab 27 f4 86 36 f7 8e a1 f2 9c 69 7f 0c   .[..'..6.....i..
|   3648: 85 4d 3c 08 3b fa 96 ee 92 af f9 8d c2 ca a9 f1   .M<.;...........
|   3664: 2b fa 90 4b a3 fb 35 c4 c6 05 c3 0f ad 5e bb f6   +..K..5......^..
|   3680: 55 66 73 bd db 98 2f 70 7d 25 3f 05 3d 24 c6 0d   Ufs.../p.%?.=$..
|   3696: 8a e2 e1 3e 19 59 51 25 a9 e8 4a 0a 68 69 05 c9   ...>.YQ%..J.hi..
|   3712: ce 1e 5f 96 c4 a1 98 2a 7b b9 e9 99 ce 84 af 0b   .._....*........
|   3728: 82 61 5b 97 b1 8c 2e ea 81 98 44 39 79 e0 d5 9c   .a[.......D9y...
|   3744: 6a b9 14 0f 36 98 ea c8 cd 6b 66 fa d1 23 cf cb   j...6....kf..#..
|   3760: c6 1b 25 6c 42 13 b2 67 f9 68 0a 62 ff 37 ab ca   ..%lB..g.h.b.7..
|   3776: 22 60 77 c1 30 e4 59 5f 17 b4 47 c3 ea c5 c4 2b   .`w.0.Y_..G....+
|   3792: 62 44 94 08 87 03 1a a5 10 ae b1 53 cd 2d 40 5a   bD.........S.-@Z
|   3808: 80 ef dd 56 6b 88 92 d7 3c d0 7a a0 2f 63 22 02   ...Vk...<.z./c..
|   3824: 61 f1 ab 36 f9 16 f0 14 ba 67 7d 9c 7f 90 cc d9   a..6.....g......
|   3840: b1 ac d3 1d 73 1e e8 bf 88 6a 6b 15 32 b3 b5 9c   ....s....jk.2...
|   3856: 4a ad bd 4f f8 f8 b8 b8 2e 48 0f e2 e9 d6 d9 72   J..O.....H.....r
|   3872: 22 9a 28 8d 24 e2 f0 33 23 27 ff 37 5e 36 55 37   ..(.$..3#'.7^6U7
|   3888: e1 92 78 19 a4 9d ff b9 22 e5 47 79 b8 de b4 9f   ..x.......Gy....
|   3904: 4e f0 65 1d 89 5e 55 86 bf 25 ff 6f 7e 27 f2 c1   N.e..^U..%.o~'..
|   3920: 9d 26 69 ab 5b 1a 16 1d a1 b7 0a f0 60 06 12 4b   .&i.[.......`..K
|   3936: ce 6b 17 d3 e7 66 ef 6d 83 10 30 96 49 8b 8d 52   .k...f.m..0.I..R
|   3952: 98 65 b1 48 a8 0d 96 ae 15 cd 00 5b f5 3e 4c f6   .e.H.......[.>L.
|   3968: 16 b3 15 5b cf 3e ba 15 86 7e 9b 92 be cb 8a de   ...[.>...~......
|   3984: d0 de c8 0e ac cb 79 cc 8f ad f6 3a 40 33 9f 91   ......y....:@3..
|   4000: 48 7c 3f d1 33 c1 d3 51 ba 44 47 0e 41 8d fa 2d   H|?.3..Q.DG.A..-
|   4016: 55 99 7f 4d 44 4a 85 dc 6b b1 9f 8a 4c 55 70 b7   U..MDJ..k...LUp.
|   4032: 2d 14 4d 72 ea 76 c8 0c 9f 9c 99 0a c2 7e 95 94   -.Mr.v.......~..
|   4048: 61 84 76 8c 20 1f a3 2d 5f 54 ab 5b 8c fc 04 0d   a.v. ..-_T.[....
|   4064: 25 33 9f d1 f3 f7 38 1d 64 4c c1 0d 38 0e 4d b8   %3....8.dL..8.M.
|   4080: 61 16 f8 ea 3d 01 e9 f7 7b 6d 10 ed 08 07 86 f3   a...=....m......
| page 12 offset 45056
|      0: 0d 00 00 00 01 04 3f 00 04 3f 00 00 00 00 00 00   ......?..?......
|   1072: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97   ................
|   1088: 3e 04 06 00 ae 7c 00 00 72 d0 44 9f 95 5b ad 14   >....|..r.D..[..
|   1104: 76 bf ee ef 64 b3 05 0c b8 3c fa 37 1b ab 5a f0   v...d....<.7..Z.
|   1120: ae 4c 14 79 98 2a 95 49 a0 1e 3e ff 44 91 47 ad   .L.y.*.I..>.D.G.
|   1136: 40 a0 7b 5e 0c 5f 86 45 28 c7 d9 03 81 2b 26 13   @..^._.E(....+&.
|   1152: 0c 38 01 db 73 e2 42 53 3c 8c d1 6c fd 51 a6 5a   .8..s.BS<..l.Q.Z
|   1168: fa 65 81 fc 71 89 ea 74 84 df da ea e0 d8 40 ce   .e..q..t......@.
|   1184: 56 a4 cb 65 0b 6b 79 7c 81 a9 55 79 8c 3e 02 dd   V..e.ky|..Uy.>..
|   1200: 17 7f 47 b6 84 c0 c2 a3 5e 79 66 83 e4 f2 73 6a   ..G.....^yf...sj
|   1216: 46 9f 20 24 f3 4e 2b 6e a9 2c 9b 51 39 96 42 82   F. $.N+n.,.Q9.B.
|   1232: ec c0 c9 78 ec ec 90 e3 57 af fb 1f 51 41 a3 37   ...x....W...QA.7
|   1248: b7 68 5d 84 5e 6a 9e 17 13 e1 87 7d 93 f5 92 8e   .h].^j..........
|   1264: 7a 8d 3b d4 40 35 df 0e 8f 80 13 f3 54 9c 57 a8   z.;.@5......T.W.
|   1280: 86 88 69 32 7d a2 22 13 ab 14 db e6 8a 1c 84 ed   ..i2............
|   1296: 54 4e d3 0a ba 5f 9e 66 88 2a 64 d8 04 86 3c 5e   TN..._.f.*d...<^
|   1312: 41 b7 2d c2 c1 a0 73 61 d8 80 3b 9d 9d 1e 11 ab   A.-...sa..;.....
|   1328: ae 20 63 ac 31 80 2e 66 d5 a7 c8 8e 0a 55 78 53   . c.1..f.....UxS
|   1344: 66 8d 5d 1e cb 04 13 d9 a8 d1 09 4b 31 3c e9 ba   f.]........K1<..
|   1360: 83 69 76 4c 12 e8 95 84 e1 fe c0 64 74 c5 74 8d   .ivL.......dt.t.
|   1376: 1f 75 28 75 1f 51 23 b7 df ef 45 66 61 1b 18 2e   .u(u.Q#...Efa...
|   1392: c8 56 69 8f fa 2a 08 41 21 2d 6a c7 79 46 8f 95   .Vi..*.A!-j.yF..
|   1408: dc b1 b2 d7 39 b9 a6 41 af 06 3e 53 85 c2 db c3   ....9..A..>S....
|   1424: 42 fb b7 4f e9 e0 11 c1 a6 9a 48 fb d6 c9 26 31   B..O......H...&1
|   1440: 3b c4 7a e2 bd 53 d7 3e d7 56 60 8f 6a 80 60 19   ;.z..S.>.V`.j.`.
|   1456: db fd 5a 7a 8c c7 43 c7 29 57 8b 6f 31 ea 13 af   ..Zz..C.)W.o1...
|   1472: de 2e 32 75 5f 63 b7 bb 45 07 9e da 69 54 a0 fd   ..2u_c..E...iT..
|   1488: 0e dc 0d f5 42 17 eb 64 60 0d d8 56 4b 61 6d 8c   ....B..d`..VKam.
|   1504: 82 09 f1 80 a2 25 5d 8b e5 67 76 13 9d 46 4a 6f   .....%]..gv..FJo
|   1520: 30 f6 eb e0 7b 0e 01 e1 a8 b2 38 1b 9b 21 48 ed   0.........8..!H.
|   1536: c8 7f 7d 6b 0c 25 ce a8 0a 78 a8 48 45 2d b5 e7   ...k.%...x.HE-..
|   1552: fd ca b2 a1 2b 2a b9 72 61 76 76 0c ae 9c b3 17   ....+*.ravv.....
|   1568: fa 83 07 24 24 62 18 18 d6 12 2d ad 58 0b b3 5e   ...$$b....-.X..^
|   1584: 80 da 40 b5 d0 e7 aa 28 52 bc 7f 68 7a 1d 5a 1f   ..@....(R..hz.Z.
|   1600: 79 65 10 9e 4d fe be 32 c7 0f aa 7d a5 0a 43 0f   ye..M..2......C.
|   1616: 3d 17 0e 88 a3 7f 3f ff 04 bc 79 56 62 0e 9b a0   =.....?...yVb...
|   1632: 51 1f 49 04 ff 40 7a c2 51 e8 36 44 85 63 df a4   Q.I..@z.Q.6D.c..
|   1648: d5 63 a4 eb a3 71 44 b4 02 51 a1 2b 00 73 69 4e   .c...qD..Q.+.siN
|   1664: 07 76 42 84 bc 87 1a e6 15 13 f7 ac 7a e8 bf c0   .vB.........z...
|   1680: a4 8a 64 fe 9c 17 a7 20 cb 67 cd e6 da f1 95 26   ..d.... .g.....&
|   1696: b6 79 d4 93 e2 52 fd 6f 44 29 db 1e 34 02 46 a4   .y...R.oD)..4.F.
|   1712: f1 c5 f0 b5 c3 19 1d 0e 14 d4 ba 08 1c 01 bf 39   ...............9
|   1728: 54 02 e2 f5 d3 cf fb d1 d6 76 65 91 ba 7b c8 22   T........ve.....
|   1744: 85 f8 fa c7 ae ae 21 85 b9 d2 09 5f f4 3b 27 c5   ......!...._.;'.
|   1760: 13 39 39 7e 79 ae 07 37 26 72 07 22 01 40 2c 10   .99~y..7&r...@,.
|   1776: 5b 2c 9b bf 30 92 2e f5 12 9f 19 f9 2d 69 2a c6   [,..0.......-i*.
|   1792: 9a 26 1b de 18 b8 05 65 a8 b4 b3 3e 2c 04 5b bc   .&.....e...>,.[.
|   1808: 63 79 56 7a ba 24 ae 69 ee d6 d5 7c 3d 5f 2f 7b   cyVz.$.i...|=_/.
|   1824: e9 e5 55 f2 88 58 72 49 89 3e d5 91 be ae ea 9e   ..U..XrI.>......
|   1840: 58 20 45 2c da c7 b8 f9 db 97 68 59 c7 f4 d3 4b   X E,......hY...K
|   1856: 95 b6 c7 73 1c 9b 96 d2 1c 56 17 eb 18 a1 fa 17   ...s.....V......
|   1872: 05 72 44 05 4f c3 2b 8c 89 d2 3c a2 25 d8 16 74   .rD.O.+...<.%..t
|   1888: 48 b7 78 36 7a 86 88 ff cc 47 ac bd 73 28 1f 3f   H.x6z....G..s(.?
|   1904: 13 3d b9 d2 df 9a 93 43 a6 9f b9 fc 7c b2 d4 84   .=.....C....|...
|   1920: c4 7e d0 14 60 01 63 fb 09 de a3 2f 1c ae 2e 6b   .~..`.c..../...k
|   1936: 9f 8d c8 f1 2d f0 c9 a5 1f 48 c1 7c 53 c5 63 8a   ....-....H.|S.c.
|   1952: 9b 0b fd f3 7f 3a 63 eb 2c 4f df 3a 57 8c 20 3e   .....:c.,O.:W. >
|   1968: 0b d1 00 0f ce e3 ab a8 77 31 63 4a aa 35 5f 3f   ........w1cJ.5_?
|   1984: 77 ba d3 38 7b a3 53 94 e6 9d 34 ec 5a 28 09 6e   w..8..S...4.Z(.n
|   2000: 5a 85 bc 72 18 bb 15 8a 20 01 f3 88 19 74 65 1b   Z..r.... ....te.
|   2016: 51 bc 8a 4d 32 a6 00 80 fc 06 f8 aa 1c ee 0e 84   Q..M2...........
|   2032: b5 70 fe 09 02 78 d4 ae 3a bb 02 ed 5a 90 d2 a9   .p...x..:...Z...
|   2048: 3e 58 8a 08 2d 4c 79 7c f2 94 89 ac 04 59 d8 17   >X..-Ly|.....Y..
|   2064: 09 e4 c3 e0 78 6b 77 58 64 4f 2f 77 15 16 c2 41   ....xkwXdO/w...A
|   2080: 96 61 8c 23 59 73 b9 56 c3 4e da 79 34 94 e5 31   .a.#Ys.V.N.y4..1
|   2096: 9b a6 92 ca 23 64 e4 78 32 e2 9d 2e ad 18 11 b7   ....#d.x2.......
|   2112: 12 0d 1b 40 44 4f 92 cf 78 80 86 fb af c9 30 20   ...@DO..x.....0 
|   2128: 52 9b 22 8f f4 ca 65 e5 f2 e7 a3 c3 e7 00 ee a1   R.....e.........
|   2144: ca ab 3d 71 40 bd cf c3 2f 7b 59 e7 9d 18 6a 65   ..=q@.../.Y...je
|   2160: a1 c9 84 cf 0f f5 36 d5 22 06 d4 6a b6 ad 38 03   ......6....j..8.
|   2176: b4 ac 9e c4 7a b0 71 24 a9 01 f0 5c 5b e3 c9 bd   ....z.q$....[...
|   2192: d6 e7 ba 71 fd 44 22 14 af f7 18 ef 29 1d f2 0f   ...q.D......)...
|   2208: 5d e1 3a 71 3b 47 44 da 21 f6 73 8b 6a a1 ff 93   ].:q;GD.!.s.j...
|   2224: d5 eb 5d d0 61 23 41 53 99 7f 23 0f c0 a3 18 3c   ..].a#AS..#....<
|   2240: bd 30 e0 bf 16 41 27 71 80 67 49 61 e9 64 71 e0   .0...A'q.gIa.dq.
|   2256: 9d 42 e6 48 9b 0e 40 82 f9 e2 a5 b4 51 37 7d 6b   .B.H..@.....Q7.k
|   2272: 74 54 03 bb a2 93 ac 47 f8 a5 75 86 73 0f 12 47   tT.....G..u.s..G
|   2288: 27 65 16 16 a2 ab 99 08 14 0b 7e 1b 2c 7e 9d 20   'e........~.,~. 
|   2304: 58 23 14 70 bd f5 7c 2b 74 ce d1 46 b3 29 03 8f   X#.p..|+t..F.)..
|   2320: 76 f3 20 ca 9e a3 fc 1a 17 f2 8e 78 97 4e 0b 5e   v. ........x.N.^
|   2336: 61 2b e1 3d f1 14 ae 9a 1f e8 a8 3c 99 02 a5 c0   a+.=.......<....
|   2352: a6 ee bd 47 a4 3c 6d db 6c 20 dd c4 60 09 17 e7   ...G.<m.l ..`...
|   2368: 65 a4 e6 a3 f5 3f 50 37 6d 45 87 ab a4 67 95 b1   e....?P7mE...g..
|   2384: 47 cb 49 00 c8 37 f5 e2 09 10 c5 5e 09 f0 e6 89   G.I..7.....^....
|   2400: cc db 49 46 51 50 6e 14 63 5f c6 88 13 a2 e3 02   ..IFQPn.c_......
|   2416: 06 21 1d d9 b6 5d 6f 01 90 9a 6c 50 e6 19 72 92   .!...]o...lP..r.
|   2432: a7 c2 84 dd 9c 6a fd 8f 5a 41 da 4f b7 fc 58 13   .....j..ZA.O..X.
|   2448: 63 3e 68 24 5e 30 86 a6 b8 ed 7a fb 9c eb c3 a5   c>h$^0....z.....
|   2464: 89 df 3b c6 e1 09 1d 16 69 40 e9 d7 f7 41 d3 2b   ..;.....i@...A.+
|   2480: 52 6a 9a d9 65 e2 44 de 45 63 be 85 41 b8 d4 4a   Rj..e.D.Ec..A..J
|   2496: 49 b9 b8 bb 4d a6 6e 60 46 13 6f 7f b1 57 9c 5b   I...M.n`F.o..W.[
|   2512: 78 69 87 3d 42 e5 c2 0a 46 9c 38 9d e2 44 80 fe   xi.=B...F.8..D..
|   2528: c8 81 f4 fe bb ef 61 46 88 c7 6f 1a f8 00 0b 63   ......aF..o....c
|   2544: d0 ac 8e 5e 88 8d 2d 56 15 79 d2 12 d9 94 ba 2b   ...^..-V.y.....+
|   2560: ae 71 63 be 62 08 75 b9 97 fc 1e 17 89 83 3b 30   .qc.b.u.......;0
|   2576: 07 6e f0 db 44 17 c0 49 7f ed 0a 0a 43 13 6a 72   .n..D..I....C.jr
|   2592: 78 9c 96 52 2c 02 ac da a0 90 b5 66 34 b7 a2 17   x..R,......f4...
|   2608: e7 71 11 8d 8f 22 0e 40 90 9b 0f 99 f5 10 c0 64   .q.....@.......d
|   2624: ac e3 24 0d 49 1a f4 2f 0b 13 fc 94 a7 18 b1 5f   ..$.I../......._
|   2640: a6 64 49 0b c2 35 99 b6 05 81 bd a8 f8 88 56 83   .dI..5........V.
|   2656: 17 56 cc f8 91 db 5b 18 7c 42 46 3f 3d 9a 2d b6   .V....[.|BF?=.-.
|   2672: 63 8c 62 bf 78 53 a0 23 53 40 c0 32 06 f1 c8 3a   c.b.xS.#S@.2...:
|   2688: f8 17 34 a7 29 1e ab 92 2d 2d 68 c5 83 e0 0a 2e   ..4.)...--h.....
|   2704: 7b f8 9c b7 32 86 c0 1e f5 29 44 a6 24 e1 d7 66   ....2....)D.$..f
|   2720: 0d 48 2b 0e 49 f8 e4 52 4a 7d bd 1c c1 44 27 f0   .H+.I..RJ....D'.
|   2736: c9 db 87 93 13 62 82 ef ad 2c ea 8f d1 3d a4 a6   .....b...,...=..
|   2752: b8 80 87 e2 0e 27 27 b3 3d 56 66 39 de e8 21 5f   .....''.=Vf9..!_
|   2768: 95 25 d9 68 f1 57 50 0e 15 54 0b a6 44 27 e8 d9   .%.h.WP..T..D'..
|   2784: f2 dc 5e 79 f0 ec 2b a3 39 77 8f 3d 53 70 8a d3   ..^y..+.9w.=Sp..
|   2800: e5 aa 14 cb 7b dc 31 72 f6 90 5e 8b 3a 8c f3 77   ......1r..^.:..w
|   2816: 4d 00 a3 1d 3a 63 47 c0 2a a2 32 98 6e 5c bc 21   M...:cG.*.2.n..!
|   2832: f0 6a 34 6c 89 a5 bc 04 f6 3b 8c 96 b0 eb 0d 70   .j4l.....;.....p
|   2848: 9f 18 d5 64 ec 2e df 19 7d 1d a4 61 48 e7 0b eb   ...d.......aH...
|   2864: f3 94 16 f5 7f 4c 9e 0c 78 aa 4b 61 14 13 eb e2   .....L..x.Ka....
|   2880: 72 14 56 27 41 70 8f 7f cb e6 a1 c3 37 c4 78 32   r.V'Ap......7.x2
|   2896: 85 ea e5 af 96 46 4b c3 93 af 8f 26 0c ea 08 b6   .....FK....&....
|   2912: b4 a6 a4 78 6d 82 51 ab fb e5 a9 e9 89 c3 a1 be   ...xm.Q.........
|   2928: 3e b9 e3 8c 61 cf 42 1d de 25 45 9e f0 ff 8b 75   >...a.B..%E....u
|   2944: 63 9b 3d d6 92 c3 ad ca c5 4c 79 9d 72 37 fd 3a   c.=......Ly.r7.:
|   2960: 21 f2 8d 34 37 b9 eb a0 86 d8 1a f2 9d aa 6a 53   !..47.........jS
|   2976: f6 c9 29 d0 39 2c 66 24 c6 8e 68 9c 70 cc 9e cc   ..).9,f$..h.p...
|   2992: 25 a8 dd 5e d8 e6 87 1b dc 3a 26 20 e3 1c 3b ba   %..^.....:& ..;.
|   3008: f8 c4 80 83 79 49 f1 2a f0 e8 70 31 e7 b2 a5 e3   ....yI.*..p1....
|   3024: 9f 5b 49 25 2c 33 b6 ea 38 ab a8 0a 9a a2 0e fd   .[I%,3..8.......
|   3040: 3a a8 9c 0f ab 93 45 a7 54 d2 18 2f 2e 94 34 cc   :.....E.T../..4.
|   3056: fa 14 b6 8e 01 8d af 80 94 e7 80 31 dc 2c b9 1e   ...........1.,..
|   3072: dd 35 91 29 28 a0 29 65 bc e3 a2 52 b0 e5 56 5a   .5.)(.)e...R..VZ
|   3088: 12 21 06 fd f3 04 77 31 6d f2 e0 66 0a a3 77 f3   .!....w1m..f..w.
|   3104: 5a 17 37 59 65 d9 32 68 82 2c 72 05 16 e9 9a 89   Z.7Ye.2h.,r.....
|   3120: 10 94 53 e9 be 63 2e 82 27 28 30 1d 2a bf ad 00   ..S..c..'(0.*...
|   3136: 49 9a a7 e3 50 d0 61 b4 bd 73 3e 99 a3 a7 69 7f   I...P.a..s>...i.
|   3152: a8 4c 4d 12 7f c0 55 b7 de 0c 93 5e 27 cf 4a 53   .LM...U....^'.JS
|   3168: 78 08 ee da 22 37 3f 94 2f dd a6 b2 28 84 0f 62   x....7?./...(..b
|   3184: bc 7f be 3c af ad 84 82 70 b2 98 d5 9a d5 07 34   ...<....p......4
|   3200: 41 6f 9c 0a 17 54 cf fc 43 1e 7c ca 48 6f 23 c5   Ao...T..C.|.Ho#.
|   3216: 50 7b b6 ec e5 3a 27 0f 65 29 97 ad 37 b1 9f e6   P....:'.e)..7...
|   3232: 6b d1 d4 41 ed 5e 0e 20 22 00 ca 41 58 d2 b9 73   k..A.^. ...AX..s
|   3248: 08 2d 01 83 db d1 57 a2 e3 d2 34 c6 73 fd 2e b2   .-....W...4.s...
|   3264: 9b f2 a4 a4 f1 1d 9f 7a cc d8 93 37 b3 95 2c 99   .......z...7..,.
|   3280: f5 92 0c 91 d5 e2 2e b2 bb 49 76 19 c9 58 16 28   .........Iv..X.(
|   3296: 1e 76 60 ba d9 a8 04 e9 91 5e 7f e6 b1 dc de 9f   .v`......^......
|   3312: 6f e6 52 f2 61 53 7b 09 f4 df c4 96 15 23 99 67   o.R.aS.......#.g
|   3328: 6b b8 e8 04 05 62 0d 5f 05 d1 8a 6c 49 e8 2b 71   k....b._...lI.+q
|   3344: 10 44 8e 93 13 bc 27 14 32 52 22 2d 11 cf cd 43   .D....'.2R.-...C
|   3360: 77 a1 60 21 70 44 60 cb 64 9e b4 c6 23 aa f2 0d   w.`!pD`.d...#...
|   3376: c0 6d 50 0b d9 73 d0 eb 6d d5 03 fc 74 e1 fb 49   .mP..s..m...t..I
|   3392: a1 18 4f bb a2 2f 09 54 28 80 8c 04 86 3d e1 fd   ..O../.T(....=..
|   3408: ff 55 c9 7a a0 35 ef 64 b8 87 1b 10 8c fc 3d 27   .U.z.5.d......='
|   3424: e3 6c 30 3c 05 4d b3 37 b8 29 ba a2 46 9b 76 5d   .l0<.M.7.)..F.v]
|   3440: ff 1b 30 65 70 57 f2 89 c3 17 3f 21 5d 26 5f 58   ..0epW....?!]&_X
|   3456: b1 50 6e 75 c3 dc be a9 0e 43 3e 34 4e 40 0e a1   .Pnu.....C>4N@..
|   3472: f4 69 6d b1 56 a7 0f 09 7e 25 74 08 83 bb 9d 67   .im.V...~%t....g
|   3488: a6 f6 68 87 e9 d9 ba 16 97 42 ca 66 29 e6 df cd   ..h......B.f)...
|   3504: e8 e4 ef ef c9 1f f7 d8 9c 8a a3 24 c9 43 60 4d   ...........$.C`M
|   3520: 9a 73 cb 73 9f b2 b1 fe 51 9d 55 9f 37 a0 d2 3c   .s.s....Q.U.7..<
|   3536: 7e be e4 35 1e 8e 81 f5 67 29 29 ac 95 0a 99 28   ~..5....g))....(
|   3552: ec 4c f2 c6 03 6b 01 76 f5 87 77 58 51 51 40 d4   .L...k.v..wXQQ@.
|   3568: 81 c7 d7 7b 40 09 8f f5 c8 a7 49 00 c9 ee 99 c9   ....@.....I.....
|   3584: 6f 4a c5 6f e7 51 8e 4c 95 a3 de 6d 53 45 7b 97   oJ.o.Q.L...mSE..
|   3600: 7b 7f 8b b4 db f7 52 97 08 2e 4f 36 41 24 79 bd   ......R...O6A$y.
|   3616: 54 bb b8 2c 32 6c 1f 54 e6 82 47 27 53 7f 57 ea   T..,2l.T..G'S.W.
|   3632: 4c 10 71 9b b2 0d 9a 80 fb d2 a6 ec 8d 6e 60 64   L.q..........n`d
|   3648: 1a 73 43 13 b9 cb b1 bd da 84 82 8d 17 ae 75 4d   .sC...........uM
|   3664: 1a af 28 9d 01 6d c7 f7 25 8c b5 ef 1b 5e 33 86   ..(..m..%....^3.
|   3680: e7 ce 59 c0 5b 3d e2 46 ab 85 3b b2 c0 9e 7a 75   ..Y.[=.F..;...zu
|   3696: 26 15 cd 6e 6d c2 19 fc cb 3e 5c 5e 95 94 ec 29   &..nm....>.^...)
|   3712: 94 8e d4 e6 0a 38 8c ef fc eb cb 3a 06 97 20 f3   .....8.....:.. .
|   3728: 5f 53 b5 5f 40 33 9e 41 9c db a8 f3 7a d8 aa 0e   _S._@3.A....z...
|   3744: a3 37 00 87 ff 13 78 1a 98 c2 b2 aa bf 2d 10 24   .7....x......-.$
|   3760: 8e e5 9f 9f 3c 4f e4 90 e0 6a 90 44 32 9f ca 6a   ....<O...j.D2..j
|   3776: 91 e1 c8 7f b8 ef 52 db 24 ec 34 cb b6 2e e9 26   ......R.$.4....&
|   3792: fc 6d c8 3c b2 73 22 25 d9 3c bf c6 d9 50 b4 42   .m.<.s.%.<...P.B
|   3808: be a0 e2 f1 5f 2c 55 17 07 0a 43 7f 55 c3 9a bb   ...._,U...C.U...
|   3824: 12 89 b1 70 c1 e5 c8 21 8a 87 04 b4 f1 d7 b7 49   ...p...!.......I
|   3840: be f9 82 75 90 9f d3 0e 3d dc c8 52 37 44 e9 46   ...u....=..R7D.F
|   3856: 09 09 89 2a 31 e7 0e bf 07 e9 4a 06 ba e5 6f b1   ...*1.....J...o.
|   3872: 1a b0 3c c3 df f4 3e 39 3d 4a 07 34 ed 9a 0b 0d   ..<...>9=J.4....
|   3888: 9c 65 c7 29 02 bf a6 97 61 3c 6f 46 48 0a e5 a6   .e.)....a<oFH...
|   3904: bb e2 8b 50 0b 0f 7b 4e 2a 0a 5f b0 1d c8 32 6e   ...P...N*._...2n
|   3920: 15 01 31 0f 3b 3b 45 ea 32 84 24 5e fa 6a 06 15   ..1.;;E.2.$^.j..
|   3936: 17 f4 19 94 b3 26 b3 0a 29 98 b6 66 3e 37 7e 17   .....&..)..f>7~.
|   3952: 43 f8 b7 ae 2e af d4 9d 67 8d fa c0 24 b2 1c 55   C.......g...$..U
|   3968: ea aa 33 67 22 d4 f3 e7 87 a5 9d fe a3 04 55 ae   ..3g..........U.
|   3984: 56 87 2d 21 a9 02 c2 4d a3 88 a3 3f 48 18 83 a7   V.-!...M...?H...
|   4000: 01 b9 6d 60 d4 0f 79 79 8a 4b 66 c3 49 c7 51 0b   ..m`..yy.Kf.I.Q.
|   4016: 15 73 df f2 53 eb 79 03 da 55 2f 5d 9f 8f 01 a7   .s..S.y..U/]....
|   4032: c7 5d cf 61 f0 c2 78 52 56 b8 45 7d f2 d8 56 ca   .].a..xRV.E...V.
|   4048: 80 84 6e ee 2a 00 ba 00 74 46 0f 76 23 76 79 55   ..n.*...tF.v#vyU
|   4064: 4f 97 57 f2 63 07 11 1f a3 46 07 14 3b 50 43 c0   O.W.c....F..;PC.
|   4080: 72 b2 89 5a 44 15 dc c8 9b 2e f8 ad 69 80 3e d7   r..ZD.......i.>.
| page 13 offset 49152
|      0: 0d 00 00 00 01 04 3f 00 04 3f 00 00 00 00 00 00   ......?..?......
|   1072: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97   ................
|   1088: 3e 05 06 00 ae 7c 00 00 40 9e 86 c7 f4 d7 a0 78   >....|..@......x
|   1104: b9 63 d2 14 9c 0c 6a 77 07 99 fe 03 10 f7 fd 07   .c....jw........
|   1120: ea be 72 a1 24 46 49 15 05 16 1f 1c 80 72 1b 98   ..r.$FI......r..
|   1136: e5 f9 d0 65 50 cb 29 09 d4 2b 17 e2 73 7e 45 4f   ...eP.)..+..s~EO
|   1152: 05 c8 b5 bb 1a 81 34 52 32 17 53 96 c8 0d 54 19   ......4R2.S...T.
|   1168: bd d8 c3 af 35 79 a8 75 ae 2d 5d c4 44 eb b2 1f   ....5y.u.-].D...
|   1184: ab 9d f6 d8 42 7b 3b dd 10 f4 34 95 57 ff ec cc   ....B.;...4.W...
|   1200: 63 3f d3 93 e5 16 6d b5 3d e3 23 7b 32 88 b7 ce   c?....m.=.#.2...
|   1216: 7b 9a 8c 46 26 6f ed 2f a7 83 fb fd a7 b7 1b 48   ...F&o./.......H
|   1232: 88 40 20 a5 9b de 7b d9 32 e5 72 1c 85 8a a2 63   .@ .....2.r....c
|   1248: e2 8d 7b 25 a2 13 51 ec fd 0a ed 1b 76 8f 9d 62   ...%..Q.....v..b
|   1264: 2e 9e cf 0f df 58 30 83 e5 90 40 df d2 9f c9 65   .....X0...@....e
|   1280: 3f ae c6 4a 11 a3 16 5b 6f 24 74 95 5e 21 6a c8   ?..J...[o$t.^!j.
|   1296: da 7a dc 82 c2 ab a0 93 c8 dd a8 f1 1d 78 5e 9b   .z...........x^.
|   1312: c8 17 c7 e0 4f 53 1d e1 5a 5f 5c bf 23 25 fb f3   ....OS..Z_..#%..
|   1328: a0 d4 f5 f7 16 78 f8 00 2e 49 1f 7b ff 41 5c 11   .....x...I...A..
|   1344: 83 9e c7 f4 f5 c7 85 d3 97 dd 67 5a 1e 47 d0 41   ..........gZ.G.A
|   1360: ae cb 4c 47 4f 5f fc 9f bf 0b 20 04 94 08 11 8b   ..LGO_.... .....
|   1376: a8 98 f2 5e 86 19 3b f1 0f 9d 49 c8 02 14 68 24   ...^..;...I...h$
|   1392: 20 71 28 49 3c 60 5a 92 ea d3 2c cd 8a 8a d7 cb    q(I<`Z...,.....
|   1408: fd 14 db 41 3c d0 24 89 46 6a c4 52 8d f0 c0 dd   ...A<.$.Fj.R....
|   1424: b4 a6 0f bd c2 5a fd d1 53 bb a9 82 88 64 4a 34   .....Z..S....dJ4
|   1440: 0f 8f ed 49 49 81 03 29 c3 c3 01 00 6a 83 21 dd   ...II..)....j.!.
|   1456: bc 98 29 fb 2b 5e 78 95 4a 57 4f a7 d3 ec 44 a8   ..).+^x.JWO...D.
|   1472: 97 6c 7f 39 11 6f aa a0 60 b1 71 43 a6 45 ea 9b   .l.9.o..`.qC.E..
|   1488: e1 6f 67 2b f9 e4 8a 55 60 5b 69 f3 54 bf 5c 78   .og+...U`[i.T..x
|   1504: 32 d4 25 22 bf 9b 7a a6 a8 a3 70 53 7d e8 50 1c   2.%...z...pS..P.
|   1520: cd 2a 4a 92 a7 f1 e4 84 39 8e 72 a4 cf 3a c8 b2   .*J.....9.r..:..
|   1536: 3e f1 06 f2 83 80 0c 1c 10 91 7b 41 92 f5 df 0f   >..........A....
|   1552: 7a dc 04 78 3c b4 cd 96 b6 15 f6 7f 85 33 db 09   z..x<........3..
|   1568: 92 de 83 ef fc 2c 75 43 49 0c 12 61 48 14 38 d3   .....,uCI..aH.8.
|   1584: b4 fb 43 33 74 3a 0a 5b c5 03 0a d8 f2 2c 1d cf   ..C3t:.[.....,..
|   1600: e9 a0 7f be 25 24 90 77 75 2f 15 a7 ff 62 83 ef   ....%$.wu/...b..
|   1616: 01 04 b1 7c c8 5d 03 5a 28 1d a3 24 e9 7f 32 73   ...|.].Z(..$..2s
|   1632: 19 59 8c 07 30 10 be 58 c2 48 f6 d1 c6 3c b3 09   .Y..0..X.H...<..
|   1648: e0 bf 5c c3 47 81 c8 04 71 ab 55 cb a5 7c 7a a8   ....G...q.U..|z.
|   1664: 45 28 03 75 e9 82 51 e8 bd 41 d4 1e cc b1 fe 43   E(.u..Q..A.....C
|   1680: 4d 5c 66 25 6f fa da a6 fa ea d3 de 0a 2e 5a 3d   M.f%o.........Z=
|   1696: 68 65 10 b6 ee 3c 0b f6 13 bf 3e 6e 57 f3 30 43   he...<....>nW.0C
|   1712: f6 f4 e0 34 e5 47 88 73 9d 9c 36 f0 90 98 0e 5a   ...4.G.s..6....Z
|   1728: 3b ab 0c 7f 8b ab ea 9c 8c 5e 34 26 d7 53 bb cb   ;........^4&.S..
|   1744: 18 58 a7 6f bf 78 43 7b 47 a6 3b 09 f7 9f 5f 81   .X.o.xC.G.;..._.
|   1760: 87 c0 17 02 8f ad 78 32 8c dd 96 0e d8 b8 66 66   ......x2......ff
|   1776: 23 91 e3 e3 37 5c 63 f4 16 c1 58 4f b7 63 de 7c   #...7.c...XO.c.|
|   1792: 36 c3 67 fc 32 a3 d8 84 20 fe e6 0f 2e 2d ee 11   6.g.2... ....-..
|   1808: 3b 97 1a 05 47 ea a1 71 c4 11 08 b1 a9 52 b7 54   ;...G..q.....R.T
|   1824: bf 4c 06 dd f5 a3 ec c2 ce eb c3 82 e0 5f 5c c1   .L..........._..
|   1840: 51 9c e9 d7 d1 45 a6 ea 62 dd 3b 25 79 0a 5e ed   Q....E..b.;%y.^.
|   1856: 5a 9d 81 8e 7c a8 fd 60 31 88 80 f3 df de 60 23   Z...|..`1.....`#
|   1872: 4e 07 7a 02 dd 89 7d 2c bd ce fa 45 ff c6 05 f4   N.z....,...E....
|   1888: ff 2d 18 f5 13 37 c8 d8 be e9 6d 81 da 8f 03 e4   .-...7....m.....
|   1904: 82 0a c3 3b 19 10 de 4a d8 12 37 37 ce 51 4d 41   ...;...J..77.QMA
|   1920: 0a ad 6a 1f c2 80 49 84 15 7d d4 f0 53 5d d1 b1   ..j...I.....S]..
|   1936: b3 c7 27 34 2f bd 05 af df 5c 5f 86 90 55 99 e5   ..'4/....._..U..
|   1952: 4a 9f 86 34 30 b1 fe 0d 14 2c 1a 85 28 0e 09 5e   J..40....,..(..^
|   1968: d0 31 99 e7 8c ff 6e f9 e6 a5 cb fd 85 9b f7 31   .1....n........1
|   1984: a0 07 f4 cc ca 5d c2 37 f9 a3 6e d2 5b 2e 04 32   .....].7..n.[..2
|   2000: 19 03 7a ee fa 9c 5c 68 89 f7 94 b9 19 fe 05 d2   ..z....h........
|   2016: 19 f8 3b fd cf dd 6f 23 3f c3 28 15 8a 8c 86 4b   ..;...o#?.(....K
|   2032: 8a ff ed ca b7 6a 69 4a fc 66 94 a0 ea b7 fa f0   .....jiJ.f......
|   2048: b1 3b 67 85 2b 82 e4 7f 3b 8d da 02 9e 27 fb 69   .;g.+...;....'.i
|   2064: 7b 20 c6 f6 fb c2 18 fa d5 6d 60 22 be 01 93 28   . .......m`....(
|   2080: 08 71 9f b2 b0 e6 79 94 91 b6 b8 b0 ff a7 3f d8   .q....y.......?.
|   2096: e3 eb b8 8f c7 02 5b f1 35 b7 15 db 01 cd c9 f6   ......[.5.......
|   2112: d9 83 36 2f d0 8b 43 66 e2 3a 14 34 70 1e 68 e3   ..6/..Cf.:.4p.h.
|   2128: e3 a7 fd 7f 51 cb ec 60 ca fb 13 fc 11 56 97 46   ....Q..`.....V.F
|   2144: 23 53 0a aa 8d 15 de d4 cd 2b 1b de 3f d5 57 9c   #S.......+..?.W.
|   2160: e5 91 3b 15 98 3e 09 d9 4e d9 25 14 01 32 fc 23   ..;..>..N.%..2.#
|   2176: 38 60 b2 8f 00 f3 21 8b 20 be 8f 6e 02 9a 58 3c   8`....!. ..n..X<
|   2192: a7 a7 6f 3e 24 cc 1f 87 ab e6 12 0f bd 0a 8b 38   ..o>$..........8
|   2208: 17 b2 ee 80 80 bb 50 df e0 cb 72 0a 98 07 40 bc   ......P...r...@.
|   2224: 8d 77 86 27 e8 07 57 4b 50 84 4c b4 73 b4 32 3d   .w.'..WKP.L.s.2=
|   2240: 89 61 e8 b8 dd bf 22 c8 06 07 e6 8f 6d 54 c7 e3   .a..........mT..
|   2256: 12 f9 1f 61 cb e2 40 e1 14 34 9a 2b 16 a7 1f ec   ...a..@..4.+....
|   2272: 85 b8 76 8e 25 59 51 5a 19 82 d9 54 7f 3d 11 05   ..v.%YQZ...T.=..
|   2288: a6 4c 43 28 9c 65 44 5e 57 fe 04 84 ae 7f 26 5b   .LC(.eD^W.....&[
|   2304: ed 26 e2 1c 07 1f fa f1 99 7b 69 f0 03 16 bf 7c   .&........i....|
|   2320: 13 16 75 80 d1 14 17 fa c9 f4 3b e5 9a 06 c0 d4   ..u.......;.....
|   2336: c2 55 53 0a 78 32 86 3c 23 a4 f8 b6 5b d4 9a 51   .US.x2.<#...[..Q
|   2352: 7c c3 1b 56 b1 e7 cd 83 02 75 8c 5e e3 6b b3 d3   |..V.....u.^.k..
|   2368: 03 23 21 75 3f 78 a7 0f 66 87 2e 85 37 6b bc 0e   .#!u?x..f...7k..
|   2384: 2f 27 cd da 3c 1e 1a 35 2b bc 2d 97 ec 55 df 22   /'..<..5+.-..U..
|   2400: fd 19 04 fa be 12 2a 1f 4b ed e3 0d 87 f0 61 db   ......*.K.....a.
|   2416: 06 1f 86 2f 9d 80 32 97 df 70 ff b4 78 df 95 7d   .../..2..p..x...
|   2432: a3 db a5 d0 db a0 b9 ed 4f a7 63 14 bf 8b 99 fd   ........O.c.....
|   2448: 6e 1b d0 02 07 93 e1 be 56 4e d5 c1 41 a6 f0 ea   n.......VN..A...
|   2464: 37 aa 21 7c 51 2f 5b c4 a0 ae ba e8 a7 1d c6 a5   7.!|Q/[.........
|   2480: 1e 8b 3b 86 7b f2 ea 57 b7 2f 88 37 5e 7a 89 e6   ..;....W./.7^z..
|   2496: 09 c0 e4 3b aa bf 78 41 7c 00 14 cc 37 f1 1a f6   ...;..xA|...7...
|   2512: a5 79 49 f0 5a e0 1e 5d ba 33 ef fe 89 6e 20 01   .yI.Z..].3...n .
|   2528: 96 70 7d 58 0a 98 e0 c4 3e 20 b2 46 83 b8 1f c9   .p.X....> .F....
|   2544: fe 78 8a 41 a9 ca 3f 2c c1 d4 35 a3 39 85 4d a1   .x.A..?,..5.9.M.
|   2560: 23 5e c7 b5 79 75 00 e7 d5 fb 30 99 00 c4 d0 31   #^..yu....0....1
|   2576: 80 68 f2 80 1b 5e c8 30 f6 36 e1 a1 b5 87 92 35   .h...^.0.6.....5
|   2592: 6b 9c ac 39 39 3f 54 e9 4d b4 8b bd 09 4c 6f 9a   k..99?T.M....Lo.
|   2608: 9a 6d 65 1a 7a 2f 98 0f 33 32 3a 4c bd d6 c3 d5   .me.z/..32:L....
|   2624: 2b 3f 7f 0a d7 f7 f0 05 88 5e 36 30 4d a2 0a 65   +?.......^60M..e
|   2640: f6 a9 5b 2d 5e 3f 0e 13 c9 45 1d c9 28 19 6d ba   ..[-^?...E..(.m.
|   2656: ff 9d af 10 17 b2 49 34 d8 a1 c8 ce d2 b7 99 3e   ......I4.......>
|   2672: 7c c6 f5 d6 74 84 05 84 2a bb 2d 25 27 67 04 f0   |...t...*.-%'g..
|   2688: b3 6d 0a a9 43 f6 c4 51 71 1d 48 8d b3 a4 47 ed   .m..C..Qq.H...G.
|   2704: d6 14 c3 27 3e 6a e9 64 ef d7 af fb b0 eb ec 3c   ...'>j.d.......<
|   2720: bb 92 77 32 5e 4f 20 6d f7 a4 94 ce d9 9b c5 78   ..w2^O m.......x
|   2736: 84 f0 c3 1a ca d8 e2 ce 76 0a 5e f8 73 9d 5a 82   ........v.^.s.Z.
|   2752: 1e f5 0a 43 41 77 b9 d1 17 ef 47 0f 04 7b 5c b9   ...CAw....G.....
|   2768: 3d 96 ec 7c b6 45 7d f9 fe 46 cb d2 50 a3 7f 99   =..|.E...F..P...
|   2784: 16 ef 8d 2d d5 55 30 d8 27 18 bb f9 fa 76 80 55   ...-.U0.'....v.U
|   2800: 13 1e f3 c2 dc 11 ef 8b 5d 67 d2 cd 70 74 b0 93   ........]g..pt..
|   2816: f9 51 ec 35 24 cc 01 55 9f 92 a5 10 7f 66 07 e9   .Q.5$..U.....f..
|   2832: f9 0a 32 06 db fd a6 ed 3e c6 b4 55 41 45 6c d3   ..2.....>..UAEl.
|   2848: da a9 57 98 b1 79 3e 3a 6a e3 c4 37 3c 81 ba 16   ..W..y>:j..7<...
|   2864: 3b 6a 3b 29 93 80 50 6d 94 05 dd 6b 37 10 f7 5c   ;j;)..Pm...k7...
|   2880: 5a 23 ef 13 1b 49 a5 fb 7b e8 49 a8 2a f4 e2 f4   Z#...I....I.*...
|   2896: 0b a6 28 03 5b 3e ce c0 f6 b4 d3 c3 b5 ed 2f 87   ..(.[>......../.
|   2912: a3 66 13 93 45 50 d5 3d 59 e4 42 fa f7 00 d8 b8   .f..EP.=Y.B.....
|   2928: 7a 3a cc ce fc d2 8d a5 e9 1b 63 f8 21 6e 4f a3   z:........c.!nO.
|   2944: 0e 17 92 56 d6 2e c9 a4 b8 07 2f 25 9e 3b ff a7   ...V....../%.;..
|   2960: 9d 31 56 43 85 d6 ea 91 ab 29 8c 1e bd 29 f2 9c   .1VC.....)...)..
|   2976: 9c 48 81 a2 a9 da 80 c8 b6 8a 67 48 1d c0 02 4a   .H........gH...J
|   2992: fa a1 e3 69 15 83 c5 ca 9d 96 43 06 ad 97 c3 5c   ...i......C.....
|   3008: 09 e0 de b9 0d 4e f5 99 75 e1 c0 98 20 91 c3 5d   .....N..u... ..]
|   3024: 93 81 0f bf 2b 96 96 c0 9d 30 d3 84 c0 9e 60 56   ....+....0....`V
|   3040: 08 0a 3d 48 be 6b 3d 32 c4 5b e8 87 02 88 f6 f3   ..=H.k=2.[......
|   3056: 71 71 07 f8 66 42 8d df 4e aa 44 6f ec 3a b8 7e   qq..fB..N.Do.:.~
|   3072: 4d b3 83 74 b4 bf 34 d2 2c 95 3c 44 9b c1 cc 9a   M..t..4.,.<D....
|   3088: a7 b2 9a 9e 02 81 b4 e1 c6 cc 53 6a 23 1c b4 0b   ..........Sj#...
|   3104: f6 5e af 3e 2b e8 8a ad d9 d3 d3 36 ea a9 23 06   .^.>+......6..#.
|   3120: 1b f5 ce 42 b0 0c 11 d4 69 a4 bf fa 4b 30 34 b4   ...B....i...K04.
|   3136: 52 48 84 cc 31 08 03 a9 93 d9 e5 c8 44 cd cf fe   RH..1.......D...
|   3152: e4 2e c5 3a c2 b2 d9 bc 15 4d 7f 7a 81 52 9c 53   ...:.....M.z.R.S
|   3168: 3e 1a 74 78 c8 38 4a 02 ce 6b 96 2d 9c 3b 74 41   >.tx.8J..k.-.;tA
|   3184: 50 06 d9 6f fa c8 98 05 f5 70 c3 7f ca 0a 78 f4   P..o.....p....x.
|   3200: 01 f1 a2 f5 46 8a 02 b8 c3 37 7e cc a0 87 b0 fc   ....F....7~.....
|   3216: 32 e5 86 6d 95 22 67 fd 10 56 c4 78 52 c5 12 e5   2..m..g..V.xR...
|   3232: e9 f2 b2 fa f6 78 2e a3 82 a6 73 1b 9f 96 a7 e6   .....x....s.....
|   3248: 81 49 e9 17 f1 0a e6 99 21 ce ec ff be aa 43 e6   .I......!.....C.
|   3264: ea 6a ac 2b a4 b9 0b 48 6c 81 1a 26 bf 93 69 36   .j.+...Hl..&..i6
|   3280: 53 1e 46 2a 43 af cc ef 96 4e 0b 32 38 93 10 d5   S.F*C....N.28...
|   3296: d8 6f 88 e7 f9 92 f8 37 28 51 55 98 fa 1a 89 80   .o.....7(QU.....
|   3312: 35 d5 d1 90 f1 91 8f 4a 5a 81 2f 79 a7 e4 80 3c   5......JZ./y...<
|   3328: a2 5e e5 b3 f8 d3 56 ec cd 02 73 0e af 8d d8 81   .^....V...s.....
|   3344: 26 7b 4d 96 f1 b3 75 7a de c3 b8 a6 b6 75 f2 5c   &.M...uz.....u..
|   3360: 97 08 a3 50 9b d8 cf 43 c0 90 f7 52 da 87 8d 12   ...P...C...R....
|   3376: 1c d4 0a de 56 26 3d af d1 d5 03 ff d8 62 a1 c5   ....V&=......b..
|   3392: f2 7c ea 1d 39 3f f0 e1 5f cb 3d db 1a 8a a1 b7   .|..9?.._.=.....
|   3408: 10 01 f1 c6 17 53 bc 83 eb 2a c4 cf 3a 04 b1 8a   .....S...*..:...
|   3424: 6d 80 20 be 7b 72 6c c9 be 4e eb f4 cd c8 60 d2   m. ..rl..N....`.
|   3440: 1c 46 b1 8a e5 9b 66 22 4f 05 bd c6 37 34 67 2d   .F....f.O...74g-
|   3456: b1 c5 bb 60 de 4b c4 3a 29 14 dc de 38 9c 0d 09   ...`.K.:)...8...
|   3472: bd 78 2f f6 e4 34 18 9b 51 41 a7 57 f9 f2 ad 0d   .x/..4..QA.W....
|   3488: 82 70 5f b4 fa 84 19 5c 72 29 8e 5f b2 8b fa 2a   .p_.....r)._...*
|   3504: e1 d1 55 bf b8 45 c3 79 e0 04 62 10 1f 76 79 de   ..U..E.y..b..vy.
|   3520: 84 93 a8 df 92 8f 41 0d 38 14 70 b3 dd 9d c6 36   ......A.8.p....6
|   3536: f6 12 72 ee 23 e6 ba ed 97 1f cd 36 55 ac 32 98   ..r.#......6U.2.
|   3552: 78 12 55 23 d5 64 ad ed cf 32 d3 2d 7b 51 d7 7f   x.U#.d...2.-.Q..
|   3568: 3c 6f 0f fb c7 06 75 96 ef 64 ce c4 09 15 4f b8   <o....u..d....O.
|   3584: d7 47 f0 b4 83 42 92 40 f7 ed 78 f0 cf 98 c6 a3   .G...B.@..x.....
|   3600: f4 ef b7 01 99 a0 36 5d a2 dd 0f 5d f8 d2 63 87   ......6]...]..c.
|   3616: f1 dc 9a 2c 40 e4 33 3a fa 57 39 ca 3c bb 51 76   ...,@.3:.W9.<.Qv
|   3632: 86 34 73 b4 a8 53 8a ef 4c c3 e9 08 df 8d 11 78   .4s..S..L......x
|   3648: 3c b0 9e d4 c4 ff cc 2a 09 c1 26 d1 b0 2d 72 25   <......*..&..-r%
|   3664: 37 e8 ea 32 71 fa 23 69 bc 43 b0 9b 55 9d 32 c1   7..2q.#i.C..U.2.
|   3680: 6d 7e 7e 08 de d2 fa fb 74 c1 93 ed 35 b2 8e 96   m~~.....t...5...
|   3696: 32 8e d0 ad b0 33 38 06 f7 8d 9d 30 e0 c9 44 3f   2....38....0..D?
|   3712: be 0e 68 2d 6b c0 71 b3 94 bb ef 6f 14 f5 36 00   ..h-k.q....o..6.
|   3728: ea 51 7a 5b af 8e 8e df c9 cb 62 3f 1f 45 15 b8   .Qz[......b?.E..
|   3744: 04 0f 81 c7 ae c8 db 4e 1b 59 d6 e6 24 e5 22 33   .......N.Y..$..3
|   3760: 15 29 b4 15 d4 36 b3 e4 57 e2 a2 60 84 84 4f c4   .)...6..W..`..O.
|   3776: d6 bd 9b eb 1b c5 2f 4a 9c 4d 15 68 60 c7 bd 1e   ....../J.M.h`...
|   3792: 87 d0 88 e0 34 31 e0 e0 6d 4d 3c f4 6b fb 4f 46   ....41..mM<.k.OF
|   3808: ab 16 f7 7d b4 be bd 3f 39 8b c2 0d 5f 4c cd 06   .......?9..._L..
|   3824: f5 36 3c c6 ce bb 8d 1a c0 1d cd 3c b3 b8 53 0c   .6<........<..S.
|   3840: b2 82 7b 79 f7 ff 64 42 61 40 26 e4 cd b8 dd af   ...y..dBa@&.....
|   3856: fb f0 91 2e 20 ad 08 f9 a9 30 ed 30 0a f4 1a 1b   .... ....0.0....
|   3872: 5f 58 9e 96 ee 92 04 01 a9 a7 8e d5 69 ab 75 7d   _X..........i.u.
|   3888: d4 58 a6 b7 60 ee 25 80 db 46 d2 20 ec c4 95 47   .X..`.%..F. ...G
|   3904: ee 39 08 88 80 d5 7e 71 33 7a 7c 42 7c c9 2e f5   .9....~q3z|B|...
|   3920: 0d 47 7c be b0 e5 74 4d 4b 59 f7 c0 0a bd f6 12   .G|...tMKY......
|   3936: 77 94 71 df ce b1 20 16 8d 39 af e3 3b 29 b0 ba   w.q... ..9..;)..
|   3952: 84 43 1f 23 b1 3a b0 dd df e9 f2 c9 c7 a9 07 2f   .C.#.:........./
|   3968: d9 e2 ae 66 f6 0b 6c 1a e6 59 7d 02 3f e5 8f 85   ...f..l..Y..?...
|   3984: 48 30 d8 fa b0 d0 f4 4d 7b 0e 09 af 1c 90 02 6a   H0.....M.......j
|   4000: 9b 1c 9c 51 63 f5 58 45 a7 53 c4 17 69 1a eb 14   ...Qc.XE.S..i...
|   4016: 9f a0 b4 80 93 0a 57 58 da 34 cc fb cb a8 cc 59   ......WX.4.....Y
|   4032: c3 f6 a3 21 16 d8 8c ce 16 8b 44 78 b4 52 78 e5   ...!......Dx.Rx.
|   4048: 1d e8 89 72 be a9 b9 59 49 38 24 4e 98 6f 21 83   ...r...YI8$N.o!.
|   4064: ff 4e 12 23 8b e7 db 91 8b 12 f4 46 7a 0a d3 4e   .N.#.......Fz..N
|   4080: 18 2a 02 c7 79 ec 85 43 b5 9a ac c5 12 ad fb 58   .*..y..C.......X
| page 14 offset 53248
|      0: 0d 00 00 00 01 04 3f 00 04 3f 00 00 00 00 00 00   ......?..?......
|   1072: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97   ................
|   1088: 3e 06 06 00 ae 7c 00 00 9e de 63 2f fd 8b ea ff   >....|....c/....
|   1104: f2 f2 37 ff aa 18 0f 69 94 cc 49 85 cd f7 bb 7b   ..7....i..I.....
|   1120: e5 c0 09 d1 a2 78 f4 c0 1b 23 e7 d5 ac 2d 85 27   .....x...#...-.'
|   1136: c2 48 c2 80 ad 93 a0 10 44 98 5a 6e 9e f1 92 a9   .H......D.Zn....
|   1152: 98 f9 0d 00 2a 3a 22 36 c5 21 63 fb 95 fb c7 7e   ....*:.6.!c....~
|   1168: 6c 07 7d d1 a5 f1 a9 8f f2 d2 e2 0f 3d 02 56 94   l...........=.V.
|   1184: ea 44 2a 17 ee 99 82 71 9c 81 c7 9c 8f cd 2e 4d   .D*....q.......M
|   1200: 8d 0a 1e 71 18 3d 4d 9d a6 ae 35 36 48 08 24 e8   ...q.=M...56H.$.
|   1216: 46 78 8e 66 f2 8a f1 3d c3 72 ad 65 18 5f ed 2d   Fx.f...=.r.e._.-
|   1232: 7e 92 18 9e 4c 23 7c f8 8d 83 20 43 50 63 db 75   ~...L#|... CPc.u
|   1248: 12 7e 52 0e 71 13 e4 b6 31 c3 5f 88 b7 d0 76 80   .~R.q...1._...v.
|   1264: d5 9f 7e dc 8c b4 be 11 da 2c e1 a9 28 5e c8 46   ..~......,..(^.F
|   1280: 3c 0d cd 7a 2f b9 9f 53 9c 11 01 d1 09 31 5f 36   <..z/..S.....1_6
|   1296: bb a4 f3 a0 ad ba b7 c4 ce d1 78 4e ad e8 cd f9   ..........xN....
|   1312: 92 ed 51 05 69 ab 12 a3 89 4c 6d f5 7a c4 c5 54   ..Q.i....Lm.z..T
|   1328: 1e 26 e7 f8 22 1c 42 cb 9e ac 7a 53 79 09 3c 04   .&....B...zSy.<.
|   1344: 14 1d 49 15 c7 13 00 84 3c 7f 15 2d 5b 62 da d8   ..I.....<..-[b..
|   1360: 8f 88 53 7a 78 f7 c4 7b be 67 25 cd 97 1f bf 19   ..Szx....g%.....
|   1376: b4 8f 4a 10 63 89 2f cf 56 c1 63 79 92 cc b1 75   ..J.c./.V.cy...u
|   1392: 45 ee 6a 9d c5 de 04 e0 60 49 c5 0e 09 a0 65 46   E.j.....`I....eF
|   1408: 57 f3 6c 5f 0f 07 99 fa 2b 2c 2c 5b bd b3 9b 50   W.l_....+,,[...P
|   1424: 38 43 94 4b 7b d2 b0 78 3b 4c e8 55 1d d3 6b 6a   8C.K...x;L.U..kj
|   1440: f7 dc 27 ef b5 b1 3a 52 9f 5a e9 7d 87 bb 61 5b   ..'...:R.Z....a[
|   1456: 39 a3 eb 5e eb f1 80 78 85 d8 86 16 76 3c b3 b0   9..^...x....v<..
|   1472: 44 72 d7 0e 91 95 5e 7d d5 93 0a 4d 60 46 ad a8   Dr....^....M`F..
|   1488: b7 d5 30 e2 39 4c d8 0a d4 ea 5e 46 95 39 1a 1e   ..0.9L....^F.9..
|   1504: 9d 81 27 20 bc 01 1e f5 2d 4a 19 4a a5 2d 94 91   ..' ....-J.J.-..
|   1520: c2 a3 31 65 aa 13 f4 92 ce b2 c1 61 25 13 7d 93   ..1e.......a%...
|   1536: f0 c9 51 e5 ce 7c 0e 2d e4 f2 d4 b5 09 73 fc 96   ..Q..|.-.....s..
|   1552: e0 a8 a7 85 b6 10 0f 95 a5 83 c5 4b ca 33 9f 98   ...........K.3..
|   1568: 38 d9 50 29 38 08 cc b9 89 40 0e d7 1d 92 cc 4a   8.P)8....@.....J
|   1584: 7f a2 53 dd 19 d3 13 63 04 29 04 18 c2 79 97 36   ..S....c.)...y.6
|   1600: 85 e8 95 4a 2c 34 7c 39 78 a5 fe 8b bb 22 93 4c   ...J,4|9x......L
|   1616: 69 b6 86 ca 0c 61 39 b3 85 c1 df ee 28 b0 3d 73   i....a9.....(.=s
|   1632: 2f 78 84 69 f4 55 ed 6c b8 98 61 0c f5 64 15 7e   /x.i.U.l..a..d.~
|   1648: 84 bd 4f de ae 6c 1b db c1 60 c9 0a b9 22 f0 7d   ..O..l...`......
|   1664: 03 23 0f e3 f5 77 3a 3b 4b 7f 33 d9 e6 7c ee 92   .#...w:;K.3..|..
|   1680: 0c 95 f6 9d 98 53 e3 7b 92 3b 15 a2 de 84 e6 75   .....S...;.....u
|   1696: 64 e1 44 b5 9d 16 77 10 78 65 e0 72 66 a9 13 db   d.D...w.xe.rf...
|   1712: 27 cf 9f 0d 33 5d ee 89 37 cf 2f b6 fc 28 b1 93   '...3]..7./..(..
|   1728: c3 6d 0f 80 d8 5a 16 33 ea 06 d7 81 d3 45 59 94   .m...Z.3.....EY.
|   1744: 07 73 bf 47 f6 fd 6e 78 13 5a ec 30 62 a4 c4 12   .s.G..nx.Z.0b...
|   1760: 2a 56 8f 29 03 37 0c 98 80 8e e9 50 4f 3a 37 a6   *V.).7.....PO:7.
|   1776: f6 29 3a 6f 17 54 45 8e df 98 62 1e 23 d0 ec 20   .):o.TE...b.#.. 
|   1792: 4b c8 f6 cb ce ef f5 8b f2 fd a9 a8 51 5c 0f d0   K...........Q...
|   1808: e4 4d 7c a1 a1 2a 88 f1 24 78 9e cb 7c 81 6b 0a   .M|..*..$x..|.k.
|   1824: 51 73 1e bf 48 21 fb b3 7a 5c 48 0f 53 04 00 5f   Qs..H!..z.H.S.._
|   1840: 7e 66 7a 2e c0 30 9f bf 2f e8 95 b5 fe ea 9c f8   ~fz..0../.......
|   1856: 0e 6d 1f 54 81 da e9 bc 28 ea 42 de 5b e0 7f 93   .m.T....(.B.[...
|   1872: 79 6d 6d 8e f3 3c ba 13 67 3a 08 31 03 43 da eb   ymm..<..g:.1.C..
|   1888: 34 40 04 3e a4 21 44 92 96 75 2c 9f 8f 03 89 98   4@.>.!D..u,.....
|   1904: f0 27 dd 27 49 3d e3 9b 37 4e 66 ef 98 bd 1b ed   .'.'I=..7Nf.....
|   1920: 3f cc a4 10 85 a4 39 90 cc a3 80 3d fd e5 44 4f   ?.....9....=..DO
|   1936: 45 79 64 37 d2 70 ba 69 99 0f 4d 33 5a 68 bd 53   Eyd7.p.i..M3Zh.S
|   1952: 92 24 0d 3f f4 e2 4b 72 35 cb 52 ea 3d d4 85 ee   .$.?..Kr5.R.=...
|   1968: e3 12 b3 87 3a 9d 70 b8 5c bb c7 c4 98 03 84 25   ....:.p........%
|   1984: 5d 39 ef 24 bc ab b3 da 13 7b 2c bc 17 b1 76 4c   ]9.$......,...vL
|   2000: 5d 5a 1c 62 14 8d 5d 20 32 dc 16 64 79 7e 13 95   ]Z.b..] 2..dy~..
|   2016: 27 f6 99 dd f2 32 c2 43 c6 77 b4 f4 11 88 6d 3f   '....2.C.w....m?
|   2032: 94 0e cb db c8 c3 9e 40 b1 7d d4 16 e6 95 f4 d9   .......@........
|   2048: 3d 9b 5d df d5 a3 39 06 c1 eb a1 30 cb 85 77 d6   =.]...9....0..w.
|   2064: 9b d9 12 7a 6a 82 9e 3a bf 5a ff 5c b8 6f 4a bb   ...zj..:.Z...oJ.
|   2080: 02 36 94 1d 5a 0c 95 da 85 d1 9c 22 5a 36 fd 28   .6..Z.......Z6.(
|   2096: 51 cf 48 60 84 a1 ce ad a9 5f 4c 51 43 71 7f d5   Q.H`....._LQCq..
|   2112: 1a e1 6f b0 01 a5 6b f1 57 91 84 78 b0 d5 06 7c   ..o...k.W..x...|
|   2128: f4 96 3d 9b e4 6d 04 b7 26 a0 5b 61 53 39 ba 49   ..=..m..&.[aS9.I
|   2144: 2c ea d8 18 e5 aa b3 ef 3e 8e 5d 91 ba 93 15 2b   ,.......>.]....+
|   2160: 4d e6 5c e7 47 ee 7c 9e d5 ca f4 82 91 84 f4 33   M...G.|........3
|   2176: 02 46 9d dc 34 8d f1 5b 1c 15 5d db 2f c9 d0 09   .F..4..[..]./...
|   2192: fb a4 cf d9 0d 30 9f 16 3b 5e 80 ff 26 ac 19 b7   .....0..;^..&...
|   2208: b2 56 1a bb 72 7f b9 2f e7 41 6a e3 fc e5 cc e0   .V..r../.Aj.....
|   2224: 27 2c 78 86 1c 11 ee f4 51 2d 22 20 73 3b ed d6   ',x.....Q-. s;..
|   2240: 42 c2 de 23 de c6 7d 43 8f 16 de 66 57 64 94 32   B..#...C...fWd.2
|   2256: 13 da a6 91 b7 d5 8f 3a d6 c4 a7 e0 93 ff f8 9c   .......:........
|   2272: e3 70 a9 e9 e9 7a 50 37 3c 38 d3 fd 68 ff 17 5f   .p...zP7<8..h.._
|   2288: 96 b7 b4 77 c5 ce 1d 37 49 35 91 6c 2e 37 ef ac   ...w...7I5.l.7..
|   2304: 18 ee 9f 7a e5 28 88 a6 33 39 05 f7 c8 1f 1a 15   ...z.(..39......
|   2320: f6 ad 55 5e 24 ea ce 21 c8 e2 1e 63 bd 7a 19 60   ..U^$..!...c.z.`
|   2336: c0 aa e4 42 2f 0f 53 f4 2c 04 99 a4 9a 13 86 6f   ...B/.S.,......o
|   2352: 24 7b 42 ad c9 a9 c9 df 82 90 23 0a b6 e8 2a e4   $.B.......#...*.
|   2368: 36 c5 04 1a e4 dd 87 06 ca 6e 04 7b be 37 b4 ef   6........n...7..
|   2384: 05 1d 6a ab 36 c8 58 52 3d ad 26 21 45 58 f4 66   ..j.6.XR=.&!EX.f
|   2400: 05 a2 95 89 9c 31 1c 3c 14 9b 59 90 29 28 f9 9d   .....1.<..Y.)(..
|   2416: f9 96 74 ab d7 30 91 81 17 ba b8 08 51 38 75 77   ..t..0......Q8uw
|   2432: 06 ca 81 1d e3 9b 67 3e 0f d9 fe 98 69 e0 d8 f1   ......g>....i...
|   2448: 78 dc 96 0e 88 50 9c b5 c1 1d 25 61 87 70 bf a5   x....P....%a.p..
|   2464: 93 2f f9 c7 7b ab fd 2c 98 10 ef 0f ce a4 bd fa   ./.....,........
|   2480: 52 7f ff 29 53 5f 9c b5 92 2e 8c f5 36 a0 7c 88   R..)S_......6.|.
|   2496: 84 18 80 59 66 d2 c6 58 55 c0 5d 07 9f 69 d2 72   ...Yf..XU.]..i.r
|   2512: 88 0d 1d 8f 08 7c d5 b7 9c 15 4c 6c c6 1d f4 76   .....|....Ll...v
|   2528: 0a 82 32 6c 72 4e 3e cc ff 8b 62 c5 37 4e 0c 0d   ..2lrN>...b.7N..
|   2544: 09 89 8a 95 1b 63 d3 85 c6 4a 41 7c 49 46 60 95   .....c...JA|IF`.
|   2560: eb 37 60 82 84 55 ea fe 22 97 16 58 ad 33 06 ae   .7`..U.....X.3..
|   2576: d0 f5 5d 06 b3 2e b9 0a 6d d0 14 c8 d5 0b 8a cf   ..].....m.......
|   2592: 51 ff 64 db a8 81 e1 8b 39 1a ef 85 18 fd a2 48   Q.d.....9......H
|   2608: 4f 47 b3 1e 5a 57 21 f0 6b 10 f0 ec 0a 4a 35 56   OG..ZW!.k....J5V
|   2624: f5 79 c5 de 62 d1 4a c2 e5 bc 69 89 9d 9b b9 4b   .y..b.J...i....K
|   2640: ba 21 99 5a 58 c6 23 ab 67 45 13 4a 1d 3e da 68   .!.ZX.#.gE.J.>.h
|   2656: cf a6 4b 20 58 b0 4e 2f 0d f2 42 83 9d 96 43 6e   ..K X.N/..B...Cn
|   2672: df 45 61 c5 bd ca 86 b3 6a ad 26 a2 8d c7 c4 03   .Ea.....j.&.....
|   2688: 63 d8 b8 02 0a f6 96 f9 15 46 2c bd 04 68 aa 1b   c........F,..h..
|   2704: 00 46 7e a0 bb 47 fe 5f 2b 7b b4 59 54 14 e3 25   .F~..G._+..YT..%
|   2720: cd 10 8b ff 05 6c 6d ab 9c 90 cb d4 d8 0d bd 58   .....lm........X
|   2736: be bc d5 c0 67 bd 0f d3 9d 22 71 c4 65 e6 2f bc   ....g.....q.e./.
|   2752: 5e 3a 54 39 7a ec ab b1 46 80 25 5e 33 19 de 3b   ^:T9z...F.%^3..;
|   2768: 4a 84 28 04 80 f6 86 aa 32 75 8e 5b 51 66 b0 64   J.(.....2u.[Qf.d
|   2784: 29 94 f6 56 6d 1c b1 2e 2f 4c 55 3b e5 82 01 75   )..Vm.../LU;...u
|   2800: 3f 58 d3 a0 b9 0b 6b 25 24 94 9e a5 ce a4 1c db   ?X....k%$.......
|   2816: 51 f9 bb 53 71 19 0a 5a e3 2e 48 e1 06 24 7a b9   Q..Sq..Z..H..$z.
|   2832: 88 fb dc 4c 2a 23 b9 b9 7e 26 a4 3f 7f c7 b5 f1   ...L*#..~&.?....
|   2848: cd cb 82 17 34 89 70 b4 10 ad be b8 4b 0d aa 07   ....4.p.....K...
|   2864: 61 6d b3 6f 56 ac a4 b2 e4 2f be 28 e6 24 3a ab   am.oV..../.(.$:.
|   2880: cc 1a 8a 7f 54 c7 a3 c8 49 50 91 76 f9 75 d8 3a   ....T...IP.v.u.:
|   2896: 76 1b ec 5b 51 c2 5f 6f c9 c7 60 24 0a 61 f4 ed   v..[Q._o..`$.a..
|   2912: d3 30 23 e7 a0 83 c7 5e f4 b8 1b 39 65 43 2a 8a   .0#....^...9eC*.
|   2928: 1d a8 64 4d c5 4a a6 ab e1 f4 66 90 f7 2b 1c d6   ..dM.J....f..+..
|   2944: ba 76 96 43 2d a1 6b 26 ee f1 3b 8b 2f e4 78 7e   .v.C-.k&..;./.x~
|   2960: 9b bd fa 2e 80 ff ec 26 74 5b 56 11 92 88 51 8c   .......&t[V...Q.
|   2976: 6d 42 4f f5 3c 53 8b 42 3e b6 57 37 fe ad 66 59   mBO.<S.B>.W7..fY
|   2992: 4a f4 0e a1 39 a2 32 c0 23 78 e0 e7 db f9 f9 44   J...9.2.#x.....D
|   3008: 34 12 00 a0 d2 1f 45 25 4f 4a 72 74 9e b2 d5 e4   4.....E%OJrt....
|   3024: 25 4e d5 0f ba 1b 87 7f 23 f2 7f dd 96 6c 1c 44   %N......#....l.D
|   3040: 0d 11 9a 22 6a f8 83 bf 37 e6 c9 5d 2e d3 dc d3   ....j...7..]....
|   3056: aa 03 03 7e bf a5 cc a1 d8 55 6f 05 1a 70 5e 89   ...~.....Uo..p^.
|   3072: d5 8e a5 08 f4 fc 90 7c d2 8a 67 53 82 25 82 02   .......|..gS.%..
|   3088: 98 e0 ad 57 bb d4 7e fc 18 8f 25 9d d7 11 57 ab   ...W..~...%...W.
|   3104: cf de 4b a5 1b 90 6b 38 a3 ef 93 ed 44 d7 9d f1   ..K...k8....D...
|   3120: 54 b1 0b 9b 2d e9 e7 d3 a6 6c 78 fd 40 d9 ea 7f   T...-....lx.@...
|   3136: ec 10 60 2f ed 4c df f4 ef fb 4a cd fd 1a ea 94   ..`/.L....J.....
|   3152: 7b ac 69 70 be d1 2c ca e3 88 a7 b4 7f 95 83 eb   ..ip..,.........
|   3168: 2e 82 0e 3e 60 27 b9 0c 62 56 3d b2 c4 7d 97 2c   ...>`'..bV=....,
|   3184: ac cd 0b 05 b3 41 ab 7c 2e eb 4e a7 3e 8f db 53   .....A.|..N.>..S
|   3200: 88 59 f3 d6 f4 bf 5e 80 2e 5b f2 08 f8 dc 68 28   .Y....^..[....h(
|   3216: a7 a3 e3 4e ef 8f 3f 4e a6 c0 4b 04 d9 59 3e 53   ...N..?N..K..Y>S
|   3232: 07 78 2c b2 58 a6 78 a4 0a 6b 9e 6b 8d f2 3e 70   .x,.X.x..k.k..>p
|   3248: 45 07 82 f9 f0 d4 0f f7 81 e9 ab 09 c6 7a 3a ff   E............z:.
|   3264: 98 6c bf 1f 43 c3 d5 ba c1 ad fe 9c a6 5e d5 f7   .l..C........^..
|   3280: 93 ec 20 dd 33 ad 35 0b 74 47 80 1e 5b 8b c3 7c   .. .3.5.tG..[..|
|   3296: 5c 81 66 82 dd 18 70 19 b0 54 18 2f 90 c2 22 bf   ..f...p..T./....
|   3312: 75 e8 b6 8e b7 3e 7c 2d b4 e9 7c b4 08 4e e9 c3   u....>|-..|..N..
|   3328: e1 80 88 63 f2 90 ee ae 3d 9e 55 15 62 7f ee df   ...c....=.U.b...
|   3344: 57 69 03 da 76 e9 f3 6b 90 9a a7 b9 bb 4b b7 2b   Wi..v..k.....K.+
|   3360: d0 a0 3b 70 b9 96 70 17 c8 0c cb ae 6e 3e e1 33   ..;p..p.....n>.3
|   3376: 02 98 53 d6 af c6 d8 55 15 7a ea f1 8f 36 6b d4   ..S....U.z...6k.
|   3392: f2 8c fd db a5 81 50 fe c8 a8 cb 7f e6 9a a9 9f   ......P.........
|   3408: 34 82 6d a5 11 6b e6 79 58 a8 54 ed 55 cd 19 46   4.m..k.yX.T.U..F
|   3424: e9 7f 92 f8 0b 3e ab b5 8d d3 9f 33 5c e7 f6 1e   .....>.....3....
|   3440: 28 f7 5f 2f 38 36 25 ed 7f 36 93 19 f1 a7 9c e7   (._/86%..6......
|   3456: ad 4e 11 33 17 93 82 cf b4 a7 93 36 97 d9 e0 3d   .N.3.......6...=
|   3472: 7e 54 b9 96 37 85 16 db e8 29 6f b0 b1 83 16 63   ~T..7....)o....c
|   3488: 9b 19 30 85 c6 17 2c b7 bc f2 2f 87 07 56 97 b3   ..0...,.../..V..
|   3504: c4 a6 47 d5 8b 7a 68 a4 d0 11 ce ff 6c 4c 28 93   ..G..zh.....lL(.
|   3520: c3 37 ef 1e 7a 51 65 a9 6b 8a a0 a4 b0 b9 ef 17   .7..zQe.k.......
|   3536: dc 44 99 34 7b 33 f4 b9 3f d3 20 36 54 5c 10 6d   .D.4.3..?. 6T..m
|   3552: 18 25 33 6e fc fa a0 16 c7 b6 78 f8 4b 0c 5e 7e   .%3n......x.K.^~
|   3568: c3 cb 95 54 90 88 57 20 d9 17 9b 82 dc e8 7f c6   ...T..W ........
|   3584: bd d8 dc 13 ca 66 06 64 8e 46 2e 48 13 eb 4d 07   .....f.d.F.H..M.
|   3600: 24 7f 8e 35 f3 bf fb 54 80 c7 6e 93 da ce 7f 2b   $..5...T..n....+
|   3616: 60 3e 53 82 33 38 fe 69 7b f6 fa 2f d8 40 bd c8   `>S.38.i.../.@..
|   3632: 95 75 6b a2 e5 53 7f 5c f1 f3 23 07 8f 42 04 8f   .uk..S....#..B..
|   3648: 64 43 a2 25 c1 40 07 e9 be b6 3c d6 1b 86 7f 91   dC.%.@....<.....
|   3664: f4 73 0f 6b ca 6b cb 8f 7c a8 5b 60 ee 20 a6 e6   .s.k.k..|.[`. ..
|   3680: dc 96 6b 8f 8d 62 1e 42 e0 1b 85 49 85 34 b4 c9   ..k..b.B...I.4..
|   3696: 85 06 ec c4 b7 b5 89 47 af fa db d1 5b 9f ac 6f   .......G....[..o
|   3712: 8a 27 53 48 4d ad a1 30 6b 3e 45 b1 b8 b9 50 17   .'SHM..0k>E...P.
|   3728: 7b b7 29 a8 b3 d5 9a 42 a9 2a e4 01 79 34 c5 21   ..)....B.*..y4.!
|   3744: a7 8b 21 69 ab c4 9b ec eb 0d 9f 34 b5 ff 46 2d   ..!i.......4..F-
|   3760: 68 55 9b 63 9a ac ac 80 4c 45 8d eb dd b2 26 4a   hU.c....LE....&J
|   3776: 91 8f ee f7 50 6f 84 81 c3 79 2e 6d 56 1c ee 01   ....Po...y.mV...
|   3792: 20 2b e5 ca 3a 51 ba 40 b6 44 15 a4 4a 3d d0 33    +..:Q.@.D..J=.3
|   3808: 7d 2d 3c ca e3 f8 e9 1d bc b2 1e 59 1e 57 10 2f   .-<........Y.W./
|   3824: 92 4b b7 50 41 98 6f 07 0b 38 ba 31 08 3e d4 34   .K.PA.o..8.1.>.4
|   3840: 4f f4 99 32 2f e5 7f 8f 14 8e 48 11 88 ad 18 d6   O..2/.....H.....
|   3856: db d0 e5 cc 17 4c b6 f7 45 f9 1e 9a d9 86 5d 56   .....L..E.....]V
|   3872: fa 76 52 49 cd f1 76 ea 84 b1 55 03 54 e2 ff 91   .vRI..v...U.T...
|   3888: 23 fb 22 b0 8a b8 da 6e 7e 54 25 03 f3 fb eb 9a   #......n~T%.....
|   3904: ce 64 cb 70 38 c9 aa 11 e8 36 45 16 8c 82 0e 18   .d.p8....6E.....
|   3920: f3 cf 81 4c 7c ef 53 6a 5c 43 85 e3 01 c9 d5 97   ...L|.Sj.C......
|   3936: 8b 03 78 90 35 c9 7c 3a 62 3d 66 d9 ff 6c 1f 3f   ..x.5.|:b=f..l.?
|   3952: 7f a1 85 ad ec 87 65 3b 48 3c 0b 0c 94 c0 05 85   ......e;H<......
|   3968: f9 a4 4a 79 c1 dc 7b 9f 87 c0 4f c9 7b a7 ce 5c   ..Jy......O.....
|   3984: cd 11 68 d5 79 d2 e7 b5 8c 13 af d6 e9 81 ef 42   ..h.y..........B
|   4000: 4c 11 2f c0 55 33 4c f4 44 c1 75 67 ae 43 95 68   L./.U3L.D.ug.C.h
|   4016: da 90 26 d5 42 75 b6 ef 99 22 ce b8 2d 52 5f 43   ..&.Bu......-R_C
|   4032: a4 f7 23 72 17 c6 66 36 84 e6 d3 a7 da a9 ec 82   ..#r..f6........
|   4048: b2 fd 87 90 51 2e 78 71 3f 56 49 96 d2 da 6b 67   ....Q.xq?VI...kg
|   4064: 2a f8 b1 eb ae 5d d0 e7 59 31 ed ed 24 b6 2c 32   *....]..Y1..$.,2
|   4080: 7a b7 97 c5 e0 f1 a4 05 d3 8e fa 0f 10 ee 19 4d   z..............M
| page 15 offset 57344
|      0: 0d 00 00 00 01 04 3f 00 04 3f 00 00 00 00 00 00   ......?..?......
|   1072: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97   ................
|   1088: 3e 07 06 00 ae 7c 00 00 07 2c f5 e5 48 a9 82 86   >....|...,..H...
|   1104: 40 71 a9 80 b9 af 28 61 b5 17 5a cb c3 67 db aa   @q....(a..Z..g..
|   1120: fa 64 ec 63 b4 34 d5 37 ee 52 d8 d5 38 6a 25 d0   .d.c.4.7.R..8j%.
|   1136: 1f 05 80 72 bd c3 b9 1a d1 ea f7 f0 73 0e 97 29   ...r........s..)
|   1152: 41 19 09 d1 53 df c8 c5 02 ab a2 e8 76 b8 09 3d   A...S.......v..=
|   1168: 8b 07 21 05 5f 80 3d 88 67 fd fe ab e6 4b 7f 97   ..!._.=.g....K..
|   1184: a6 17 42 02 f5 ad f3 74 6b bb 6e 2a fd af 88 3b   ..B....tk.n*...;
|   1200: d9 b2 3c 0d 33 a7 93 69 c0 97 c5 c4 c0 e9 29 d5   ..<.3..i......).
|   1216: c3 78 96 13 55 f3 41 e6 87 eb 7a 2f b9 e2 28 f3   .x..U.A...z/..(.
|   1232: e1 ed b8 c8 5d bd 80 80 a6 52 50 ff 0d db 2b f2   ....]....RP...+.
|   1248: 7e 9e 91 32 fd 08 46 ba db 2b 41 00 70 6f cf 80   ~..2..F..+A.po..
|   1264: 46 1b 49 cf ab 6e 1d 14 21 f2 3f 55 0a 4a ed 19   F.I..n..!.?U.J..
|   1280: 11 9b 9e c0 f2 c4 55 86 2c 05 4e a2 6f 8c b2 9c   ......U.,.N.o...
|   1296: 11 fd 85 0c 5b d5 ee ef 9c f2 4b 1e 74 72 bd a4   ....[.....K.tr..
|   1312: 29 8d 0d 92 67 97 b5 b5 03 b4 a7 68 15 50 c7 7e   )...g......h.P.~
|   1328: 91 22 a8 39 3e e2 18 bd 68 20 74 c1 e5 f2 8a e5   ...9>...h t.....
|   1344: 1e 72 0c 2a e3 1a b2 60 57 ad 2b ee 1f 59 57 ce   .r.*...`W.+..YW.
|   1360: 6f b2 e0 15 96 73 f6 2e 5b 82 b7 ca 6b bf ed 78   o....s..[...k..x
|   1376: e5 af 82 82 73 16 6a ce cb 09 b9 5f b3 2d c0 0c   ....s.j...._.-..
|   1392: 1d 46 5f 7e be ee 0c b3 54 e7 ed e7 cc cf f9 9d   .F_~....T.......
|   1408: 42 90 94 e2 e9 c2 76 2b 02 b9 a8 73 20 0a e3 6f   B.....v+...s ..o
|   1424: 23 a0 c0 59 f2 af 9d c4 78 90 ba 8e 0c ef b4 d6   #..Y....x.......
|   1440: 37 03 5e f4 7f 54 a6 d7 87 bc 20 3f e1 7a 84 d9   7.^..T.... ?.z..
|   1456: 1b 33 4a fc bd 1f c1 8b b3 db 8f 0c fa 49 7f d7   .3J..........I..
|   1472: 9a d0 48 8e c6 3b 79 22 d6 0c fa 93 4d 43 f3 de   ..H..;y.....MC..
|   1488: bb 10 3e 81 d2 6b b4 9f 4c 91 05 d7 87 b5 35 98   ..>..k..L.....5.
|   1504: eb 84 9d 2c 0e 4e 2b de 1b 23 0d f5 bd aa 4a 9c   ...,.N+..#....J.
|   1520: 6d 7e 48 23 18 f9 72 5b ef 9e da a9 ef 1b 29 08   m~H#..r[......).
|   1536: 03 34 e2 86 97 ff c9 2d c6 04 34 65 84 20 5b 7c   .4.....-..4e. [|
|   1552: df e3 2c bc 73 04 22 70 f5 03 f2 8f fe fb 72 b5   ..,.s..p......r.
|   1568: a1 93 91 a4 3e a5 20 ac 21 19 8a 60 60 48 63 a0   ....>. .!..``Hc.
|   1584: 47 80 a8 ac 9f 68 a9 ab b7 0f 71 d5 44 1a fb 4a   G....h....q.D..J
|   1600: 99 06 2b fc 96 ad ac 5e 37 37 84 6e 4e de 66 ba   ..+....^77.nN.f.
|   1616: c6 10 fc e9 a0 26 cf 48 f6 f6 96 b7 69 35 30 06   .....&.H....i50.
|   1632: f2 7a db 70 53 4d f9 5b 9b 5f 51 b8 f6 af fb 1c   .z.pSM.[._Q.....
|   1648: f5 2a d7 01 80 d2 0e b3 fe cc 99 ad 74 ad fa df   .*..........t...
|   1664: 26 86 c7 29 b2 b3 36 98 b8 b7 2c de 9c 78 41 99   &..)..6...,..xA.
|   1680: ff 46 40 76 64 64 0c f5 46 d5 bd 72 a3 46 b0 b3   .F@vdd..F..r.F..
|   1696: 75 45 03 d1 06 4b c9 ca a6 4f 90 f7 9b 60 4a 46   uE...K...O...`JF
|   1712: ed af a1 d5 68 30 db a7 5e ca 76 bf 66 64 e7 fa   ....h0..^.v.fd..
|   1728: 50 5c 31 5f 86 94 3a 5c f4 98 3d d5 52 80 26 1e   P.1_..:...=.R.&.
|   1744: 55 07 14 d5 f5 2a 17 46 8b 6d 71 d2 da 4b e7 c8   U....*.F.mq..K..
|   1760: 3d 8f 97 b7 97 51 c5 fb aa 4f 3f 3b 85 c1 aa e8   =....Q...O?;....
|   1776: bf 3a d9 56 c0 d3 23 31 28 46 bd 45 2e 4b b5 e7   .:.V..#1(F.E.K..
|   1792: f6 8e fa e2 28 65 6c 42 f2 68 8f 37 cb 4d e9 26   ....(elB.h.7.M.&
|   1808: f7 63 58 8c 99 09 71 7c 14 3a d7 92 c4 cf 14 51   .cX...q|.:.....Q
|   1824: af fe 6e 6b 50 e9 3a 70 0f ac 53 9d 57 01 4f 7a   ..nkP.:p..S.W.Oz
|   1840: cc b2 c5 b9 2a 3e 02 6a d4 15 6f 2e d3 20 99 ed   ....*>.j..o.. ..
|   1856: d7 1f 71 01 2f b4 e4 08 fe 8c 38 02 2c 14 e0 fd   ..q./.....8.,...
|   1872: ec 3e 61 a8 b7 fa de f0 81 56 6a e2 d1 3d 2f de   .>a......Vj..=/.
|   1888: f8 a3 75 5d 35 1b a4 a3 8e 6e 8c 9d b2 56 56 ba   ..u]5....n...VV.
|   1904: 89 ab 42 86 70 59 5e 70 51 27 fc 87 b4 5c e5 89   ..B.pY^pQ'......
|   1920: 20 b5 bd 40 6a 68 cb 1a 70 49 b5 2f c4 02 34 66    ..@jh..pI./..4f
|   1936: be cc 14 12 e0 f9 c7 4c 84 ff 37 a6 a5 ae 5c 36   .......L..7....6
|   1952: 03 58 8e 44 17 e1 ca 30 3e 7f c9 54 94 f4 ff 86   .X.D...0>..T....
|   1968: 57 8b 5e 2c aa 0b 28 30 ac 5a 1a 14 39 70 8a 84   W.^,..(0.Z..9p..
|   1984: c2 4c 64 28 b1 87 6a 34 cf 50 b7 37 2e 96 ca ba   .Ld(..j4.P.7....
|   2000: c9 b1 37 d5 56 e7 39 b6 70 b1 16 2b 67 8a fb 0f   ..7.V.9.p..+g...
|   2016: b3 ec 53 b4 27 ba 3e 60 16 96 86 b0 02 ba c9 d7   ..S.'.>`........
|   2032: e1 d9 17 0f d4 12 aa 5d 65 53 29 47 04 47 2f 6f   .......]eS)G.G/o
|   2048: 76 be c9 87 4b 41 27 63 28 f9 b0 48 a9 91 36 32   v...KA'c(..H..62
|   2064: b7 e1 1f 84 52 c5 3f 81 98 6d de e0 31 27 eb 49   ....R.?..m..1'.I
|   2080: 0c f6 0c 00 5c db 30 f4 67 4e 90 f8 32 10 87 0f   ......0.gN..2...
|   2096: 27 0c 19 71 b1 b8 e6 ea 40 e9 e0 fa 30 44 f0 d0   '..q....@...0D..
|   2112: ae 89 05 c6 71 0d 18 36 f5 75 4d 6e b9 cf 60 2a   ....q..6.uMn..`*
|   2128: e9 3e 54 d3 86 34 3b 69 87 47 64 9f 0d 99 d5 d7   .>T..4;i.Gd.....
|   2144: 42 bf c6 dd 24 51 32 5d e8 70 cf dc 67 55 58 bd   B...$Q2].p..gUX.
|   2160: a0 93 c4 f2 05 73 91 bc 46 d1 4a ac 03 9d b1 ab   .....s..F.J.....
|   2176: e9 6a de 28 8e d4 2a 75 e6 0b f5 ed a0 a6 45 e2   .j.(..*u......E.
|   2192: ea 86 1e a9 9d ad d9 8c 82 72 26 9e 7b ca a5 13   .........r&.....
|   2208: 3e ab 9f ed bf 81 9d 51 f0 f4 47 be 89 e1 0b a4   >......Q..G.....
|   2224: ec 5f 1c 5d b2 64 d0 7f 31 59 2e 68 2c 54 d2 69   ._.].d..1Y.h,T.i
|   2240: 91 34 56 e5 b9 83 0d 3a 00 9d e3 3d 78 6d 47 1d   .4V....:...=xmG.
|   2256: 09 7d 67 de d8 a2 92 e6 b1 36 4d 89 c0 dd ce 76   ..g......6M....v
|   2272: df 73 aa 1d 88 38 c5 63 43 ac af 28 35 f8 48 5c   .s...8.cC..(5.H.
|   2288: 9c 4d 50 ab f4 f3 c8 3c 6a 82 99 68 f9 25 7e 86   .MP....<j..h.%~.
|   2304: 18 31 73 f9 f7 05 15 11 9f e4 e1 42 f1 26 14 2d   .1s........B.&.-
|   2320: e5 fc 28 09 35 71 a6 23 6f 55 25 89 c3 73 13 f1   ..(.5q.#oU%..s..
|   2336: 91 52 d4 e7 8a 20 b9 53 be 2f 30 d7 7a 10 e4 89   .R... .S./0.z...
|   2352: 5f d1 84 df 5b 27 96 6f fd e2 7c 8b 8e 69 d7 1c   _...['.o..|..i..
|   2368: e4 d9 95 4b 6a e7 f4 6e 0a 22 ac 21 6a 0d 1f 32   ...Kj..n...!j..2
|   2384: 3b 6a 15 32 ce a2 38 6e 10 52 42 65 48 f7 67 0a   ;j.2..8n.RBeH.g.
|   2400: 6c 1e 91 ec 39 01 e7 3a 22 0e 45 30 ee e7 f5 a3   l...9..:..E0....
|   2416: 75 78 f5 09 6c a7 12 6f 81 46 b3 7e ae d5 79 88   ux..l..o.F.~..y.
|   2432: c0 d0 dc 26 24 33 b4 86 cf 58 9f f0 70 48 74 8b   ...&$3...X..pHt.
|   2448: c9 70 03 f4 1a b3 43 c9 f3 ea 8e ee 7c 1f fc 4d   .p....C.....|..M
|   2464: c3 9f c6 d1 b7 ad 0f 79 62 7b 9b b3 5b d0 fa 6e   .......yb...[..n
|   2480: 9f c0 ff 15 cc 71 5e a7 56 c5 ff 1d 0c ea 8e 48   .....q^.V......H
|   2496: 81 87 6a e5 79 c7 06 9b 7b 02 d0 78 65 1d aa 96   ..j.y......xe...
|   2512: 23 4a a4 67 1e 05 a9 70 03 de 96 91 9e 91 a5 ca   #J.g...p........
|   2528: b0 98 25 89 a6 2d 00 0f 0e ec 2d b0 92 72 f6 56   ..%..-....-..r.V
|   2544: fc d8 18 06 27 b7 b9 c9 9f db a5 30 51 48 f9 ed   ....'......0QH..
|   2560: 74 0a a3 a3 82 8a fc 6b 31 a0 dd 29 99 1e 61 d6   t......k1..)..a.
|   2576: b5 5f 28 37 23 e7 e9 c8 8c 2b b4 bb e4 f0 7d d3   ._(7#....+......
|   2592: 44 2a 86 2d 3e 3e 97 b3 74 4a 55 b5 cf 4f 28 29   D*.->>..tJU..O()
|   2608: f8 00 70 ee 67 18 5e 7d 4d 1a fd b5 92 84 69 4e   ..p.g.^.M.....iN
|   2624: c4 de 4d 45 90 3e 70 22 d3 b6 b0 74 b3 b0 21 86   ..ME.>p....t..!.
|   2640: 2d 10 d1 d3 2f d8 89 d5 b5 bd e0 92 66 a0 99 30   -.../.......f..0
|   2656: 0f 6d de e8 db 9a 2d 6c 20 89 43 3c e0 61 32 67   .m....-l .C<.a2g
|   2672: ee f6 be 79 20 b4 06 11 63 b3 89 0f df 28 56 df   ...y ...c....(V.
|   2688: 94 3c f2 31 b0 b8 5f 11 6c 6b 9b d3 43 cc f0 38   .<.1.._.lk..C..8
|   2704: 6a 92 3d ee a6 92 95 9c 6c 02 94 31 7b ae 7a 0c   j.=.....l..1..z.
|   2720: 0b 49 0f 82 54 ae c4 b8 58 4d 57 75 d6 e9 20 5a   .I..T...XMWu.. Z
|   2736: bf 5a 2e ae 2d 18 4f 60 62 d9 1f 91 1d cd da f4   .Z..-.O`b.......
|   2752: 00 e2 d8 fd f0 20 d3 70 2b 4d 6f a1 80 a2 25 16   ..... .p+Mo...%.
|   2768: 7e 75 5e 7b 45 8d 72 62 11 ba 36 7e 4f 89 ba 4d   ~u^.E.rb..6~O..M
|   2784: e2 0c e3 f4 0d da ac 14 89 36 e5 c8 4f 67 a5 33   .........6..Og.3
|   2800: ff c2 91 ac 81 25 39 21 c4 79 5c 97 6d 97 45 3a   .....%9!.y..m.E:
|   2816: 6e 00 60 1e c0 e4 ee f3 a6 98 16 43 ee 56 62 32   n.`........C.Vb2
|   2832: 85 db 7a 83 af 26 a6 3f be 66 c6 5b ff 51 d7 f2   ..z..&.?.f.[.Q..
|   2848: 8f 2e 13 c4 b2 67 72 ac c4 4d a3 3a 69 cb b5 bc   .....gr..M.:i...
|   2864: 01 74 09 53 16 3a fa 7d 0e 24 8a c8 93 14 4d ca   .t.S.:...$....M.
|   2880: 95 2f 30 dc d1 6c 42 d6 78 04 c8 91 4e 86 2a a0   ./0..lB.x...N.*.
|   2896: 0f 71 da 74 20 b0 a9 a5 a5 7e 96 44 e1 86 d1 af   .q.t ....~.D....
|   2912: bc 1d 24 19 11 54 3a e1 a6 db 38 f8 64 59 29 0f   ..$..T:...8.dY).
|   2928: 3d 7b ce 0d c5 38 bd cd c2 85 13 f8 62 09 83 96   =....8......b...
|   2944: 20 2c 3d 81 6b 9d 48 24 4e d6 eb 88 7e f4 6f f4    ,=.k.H$N...~.o.
|   2960: fc 55 32 3d ab 74 bd f1 4f 75 66 f5 53 a5 a6 7f   .U2=.t..Ouf.S...
|   2976: f5 89 da df 35 a7 44 0b 84 8d 85 f3 08 9b 63 14   ....5.D.......c.
|   2992: 8b ea 66 43 6f 07 a3 e5 33 eb fb 8b 11 40 10 7d   ..fCo...3....@..
|   3008: 11 cd 65 d7 38 4a 50 d7 02 73 ed a6 15 ac 82 77   ..e.8JP..s.....w
|   3024: 0d 8c f3 7a ea a2 36 32 11 52 71 d3 f4 24 13 5a   ...z..62.Rq..$.Z
|   3040: 22 e6 75 14 28 7f b7 0c a8 71 16 20 3c 79 f5 ce   ..u.(....q. <y..
|   3056: f2 0f 05 4a 91 1f 32 d0 da 6a ad 47 ca a3 99 66   ...J..2..j.G...f
|   3072: 89 da ac 67 bc 1a f0 84 4c 71 a6 7f aa 30 45 01   ...g....Lq...0E.
|   3088: dd 31 cd 34 43 b7 0c 2c 24 9a 21 c3 97 3a 40 72   .1.4C..,$.!..:@r
|   3104: 55 09 a4 d1 6b 18 78 91 20 e5 4f c6 46 ab fd fd   U...k.x. .O.F...
|   3120: 36 19 d0 6a 44 c8 49 61 d8 e4 e1 b1 30 74 68 82   6..jD.Ia....0th.
|   3136: b6 70 9f 54 c8 f1 69 b7 89 61 24 1b e9 6e 99 f1   .p.T..i..a$..n..
|   3152: 9b d5 68 b2 ac ec 67 99 3d e6 30 73 92 b5 c9 e4   ..h...g.=.0s....
|   3168: 73 f7 ff b5 d4 8a 35 85 8c 9f 3c e2 7e df f8 e4   s.....5...<.~...
|   3184: 17 0a ed c0 0f f2 4e a9 72 0d 9d d7 35 90 bc 2a   ......N.r...5..*
|   3200: 9f 95 09 ef 77 19 1b 2e 71 af 3c 83 f4 85 fe fa   ....w...q.<.....
|   3216: 14 dc 19 38 4b a4 c0 71 c7 a4 ba 47 db 00 a1 0a   ...8K..q...G....
|   3232: a4 ee 3c 2f 5a 08 9c 6c 8e bb 47 66 6d ad de 91   ..</Z..l..Gfm...
|   3248: 21 ee b4 9a 90 24 96 91 36 6b cd 33 fd 4e 64 07   !....$..6k.3.Nd.
|   3264: bf 04 37 54 ed b3 88 34 65 ed 59 0b f6 45 ea aa   ..7T...4e.Y..E..
|   3280: c5 2e 54 c0 f1 6b 22 de cd fd 1b be 57 76 b7 24   ..T..k......Wv.$
|   3296: 57 f3 d3 06 f8 86 82 f6 cc cb e4 e9 cb 5f e2 26   W............_.&
|   3312: 6e a2 4d 35 85 f1 03 75 92 8a 8b 1a 58 ea b7 a6   n.M5...u....X...
|   3328: 21 f1 15 ef 55 d2 19 43 d7 66 fb a4 7d 8a 0a 09   !...U..C.f......
|   3344: 28 64 13 6c 71 47 84 de ab 05 15 4d 8c 01 5d 68   (d.lqG.....M..]h
|   3360: 92 ea e3 2d 80 5d 4f ce 99 65 e6 8a f5 4a 78 52   ...-.]O..e...JxR
|   3376: 4c b9 6c 98 8c e8 e7 9e a2 0c ed b5 be 81 c0 a8   L.l.............
|   3392: 32 b2 9e 76 ef 89 9e f1 6a 26 7e 5c 74 e1 e7 c3   2..v....j&~.t...
|   3408: b2 75 6a 49 85 50 41 6c 87 37 13 8d 3c 3a 60 6d   .ujI.PAl.7..<:`m
|   3424: f0 2c e5 30 a9 51 39 ac 4f b2 63 17 e5 c8 16 26   .,.0.Q9.O.c....&
|   3440: ce d5 9d de 8e ae 81 25 ed f5 cd 2c de 5e 55 bd   .......%...,.^U.
|   3456: 6c d5 28 96 13 8b ce 68 b6 2a 88 90 9d c5 4c 18   l.(....h.*....L.
|   3472: f6 cd b6 75 1d 49 22 ea 80 f9 24 b9 9f 05 6f 62   ...u.I....$...ob
|   3488: 45 30 7b b9 e3 67 0a 61 aa a8 fc 2f 85 00 2f 2f   E0...g.a.../..//
|   3504: d0 64 3d dd 87 3d e2 dd f7 03 ff 18 d2 96 c3 86   .d=..=..........
|   3520: b2 7e f2 12 f5 9e 9e fb 8c 95 95 98 48 51 a2 4d   .~..........HQ.M
|   3536: 8d 8a 3b 1a a1 5d e0 3e 95 dc 4c 1e 89 bb cd cb   ..;..].>..L.....
|   3552: 7f e9 e1 a6 3b 68 b0 1e a0 81 5a 54 f7 3c a2 7a   ....;h....ZT.<.z
|   3568: 24 ee 8e 43 a7 df 14 22 da b2 8c 80 6a 40 4c bf   $..C........j@L.
|   3584: f8 5a 4e d1 34 af 19 3f dc 4f 93 29 83 d1 af 7a   .ZN.4..?.O.)...z
|   3600: 33 fe 25 1a 1c d5 c1 e5 98 4e 30 4d 2b 2c 6e 55   3.%......N0M+,nU
|   3616: 8d d3 0f d5 f5 a3 a1 44 10 ba d6 2d 05 71 5d 4d   .......D...-.q]M
|   3632: 15 e6 06 21 00 56 c1 45 21 63 f8 61 bf c5 75 79   ...!.V.E!c.a..uy
|   3648: f5 5f 83 53 ba cd a0 e6 12 45 3b 8b 33 b6 4d 29   ._.S.....E;.3.M)
|   3664: 41 c9 ad 09 a3 f1 a7 a6 6d 8d ec 16 68 b4 a3 fb   A.......m...h...
|   3680: 01 1a c3 ee 78 17 d9 de cb 2e 42 d4 a3 56 8f f4   ....x.....B..V..
|   3696: 3c 75 b1 92 d0 b5 75 10 69 cc c0 50 a4 bb d0 4c   <u....u.i..P...L
|   3712: 37 3d 0a e8 8b 38 6a 70 88 a7 f9 00 26 43 fc 47   7=...8jp....&C.G
|   3728: 19 ea e1 43 08 b3 0d c0 f1 d5 30 c6 3d c4 86 68   ...C......0.=..h
|   3744: 32 9f fb 35 a5 1d 5c 02 1a 07 2b 1e 8a c9 d3 1a   2..5......+.....
|   3760: 53 43 54 c1 0c 06 51 3b fc df a1 a9 69 3e 72 cd   SCT...Q;....i>r.
|   3776: 8d e5 f5 f6 d4 49 8d b4 65 50 38 8b b3 3e 20 c1   .....I..eP8..> .
|   3792: 07 cd ad 7d e3 d1 8e 5f 6e 76 7b fe 01 ba 08 74   ......._nv.....t
|   3808: 16 a5 1b 5e 95 a2 ff 91 bb 9f 64 3f a4 e5 95 be   ...^......d?....
|   3824: d2 59 02 aa c5 06 66 9e fe 56 6e d1 1d 31 6f b3   .Y....f..Vn..1o.
|   3840: da 6d b4 3a 17 86 e0 e6 c1 37 21 68 6c 33 d3 58   .m.:.....7!hl3.X
|   3856: e8 67 fa 04 8d 59 ae e4 fb 1f 8c 48 17 7e bb 8c   .g...Y.....H.~..
|   3872: 17 61 b4 a7 e4 6b 87 c0 6a 8b 5f d1 76 16 5c f7   .a...k..j._.v...
|   3888: 81 b4 2d 66 ad ba 46 6f 95 bf a8 19 e8 82 05 7f   ..-f..Fo........
|   3904: 43 47 8b 63 b4 14 c6 2a de 90 8c 6d 04 3d 90 dc   CG.c...*...m.=..
|   3920: c4 6b d0 4c 33 9f 6c a7 38 6b fd b8 53 de 17 5e   .k.L3.l.8k..S..^
|   3936: ef e4 17 19 25 32 eb 12 86 03 3c 61 2e b4 06 ca   ....%2....<a....
|   3952: 3b ff d8 cf de 77 58 e9 73 f4 49 8f ba ca 41 9c   ;....wX.s.I...A.
|   3968: 76 70 52 1c ea 26 76 44 38 81 b0 07 a2 e9 bb 08   vpR..&vD8.......
|   3984: 7d b3 9f b5 2a 55 de 4b f4 b5 fd ff a2 e0 25 ef   ....*U.K......%.
|   4000: b3 d6 88 0a 68 3a 6f 24 07 ce fd 32 c4 3f fa 98   ....h:o$...2.?..
|   4016: dc ee 60 4c 54 17 a8 82 0f a9 9d 2d 04 73 db 47   ..`LT......-.s.G
|   4032: f3 56 3a cb 9d 68 e8 f5 d8 fa cd 78 ee 65 74 ed   .V:..h.....x.et.
|   4048: b5 ae 5a 8c ae 4d 2f 34 54 b4 ac f9 5f b4 70 89   ..Z..M/4T..._.p.
|   4064: ea 58 fa 8b 70 6d 6c 54 b9 ea eb e8 08 fc 52 bd   .X..pmlT......R.
|   4080: c4 d5 6b 1c 64 db 93 a9 d9 5d 32 e3 12 06 ca 14   ..k.d....]2.....
| page 16 offset 61440
|      0: 0d 00 00 00 01 04 3f 00 04 3f 00 00 00 00 00 00   ......?..?......
|   1072: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97   ................
|   1088: 3e 08 06 00 ae 7c 00 00 7e 76 33 c8 5d be 03 93   >....|..~v3.]...
|   1104: a8 31 d7 92 4a d2 68 29 8d e4 3c 76 6f d3 a0 f2   .1..J.h)..<vo...
|   1120: 70 1e 80 3a 2a 79 78 9e ff e4 6c 64 4d 6e 86 73   p..:*yx...ldMn.s
|   1136: 39 5d 1e 22 92 26 3e 38 0d b3 e3 6a 13 01 3a 81   9]...&>8...j..:.
|   1152: 2a 01 f9 21 05 ec 07 3f 6f 7d ba 17 5d ba 3a 04   *..!...?o...].:.
|   1168: a9 cc 88 35 4f 43 4c dc ab 1d 1d b0 24 1f a2 83   ...5OCL.....$...
|   1184: 69 4a 89 1e a8 a3 de bc 17 15 be 3d 07 ae 42 02   iJ.........=..B.
|   1200: f6 60 ff 36 08 cf 63 1f b5 be b1 1c 45 14 b0 56   .`.6..c.....E..V
|   1216: 0c 2e b9 49 49 69 47 17 da 41 4e 91 0b 5a bd 76   ...IIiG..AN..Z.v
|   1232: be 67 65 82 27 35 0a 23 a4 21 f4 ba 78 af 0a 7c   .ge.'5.#.!..x..|
|   1248: 0e f0 ca 90 c6 32 d9 dc f1 dc 25 33 da 76 c0 f5   .....2....%3.v..
|   1264: c2 4d ed 55 d7 f8 1f 44 82 37 c3 d3 90 12 23 52   .M.U...D.7....#R
|   1280: 8d 3c 3d f0 9e bf 7b 0e 49 8a 32 5d a1 64 53 26   .<=.....I.2].dS&
|   1296: cb be bc 26 dd bf f8 a6 ad 57 e5 35 68 c1 6c b9   ...&.....W.5h.l.
|   1312: 02 d7 0d 70 f4 d9 10 8f 75 35 8b 60 21 46 62 60   ...p....u5.`!Fb`
|   1328: e4 e7 70 35 0f a9 70 0d 50 da 5c c2 17 9b c6 3b   ..p5..p.P......;
|   1344: 61 83 9f 3f 1d f4 28 dc c6 32 a6 12 ff 56 dd 0e   a..?..(..2...V..
|   1360: 57 08 0e 0d 5b f8 ea 32 33 20 a7 a1 a4 9b b3 77   W...[..23 .....w
|   1376: 4f db 85 06 dd 0b 52 b0 45 ff a4 e5 23 5e ea c0   O.....R.E...#^..
|   1392: d6 54 d6 84 cd c4 fc 2e 95 ec 78 13 cf 9a fa e3   .T........x.....
|   1408: a1 5a b3 60 1a ab 1a 97 21 67 9c cd 44 6f ee a9   .Z.`....!g..Do..
|   1424: bf 1f 07 52 d0 1a a4 ae 15 1e b5 01 0d ac 31 32   ...R..........12
|   1440: 11 7f 67 b4 9c 20 78 28 8b 4a 79 32 44 c8 aa 1d   ..g.. x(.Jy2D...
|   1456: 05 4b 94 3e e2 f0 d4 f2 16 3c 8e b7 67 13 98 47   .K.>.....<..g..G
|   1472: 2b 6a 1a 98 c9 82 7d a7 a7 7d ee 62 dd a8 29 58   +j.........b..)X
|   1488: 98 5b 2e 5b 62 1b 1b 21 37 4d eb e7 85 ac a3 8d   .[.[b..!7M......
|   1504: fe 69 ca 05 34 83 84 34 47 8d 5b b0 8d 71 f1 22   .i..4..4G.[..q..
|   1520: 07 b5 a9 be 42 88 58 27 84 3e 37 1c 0f c7 1f 77   ....B.X'.>7....w
|   1536: 72 5e 2c fc 80 43 03 71 00 22 7f fe 5d fe ea a7   r^,..C.q....]...
|   1552: 33 3a c6 ae db e7 1d ba 8b 61 8c b9 b4 b2 ab b4   3:.......a......
|   1568: 2f ec 9d b1 9c bb 13 7b 6e 3a b9 aa 43 b2 14 6f   /.......n:..C..o
|   1584: f0 27 00 31 f6 5b 9c e9 96 40 3a 13 2f fc 6b ae   .'.1.[...@:./.k.
|   1600: 0a 55 bf b3 cd 83 23 25 f1 15 e2 2e bc 7c 6b 29   .U....#%.....|k)
|   1616: 90 8f 85 ff 5b 5a 18 52 03 84 4d f9 f9 fa e1 a0   ....[Z.R..M.....
|   1632: e8 32 29 9c 5b 9e ed 39 b3 17 f8 ef 7f 55 b4 3f   .2).[..9.....U.?
|   1648: c3 f3 66 f1 bc 15 1b 78 2c 9b ab cf e1 10 d0 46   ..f....x,......F
|   1664: 3d 21 2b eb 4f 8f 1d eb 8a 5e 87 23 72 50 04 ea   =!+.O....^.#rP..
|   1680: 8f 53 1b 3a 3f cf d5 92 5a 06 c1 18 25 33 41 84   .S.:?...Z...%3A.
|   1696: 77 56 bf a5 8a d1 ff 97 51 34 d3 24 88 12 dc 33   wV......Q4.$...3
|   1712: 09 09 fc 68 b5 2a 4a cf 7c 73 d8 ff 93 29 40 1c   ...h.*J.|s...)@.
|   1728: 8e ea 7d e3 7f 25 57 f5 bf 2b 19 80 4d fa 23 35   .....%W..+..M.#5
|   1744: 18 8b ad af 46 85 3b 51 34 49 dd cb 39 d8 50 50   ....F.;Q4I..9.PP
|   1760: 7a a5 58 af 72 66 5d 21 c2 e2 03 1f ee bb d2 b4   z.X.rf]!........
|   1776: 62 d2 f4 c0 fb 04 12 b2 35 0c 0f 0d b9 e2 a5 28   b.......5......(
|   1792: 87 5b 76 c7 39 4d 18 8d 3f 61 ab a0 84 4a 11 22   .[v.9M..?a...J..
|   1808: e1 a9 69 55 2b 03 41 34 73 83 0d 0b ed da a6 d8   ..iU+.A4s.......
|   1824: f8 ff 9b d2 62 1b ca 1a 40 4f 0a 86 ad e7 92 af   ....b...@O......
|   1840: ce 69 19 8e 35 5d cd 50 4e 53 2d 90 46 90 ae 8a   .i..5].PNS-.F...
|   1856: 43 ac 8b 30 7f 3b b3 05 78 63 b3 b7 0b 3d 2a 13   C..0.;..xc...=*.
|   1872: 55 83 ed a0 61 6b 12 30 5c 46 f3 1f 18 1f bd 89   U...ak.0.F......
|   1888: af 86 9a 82 ed 89 35 0e 29 06 2c b8 97 c5 ef 46   ......5.).,....F
|   1904: 90 ce 6c 83 f8 7d 08 75 76 b4 07 6b 48 15 bb bd   ..l....uv..kH...
|   1920: c2 fd 79 a8 7f 54 e4 d5 93 c2 17 09 3f bb 58 84   ..y..T......?.X.
|   1936: dd 78 7a 81 c4 13 70 e5 23 73 d4 60 25 0f 91 bc   .xz...p.#s.`%...
|   1952: a9 8e 54 64 46 e1 8f 11 66 7c 1e 31 5b 9e 10 d9   ..TdF...f|.1[...
|   1968: 7e 09 e8 bc 2f 73 d4 f6 27 0c a0 62 5d ce 65 40   ~.../s..'..b].e@
|   1984: f7 24 b0 bf f0 26 c0 17 1a dd d3 5d 16 35 22 10   .$...&.....].5..
|   2000: 4d c4 cf 5b 22 2f 12 b2 5b f2 87 04 34 4d 5c 9d   M..[./..[...4M..
|   2016: 50 48 71 c7 8e bb 7d ce 89 f3 e4 4a c1 f2 92 4f   PHq........J...O
|   2032: 90 4d 58 ac 27 60 a7 e9 31 41 ca b1 c0 38 ce 2d   .MX.'`..1A...8.-
|   2048: df 40 e9 cd db 2f f3 28 09 ef 14 79 99 ef 66 1b   .@.../.(...y..f.
|   2064: e6 c0 7f 4c cc 61 96 b6 f9 95 9d 1b 90 16 55 08   ...L.a........U.
|   2080: 71 ad 92 88 98 01 7f b9 8e 9c a2 f4 d4 24 33 a0   q............$3.
|   2096: 53 f2 01 df 47 3f 8d 15 a8 d1 70 a9 c2 70 f8 75   S...G?....p..p.u
|   2112: b4 ed b6 7d 82 95 63 5e 86 c1 3a 7c de b1 46 fd   ......c^..:|..F.
|   2128: b8 30 42 36 83 35 e2 4a 78 c2 b5 b9 1e 57 f2 19   .0B6.5.Jx....W..
|   2144: 91 6d ff 4f 87 97 55 98 a3 86 a2 54 1f 2f 0c 8e   .m.O..U....T./..
|   2160: 72 d6 a0 37 f2 bf 84 a3 a5 b3 87 12 a3 ef 0a 00   r..7............
|   2176: 31 69 49 83 8c 6e 82 3a 84 62 a8 ce ee ce 91 61   1iI..n.:.b.....a
|   2192: b7 26 c1 fd bf 77 15 81 23 e6 d5 6f bb c4 ab eb   .&...w..#..o....
|   2208: 8b a7 fc b6 4e cb c1 61 ab 59 a2 dc ca ca f3 42   ....N..a.Y.....B
|   2224: 90 16 d8 d0 03 43 c1 e0 d9 25 50 b0 17 65 64 d0   .....C...%P..ed.
|   2240: 11 be 52 a8 e3 bd dd 7f 39 1e 0b 85 ae 92 c0 1c   ..R.....9.......
|   2256: 0c 3b 06 2a bb be b6 c7 94 d6 83 6b b0 17 6d 24   .;.*.......k..m$
|   2272: b1 b5 2d 22 5e 7f b9 db 47 65 e6 21 37 a2 2f d3   ..-.^...Ge.!7./.
|   2288: 03 8a 91 c0 5a de 52 27 dc 4b 9a 92 f1 fc f0 93   ....Z.R'.K......
|   2304: d1 de 9e 04 73 13 c5 ec 25 36 54 15 94 92 b9 de   ....s...%6T.....
|   2320: bd e2 39 b3 5c 88 8c e6 11 48 28 b8 0d 50 5a 6f   ..9......H(..PZo
|   2336: d9 8a a6 17 4f a0 82 ff 94 70 28 10 0c 41 80 c4   ....O....p(..A..
|   2352: d9 42 a9 fe d2 f7 1c 70 45 74 fa 65 d2 cf 49 00   .B.....pEt.e..I.
|   2368: b8 24 83 06 97 f5 1c 48 a7 dd 82 2f f0 77 f5 e6   .$.....H.../.w..
|   2384: 5c 03 11 fa 65 46 57 90 c0 6f 1f 86 58 de 34 21   ....eFW..o..X.4!
|   2400: 5f 76 d7 1e 1a 16 6a e1 ad 26 ae 6a 32 53 30 8b   _v....j..&.j2S0.
|   2416: db d9 05 93 22 87 58 e8 91 d8 26 80 85 f0 01 93   ......X...&.....
|   2432: 77 0e 88 91 bc bc ce e9 5e 6e e8 b8 aa 4e ad fa   w.......^n...N..
|   2448: a8 a2 5a 17 b8 88 56 f5 71 8a 70 fe 83 4f 5c 8c   ..Z...V.q.p..O..
|   2464: 07 1a 45 cf a9 89 05 c6 81 79 90 a5 d2 53 a4 3e   ..E......y...S.>
|   2480: ac be 52 ae aa 9d 30 66 c5 b7 1f 7a c8 8e 6a 3b   ..R...0f...z..j;
|   2496: 82 54 6a 62 aa 6e 4a c4 02 11 5b 69 12 6f 84 23   .Tjb.nJ...[i.o.#
|   2512: 17 f6 3d 81 1f 29 60 28 7c e2 95 b4 ae 39 e6 6b   ..=..)`(|....9.k
|   2528: 5e c5 df 82 66 82 57 d4 84 cd 2b 1e f2 a0 31 82   ^...f.W...+...1.
|   2544: 8b 9f 0e 0c 72 76 6b 6c 5b cb 0c 5c 2a 77 22 df   ....rvkl[...*w..
|   2560: 1e 96 44 f9 4e 22 dd 22 ff fc 14 a2 cc 36 77 02   ..D.N........6w.
|   2576: 81 8f 22 1e 46 ea 11 e1 85 41 8a ee 69 64 e6 27   ....F....A..id.'
|   2592: 8b 46 0b 4a 47 35 f4 72 71 62 a1 0c 4d 55 be a0   .F.JG5.rqb..MU..
|   2608: 1f ae ae 8b a6 2d de 54 04 24 05 98 06 43 04 57   .....-.T.$...C.W
|   2624: 09 8e ff 81 ff 9c 9a 18 02 bf c3 66 8f 65 fb e3   ...........f.e..
|   2640: 66 0c 20 bb 50 f5 0c a8 a8 e9 6f 53 65 b5 3a e4   f. .P.....oSe.:.
|   2656: 48 d2 1c 86 e2 a6 35 c0 91 d4 72 b6 67 21 49 fb   H.....5...r.g!I.
|   2672: 0c f9 91 b8 64 46 c2 75 28 df ac c0 bc 4f 61 d9   ....dF.u(....Oa.
|   2688: 92 06 6b 48 d8 29 ba 4f e6 40 a8 c8 35 8b 83 e6   ..kH.).O.@..5...
|   2704: 79 ec a1 d3 c1 73 82 64 42 13 3c 7b 73 3e 7a 14   y....s.dB.<.s>z.
|   2720: 2d db ac 00 76 00 81 ae fb c1 30 7b dc 57 39 f5   -...v.....0..W9.
|   2736: 27 6b 1a d5 ed c2 4b 21 12 3e 4d e0 8e 58 69 9b   'k....K!.>M..Xi.
|   2752: f5 cb 26 7a 62 e5 7b 3a fd 1a 8a e6 7d e6 f1 60   ..&zb..:.......`
|   2768: cc 4f 30 39 76 b7 3d 49 3f b7 59 a3 d0 a6 c8 8e   .O09v.=I?.Y.....
|   2784: 3e a8 e1 a0 1b 7d 82 39 8b c6 a5 87 3e 2c da 16   >......9....>,..
|   2800: f0 71 cc 5e 02 17 49 6d 48 24 8c 19 9e c4 d1 97   .q.^..ImH$......
|   2816: a6 cc 28 28 c9 3e c2 e3 19 6a 05 f2 bd 4c ef 44   ..((.>...j...L.D
|   2832: df 84 da 8c 3f 41 16 2f 87 b8 88 bd 6d 8b 6e dc   ....?A./....m.n.
|   2848: fa b0 44 08 ee ef 22 84 bf c0 5c a4 2f 2c 7e a2   ..D........./,~.
|   2864: 50 8b 84 cd 60 08 d8 53 4b 2d 4f 1e 3b 14 b4 62   P...`..SK-O.;..b
|   2880: 97 a1 66 49 2a 6f 3b 36 85 c2 42 58 98 5a db 3e   ..fI*o;6..BX.Z.>
|   2896: 64 fd ad 32 f2 e0 f9 5a 13 dd e1 68 6c 35 34 a5   d..2...Z...hl54.
|   2912: 3c 9a b1 8a 51 78 49 5b c6 ef 57 7f 6e de fe 2d   <...QxI[..W.n..-
|   2928: 0a 2c 1b 74 3f 19 bf 8e 6d 2f 0b 22 91 36 95 5d   .,.t?...m/...6.]
|   2944: a3 65 b6 3b 3a e4 de 70 9e 29 f4 c6 0a 23 27 d6   .e.;:..p.)...#'.
|   2960: d1 4a f6 2e 2b a0 ee 8d cd fc 42 7a c8 1a a6 36   .J..+.....Bz...6
|   2976: 17 aa f4 03 b5 cc e2 54 7a c4 fb 27 e5 90 62 20   .......Tz..'..b 
|   2992: 03 77 4d fc 35 7c 59 87 01 49 86 ae 82 6b 8b a7   .wM.5|Y..I...k..
|   3008: bc b0 b0 dd f2 ef f7 ef 0a 36 a6 25 f1 70 ba 89   .........6.%.p..
|   3024: e8 00 f4 fc c0 98 73 f2 b0 9a a2 ed d5 1e 17 d1   ......s.........
|   3040: 79 82 18 84 b0 f8 2a 5d f2 a1 03 d6 45 b0 01 26   y.....*]....E..&
|   3056: 19 01 6d b3 0e 5f 55 6c 2b 21 72 33 84 a9 ab fb   ..m.._Ul+!r3....
|   3072: 64 4d bc f0 1d 16 ae aa 09 c1 29 60 e2 63 e1 d5   dM........)`.c..
|   3088: 84 41 6e 5c 12 08 9a 04 dd 27 b8 fe 2f fb ca 83   .An......'../...
|   3104: 2a 7b eb 05 3b 77 fd 42 31 42 84 98 89 24 3c cc   *...;w.B1B...$<.
|   3120: 47 f6 bc 13 37 d7 97 98 c4 61 24 50 0b 9e e5 53   G...7....a$P...S
|   3136: 46 05 49 5e a5 51 d5 48 26 fa 31 eb 0e 76 14 16   F.I^.Q.H&.1..v..
|   3152: e9 60 f6 05 d5 bb 47 85 e2 da f6 5a 0a c0 14 38   .`....G....Z...8
|   3168: bb 70 4d be eb d8 6d 10 61 d6 9b c6 c4 f4 56 7f   .pM...m.a.....V.
|   3184: ff b8 fb 1f 92 a3 f5 74 78 7f c0 8d 9d f4 b1 a2   .......tx.......
|   3200: f4 0c 33 da 98 9e a2 61 4c c7 41 9c ea 0f 33 54   ..3....aL.A...3T
|   3216: 40 54 31 c3 04 fa d1 4b 67 80 e2 a7 6a 77 c6 ca   @T1....Kg...jw..
|   3232: 04 fc 71 ea fa 0f 92 8e d3 40 e8 0e 1c 48 a4 55   ..q......@...H.U
|   3248: 7f 74 67 ea c9 29 67 73 b9 b9 73 b1 00 1a d4 0b   .tg..)gs..s.....
|   3264: 21 95 d6 1c b4 68 2b c5 e1 18 40 7e 8e 09 6f 28   !....h+...@~..o(
|   3280: 88 2d 6f 24 d3 73 7b 89 7a a6 aa df ad ae 7b 14   .-o$.s..z.......
|   3296: d9 f0 ff 20 ba fd bf a7 d7 04 6c 35 5c 76 4e f5   ... ......l5.vN.
|   3312: d3 5b a9 2b 8f 3a 11 fa 35 26 eb 78 45 da cb 00   .[.+.:..5&.xE...
|   3328: 78 97 b1 49 82 4e c1 4d b1 aa b7 80 75 fb 20 75   x..I.N.M....u. u
|   3344: cb 3f ba 05 95 33 cd e9 b3 bd b2 84 c4 4f df af   .?...3.......O..
|   3360: 77 c2 44 24 57 01 f9 9d c1 ef b6 ce 01 6f a6 5d   w.D$W........o.]
|   3376: 3d 4b 12 e9 8f c2 a6 d5 1c 3b e4 05 83 48 aa 78   =K.......;...H.x
|   3392: 4b 3a 1c 1b ad 8e bc 49 c5 ee 91 68 28 8d 74 74   K:.....I...h(.tt
|   3408: a0 e1 20 ba 3d 62 97 0a 40 58 6b 1a c9 be 53 00   .. .=b..@Xk...S.
|   3424: 5d 9f e7 8e b6 05 7a d2 d1 89 ac fd 7f 9b ec 19   ].....z.........
|   3440: d0 95 35 e6 41 32 eb 68 85 eb 06 8c 53 f2 25 f3   ..5.A2.h....S.%.
|   3456: 19 d9 1c e7 a8 c2 c3 1c cd 78 50 4d 73 2d 5c 15   .........xPMs-..
|   3472: 7c 3e b5 f0 e8 64 f5 72 a1 4a 9d f3 87 1d 12 0b   |>...d.r.J......
|   3488: d6 50 21 18 ca 10 f9 29 32 53 14 54 08 ef 51 6d   .P!....)2S.T..Qm
|   3504: 6e 20 ae f1 3c b5 6b 8b 4c 4d 68 9f 73 99 2f d2   n ..<.k.LMh.s./.
|   3520: f2 ea ba bd 72 e4 d5 de 71 c2 15 a2 57 f7 69 c0   ....r...q...W.i.
|   3536: c4 6b cb c1 72 8e a8 fe f8 79 d2 6d 97 82 bf a1   .k..r....y.m....
|   3552: 11 35 dc 30 36 e5 32 b5 81 f7 2b 58 06 c3 28 3a   .5.06.2...+X..(:
|   3568: 43 c0 bd 16 a4 b8 f7 37 2b 1f 5f 8a 2a 09 21 4e   C......7+._.*.!N
|   3584: d7 14 35 31 e6 36 8d 6f 2b 2a e2 63 1f 59 8d 62   ..51.6.o+*.c.Y.b
|   3600: 16 cd 16 d5 5a 20 b0 4b 9c 44 4d bb 0e 8a 01 6d   ....Z .K.DM....m
|   3616: 6c 2e 09 48 6c 32 f5 96 45 0b df 3a a4 09 a4 1c   l..Hl2..E..:....
|   3632: 44 81 72 60 8a ed 10 29 c0 62 da ba 51 4f a0 7d   D.r`...).b..QO..
|   3648: e0 9b ed 31 6a 0e f8 b5 f4 69 b2 15 d4 01 ed c5   ...1j....i......
|   3664: e2 09 df cc 97 13 70 57 48 1b bd 4a ad 0b ad 8a   ......pWH..J....
|   3680: 80 3d c1 c0 c7 f2 2d d9 a8 b7 3f b8 e5 aa 0f 5c   .=....-...?.....
|   3696: e6 95 2a c6 80 83 69 ca 0e dd f9 7e 04 48 7d d3   ..*...i....~.H..
|   3712: d5 29 fd 9d 7f 59 d7 1d 9b cd c3 06 e7 51 13 bc   .)...Y.......Q..
|   3728: 60 d5 c3 d5 a9 0b 78 ab 01 3e 34 06 4f 8a 47 4a   `.....x..>4.O.GJ
|   3744: 0d a9 c1 b5 29 c4 26 c4 5d cb bd 80 f1 d4 eb b9   ....).&.].......
|   3760: 6b 7d 2f c3 95 7c 2c e3 86 c9 5d 41 ee 76 89 9f   k./..|,...]A.v..
|   3776: 3a f3 e2 c8 6e f5 37 a7 68 01 06 26 47 9c 1b aa   :...n.7.h..&G...
|   3792: 5a dc 55 89 af 53 89 9f f2 30 ee 04 90 cc 30 de   Z.U..S...0....0.
|   3808: f4 2a c9 23 59 9d cf 65 7d 2c 30 7e ae 7d 08 43   .*.#Y..e.,0~...C
|   3824: 1f a9 b8 14 3b e8 3d 1e 3e 4b 46 93 18 4b 08 ee   ....;.=.>KF..K..
|   3840: 53 f4 07 0d 4e 69 87 a4 61 9f b0 75 a7 fc 64 34   S...Ni..a..u..d4
|   3856: 86 aa a2 82 21 40 d7 7a 03 30 d0 f4 47 d2 4a ff   ....!@.z.0..G.J.
|   3872: dd 27 02 69 99 d2 c9 61 d0 fa 46 dc 07 1d f7 0b   .'.i...a..F.....
|   3888: 39 0b a3 2d 7f 9f 1b ce ca 79 69 62 bc 50 1a 07   9..-.....yib.P..
|   3904: 2c 1b 38 37 9f 93 65 dc 45 3a 1e 2b ff 3f d0 bb   ,.87..e.E:.+.?..
|   3920: 05 f2 9b 36 b5 79 9c ca 4f 7d 8a 2f 6e 62 1d 20   ...6.y..O../nb. 
|   3936: ab 6e 5f 75 19 67 e9 4a e1 c4 6a 2e 8a 06 b0 36   .n_u.g.J..j....6
|   3952: 37 47 5f a1 27 93 d4 36 80 85 f9 29 94 db 83 13   7G_.'..6...)....
|   3968: f5 16 1e 0e 6b 6c b1 c1 f2 66 0a 8e 63 ea ca 6b   ....kl...f..c..k
|   3984: f3 74 91 9e 73 62 d4 09 bd a9 64 54 e1 64 b0 e4   .t..sb....dT.d..
|   4000: b6 47 e0 ff 92 09 88 39 e1 44 f8 50 20 b2 3c 6b   .G.....9.D.P .<k
|   4016: e4 c1 a9 f8 b1 92 b1 9d f7 90 7f 96 44 0a 56 7d   ............D.V.
|   4032: 1f 50 a5 04 4a eb 4c 71 70 14 0d b1 99 65 61 7e   .P..J.Lqp....ea~
|   4048: 9d 53 e6 59 24 5c 3d 22 39 74 f7 de ec 18 93 33   .S.Y$.=.9t.....3
|   4064: 5d 1e d8 61 94 f5 5f ca cb c5 a0 ec 13 56 78 51   ]..a.._......VxQ
|   4080: f7 a6 32 d6 c0 02 d8 9c 38 9e af e3 ba 46 69 b2   ..2.....8....Fi.
| page 17 offset 65536
|      0: 0d 00 00 00 01 04 3f 00 04 3f 00 00 00 00 00 00   ......?..?......
|   1072: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97   ................
|   1088: 3e 09 06 00 ae 7c 00 00 67 b9 3e 40 aa 45 11 79   >....|..g.>@.E.y
|   1104: ad 46 a6 a7 42 e7 7c 05 62 a4 28 61 03 fc 1c e4   .F..B.|.b.(a....
|   1120: 48 2e f1 ef d9 09 23 04 f4 d7 c2 ad 73 c4 d8 69   H.....#.....s..i
|   1136: cf 15 ef a5 1a ba db 63 7c d8 e9 4c 70 cf 08 d8   .......c|..Lp...
|   1152: 62 d3 ec 60 a0 93 06 fe 50 87 b5 22 48 37 b8 46   b..`....P...H7.F
|   1168: 30 26 ed 8d 2c f3 ed c1 51 62 e8 ce 13 45 b4 4a   0&..,...Qb...E.J
|   1184: 9a 3c 76 c4 fd a6 e2 de 26 04 93 69 30 3c 26 4d   .<v.....&..i0<&M
|   1200: da d6 eb b8 33 b3 b3 c2 d6 13 d3 42 b4 93 1f 36   ....3......B...6
|   1216: e4 12 72 d5 81 36 3f 83 12 92 ec cd 23 c0 d6 14   ..r..6?.....#...
|   1232: 63 8d 04 d8 e1 9b 21 3e 31 a9 dc 33 9a 20 e3 01   c.....!>1..3. ..
|   1248: 2f 8f 00 d5 47 ae 22 01 bf 83 40 da c4 74 43 56   /...G.....@..tCV
|   1264: 32 35 6e c9 3a 82 44 0e 86 32 5a 8e 46 5c 16 23   25n.:.D..2Z.F..#
|   1280: e5 dc 7e 38 26 fd ba d1 d3 d0 7e 4e 88 6e 2a 85   ..~8&.....~N.n*.
|   1296: d1 25 70 b4 fc 55 2b 5a 5b 4e 01 1b 20 21 d2 2b   .%p..U+Z[N.. !.+
|   1312: c1 5b e9 3e f1 fe 3f 65 18 07 a6 10 3a 88 e5 9b   .[.>..?e....:...
|   1328: 4d 83 91 f2 1f b5 03 2a cb 57 21 e2 20 fc 35 99   M......*.W!. .5.
|   1344: b1 49 4a 0c b9 04 35 b9 b0 43 52 14 e7 2d 03 30   .IJ...5..CR..-.0
|   1360: 73 cc 40 39 c3 d6 58 1b 90 85 df 21 6b e4 03 87   s.@9..X....!k...
|   1376: e1 de 4c 36 2c f3 c1 0b 75 92 a9 11 6e 9b de ac   ..L6,...u...n...
|   1392: cb 26 b9 8d 48 47 f3 63 44 30 b0 e6 84 31 ec aa   .&..HG.cD0...1..
|   1408: f9 64 3b b2 12 b4 13 46 be 97 6f 36 37 3a ea 4b   .d;....F..o67:.K
|   1424: ef 0d d6 04 44 21 e3 25 72 6c 70 d5 58 87 7d 16   ....D!.%rlp.X...
|   1440: 37 39 d3 0a 7b fe e2 81 d1 50 6a 62 6c a8 86 ca   79.......Pjbl...
|   1456: b9 f4 4e b5 04 c3 97 1b 4e 65 49 ee f4 cd 9c e4   ..N.....NeI.....
|   1472: 89 7d 7e c8 29 9b 3e 88 82 b7 68 c4 9b ea 75 48   ..~.).>...h...uH
|   1488: 1b 5b 93 0d 12 86 df 35 44 28 95 6c f2 c4 e5 3b   .[.....5D(.l...;
|   1504: 89 a7 bf 11 ce 79 76 99 bb 0d 01 2e 58 e3 e1 0d   .....yv.....X...
|   1520: 06 19 5e 28 bc 06 32 4e 76 bd e5 01 a0 20 5c 3f   ..^(..2Nv.... .?
|   1536: 15 ad e8 4e 64 5a 67 a4 77 3f 23 c2 be 0d 96 b5   ...NdZg.w?#.....
|   1552: 28 e9 c3 60 ec 5d 09 73 e9 dd 40 a8 7d a0 ac 4f   (..`.].s..@....O
|   1568: ef 82 ac 4d 25 19 a8 1b 22 71 c2 fa 97 c3 27 da   ...M%....q....'.
|   1584: 44 14 f0 41 26 20 fd 57 4f 4e 9d f5 b3 d5 7c 72   D..A& .WON....|r
|   1600: f4 e5 56 0c 8e e8 c0 39 1c 3c 0e bb ce 8f 08 cb   ..V....9.<......
|   1616: 7f dd 0c fc 11 17 4b 41 03 b6 43 17 25 92 84 8b   ......KA..C.%...
|   1632: f8 51 57 92 93 14 25 11 83 ce da bf 04 0d ed 32   .QW...%........2
|   1648: 07 dc 6d b5 e1 c5 74 42 07 06 2a eb 2c a0 78 a7   ..m...tB..*.,.x.
|   1664: de 21 66 0b ea 49 fc e9 26 87 63 5c 8f 66 59 95   .!f..I..&.c..fY.
|   1680: c1 cd e9 00 79 05 0f 57 d0 d5 a9 1e 48 f6 7a 9d   ....y..W....H.z.
|   1696: 80 6d 5c 74 55 3d fd 67 0e ff 74 26 70 bf c3 9b   .m.tU=.g..t&p...
|   1712: 5f af 8b 43 69 e0 49 31 63 2b e4 9f 59 09 0e 5a   _..Ci.I1c+..Y..Z
|   1728: 18 84 b3 f4 19 17 18 16 5b fd ed 78 5f 68 ec 2c   ........[..x_h.,
|   1744: d7 66 05 6e 47 eb 9b a1 52 90 0f 34 99 4f a0 fd   .f.nG...R..4.O..
|   1760: 21 f7 4d da f6 ae e4 57 51 63 59 e1 ee b8 32 6a   !.M....WQcY...2j
|   1776: 03 ac c4 c4 69 73 10 32 d5 94 25 7e 6b d0 ec 62   ....is.2..%~k..b
|   1792: 0d 17 f7 16 24 b5 df 11 7b 29 01 03 d8 ff 1a 2f   ....$....)...../
|   1808: 7f 51 ab 9e 41 5b aa 0c a5 5d e9 69 ce 3b 85 4e   .Q..A[...].i.;.N
|   1824: 7d ff 5a 37 b5 74 18 78 85 95 4d 44 8a d9 8c ea   ..Z7.t.x..MD....
|   1840: 2e 10 6e e6 cb a1 3d ef 57 38 f0 9b f0 8b 0b 68   ..n...=.W8.....h
|   1856: f9 f8 9f ac 58 da f3 9c 2b 2a 90 c7 4d 00 e4 4c   ....X...+*..M..L
|   1872: 46 59 01 1c 0c 6b 08 6d 33 07 41 d0 5d 23 20 3b   FY...k.m3.A.]# ;
|   1888: 00 e0 6b 32 2e 76 3a 7e 09 3e c9 66 90 4f d5 9b   ..k2.v:~.>.f.O..
|   1904: 8a bd b1 6d f9 33 d9 5a b3 bb a1 2a 45 31 0b c6   ...m.3.Z...*E1..
|   1920: ce 44 34 5d 88 61 89 d1 cc 7c 14 86 a3 d7 6b 6b   .D4].a...|....kk
|   1936: 22 d2 98 ab 62 7c 43 2e a8 92 12 de 43 d4 0a 9d   ....b|C.....C...
|   1952: 94 f0 41 2d 14 86 69 fe 98 71 1a a2 2b db 5b ec   ..A-..i..q..+.[.
|   1968: 23 00 e3 a3 03 1d 31 97 94 e4 85 1e 5f 53 44 66   #.....1....._SDf
|   1984: 0a 21 df ec ca 6a a6 a3 f4 c8 00 40 8e 0f 19 3f   .!...j.....@...?
|   2000: 36 69 a3 7c de fc 73 16 d8 d3 f9 ff 03 ac 94 dd   6i.|..s.........
|   2016: 38 d5 d9 20 2e d8 97 2a 22 9d bb a5 cc 04 07 8f   8.. ...*........
|   2032: be 18 b4 a8 ae e5 b4 45 27 7f e2 7e 3f 91 67 98   .......E'..~?.g.
|   2048: 86 3d 3c 05 3a 1e 71 bf 40 f8 a6 ca 48 7a ca c7   .=<.:.q.@...Hz..
|   2064: b7 67 10 bd 99 79 53 32 70 b0 74 fc d9 93 60 c8   .g...yS2p.t...`.
|   2080: 3e 39 5c fa 3c 97 34 70 57 a3 0f f8 ab 4e 3f a6   >9..<.4pW....N?.
|   2096: a5 25 26 ea 0c 60 fe 32 f3 7a 68 d0 9f 50 a4 45   .%&..`.2.zh..P.E
|   2112: 13 2e f8 41 3f e9 d1 9f 78 4a d0 a7 d3 57 3c af   ...A?...xJ...W<.
|   2128: a6 69 6f 2b 4e f0 86 b5 96 2d b2 de 06 5b 68 b2   .io+N....-...[h.
|   2144: 9a b9 de e7 7d 54 0a ff b1 26 17 ea bc a7 37 ff   .....T...&....7.
|   2160: 46 7b f7 00 90 ec 71 92 cb 5a b7 c8 7f 45 60 ec   F.....q..Z...E`.
|   2176: 9e 30 ca 80 69 4c 07 4d c8 c9 53 c4 77 3c 93 15   .0..iL.M..S.w<..
|   2192: 17 63 15 c0 3a 1d a2 02 82 6d 4b ed 50 4c 5d 93   .c..:....mK.PL].
|   2208: 2d ef bf 1e 9a ff 04 26 1a f6 7b da c9 21 7b 50   -......&.....!.P
|   2224: 4d 2f 53 c4 1e b4 dc 9f 5f 33 26 80 4a 8c ef 54   M/S....._3&.J..T
|   2240: fb 58 95 55 3c ec c0 a7 c5 78 a0 91 08 b4 d6 ce   .X.U<....x......
|   2256: d8 25 27 2b 37 e9 63 72 94 c3 89 5a 58 85 f4 95   .%'+7.cr...ZX...
|   2272: 09 fe db 6c 9c 71 54 af 1a 0c eb 2d e6 a9 db a0   ...l.qT....-....
|   2288: 04 2c 29 70 12 b2 7e 66 ae 25 ce b4 b9 5c a2 12   .,)p..~f.%......
|   2304: 1c 75 10 d5 54 f8 04 c5 8d be 38 29 64 f8 29 00   .u..T.....8)d.).
|   2320: 07 35 e4 e7 6e bc 64 db 39 d8 98 ee 72 28 a8 8b   .5..n.d.9...r(..
|   2336: 0f 1b 87 26 6e d4 73 1b ef b6 d4 db 05 12 1b c7   ...&n.s.........
|   2352: c6 1e 02 b1 ab bb e2 29 81 9a 9e b6 80 22 6e b4   .......)......n.
|   2368: 3c 30 ad e7 8b a9 60 7e de 01 a3 74 0b 76 0b d6   <0....`~...t.v..
|   2384: e8 a0 91 65 ce bb 6a d7 96 cc fa 96 d0 c0 39 d0   ...e..j.......9.
|   2400: 54 80 1d 8d 79 17 11 86 c5 8f a7 7f 57 92 8d b2   T...y.......W...
|   2416: 41 5b 86 61 94 23 99 77 b0 5d 5d f9 29 86 36 c8   A[.a.#.w.]].).6.
|   2432: ea f8 2f b5 7d 42 66 fe c7 0d 19 17 e6 6f c5 79   ../..Bf......o.y
|   2448: e0 22 24 70 eb 79 23 ec 45 77 d3 44 8f 74 15 bc   ..$p.y#.Ew.D.t..
|   2464: cf 46 cc ff 5b 05 1e 03 7d ea c5 82 14 11 86 4b   .F..[..........K
|   2480: cb 23 5b e0 1d 96 ca ea 62 d8 71 56 c4 1f d6 ed   .#[.....b.qV....
|   2496: 9e 8f bd b0 4a fe 53 87 c8 16 1a 31 cb 25 ba 18   ....J.S....1.%..
|   2512: 66 c3 b2 a7 91 68 ff b9 2b bc c4 f5 50 36 79 e5   f....h..+...P6y.
|   2528: 33 c3 d4 98 e1 fd f9 3a c7 a1 ef 79 29 c1 bf 7e   3......:...y)..~
|   2544: db 7b 66 3b 95 37 02 c7 ee ca 7f 9f 50 8f 47 5d   ..f;.7......P.G]
|   2560: af 45 29 e3 f5 7e 07 93 73 a0 42 ef 05 a6 2b 74   .E)..~..s.B...+t
|   2576: 92 ab 8a 9a 19 be 2f 21 cf 6a 90 02 a3 1f f4 5c   ....../!.j......
|   2592: 72 b3 31 00 85 9b 20 d8 f3 c5 00 a7 15 30 56 6c   r.1... ......0Vl
|   2608: 0f 7c 84 be 55 5b 8b aa df d6 bd 9e d9 55 54 93   .|..U[.......UT.
|   2624: 44 7d 9a 9b b8 38 46 b7 1e 1c 75 17 bb 29 05 5f   D....8F...u..)._
|   2640: da 39 7e fe 9e 40 e3 a5 7c a2 ba 5d 7e 9d 14 57   .9~..@..|..]~..W
|   2656: 19 10 2a d1 85 d3 06 0f d4 d8 ac f0 03 8a bd 61   ..*............a
|   2672: 26 89 4e c6 92 0a 4b 0b a2 3e 1d 5e 88 8c ce 33   &.N...K..>.^...3
|   2688: 47 e7 4e 69 0c e3 09 ef 3a 9f af 19 ae 83 68 21   G.Ni....:.....h!
|   2704: 75 c3 54 7b 00 a5 f3 d2 32 41 69 ac fc 31 2e 0c   u.T.....2Ai..1..
|   2720: 91 dd 90 78 2c ab 3f 0c 37 a4 8c 69 a9 ae 41 8e   ...x,.?.7..i..A.
|   2736: 6b b5 b5 ee bf df bc 1c 61 bb c9 51 37 a5 d5 96   k.......a..Q7...
|   2752: 0c 26 aa 97 67 72 73 cc c1 92 d3 46 cd 3e d8 ad   .&..grs....F.>..
|   2768: e6 8b 51 ee 41 ed 39 57 65 2e 5c 39 2b eb a7 72   ..Q.A.9We..9+..r
|   2784: b6 4c a8 87 72 a4 16 b4 d9 90 db e9 25 11 53 4e   .L..r.......%.SN
|   2800: ef 24 1d b0 21 bc 97 52 38 53 49 c8 31 c1 c4 9f   .$..!..R8SI.1...
|   2816: 2b 13 0c 10 5b 4a 0c 6e 07 c0 ec d4 77 f0 f0 38   +...[J.n....w..8
|   2832: a6 88 d4 28 40 30 76 f4 ab 2e 94 b5 6d 47 79 84   ...(@0v.....mGy.
|   2848: f9 aa 28 32 66 c8 aa cf 17 18 3d 92 0e 66 4e fe   ..(2f.....=..fN.
|   2864: 5d 80 51 29 df 97 de a4 c6 57 23 67 84 f4 32 86   ].Q).....W#g..2.
|   2880: 51 03 b6 67 29 54 74 87 da c0 41 e9 3a 3e 07 02   Q..g)Tt...A.:>..
|   2896: d9 85 dc 55 e7 23 60 80 b0 01 48 cd 59 21 82 fe   ...U.#`...H.Y!..
|   2912: 14 65 1a 5d 9e 5e 2b 69 52 ee 64 01 4d 46 ac 94   .e.].^+iR.d.MF..
|   2928: 60 04 d9 2c 41 e3 5b 35 e7 cc 75 06 7d ff 48 ae   `..,A.[5..u...H.
|   2944: 13 e5 4f 54 f6 78 86 c5 c4 99 58 02 41 87 a9 82   ..OT.x....X.A...
|   2960: 34 95 75 b2 e5 5e 92 23 a1 7b 3c 7b 1d 94 dd 5f   4.u..^.#..<...._
|   2976: f6 56 07 06 41 12 a0 56 7a 15 01 58 1f 9f 15 1a   .V..A..Vz..X....
|   2992: bd 2e c6 ea b8 29 ae 13 19 a6 40 b0 8d ec 3a cd   .....)....@...:.
|   3008: ca 6b b4 d5 96 95 fe 8d 34 23 aa ab df c3 23 fa   .k......4#....#.
|   3024: c4 02 eb 10 8c f2 e8 e0 5f d4 e9 4a ae f4 8d 60   ........_..J...`
|   3040: a9 1f 65 40 93 26 bf 1c 49 9d b6 8f e3 f1 c7 0b   ..e@.&..I.......
|   3056: a7 bb d1 ae 56 60 5c 80 d8 e0 e4 f0 72 62 45 b7   ....V`......rbE.
|   3072: 31 33 66 a7 17 a4 34 67 f6 55 b1 09 eb 75 8f f0   13f...4g.U...u..
|   3088: cd c1 86 e3 f5 3a e7 d8 08 da 4c a7 b4 45 8b ce   .....:....L..E..
|   3104: 9c 8d 48 41 b4 3e 6b 2d fb be c3 e7 bf 80 d3 29   ..HA.>k-.......)
|   3120: 9f 8c 5d 7e 48 76 dc 95 cc 30 bf 9f e1 e0 dc c1   ..]~Hv...0......
|   3136: da 9c 73 18 3c ff 53 49 88 dc ef 90 20 5f 3f 75   ..s.<.SI.... _?u
|   3152: 85 02 0c d4 c3 f4 c1 ed f7 82 05 c4 e9 80 97 65   ...............e
|   3168: 09 2a ac 52 c5 77 6c f4 6b 35 30 c2 fd 38 48 ae   .*.R.wl.k50..8H.
|   3184: b6 f6 38 0f 87 1a 66 54 91 3a 5b a7 48 5c 9d 36   ..8...fT.:[.H..6
|   3200: e5 7f 60 4d 68 19 ff 8d 2e 6a 8a 99 37 72 11 f9   ..`Mh....j..7r..
|   3216: 5b 29 77 3e 76 cd 57 6b 07 d0 cf d6 b4 cd d0 1e   [)w>v.Wk........
|   3232: dd 6e 1c a1 bd 7f bd 9d 57 0d 14 25 9e 4a 36 8c   .n......W..%.J6.
|   3248: 9f 7b b4 f9 db 57 22 f1 0b 47 e8 2e 04 70 e2 d6   .....W...G...p..
|   3264: 29 0e bb 52 33 80 6b 12 a5 20 97 3b 60 01 a2 8c   )..R3.k.. .;`...
|   3280: 74 68 0f b1 b0 44 63 04 fe 69 2f 98 ee d9 e9 39   th...Dc..i/....9
|   3296: af 0d 7a 79 00 ca d4 3e 96 e1 27 f8 27 e6 a7 d5   ..zy...>..'.'...
|   3312: 0c 7d 0c 13 de 31 bd 75 cf 41 04 1f 03 bb df 1d   .....1.u.A......
|   3328: c7 c0 3b a8 15 d8 15 4b b5 89 ff 4c 16 31 7a 62   ..;....K...L.1zb
|   3344: bb f8 d0 f2 43 fe 03 68 b0 35 7a 33 ae 4e a9 0b   ....C..h.5z3.N..
|   3360: 6a c8 35 d3 2c bf 6c 35 7b 1d 4c 9d 62 c1 96 01   j.5.,.l5..L.b...
|   3376: cf 7f 5f f0 20 ce 16 25 32 bc b2 bb 29 7a 6c f5   .._. ..%2...)zl.
|   3392: 36 17 6e 1b 93 4f 0f f0 de eb 67 a8 be 6a ad 7a   6.n..O....g..j.z
|   3408: e6 42 1f 63 d2 de 72 1b f6 01 08 e8 72 d6 85 81   .B.c..r.....r...
|   3424: 3d ec 80 70 f3 84 5c 54 2a 2d 66 f8 e9 ba d7 7c   =..p...T*-f....|
|   3440: af df 2a 43 f4 6c 78 3e 5d e6 92 b4 9f 02 05 bb   ..*C.lx>].......
|   3456: 84 9e ed 44 71 74 21 c9 be 07 3b 98 b1 49 b7 81   ...Dqt!...;..I..
|   3472: 6a 4a c4 08 28 1c 19 0f ae 36 c2 6c a2 55 af 09   jJ..(....6.l.U..
|   3488: 47 da e4 a8 32 df 4f 68 83 b1 c8 89 a0 1a e1 72   G...2.Oh.......r
|   3504: b2 dd ab e9 fd 2f c8 79 d1 7e 69 16 e7 72 85 09   ...../.y.~i..r..
|   3520: 95 77 18 1f 2c d1 51 31 68 88 8f 0a fb a1 4f 3b   .w..,.Q1h.....O;
|   3536: 6d fb 24 cc 0a 77 34 cb 49 35 06 07 a6 cd 5e 27   m.$..w4.I5....^'
|   3552: d6 87 cc ae e1 00 cc 69 22 0e 4f 5a 59 cc 8f 30   .......i..OZY..0
|   3568: c3 65 8f 8d bc 1a 86 8f 02 9b 0a 2c 5b b5 3d fa   .e.........,[.=.
|   3584: c9 fd 1c 96 4c 59 e1 ac 43 17 e8 b1 18 57 c8 48   ....LY..C....W.H
|   3600: c7 df e9 d1 d3 11 d9 4b 44 33 d9 da 9d 86 7a cb   .......KD3....z.
|   3616: de 17 ce 40 aa b8 2d b6 26 a9 68 e8 72 f3 cb e0   ...@..-.&.h.r...
|   3632: ae ec b1 1e 76 0b 5c 49 93 f5 f1 04 56 fa ac 33   ....v..I....V..3
|   3648: 65 de d4 36 6b 3a 3c e1 a7 7b b6 66 e1 69 e7 86   e..6k:<....f.i..
|   3664: c0 42 a2 71 e5 f1 35 3b 38 1e 52 a2 bb 72 39 de   .B.q..5;8.R..r9.
|   3680: e2 78 23 3a 71 b3 0b 8d 94 e5 26 80 9d d3 67 76   .x#:q.....&...gv
|   3696: 14 aa 98 b4 f8 42 78 6c a1 8f 7a bd 5a 5f 99 1f   .....Bxl..z.Z_..
|   3712: 14 5a d4 02 bf c3 60 a7 c7 34 8f 81 4b 4a f6 c2   .Z....`..4..KJ..
|   3728: 21 0e 6e 26 55 79 10 67 13 dc da ac 80 37 ad 95   !.n&Uy.g.....7..
|   3744: 11 4a 54 b5 f9 da f6 66 26 99 51 98 1e 05 c0 5b   .JT....f&.Q....[
|   3760: 2d 23 b8 a2 5b de c3 f4 4f 2b 3a 22 10 1c 25 cc   -#..[...O+:...%.
|   3776: 57 db 91 c4 6c df 33 a1 1f d6 a3 2e 56 de 54 d1   W...l.3.....V.T.
|   3792: 02 ac 2d ff 96 d6 db ec 80 f7 79 ea 81 30 68 d0   ..-.......y..0h.
|   3808: 90 b2 d1 cc 5e ac 50 df 5e 1b 0a 78 01 70 e8 21   ....^.P.^..x.p.!
|   3824: 35 08 64 46 9a 55 91 aa 9e 41 df 4f 5b 2b 3e 1c   5.dF.U...A.O[+>.
|   3840: bc f5 90 37 d7 35 ac 34 8e 70 94 28 46 eb c8 42   ...7.5.4.p.(F..B
|   3856: 10 df 40 b6 c0 76 57 6d 79 d6 f7 b6 cf ca 88 bc   ..@..vWmy.......
|   3872: f9 f6 ce ad 69 d8 a6 a7 41 cb cb c6 bf 91 ef ff   ....i...A.......
|   3888: 72 6f d2 b0 1e bf db 33 4b cd 1b 81 2d 65 de ff   ro.....3K...-e..
|   3904: 5c 4b 45 f0 57 c3 5e 1f 77 6d 14 b7 ea e4 8c 88   .KE.W.^.wm......
|   3920: d0 b1 63 86 fc 68 26 e3 b2 7a 5f ca ec 09 00 4b   ..c..h&..z_....K
|   3936: dc f0 d4 70 fd c1 10 36 a9 cc fc 0d fd 24 12 13   ...p...6.....$..
|   3952: d9 bd f0 2f 87 99 00 d1 d4 7c c6 41 f3 59 2a db   .../.....|.A.Y*.
|   3968: e1 7c 44 99 65 e7 4b 2f 42 a6 02 ad eb 7b db 14   .|D.e.K/B.......
|   3984: e4 c7 0d bf a7 f1 3d 69 01 cc c0 2e 82 06 fe 13   ......=i........
|   4000: a3 f2 df 3f fe 65 d6 73 b3 d1 48 0c 00 5f 6c 4e   ...?.e.s..H.._lN
|   4016: 1e ff f6 d2 69 08 a0 7a ed 50 16 a5 b1 56 1c f5   ....i..z.P...V..
|   4032: 14 b0 b8 3a 38 19 a6 e7 ef 28 3d b9 9f 5e 38 39   ...:8....(=..^89
|   4048: bc 41 c2 b1 fa 0b be 8b e9 9f 2f a0 be 8a eb 7f   .A......../.....
|   4064: eb 55 5e fb 3a 36 82 02 fd 50 a6 b2 7d fb e7 5a   .U^.:6...P.....Z
|   4080: a4 b2 d9 d9 8b 93 7a 2e ed c3 0c 13 68 22 cf f9   ......z.....h...
| page 18 offset 69632
|      0: 0d 00 00 00 01 04 3f 00 04 3f 00 00 00 00 00 00   ......?..?......
|   1072: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97   ................
|   1088: 3e 0a 06 00 ae 7c 00 00 18 91 e3 df f3 2f 7b 53   >....|......./.S
|   1104: 6d 25 6e 2a df e7 b0 18 33 2f 73 08 d7 a8 04 75   m%n*....3/s....u
|   1120: 49 89 b0 84 41 57 fb 8f 24 85 4e 24 c6 f1 14 03   I...AW..$.N$....
|   1136: 9e 8e ef 9d f0 5c 54 69 11 78 d5 0f d6 97 22 1e   ......Ti.x......
|   1152: b5 17 73 66 0d 95 db ce c4 12 cb b0 ae a8 53 70   ..sf..........Sp
|   1168: c7 6b 02 f6 7d 56 49 eb 11 75 da b6 c2 ba a1 f2   .k...VI..u......
|   1184: 19 8d c3 fc 6f 9d 3e e8 0e 1a 51 37 d7 ff b1 19   ....o.>...Q7....
|   1200: 50 bd a1 74 26 2b 53 c6 1e 12 75 20 ed 43 51 0e   P..t&+S...u .CQ.
|   1216: 28 f7 c4 a3 b5 8c ec de 2c 58 29 8c 74 81 d7 2d   (.......,X).t..-
|   1232: a2 8d 0a d3 85 98 6b f2 3e 34 94 08 73 06 e7 06   ......k.>4..s...
|   1248: 04 e3 81 81 2a d8 5c 61 1b e9 7c ff 92 a8 c9 50   ....*..a..|....P
|   1264: 97 a0 8e f6 1f 4b 25 ae 8e fa 84 7a 6f a7 11 42   .....K%....zo..B
|   1280: c2 97 7a 93 42 39 ab 41 9f c1 7c 86 4a 66 06 cd   ..z.B9.A..|.Jf..
|   1296: e3 20 2c 3e ba f5 3c 32 fd a7 4a 73 50 74 a4 50   . ,>..<2..JsPt.P
|   1312: 89 28 57 71 bc 3d 31 77 89 ef cd cd ff b4 fb 2c   .(Wq.=1w.......,
|   1328: 5f a0 55 da b0 d9 18 d4 f7 a3 e4 f0 bf a8 86 b8   _.U.............
|   1344: 64 97 49 26 1b 4a b7 e7 6f 88 a9 a8 ab 54 1c 48   d.I&.J..o....T.H
|   1360: 0c 77 2c e3 7a 83 7d 05 c8 22 f7 b7 57 92 61 97   .w,.z.......W.a.
|   1376: 69 52 51 f7 8d 4c 2a b5 5e d5 55 f4 fc ae 35 bc   iRQ..L*.^.U...5.
|   1392: fa 44 c5 19 ec 62 5e 98 12 bf a8 e1 53 32 76 4c   .D...b^.....S2vL
|   1408: fb 4e 80 40 85 39 71 69 bd 55 90 9b 4c 46 b1 06   .N.@.9qi.U..LF..
|   1424: 84 14 80 f3 2b ba 43 15 7e 12 44 4b 38 2e 01 a8   ....+.C.~.DK8...
|   1440: 2e 58 11 e1 dd 6b 24 9e 6a fb 21 14 f5 ae be 7a   .X...k$.j.!....z
|   1456: 9b 26 0d a8 2f 29 8c 5a 63 8a cf 58 36 e1 76 fb   .&../).Zc..X6.v.
|   1472: ca 95 7a 0c 74 0d d5 57 04 a4 65 5f 2a 0d 46 ee   ..z.t..W..e_*.F.
|   1488: 0c 2e a6 a1 dd 04 b8 1d b7 72 a0 d5 ad cc 8e d3   .........r......
|   1504: bb 04 bc 39 4d 22 0f 4e 6c b1 4d b4 08 3b 7f a5   ...9M..Nl.M..;..
|   1520: f1 7d 18 c5 bf 43 86 b3 c1 3b 85 6f 30 84 1a 7b   .....C...;.o0...
|   1536: 17 d0 91 d3 6d 99 cc ff ac 64 88 53 d3 ad 1e 5f   ....m....d.S..._
|   1552: ba 4c af 64 80 ae ca c7 27 56 7e 41 02 61 f1 d2   .L.d....'V~A.a..
|   1568: e4 4b 99 7c e4 18 41 9c f7 b9 e8 5a 3f 6e a3 57   .K.|..A....Z?n.W
|   1584: ca 18 c5 8a a8 39 c6 fe 02 d0 9d 26 37 42 07 3d   .....9.....&7B.=
|   1600: 38 4e fe 9a 3b 54 39 20 23 53 8a 84 2f 4a 06 06   8N..;T9 #S../J..
|   1616: ed 56 dd d8 bf 56 ef ca a5 c0 a4 aa d5 88 41 42   .V...V........AB
|   1632: 8a c0 37 65 f3 c8 4c 87 a5 f3 3d 99 78 2b d7 4e   ..7e..L...=.x+.N
|   1648: d7 6e 51 28 3f 5c 93 cb 56 08 91 39 8e 1d fb 26   .nQ(?...V..9...&
|   1664: 5d 80 7c 44 59 c4 d4 b3 5e 0c c1 3f 85 f8 d6 d0   ].|DY...^..?....
|   1680: 25 0f a8 c4 40 a5 f7 63 ec 2b fc 78 e6 b4 7c 72   %...@..c.+.x..|r
|   1696: 87 f0 6d 2c 00 63 dc 29 4a e5 b5 6b 9e 73 33 b4   ..m,.c.)J..k.s3.
|   1712: 19 03 1a 5c de 8f 98 fa ce 4d e3 1a 62 6b 5b f5   .........M..bk[.
|   1728: 60 d6 4c 13 39 14 06 83 90 09 56 8b 71 3b b9 bc   `.L.9.....V.q;..
|   1744: e3 7e 5e ae f5 3e b7 aa bd 73 d6 f1 47 4a 84 60   .~^..>...s..GJ.`
|   1760: 20 d7 93 ce f0 f2 1a 63 b7 f0 7e 3b 4e 36 1c dd    ......c..~;N6..
|   1776: cc ef 50 7a a9 90 f7 48 05 fb 78 e8 72 71 df 3a   ..Pz...H..x.rq.:
|   1792: 41 51 2c 4c 5d 0f cd 51 0e f3 5a a1 e6 81 15 b3   AQ,L]..Q..Z.....
|   1808: bb 48 5e 13 cf 46 4c f1 26 47 4b 51 87 d7 39 a6   .H^..FL.&GKQ..9.
|   1824: 38 c5 72 52 55 97 f6 81 bc 0f a1 95 72 b8 ec 6d   8.rRU.......r..m
|   1840: dd 6d 92 03 b5 0f d6 fd 7e 29 c9 55 50 57 71 2c   .m......~).UPWq,
|   1856: 34 35 21 75 6a 4e e6 f0 6a 99 b7 51 b5 3e 0a 6c   45!ujN..j..Q.>.l
|   1872: 1b c0 ba cb 92 90 15 b8 35 b9 6b 78 f2 c6 03 48   ........5.kx...H
|   1888: 66 d6 2e 75 47 b8 eb d0 30 48 c9 4d 67 d1 c1 8a   f..uG...0H.Mg...
|   1904: b2 9c a9 c0 3d a1 77 e3 35 e4 85 01 e7 dc 74 bc   ....=.w.5.....t.
|   1920: 8d ff f6 f0 ad e1 35 63 75 6d ee 28 53 29 1c 9c   ......5cum.(S)..
|   1936: 67 dd ea 7d 1f af 87 c3 2e 8d a4 23 d2 6b db 49   g..........#.k.I
|   1952: 1a 36 10 7b e1 6c 9a 1c a2 5f 17 fb 43 e5 da f5   .6...l..._..C...
|   1968: 2c 60 86 42 1d 28 a1 5f cc 73 b2 5d 69 2b fa 18   ,`.B.(._.s.]i+..
|   1984: 85 a2 de 30 9a c7 08 42 b9 e3 b1 a1 32 1d 70 31   ...0...B....2.p1
|   2000: b4 7a cf f4 57 5d 5e 45 53 1d 79 35 7b 4f 9a 2f   .z..W]^ES.y5.O./
|   2016: 80 11 76 23 60 dc 86 e7 f0 74 2d 46 51 40 01 10   ..v#`....t-FQ@..
|   2032: 13 69 90 a9 fb cb 66 8e 3f e0 a1 4e 99 eb 61 1b   .i....f.?..N..a.
|   2048: fe c7 5e b5 f5 0f a3 46 64 19 09 11 c0 83 c7 28   ..^....Fd......(
|   2064: 41 20 81 d3 f5 9c 21 2b ed 06 1a 4a 89 4d 6a e5   A ....!+...J.Mj.
|   2080: 2d 4f 95 d7 3b 95 8c 59 6f 3e 79 51 5f ef b8 2a   -O..;..Yo>yQ_..*
|   2096: 43 ef 07 e2 d1 d1 13 38 67 54 88 e2 6f 03 fe 05   C......8gT..o...
|   2112: 10 0e e8 e9 4e 9a 75 92 ec 1f e7 56 61 3b 54 43   ....N.u....Va;TC
|   2128: 08 af e9 d5 56 bc 87 a3 25 6f e2 b8 01 62 1a 30   ....V...%o...b.0
|   2144: ba 26 8a b1 9a 7e 44 a2 f5 d4 75 2e a0 d0 b8 71   .&...~D...u....q
|   2160: 61 61 92 ff 32 0b a8 94 a5 81 80 d0 3b b5 51 4a   aa..2.......;.QJ
|   2176: 01 e2 8e 0a 38 90 19 f7 b4 38 b0 9c 32 e1 6a f0   ....8....8..2.j.
|   2192: f8 7b f0 58 0a d1 19 c0 20 d6 54 fe 28 ac 02 64   ...X.... .T.(..d
|   2208: c4 33 55 01 d2 bd 01 51 87 01 0c 66 bb 6e 1b 94   .3U....Q...f.n..
|   2224: 9c 24 50 40 5b 2f 64 f9 b5 b6 6b 15 fd f8 e7 05   .$P@[/d...k.....
|   2240: 37 92 95 d3 b4 1e be b3 09 c0 74 f8 ca 03 10 89   7.........t.....
|   2256: 2d 4d f5 56 0f 6e 20 72 a7 5e 1d 9f fd d5 43 af   -M.V.n r.^....C.
|   2272: 2e 7b f7 91 99 ed 47 ea c7 a4 76 82 ca 5f 94 20   ......G...v.._. 
|   2288: 52 01 b4 21 cb 50 d5 f2 d6 cf 1d 11 0f b2 07 ee   R..!.P..........
|   2304: f2 cf 2b 52 7b 1d e0 be 16 a1 cf 06 52 1b 33 f5   ..+R........R.3.
|   2320: c2 8e ac f1 00 2b 82 cf b4 ae d5 f0 9b 4b 11 14   .....+.......K..
|   2336: b5 c5 43 f4 08 9d 4a 59 ba a6 52 67 fe e1 bd 2d   ..C...JY..Rg...-
|   2352: c2 40 c6 3e d1 8a d1 f5 a0 b4 d0 b1 92 3f 9e 1d   .@.>.........?..
|   2368: 18 5e b4 78 30 45 57 29 30 e1 5a bb ee 7b 1e 99   .^.x0EW)0.Z.....
|   2384: 0d 10 ea 14 7b 5e 36 32 8e e1 a7 e4 76 19 48 a8   .....^62....v.H.
|   2400: c6 19 74 b9 4e 31 81 24 fe 07 e3 86 ec c4 1d 05   ..t.N1.$........
|   2416: 1f 5a 52 14 0c 08 3f d1 93 fe b1 46 27 87 58 21   .ZR...?....F'.X!
|   2432: 4b d5 ff bb 98 d8 f8 0c 96 66 02 9c 86 f9 0e 0b   K........f......
|   2448: f0 11 7a 99 39 52 38 84 22 04 58 07 f1 95 eb c7   ..z.9R8...X.....
|   2464: 44 2e a5 fe d4 68 a9 98 77 14 4f 8a 44 4c 7d c4   D....h..w.O.DL..
|   2480: 49 8a d7 89 83 8e e6 1e d0 af b7 41 3d 1a 85 14   I..........A=...
|   2496: ec 3a e5 1b 2c c5 17 77 85 82 19 57 37 94 93 7e   .:..,..w...W7..~
|   2512: 52 16 a3 dd 0a fd 57 1a 57 32 11 4d 71 e3 4b 1b   R.....W.W2.Mq.K.
|   2528: c5 02 d7 89 74 85 b0 3d 8d 7b 53 a2 d6 60 99 d4   ....t..=..S..`..
|   2544: ce f0 1c 3d a3 aa db db c4 80 38 7a cb 12 7e 66   ...=......8z..~f
|   2560: 3f 69 af fa 57 49 35 05 94 33 df fe 91 8a 25 3d   ?i..WI5..3....%=
|   2576: 9b 32 71 72 d2 bc bc 23 61 69 9c 68 a7 58 c0 f1   .2qr...#ai.h.X..
|   2592: 0e 20 a9 d3 d2 a9 11 d7 ee 52 46 70 b7 aa 6b f3   . .......RFp..k.
|   2608: 4a 51 a7 a5 26 92 35 44 f9 cc 7b c7 ec db 5d b6   JQ..&.5D......].
|   2624: 5c 88 d9 bd 14 df a0 14 35 09 2f c8 76 d4 4c 19   ........5./.v.L.
|   2640: 12 29 b9 dd 9b 21 ed b8 ee 1f f9 38 05 9e 93 aa   .)...!.....8....
|   2656: ab 82 15 69 88 81 f6 4f 1b 72 bb 84 cb 9c 33 ec   ...i...O.r....3.
|   2672: 94 4d 44 42 8e 8f 12 91 1f 32 07 09 38 8b 44 be   .MDB.....2..8.D.
|   2688: 9e 31 49 9e 76 04 d8 b7 69 ad f1 59 81 5f d7 a0   .1I.v...i..Y._..
|   2704: 2f 34 94 27 b4 c1 e9 f0 18 a7 43 7e 1e fd 27 5b   /4.'......C~..'[
|   2720: d8 e9 c3 5d be 8f 91 f2 4a cd 33 5f 6c 76 f6 f1   ...]....J.3_lv..
|   2736: 17 ae 80 87 e7 ec 22 ef 73 8e a7 3a 30 dd 27 3d   ........s..:0.'=
|   2752: 6d 95 59 eb f3 7f 97 b7 b9 8d ff 86 ed dd 5d f4   m.Y...........].
|   2768: 39 3c 6a 13 3d 7a 93 3d 37 ed 8c d6 98 0f 0b 7a   9<j.=z.=7......z
|   2784: 18 f6 78 af 91 f4 b3 2f 4a cb 19 61 c1 a9 82 9b   ..x..../J..a....
|   2800: 1e a1 c2 4e ad 14 17 09 4a 85 5a fb ed aa 51 3c   ...N....J.Z...Q<
|   2816: 21 e5 be 54 ec 0f 51 de 73 59 29 51 1d fa d6 ce   !..T..Q.sY)Q....
|   2832: c2 d1 b7 71 8e 36 a8 1f fc 07 67 fe ce 81 6b 08   ...q.6....g...k.
|   2848: 7b ea 6f 56 22 ba df 64 80 b1 47 9a 0e 04 e2 c4   ..oV...d..G.....
|   2864: ee e9 7b 8e 3c 39 bc af 24 15 38 77 80 c1 1f 56   ....<9..$.8w...V
|   2880: 3f 50 b8 69 5d f3 4c 33 86 c1 20 90 6d 44 ae 3f   ?P.i].L3.. .mD.?
|   2896: 91 f0 94 65 91 5f f8 04 d8 9d 53 a1 93 b0 30 45   ...e._....S...0E
|   2912: 1f db 30 bc 15 56 40 14 eb 0b c9 a5 02 58 09 87   ..0..V@......X..
|   2928: b8 1a 2f 3c 61 26 b1 c7 27 71 a4 36 c3 c5 22 4d   ../<a&..'q.6...M
|   2944: c9 83 78 0b bc 9b da 14 54 1d 4c 41 de e3 fa 29   ..x.....T.LA...)
|   2960: 48 08 45 62 e0 c6 fc 54 76 41 b0 a2 45 2f e6 9c   H.Eb...TvA..E/..
|   2976: 16 61 37 4a 77 b9 00 c9 46 0d 4b ae b7 ca 25 64   .a7Jw...F.K...%d
|   2992: 2e 28 1a 43 57 8a 79 97 c7 e6 41 a9 b1 0e f3 f8   .(.CW.y...A.....
|   3008: 00 57 e1 4e c9 8f 99 80 2b 13 dc fc 8f 29 60 c8   .W.N....+....)`.
|   3024: 3e 0e da ce c9 ee 70 a1 94 24 6f c4 ec 89 14 96   >.....p..$o.....
|   3040: e1 6a a9 0a d8 f6 89 09 51 98 1f 89 1b f1 34 87   .j......Q.....4.
|   3056: a5 b3 22 d0 65 53 bd ae 57 7a 8a 8f a8 a6 10 9e   ....eS..Wz......
|   3072: 72 7c 6e 37 8f 67 db d8 89 54 77 87 6d 63 6e 31   r|n7.g...Tw.mcn1
|   3088: ef ae 41 51 22 cc 24 08 89 f6 dd 2c f9 cb a4 f8   ..AQ..$....,....
|   3104: ea f9 42 33 01 fd cf b9 d6 73 aa b4 9d 45 31 eb   ..B3.....s...E1.
|   3120: 42 ca df 3a d2 3c c9 41 28 fd e4 a2 2f cf bf ca   B..:.<.A(.../...
|   3136: 63 94 a2 74 ee 6b 4c 62 bb 74 5f cc 39 68 b5 e9   c..t.kLb.t_.9h..
|   3152: 68 47 90 45 85 f0 20 4e 3a fe 4a 4f ab f2 fe c7   hG.E.. N:.JO....
|   3168: f5 23 56 6e 09 9e c6 3d 36 30 82 62 6f 5f 78 f6   .#Vn...=60.bo_x.
|   3184: f6 07 58 e8 fd 98 09 e5 a5 5b 65 27 43 e6 9e 3d   ..X......[e'C..=
|   3200: 98 d5 db 1d 09 35 48 b0 cd 5e 53 a1 d6 b2 4f 85   .....5H..^S...O.
|   3216: e5 4d 80 18 8f 78 6e a0 0e 35 08 7d 1d 5d 3e ab   .M...xn..5...]>.
|   3232: c3 5c dc ec c9 e0 22 1a 17 a3 80 40 3d e7 66 df   ...........@=.f.
|   3248: b2 38 f4 59 6d 20 e8 83 93 53 8c ac 52 26 ec 60   .8.Ym ...S..R&.`
|   3264: f8 50 85 1c 97 9c ae a3 9f bd af 75 be 73 23 b5   .P.........u.s#.
|   3280: 7f fa 1f 7f 28 16 c7 7c 5f 0a 5b 32 1a c8 45 cf   ....(..|_.[2..E.
|   3296: df 2e 8e d1 d9 59 76 d5 6c 8d b5 12 8a c5 77 32   .....Yv.l.....w2
|   3312: d4 87 02 80 09 b6 43 34 76 09 f9 b4 74 66 ce ee   ......C4v...tf..
|   3328: 26 77 62 11 b0 23 92 5c 72 38 41 e9 70 4f b5 83   &wb..#..r8A.pO..
|   3344: e4 35 7c b2 2a 38 49 12 48 18 1c 95 5c b1 18 1a   .5|.*8I.H.......
|   3360: 51 cd 4b 7b 22 94 0e c7 da c1 30 97 d1 be 42 07   Q.K.......0...B.
|   3376: 94 01 a5 fd 2f 0d 2c 53 33 c0 91 c6 bc af 2c f2   ..../.,S3.....,.
|   3392: f2 07 6e 4a d2 22 3e 3c 18 3c ca 24 bf 42 78 7a   ..nJ..><.<.$.Bxz
|   3408: 69 0e a9 12 e3 20 fa 8b ad 75 27 0c c3 82 84 8d   i.... ...u'.....
|   3424: 46 af 3e 1e 89 27 4d 7e f7 21 96 b4 6c 17 7f 19   F.>..'M~.!..l...
|   3440: 8a 78 d7 bb 40 67 35 45 2d d4 97 6a 4c e9 4a 58   .x..@g5E-..jL.JX
|   3456: 22 a3 bb 31 d5 4f 26 40 cc fe c8 cd 1d a4 0d 67   ...1.O&@.......g
|   3472: 14 13 05 4d 0e 15 40 ea 7d 62 c6 80 08 b9 f6 b2   ...M..@..b......
|   3488: 44 58 66 d5 ca b6 f4 20 b0 4a b8 37 64 3d b0 a7   DXf.... .J.7d=..
|   3504: a7 87 70 26 b2 ea f9 cf 98 03 6e 63 5a fe c4 cd   ..p&......ncZ...
|   3520: 80 cb ca f4 a6 02 11 39 4f 6c bf bf a4 8e 99 32   .......9Ol.....2
|   3536: e3 47 51 3e 85 f6 84 6b 3d 9a fe 2f 96 18 49 2a   .GQ>...k=../..I*
|   3552: dc a4 56 77 d1 3f 94 61 2b 58 e7 74 ee c9 16 7b   ..Vw.?.a+X.t....
|   3568: 6f 76 47 da b2 fb 89 75 80 78 05 69 c8 3e f0 97   ovG....u.x.i.>..
|   3584: 1b 40 f1 48 43 7f cd 0b b1 c6 cf 59 73 4f 3f 33   .@.HC......YsO?3
|   3600: 2e 32 d2 b6 69 fc 6b f2 20 0f 12 bf f0 98 2e e2   .2..i.k. .......
|   3616: 4f ed 80 27 00 e2 b1 c2 ca cd 6b de e1 b4 af 9e   O..'......k.....
|   3632: df 4f d2 da 6d 9f b4 5d 99 4a c4 59 d4 e1 98 05   .O..m..].J.Y....
|   3648: 68 00 a5 72 3f 0e 35 29 59 81 8a f9 f2 c0 5a de   h..r?.5)Y.....Z.
|   3664: 25 35 d5 60 03 f7 0f 20 3a bb a6 45 fc cc 2d e9   %5.`... :..E..-.
|   3680: fe 37 0b 6c f2 96 19 dc 39 62 6e f7 9c 17 37 8c   .7.l....9bn...7.
|   3696: 8a dd 62 a2 a3 e6 b8 a0 cd 61 f5 27 3b 29 e2 f4   ..b......a.';)..
|   3712: 0a 06 21 c3 b9 8e 70 34 59 ca d9 a1 92 db a9 74   ..!...p4Y......t
|   3728: d1 7c a1 ef 64 c2 75 51 02 b3 6a 57 6d 12 f6 eb   .|..d.uQ..jWm...
|   3744: 3b 41 ce a5 ca 69 62 3e c3 55 eb 1c 80 01 79 05   ;A...ib>.U....y.
|   3760: a4 51 7c 45 00 76 41 5e 57 1a 88 aa 15 c8 42 82   .Q|E.vA^W.....B.
|   3776: d5 83 74 97 93 b4 28 df 4d 82 7d 6f ef 6a d4 e4   ..t...(.M..o.j..
|   3792: 03 e7 20 4a e8 84 54 0c 6e 5f 8e b0 d1 0d 67 aa   .. J..T.n_....g.
|   3808: f9 20 21 ea c0 4e 5c e3 f8 65 d7 67 0a 7a e0 0b   . !..N...e.g.z..
|   3824: d8 1e 53 95 bf 24 39 12 d4 30 8c 2c b4 13 2e bd   ..S..$9..0.,....
|   3840: f8 81 d5 15 35 d7 3f f2 23 a4 2c 1b cd 29 e8 88   ....5.?.#.,..)..
|   3856: a8 f1 cc 3f 9b 72 d0 8e c0 cb 80 ca c9 68 1a ca   ...?.r.......h..
|   3872: 38 09 59 e5 a6 33 95 57 55 c9 dd c4 8a 8d 36 e5   8.Y..3.WU.....6.
|   3888: 0c 40 95 77 63 4b 82 53 98 d0 bd cd 57 b6 f7 2b   .@.wcK.S....W..+
|   3904: fe 1c 25 d4 95 3d 4c 63 b7 fb 94 37 3f 6d 96 28   ..%..=Lc...7?m.(
|   3920: 1d 13 76 d2 ab 9a 7e 8f f5 a2 e6 15 0b 1c 10 14   ..v...~.........
|   3936: c3 b5 c0 1c 52 af 2a 32 35 05 4a 0c f1 cb ed 5e   ....R.*25.J....^
|   3952: 42 6c 31 8b dc 78 4b 68 5a b7 0f e3 6c d6 da e6   Bl1..xKhZ...l...
|   3968: 59 f3 34 43 47 1c 2b f6 f4 eb 6e 12 4d 60 f4 d9   Y.4CG.+...n.M`..
|   3984: 39 2f 84 a5 8f f0 03 e7 ce b6 10 d0 a9 f9 69 76   9/............iv
|   4000: 94 29 2e 60 db fc e7 5f e6 c5 5b b9 c5 a7 1f 95   .).`..._..[.....
|   4016: 0d 66 aa 55 7b f5 ec 67 c6 f7 26 52 c4 02 60 31   .f.U...g..&R..`1
|   4032: 7d 5e de ba 06 2f 09 1d a1 db 61 83 c8 13 be 98   .^.../....a.....
|   4048: 14 9d c9 15 1e 33 04 de a5 53 ed 42 ab 45 b1 f3   .....3...S.B.E..
|   4064: 09 a7 47 54 14 bc a0 88 80 58 94 0a 78 f2 31 3d   ..GT.....X..x.1=
|   4080: bc 0d 85 bf da a0 7e d2 be e4 1c cc b4 45 a8 bd   ......~......E..
| page 19 offset 73728
|      0: 0d 0f e6 00 03 0c 8a 00 0c 8a 0f ec 0c 94 00 00   ................
|   3200: 00 00 00 00 00 00 00 00 00 00 08 01 03 00 16 2e   ................
|   3216: b1 7d 24 24 86 4a 84 80 80 80 80 01 04 00 8d 18   ..$$.J..........
|   3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06   ...+.00.........
|   3248: 1f 02 03 01 02 03 01 02 03 01 08 32 30 31 36 30   ...........20160
|   3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 34 00   609...........4.
|   3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 04 01 02   ..........5.....
|   3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 3d   ......0000000..=
|   3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06   ........binary..
|   3328: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01   ................
|   3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02   ................
|   3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02   ................
|   3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70   ............comp
|   3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64   iler...........d
|   3408: 62 73 74 61 74 07 02 03 01 02 03 01 02 03 02 04   bstat...........
|   3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 07 65   ebug...........e
|   3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 d3 02 01 02   nable...........
|   3456: 02 01 02 02 02 02 02 01 02 02 01 02 02 01 02 02   ................
|   3472: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01   ................
|   3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02   ................
|   3504: 02 01 02 02 02 08 78 74 65 6e 73 69 6f 6e 1f 02   ......xtension..
|   3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03   .........fts4...
|   3536: 01 02 03 01 02 03 04 01 35 0d 02 03 01 02 03 01   ........5.......
|   3552: 02 03 01 03 67 63 63 01 02 54 01 02 03 01 02 03   ....gcc..T......
|   3568: 02 06 65 6f 70 6f 6c 79 10 02 03 01 02 03 01 02   ..eopoly........
|   3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02   ...json1........
|   3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03   ...load.........
|   3616: 01 03 6d 61 78 1c 02 02 01 02 02 01 02 02 02 05   ..max...........
|   3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04   emory...........
|   3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e   sys5...........n
|   3664: 6f 63 61 73 65 02 06 01 02 02 03 06 01 02 02 03   ocase...........
|   3680: 06 01 02 02 13 06 01 02 02 03 06 01 02 02 03 06   ................
|   3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01   ................
|   3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02   ................
|   3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 02   ...omit.........
|   3744: 01 05 72 74 72 65 65 19 02 03 01 02 03 01 02 03   ..rtree.........
|   3760: 04 02 69 6d 01 06 01 02 02 03 06 01 02 02 03 06   ..im............
|   3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01   ................
|   3792: 02 01 f3 06 01 02 02 03 06 01 02 02 03 06 01 02   ................
|   3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 08   ................
|   3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01   ..threadsafe....
|   3840: 02 02 01 02 02 01 04 76 74 61 62 07 02 04 01 02   .......vtab.....
|   3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01   ......x.........
|   3872: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02   ................
|   3888: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01   ................
|   3904: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06   ................
|   3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01   ................
|   3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01   ................
|   3952: 02 01 06 01 01 02 01 06 01 01 02 ad 06 01 01 02   ................
|   3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01   ................
|   3984: 06 01 01 01 01 06 01 01 02 01 06 01 01 02 01 06   ................
|   4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01   ................
|   4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01   ................
|   4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c   ................
|   4048: 12 44 13 11 0f 47 13 0e fc 0e 11 10 0f 0e 10 0f   .D...G..........
|   4064: 44 0f 10 40 15 0f 00 00 00 06 14 24 12 0a 03 00   D..@.......$....
|   4080: 2a 00 00 00 00 01 02 08 00 02 01 01 01 02 01 07   *...............
| page 20 offset 77824
|      0: 0d 00 00 00 01 00 22 00 00 22 00 00 00 00 00 00   ................
|     32: 00 00 9f 56 88 80 80 80 80 01 04 00 bf 30 00 00   ...V.........0..
|     48: 0e 9c 02 30 30 01 0c 74 81 44 06 81 0b 01 0a 81   ...00..t.D......
|     64: 03 58 58 04 01 10 82 66 10 0f 0b 81 14 24 01 0c   .XX....f.....$..
|     80: 81 14 47 4a 20 6e 01 0e 71 81 41 05 82 0f 03 01   ..GJ n..q.A.....
|     96: 0c 53 54 4c 2c 70 7d 01 12 81 43 06 1e 37 42 37   .STL,p....C..7B7
|    112: 77 3e 01 14 81 22 07 81 30 81 5d 03 05 0d 01 08   w>......0.].....
|    128: 82 01 81 21 01 0e 81 45 54 51 81 0a 61 02 01 30   ...!...ETQ..a..0
|    144: 01 04 82 6e 02 01 36 08 04 83 7e 02 01 38 02 04   ...n..6...~..8..
|    160: 83 4f 02 01 62 06 04 81 11 03 01 36 08 04 81 5b   .O..b......6...[
|    176: 03 01 64 02 04 84 5d 02 01 63 05 04 81 02 02 01   ..d...]..c......
|    192: 64 07 04 81 67 02 01 65 0a 04 83 0c 03 02 70 77   d...g..e......pw
|    208: 04 04 83 70 02 02 66 79 08 04 82 25 02 01 68 0a   ...p..fy...%..h.
|    224: 04 81 34 02 01 6b 03 02 4d 03 04 84 32 02 01 70   ..4..k..M...2..p
|    240: 01 04 81 15 02 01 73 07 04 83 4d 02 02 37 02 01   ......s...M..7..
|    256: 74 02 02 40 03 01 68 07 04 83 45 02 02 76 69 09   t..@..h...E..vi.
|    272: 04 82 66 03 01 6c 09 04 82 34 02 01 79 01 04 84   ..f..l...4..y...
|    288: 13 02 02 c2 ba 0a 04 81 68 03 01 bc 0a 04 83 0d   ........h.......
|    304: 02 04 ca 80 69 6c 09 04 81 5a 02 02 d3 84 05 04   ....il...Z......
|    320: 83 0a 01 01 31 01 16 18 1a 30 81 4c 31 12 54 81   ....1....0.L1.T.
|    336: 00 1d 01 0e 02 25 82 4b 1d 3f 76 01 0c 43 79 4b   .....%.K.?v..CyK
|    352: 5b 0b 76 01 0e 35 1a 81 08 82 77 10 01 0c 81 24   [.v..5....w....$
|    368: 18 07 74 6f 01 08 29 81 08 69 01 10 81 0e 0d 4a   ..to..)..i.....J
|    384: 81 01 07 58 01 08 6b 51 76 7a 01 0c 20 81 18 6c   ...X..kQvz.. ..l
|    400: 2c 18 01 08 83 7c 7b 0e 02 01 32 08 02 48 03 04   ,....|....2..H..
|    416: f3 a1 97 a5 03 04 83 71 02 01 33 02 04 81 2f 03   .......q..3.../.
|    432: 01 66 09 04 83 15 02 03 61 ca b1 08 04 81 48 02   .f......a.....H.
|    448: 01 63 01 02 1c 02 03 65 c2 aa 06 02 5a 02 01 68   .c.....e....Z..h
|    464: 03 04 81 6e 02 01 69 0a 04 82 5a 03 01 69 08 04   ...n..i...Z..i..
|    480: 81 65 02 01 6a 02 02 64 06 04 84 12 02 01 6c 01   .e..j..d......l.
|    496: 02 1f 02 01 6e 03 04 83 24 02 03 6f c2 b3 07 04   ....n...$..o....
|    512: 84 52 02 03 72 c9 9b 04 04 82 6e 02 01 73 07 04   .R..r.....n..s..
|    528: 82 10 02 01 77 0a 02 31 02 01 79 07 04 81 7f 02   ....w..1..y.....
|    544: 02 7a 62 09 04 83 49 02 02 c2 b9 02 04 83 01 03   .zb...I.........
|    560: 02 bd 75 09 04 83 45 02 02 c6 aa 02 04 83 08 02   ..u...E.........
|    576: 03 d7 92 6a 08 02 04 01 01 32 01 0c 81 7d 72 81   ...j.....2....r.
|    592: 4e 36 01 0e 1a 81 10 81 10 11 2e 01 08 78 49 82   N6...........xI.
|    608: 3b 01 0e 73 81 64 05 1b 81 69 01 1a 18 06 7e 2c   ;..s.d...i....~,
|    624: 21 12 20 5a 28 69 06 1e 06 01 0c 81 48 05 31 81   !. Z(i......H.1.
|    640: 24 01 14 25 81 42 3e 81 16 81 37 13 13 01 0c 21   $..%.B>...7....!
|    656: 0d 0f 3e 82 03 01 08 6b 60 81 27 01 10 2d 81 41   ..>....k`.'..-.A
|    672: 06 69 81 08 30 02 01 32 03 04 81 01 02 01 33 08   .i..0..2......3.
|    688: 02 3c 02 01 35 0a 04 84 64 02 01 38 05 04 83 41   .<..5...d..8...A
|    704: 02 02 61 69 09 04 82 49 02 03 66 c8 ab 09 04 82   ..ai...I..f.....
|    720: 68 02 01 68 04 04 83 27 02 01 6c 04 04 84 18 03   h..h...'..l.....
|    736: 02 72 6e 06 04 82 30 02 01 6e 04 04 84 55 03 01   .rn...0..n...U..
|    752: 6d 05 04 83 30 03 03 76 c2 bd 09 02 57 02 01 71   m...0..v....W..q
|    768: 02 04 84 22 03 04 84 11 03 05 72 f0 92 bc bc 0a   ..........r.....
|    784: 04 82 40 02 01 72 04 04 83 5b 02 01 73 05 02 6f   ..@..r...[..s..o
|    800: 03 04 83 6f 02 01 75 04 02 55 02 01 78 03 04 82   ...o..u..U..x...
|    816: 56 02 01 7a 06 04 85 01 03 02 25 02 02 c2 b2 07   V..z......%.....
|    832: 04 83 7a 03 03 b3 ce bc 03 04 84 2b 03 03 bc c2   ..z........+....
|    848: b2 09 04 83 53 02 04 ce a2 38 6e 07 04 82 23 03   ....S....8n...#.
|    864: 01 bc 08 04 83 7f 02 03 d2 b7 69 0a 04 84 19 02   ..........i.....
|    880: 02 d6 84 09 04 81 0e 01 01 33 01 06 2a 83 69 01   .........3..*.i.
|    896: 18 0f 0e 25 42 81 71 81 21 17 07 03 0d 01 1a 15   ...%B.q.!.......
|    912: 13 42 03 81 40 45 21 60 4d 1a 04 0e 01 0a 83 18   .B..@E!`M.......
|    928: 81 11 0a 01 08 64 83 24 24 01 16 62 1d 0c 06 62   .....d.$$..b...b
|    944: 50 2c 73 17 15 4d 01 0e 1b 82 15 4d 31 3a 4f 01   P,s..M.....M1:O.
|    960: 0e 22 63 51 81 7f 81 22 01 0e 21 81 0a 3e 42 82   ..cQ......!..>B.
|    976: 08 01 12 05 82 0a 33 19 10 81 37 63 02 01 32 05   ......3...7c..2.
|    992: 04 82 3c 02 01 36 02 04 84 0f 02 01 38 06 04 84   ..<..6......8...
|   1008: 1f 02 01 39 06 04 82 06 02 01 61 08 04 81 00 03   ...9......a.....
|   1024: 03 33 6f 62 01 02 69 02 01 65 02 04 84 05 07 04   .3ob..i..e......
|   1040: 84 0e 02 01 67 09 04 82 44 02 01 6a 07 02 55 02   ....g...D..j..U.
|   1056: 01 6b 02 04 84 04 07 04 84 44 02 01 6c 06 04 84   .k.......D..l...
|   1072: 0d 02 01 6e 06 04 84 10 03 01 77 03 02 46 02 01   ...n......w..F..
|   1088: 74 08 04 83 33 03 01 77 03 04 81 5b 02 01 75 0a   t...3..w...[..u.
|   1104: 04 81 75 02 01 78 01 04 83 48 03 02 c2 b2 02 04   ..u..x...H......
|   1120: 81 77 02 04 c2 b3 c2 b3 09 02 1b 02 06 f2 98 9e   .w..............
|   1136: a2 61 6c 08 04 83 31 01 01 34 01 0e 81 1c 82 11   .al...1..4......
|   1152: 4e 81 06 01 10 4a 12 64 39 18 81 24 72 01 04 81   N....J.d9..$r...
|   1168: 0b 01 10 81 08 81 50 48 2a 79 15 01 14 13 72 07   ......PH*y....r.
|   1184: 2f 42 81 21 50 81 02 01 10 6d 46 3e 81 0c 81 17   /B.!P....mF>....
|   1200: 23 01 08 0a 5f 83 38 01 0a 57 81 3e 82 0f 01 10   #..._.8..W.>....
|   1216: 81 07 81 7e 0c 81 14 1d 01 08 1f 82 42 4e 02 01   ...~........BN..
|   1232: 30 01 04 81 36 04 04 81 39 03 02 c2 bd 02 04 81   0...6...9.......
|   1248: 1e 02 01 31 05 04 84 31 02 01 35 0a 04 81 2b 02   ...1...1..5...+.
|   1264: 06 37 c2 b9 eb a0 86 04 04 83 0d 02 02 61 6f 04   .7...........ao.
|   1280: 04 83 39 02 01 63 07 04 83 3c 03 01 67 0a 04 84   ..9..c...<..g...
|   1296: 6a 02 01 65 07 06 68 82 7d 02 03 66 c2 be 07 04   j..e..h....f....
|   1312: 81 3d 02 01 67 08 02 58 01 04 83 16 02 01 6c 03   .=..g..X......l.
|   1328: 04 81 73 02 01 6d 08 04 81 42 02 01 6e 04 04 83   ..s..m...B..n...
|   1344: 75 02 03 6f 65 32 06 04 84 4f 02 01 70 05 04 81   u..oe2...O..p...
|   1360: 56 03 01 77 09 04 81 47 02 02 72 32 05 02 0b 02   V..w...G..r2....
|   1376: 01 73 01 02 47 04 04 84 09 02 01 74 07 04 85 05   .s..G......t....
|   1392: 02 01 75 01 02 5b 02 04 76 e5 b9 83 07 04 82 03   ..u..[..v.......
|   1408: 02 01 78 01 04 81 11 02 02 c6 bf 02 04 81 3b 02   ..x...........;.
|   1424: 02 ce bc 06 04 84 3a 02 03 e1 83 93 03 04 81 2b   ......:........+
|   1440: 01 01 35 01 0e 81 7b 61 23 71 55 0c 01 08 82 30   ..5....a#qU....0
|   1456: 2a 7b 01 0c 81 45 81 20 72 38 01 0c 29 82 25 55   *....E. r8..).%U
|   1472: 4c 21 01 0c 81 53 38 25 3a 63 01 08 83 55 81 0f   L!...S8%:c...U..
|   1488: 01 0e 81 32 5b 81 1b 31 6f 01 16 1e 6d 17 0e 17   ...2[..1o...m...
|   1504: 1f 6b 0b 3e 3d 3a 01 12 32 81 4a 81 04 55 47 20   .k.>=:..2.J..UG 
|   1520: 09 01 10 82 4b 81 0a 17 3e 05 2a 02 01 31 08 04   ....K...>.*..1..
|   1536: 84 04 02 02 36 68 06 02 18 02 01 61 02 04 84 3d   ....6h.....a...=
|   1552: 08 04 81 38 03 01 34 01 02 71 02 03 63 75 6d 0a   ...8..4..q..cum.
|   1568: 04 81 3a 02 01 64 09 02 52 01 04 82 48 02 01 68   ..:..d..R...H..h
|   1584: 08 02 30 02 04 83 4e 02 01 6e 01 02 42 02 05 6f   ..0...N..n..B..o
|   1600: 63 6c dc ab 08 02 11 03 04 67 69 c2 be 03 04 82   cl.......gi.....
|   1616: 29 02 01 71 07 04 82 12 02 01 79 06 04 84 1b 02   )..q......y.....
|   1632: 02 7a 33 09 04 83 4c 02 02 c2 b2 05 04 84 17 03   .z3...L.........
|   1648: 01 b9 09 02 35 04 02 6b 78 0a 04 81 31 03 01 bc   ....5..kx...1...
|   1664: 0a 02 41 02 08 cb 8a f0 9c bb a1 67 68 02 04 81   ..A........gh...
|   1680: 75 01 01 36 01 10 55 77 30 36 21 31 69 60 01 0e   u..6..Uw06!1i`..
|   1696: 3b 0b 3e 4e 1c 2c 1b 01 16 44 32 54 07 2f 0e 81   ;.>N.,...D2T./..
|   1712: 11 81 03 14 01 04 81 63 01 0e 81 16 82 5c 15 20   .......c....... 
|   1728: 19 01 12 0d 1f 43 6e 39 06 18 81 54 01 0c 81 40   .....Cn9...T...@
|   1744: 2c 81 0f 4d 01 10 16 82 5e 0e 08 0d 78 51 01 12   ,..M....^...xQ..
|   1760: 1d 81 73 81 22 29 17 66 1a 01 0a 81 3f 81 3f 19   ..s..).f....?.?.
|   1776: 02 01 30 0a 04 83 47 03 01 6d 05 04 82 3e 02 01   ..0...G..m...>..
|   1792: 32 07 04 81 5e 03 04 82 19 02 04 34 71 6c 38 01   2...^......4ql8.
|   1808: 04 83 6b 02 02 37 67 08 04 84 53 02 01 64 04 02   ..k..7g...S..d..
|   1824: 7b 03 01 71 02 04 81 71 02 01 65 01 04 83 66 05   ...q...q..e...f.
|   1840: 04 84 5c 02 01 69 09 04 81 3a 02 01 6a 03 04 83   .....i...:..j...
|   1856: 35 02 01 6b 06 04 83 6d 01 04 83 5f 02 04 84 0f   5..k...m..._....
|   1872: 02 01 73 03 04 83 2d 02 01 74 06 04 84 0e 02 04   ..s...-..t......
|   1888: 82 02 02 01 75 05 04 83 73 03 01 37 03 04 84 32   ....u...s..7...2
|   1904: 02 01 76 03 04 83 0f 02 01 77 08 04 82 33 03 01   ..v......w...3..
|   1920: 6f 01 02 0b 02 01 78 02 02 36 02 02 c2 b3 03 04   o.....x..6......
|   1936: 81 07 02 04 84 29 02 02 ca a9 05 04 83 19 02 03   .....)..........
|   1952: ce bc 79 08 04 84 4b 02 02 d0 b8 05 04 81 06 02   ..y...K.........
|   1968: 06 f1 b5 87 92 35 6b 05 04 82 34 01 01 37 01 14   .....5k...4..7..
|   1984: 81 3d 4b 17 08 16 81 03 81 20 01 0e 42 81 27 32   .=K...... ..B.'2
|   2000: 20 0c 7a 01 0a 4c 83 12 40 19 01 16 06 21 6f 81    .z..L..@....!o.
|   2016: 02 70 36 0d 49 2e 2d 01 14 81 12 19 19 60 06 4c   .p6.I.-......`.L
|   2032: 44 17 4f 01 12 03 81 12 04 81 23 81 4b 0a 01 12   D.O.......#.K...
|   2048: 0b 48 50 22 10 7f 81 38 56 01 0e 27 38 81 21 82   .HP....8V..'8.!.
|   2064: 08 2a 01 08 81 6b 41 24 01 0c 81 7c 73 81 3e 05   .*...kA$...|s.>.
|   2080: 02 02 34 67 05 04 83 5d 02 01 37 05 04 81 2f 02   ..4g...]..7.../.
|   2096: 02 73 02 01 38 01 02 21 02 01 39 09 02 4a 02 01   .s..8..!..9..J..
|   2112: 62 0a 02 70 03 02 71 7a 01 04 83 26 02 01 64 0a   b..p..qz...&..d.
|   2128: 04 84 04 02 01 65 0a 02 78 02 01 68 02 04 82 26   .....e..x..h...&
|   2144: 02 02 69 35 06 04 82 02 02 01 6b 02 04 82 0a 03   ..i5......k.....
|   2160: 02 c2 bc 05 04 82 08 02 01 6d 08 02 54 02 01 6e   .........m..T..n
|   2176: 06 04 82 32 02 03 6f 74 61 02 04 81 2a 02 05 71   ...2..ota...*..q
|   2192: f2 96 8c 90 01 04 83 5a 02 01 72 09 04 83 31 02   .......Z..r...1.
|   2208: 01 74 03 02 71 04 04 83 62 02 02 79 65 04 04 83   .t..q...b..ye...
|   2224: 26 02 02 c2 aa 05 04 82 19 03 01 b3 02 02 10 02   &...............
|   2240: 04 83 48 03 01 bd 01 04 84 10 02 02 cf ad 06 04   ..H.............
|   2256: 82 04 02 04 f0 97 97 98 08 04 83 1f 02 04 f3 a5   ................
|   2272: b3 87 08 04 81 64 01 01 38 01 0a 16 82 49 81 30   .....d..8....I.0
|   2288: 01 0e 81 19 27 34 53 82 19 01 12 20 1f 5c 5f 81   ....'4S.... .._.
|   2304: 50 81 17 04 01 10 0e 81 2e 2d 51 67 81 16 01 0c   P........-Qg....
|   2320: 81 62 09 81 79 10 01 08 63 04 81 1c 01 0a 81 2e   .b..y...c.......
|   2336: 5d 81 0f 01 0a 0b 81 40 81 63 01 10 27 81 17 81   ]......@.c..'...
|   2352: 2b 48 6c 4c 01 10 81 23 4d 64 0a 7f 81 01 02 01   +HlL...#Md......
|   2368: 31 03 02 6b 02 01 36 06 04 83 79 02 01 37 08 04   1..k..6...y..7..
|   2384: 84 47 02 04 39 c2 bc 61 09 04 84 61 02 05 64 c2   .G..9..a...a..d.
|   2400: b9 da 9c 01 04 81 73 02 01 66 01 04 81 58 08 04   ......s..f...X..
|   2416: 82 39 02 02 67 74 0a 04 81 5f 02 01 68 09 04 83   .9..gt..._..h...
|   2432: 2a 02 01 69 0a 04 83 6a 03 01 78 02 04 83 11 02   *..i...j..x.....
|   2448: 01 6a 05 04 83 26 02 06 0d 82 58 03 01 70 07 04   .j...&....X..p..
|   2464: 83 2b 02 01 6b 07 08 83 58 81 12 02 01 6e 0a 02   .+..k...X....n..
|   2480: 71 02 01 77 0a 04 83 04 02 03 c2 ba 31 06 04 84   q..w........1...
|   2496: 4e 03 01 bd 07 04 83 18 02 02 d3 b5 05 02 68 01   N.............h.
|   2512: 01 39 01 0a 53 81 03 81 24 01 0e 13 82 3d 81 1e   .9..S...$....=..
|   2528: 37 2d 01 0c 6a 15 09 13 82 58 01 08 83 0f 81 3f   7-..j....X.....?
|   2544: 01 10 4f 81 60 81 29 64 15 0c 01 0e 4b 0d 62 0d   ..O.`.)d....K.b.
|   2560: 81 00 5e 01 0a 37 81 1b 59 56 01 0e 81 0c 6b 6d   ..^..7..YV....km
|   2576: 81 67 1d 01 10 38 2f 63 38 0c 37 20 6b 01 10 7e   .g...8/c8.7 k..~
|   2592: 10 18 81 4a 81 64 23 02 01 32 02 04 83 2c 02 01   ...J.d#..2...,..
|   2608: 39 04 04 81 10 01 04 82 35 02 04 62 6e c7 9c 0a   9.......5..bn...
|   2624: 04 84 2b 02 02 65 63 06 04 83 0a 03 01 6a 02 04   ..+..ec......j..
|   2640: 84 4d 02 01 66 01 04 83 4d 02 04 81 0a 02 03 68   .M..f...M......h
|   2656: ce bc 0a 04 83 41 02 01 6c 06 02 54 02 01 6d 08   .....A..l..T..m.
|   2672: 04 81 14 02 02 6f 6c 0a 04 84 0a 02 01 70 02 04   .....ol......p..
|   2688: 82 2b 05 04 81 49 02 05 71 69 c2 bd 75 0a 02 46   .+...I..qi..u..F
|   2704: 02 02 72 38 0a 04 82 26 02 01 74 04 04 81 0b 04   ..r8...&..t.....
|   2720: 04 84 6e 02 01 77 03 04 81 6a 01 04 82 6b 03 01   ..n..w...j...k..
|   2736: 65 09 04 82 58 02 01 78 06 02 6e 02 02 c2 b3 08   e...X..x..n.....
|   2752: 06 76 81 10 03 01 b9 04 02 47 03 01 bc 0a 04 83   .v.......G......
|   2768: 03 02 02 ce bc 02 06 83 3f 19 02 03 d9 be 7a 03   ........?.....z.
|   2784: 04 82 5d 01 01 61 01 1e 17 50 16 12 12 2d 32 81   ..]..a...P...-2.
|   2800: 1e 56 81 06 04 06 1b 01 16 43 5c 52 64 19 15 27   .V.......C.Rd..'
|   2816: 1d 29 0e 52 01 1c 1d 03 81 1c 13 6b 3d 64 14 32   .).R.......k=d.2
|   2832: 16 29 09 0a 01 22 32 13 07 81 08 03 22 05 17 20   .)....2........ 
|   2848: 07 0e 7a 15 71 22 22 01 1c 30 05 06 0b 22 40 11   ..z.q....0....@.
|   2864: 49 1c 0c 15 81 1f 27 01 0c 4a 14 1c 7a 36 66 01   I.....'..J..z6f.
|   2880: 1c 10 19 81 0a 81 1c 81 02 10 54 33 09 0c 07 01   ..........T3....
|   2896: 1e 38 2e 33 3a 22 1e 2e 35 3a 0f 07 77 15 0b 2f   .8.3:...5:..w../
|   2912: 01 2a 08 5a 35 13 0b 07 05 04 17 42 32 14 04 09   .*.Z5......B2...
|   2928: 1d 0b 09 06 42 72 1c 01 1e 22 0a 15 2b 03 04 6c   ....Br......+..l
|   2944: 05 81 3d 14 19 58 21 4a 02 01 32 08 04 83 64 03   ..=..X!J..2...d.
|   2960: 01 67 07 04 82 5c 02 02 34 66 03 04 83 6d 03 01   .g......4f...m..
|   2976: 73 08 04 81 18 02 05 37 6a 77 c2 b9 0a 04 83 1d   s......7jw......
|   2992: 02 02 38 7a 0a 04 82 3a 02 01 39 05 02 5c 03 02   ..8z...:..9.....
|   3008: c2 b3 06 02 70 02 01 61 01 04 83 03 02 01 66 02   ....p..a......f.
|   3024: 04 81 5b 02 04 82 37 02 01 68 04 04 82 78 01 02   ..[...7..h...x..
|   3040: 67 02 01 69 04 04 84 0e 06 04 82 41 02 01 6a 01   g..i.......A..j.
|   3056: 04 82 4c 02 02 4e 03 04 81 73 03 01 6c 02 04 81   ..L..N...s..l...
|   3072: 5f 02 01 6b 08 04 81 26 02 05 6d c2 b3 6f 76 06   _..k...&..m..ov.
|   3088: 04 82 7c 02 01 6e 08 02 1c 02 01 6f 02 04 83 24   ..|..n.....o...$
|   3104: 07 04 83 77 02 01 70 04 04 82 7e 02 01 71 0a 04   ...w..p...~..q..
|   3120: 81 19 02 06 72 f1 b6 bc b3 68 01 04 83 0e 02 01   ....r....h......
|   3136: 73 03 04 82 17 01 08 81 70 81 65 03 04 39 c2 ba   s.......p.e..9..
|   3152: 69 06 04 81 65 03 01 76 02 04 81 26 02 01 74 01   i...e..v...&..t.
|   3168: 02 4c 02 01 75 01 04 84 67 02 02 77 69 0a 02 09   .L..u...g..wi...
|   3184: 02 04 78 d2 b9 73 04 04 83 42 02 03 7a c2 b3 08   ..x..s...B..z...
|   3200: 02 43 02 02 c2 aa 01 04 82 61 06 04 84 10 02 02   .C.......a......
|   3216: c6 88 07 02 1f 02 04 c8 b8 dd bf 05 04 81 72 02   ..............r.
|   3232: 02 c9 ad 07 04 84 2f 02 02 ce bc 07 02 05 02 02   ....../.........
|   3248: cf 85 0a 04 84 36 02 02 d9 a3 02 04 81 72 02 04   .....6.......r..
|   3264: f1 a9 82 9b 0a 04 82 72 01 01 62 01 1c 81 17 06   .......r..b.....
|   3280: 4a 46 28 2a 0a 4a 10 36 05 52 20 01 1c 1f 15 5f   JF(*.J.6.R ...._
|   3296: 17 12 2b 46 03 81 2b 0f 1b 1f 4f 01 26 6d 68 10   ..+F..+...O.&mh.
|   3312: 04 08 06 20 04 10 05 20 05 07 6d 2e 09 14 05 24   ... ... ..m....$
|   3328: 01 18 21 2b 11 12 81 0f 3e 22 11 28 51 28 01 18   ..!+....>..(Q(..
|   3344: 12 11 4e 36 81 5a 23 3b 1a 16 26 2a 01 20 34 79   ..N6.Z#;..&*. 4y
|   3360: 1e 32 14 05 27 17 0c 4a 49 46 09 03 0d 2f 01 0e   .2..'..JIF.../..
|   3376: 15 35 6f 3c 24 5e 2e 01 14 15 40 49 25 2c 0a 1d   .5o<$^....@I%,..
|   3392: 67 70 2e 01 1c 06 03 0b 0e 76 81 0e 15 81 25 0b   gp.......v....%.
|   3408: 39 2d 1a 01 14 27 1e 81 01 27 81 54 76 14 3e 02   9-...'...'.Tv.>.
|   3424: 02 31 62 08 04 83 1d 02 01 33 0a 04 83 35 02 01   .1b......3...5..
|   3440: 37 02 04 82 6b 02 01 39 0a 02 29 02 01 61 03 04   7...k..9..)..a..
|   3456: 82 72 02 01 64 01 04 81 05 02 04 84 1f 02 01 65   .r..d..........e
|   3472: 01 04 81 69 02 01 66 04 04 82 50 05 04 82 10 02   ...i..f...P.....
|   3488: 01 69 01 02 0d 02 01 6b 0a 04 81 0a 02 01 6c 02   .i.....k......l.
|   3504: 04 81 79 04 04 84 6e 03 01 31 0a 04 84 66 02 01   ..y...n..1...f..
|   3520: 6f 0a 04 83 48 02 01 73 01 02 3d 03 02 10 02 01   o...H..s..=.....
|   3536: 74 02 04 82 0e 02 01 75 06 04 84 74 03 01 32 01   t......u...t..2.
|   3552: 04 82 0d 02 01 76 06 04 83 3a 02 01 78 08 04 82   .....v...:..x...
|   3568: 73 03 01 6c 09 04 84 1c 03 01 78 02 04 82 08 03   s..l......x.....
|   3584: 02 7a 69 0a 04 83 73 02 01 79 03 04 82 42 02 01   .zi...s..y...B..
|   3600: 7a 08 04 83 03 02 06 c2 b9 e3 b1 a1 32 0a 04 81   z...........2...
|   3616: 46 03 01 bc 04 04 83 36 03 01 be 04 04 84 3f 02   F......6......?.
|   3632: 02 c6 80 0a 04 84 00 02 03 d4 a3 76 07 04 84 33   ...........v...3
|   3648: 02 04 da ba 71 6f 08 04 84 11 02 02 dd a8 08 02   ....qo..........
|   3664: 51 02 06 eb 9e ac 7a 73 79 06 02 32 01 01 63 01   Q.....zsy..2..c.
|   3680: 18 04 39 12 3a 05 34 56 46 59 81 0b 43 01 22 2a   ..9.:.4VFY..C..*
|   3696: 1d 1f 53 2b 60 22 12 0d 13 1c 2e 35 05 03 0f 54   ..S+`......5...T
|   3712: 01 14 81 1e 81 1f 17 03 24 2a 81 0b 01 24 34 20   ........$*...$4 
|   3728: 06 21 0a 30 05 08 03 62 0c 26 10 6c 3b 0d 44 3a   .!.0...b.&.l;.D:
|   3744: 01 1a 15 0b 77 04 45 3f 34 37 3f 08 13 36 53 01   ....w.E?47?..6S.
|   3760: 1c 02 38 33 49 1e 2e 81 19 43 33 3e 24 15 08 01   ..83I....C3>$...
|   3776: 1a 09 81 55 40 43 09 21 27 4c 04 5b 07 07 07 07   ...U@C.!'L.[....
|   3792: 07 07 07 07 07 08 08 07 0a 07 0a 06 07 08 07 07   ................
|   3808: 08 07 0a 08 56 06 0a 07 07 09 06 08 07 07 07 0a   ....V...........
|   3824: 06 07 09 09 07 06 07 08 08 08 08 08 5e 07 06 07   ............^...
|   3840: 07 08 09 07 07 08 07 07 08 0b 0b 07 0a 06 07 0a   ................
|   3856: 08 09 09 0a 07 09 08 65 07 07 07 07 07 08 0b 07   .......e........
|   3872: 06 0b 07 07 06 07 07 07 07 08 09 0c 57 0b 08 07   ............W...
|   3888: 07 0c 08 07 07 08 09 0a 07 07 07 09 07 07 07 0a   ................
|   3904: 07 06 0a 07 08 08 09 5b 07 07 0b 06 09 0a 0a 06   .......[........
|   3920: 0a 0a 07 07 08 08 06 08 06 0e 5f 07 07 0b 0a 08   .........._.....
|   3936: 06 07 0b 07 07 0f 07 0b 07 07 07 07 06 06 0c 08   ................
|   3952: 09 08 0c 65 08 0a 06 06 06 08 07 06 07 08 07 08   ...e............
|   3968: 06 07 09 0b 07 0a 08 08 0a 07 08 0a 0a 58 06 07   .............X..
|   3984: 07 0a 0b 0b 08 07 07 07 0c 07 09 06 07 09 07 07   ................
|   4000: 58 07 0b 0a 08 07 0b 09 06 07 08 0b 0a 08 0b 0b   X...............
|   4016: 07 06 09 06 07 09 09 81 25 07 07 08 07 0b 08 06   ........%.......
|   4032: 07 07 0b 0a 0b 0e 07 07 0b 06 0b 07 07 0c 0d 0a   ................
|   4048: 07 06 07 07 0a 08 0c 07 0a 08 07 08 08 0a 81 17   ................
|   4064: 08 07 07 06 07 0b 07 0b 06 07 0b 07 07 09 07 07   ................
|   4080: 07 07 07 07 07 08 07 07 0c 07 07 08 09 0a 07 0b   ................
| page 21 offset 81920
|      0: 0d 00 00 00 01 00 21 00 00 21 00 00 00 00 00 00   ......!..!......
|     32: 00 9f 57 88 80 80 80 80 02 04 00 bf 32 00 08 0e   ..W.........2...
|     48: 8c 3a 14 04 29 08 18 17 4a 44 3a 19 4e 5f 56 16   .:..)...JD:.N_V.
|     64: 08 30 25 01 1c 0e 13 32 1b 0b 41 03 2f 81 34 3c   .0%....2..A./.4<
|     80: 14 09 21 01 14 81 01 06 10 30 1f 28 0f 51 5f 04   ..!......0.(.Q_.
|     96: 30 63 33 74 05 02 69 02 02 34 76 0a 04 83 63 02   0c3t..i..4v...c.
|    112: 04 36 e7 8e a1 03 04 84 03 02 04 61 77 c2 b9 05   .6.........aw...
|    128: 04 82 56 02 01 63 03 04 82 02 04 04 82 0a 02 02   ..V..c..........
|    144: 64 30 09 02 40 02 01 67 02 06 61 83 38 02 04 82   d0..@..g..a.8...
|    160: 70 03 04 84 62 03 01 73 02 04 84 5f 02 01 68 01   p...b..s..._..h.
|    176: 04 81 76 03 01 32 07 04 84 3f 02 01 69 09 02 7e   ..v..2...?..i..~
|    192: 02 01 6a 01 04 81 57 02 01 6b 01 04 82 33 02 01   ..j...W..k...3..
|    208: 6d 05 02 7b 02 01 6e 06 04 82 51 02 01 6f 06 02   m.....n...Q..o..
|    224: 0e 03 01 65 01 04 81 3c 02 02 70 63 06 02 1e 02   ...e...<..pc....
|    240: 01 71 02 04 84 3b 08 02 1a 02 01 72 09 06 36 81   .q...;.....r..6.
|    256: 38 02 01 75 02 04 83 3b 03 02 54 02 01 77 04 04   8..u...;..T..w..
|    272: 83 5c 06 04 83 21 02 01 78 07 04 81 21 02 01 79   .....!..x...!..y
|    288: 06 02 3a 02 02 7a 31 02 04 84 2a 02 02 c2 b2 02   ..:..z1...*.....
|    304: 04 81 01 03 01 b3 07 04 82 5e 03 02 bd 7a 06 04   .........^...z..
|    320: 82 08 02 02 c6 9e 0a 04 83 4d 02 02 ce bc 05 04   .........M......
|    336: 84 70 02 02 d3 86 06 04 82 33 02 02 d4 a7 01 02   .p.......3......
|    352: 7c 02 02 d8 b8 06 04 82 53 02 02 df a4 04 02 7c   |.......S......|
|    368: 02 03 e0 b7 ae 04 04 84 5e 02 03 e6 91 9a 03 04   ........^.......
|    384: 81 18 02 04 f0 90 ac 8e 04 04 82 39 01 01 64 01   ...........9..d.
|    400: 16 23 2f 1a 6d 81 47 65 09 1b 42 25 01 10 0d 82   .#/.m.Ge..B%....
|    416: 18 81 3c 50 06 34 01 10 60 31 5a 14 18 16 5f 18   ..<P.4..`1Z..._.
|    432: 01 24 03 0a 28 2b 7c 18 40 0f 0e 09 13 08 0c 10   .$..(+|.@.......
|    448: 64 07 0e 39 01 12 11 3e 82 02 4a 0c 5a 07 21 01   d..9...>..J.Z.!.
|    464: 18 0a 0a 67 3d 81 37 40 68 0e 30 17 18 01 12 08   ...g=.7@h.0.....
|    480: 6a 54 81 0c 49 14 4f 21 01 16 26 82 0d 3c 0c 60   jT..I.O!..&..<.`
|    496: 19 27 51 05 07 01 16 24 20 07 1a 81 1c 1f 24 43   .'Q....$ .....$C
|    512: 81 5b 01 16 42 21 05 81 07 0d 36 5b 21 81 15 02   .[..B!....6[!...
|    528: 01 30 01 04 84 4d 02 01 32 04 04 84 38 02 01 34   .0...M..2...8..4
|    544: 06 04 83 1e 02 04 84 3c 01 04 81 2c 02 01 62 08   .......<...,..b.
|    560: 04 82 51 03 01 61 05 04 84 3e 02 01 63 06 04 84   ..Q..a...>..c...
|    576: 24 03 04 83 40 02 01 64 01 08 81 18 83 2e 02 01   $...@..d........
|    592: 65 03 04 82 46 02 01 66 09 04 84 33 02 01 67 03   e...F..f...3..g.
|    608: 04 81 55 02 07 68 c2 b9 62 71 61 30 02 02 48 02   ..U..h..bqa0..H.
|    624: 01 69 04 04 82 4b 03 01 78 03 04 81 3c 02 02 6a   .i...K..x...<..j
|    640: 34 05 02 47 02 01 6b 01 04 82 29 03 01 38 0a 02   4..G..k...)..8..
|    656: 49 02 01 6c 02 04 84 1a 01 04 84 58 07 04 82 2c   I..l.......X...,
|    672: 02 01 6d 06 04 83 0b 02 04 84 0c 03 02 c2 bc 08   ..m.............
|    688: 04 83 17 02 01 6e 02 04 83 70 02 01 6f 04 04 81   .....n...p..o...
|    704: 56 03 01 61 03 02 5b 03 04 65 79 64 37 06 04 81   V..a..[..eyd7...
|    720: 38 03 03 ee a9 bf 08 02 45 02 01 71 04 04 81 75   8.......E..q...u
|    736: 03 01 74 09 04 83 66 02 01 72 06 02 4f 02 01 73   ..t...f..r..O..s
|    752: 01 04 81 26 07 02 2d 02 01 74 02 02 14 02 02 3c   ...&..-..t.....<
|    768: 04 04 84 5d 02 02 77 64 02 02 31 02 01 78 02 04   ...]..wd..1..x..
|    784: 84 59 03 04 84 65 02 01 79 02 02 58 04 04 81 49   .Y...e..y..X...I
|    800: 01 04 83 17 03 02 7f 02 02 c2 b3 04 02 05 03 01   ................
|    816: b9 01 04 84 09 03 01 be 0a 04 82 59 02 02 ce bc   ...........Y....
|    832: 06 04 81 02 02 02 d7 9d 06 04 83 31 02 04 df 84   ...........1....
|    848: da 8c 08 04 82 67 02 04 e1 b5 b6 6b 0a 04 81 7b   .....g.....k....
|    864: 02 03 e3 a1 92 03 04 83 66 02 04 f0 9b 93 a9 07   ........f.......
|    880: 04 85 0b 04 02 a8 81 06 04 82 3e 01 01 65 01 24   ..........>..e.$
|    896: 43 34 18 15 08 09 51 19 5b 17 28 26 11 06 23 38   C4....Q.[.(&..#8
|    912: 2b 2b 01 1e 1c 32 20 17 0f 2c 03 0c 1b 0c 6f 25   ++...2 ..,....o%
|    928: 73 16 40 01 1e 07 12 81 5a 44 19 06 03 24 5c 0e   s.@.....ZD...$..
|    944: 16 18 39 0d 01 26 0d 09 06 41 42 09 24 1d 25 0c   ..9..&...AB.$.%.
|    960: 06 1d 63 14 26 18 7d 0a 1d 01 14 25 56 29 0a 81   ..c.&......%V)..
|    976: 1a 1b 37 5d 3d 01 16 1c 81 26 25 7f 41 52 46 08   ..7]=....&%.ARF.
|    992: 1b 16 01 12 81 0f 6b 7b 0f 2d 03 7f 07 01 18 19   ......k..-......
|   1008: 28 81 01 50 36 41 16 81 22 17 03 01 1c 16 1a 81   (..P6A..........
|   1024: 1f 10 17 41 4c 1c 0b 66 49 10 06 01 18 54 82 38   ...AL..fI....T.8
|   1040: 13 2a 0b 14 4c 15 0f 36 0b 02 01 30 07 04 82 28   .*..L..6...0...(
|   1056: 02 01 31 09 04 81 2b 01 04 83 38 02 01 33 03 04   ..1...+...8..3..
|   1072: 81 76 02 01 61 08 04 84 6b 03 05 7a ea 86 b3 6a   .v..a...k..z...j
|   1088: 06 04 82 52 02 01 62 0a 04 83 19 02 01 63 02 04   ...R..b......c..
|   1104: 82 4d 03 02 c2 be 04 04 82 29 02 01 64 05 04 81   .M.......)..d...
|   1120: 7a 03 04 81 72 02 02 66 61 04 02 41 03 01 77 06   z...r..fa..A..w.
|   1136: 02 3e 02 04 82 10 02 01 67 05 04 84 48 02 01 69   .>......g...H..i
|   1152: 01 04 83 12 02 02 6c 62 07 04 81 1d 02 01 6d 01   ......lb......m.
|   1168: 04 83 6e 02 01 6f 05 02 09 02 04 81 16 02 01 70   ..n..o.........p
|   1184: 05 06 07 82 72 03 01 38 07 04 84 46 02 01 73 02   ....r..8...F..s.
|   1200: 04 84 2d 05 04 81 58 03 04 81 4a 03 02 c2 bd 0a   ..-...X...J.....
|   1216: 04 83 2d 02 01 74 02 04 84 55 05 04 85 02 02 01   ..-..t...U......
|   1232: 75 02 04 82 62 02 01 76 01 04 84 31 02 01 77 09   u...b..v...1..w.
|   1248: 04 82 15 02 01 78 01 02 45 05 04 82 14 03 04 83   .....x..E.......
|   1264: 01 02 01 79 06 04 81 0c 02 02 7a 78 09 04 81 6d   ...y......zx...m
|   1280: 02 04 c2 bc 61 72 04 04 83 20 04 01 6f 01 02 70   ....ar... ..o..p
|   1296: 02 02 c9 9e 01 04 82 02 02 02 ca 83 05 04 82 3f   ...............?
|   1312: 03 01 9b 05 02 52 03 01 aa 07 04 83 65 02 02 cd   .....R......e...
|   1328: bb 01 04 83 07 02 02 ce b2 06 02 5b 02 03 cf a7   ...........[....
|   1344: 78 03 04 81 3b 02 03 ef a9 89 08 04 82 20 02 04   x...;........ ..
|   1360: f5 87 b0 93 02 04 84 18 01 01 66 01 1c 2b 3d 5b   ..........f..+=[
|   1376: 23 45 2d 41 17 0e 81 1d 0f 15 1f 01 16 05 81 20   #E-A........... 
|   1392: 0d 27 81 0f 3e 28 2b 13 01 14 62 2c 44 26 17 04   .'..>(+...b,D&..
|   1408: 23 50 6d 5b 01 1c 30 5b 81 27 07 29 38 15 4d 11   #Pm[..0[.'.)8.M.
|   1424: 2e 20 17 20 01 1a 19 65 4f 14 2e 55 0e 12 39 13   . . ...eO..U..9.
|   1440: 1d 70 12 01 20 1a 0d 2f 05 81 19 2b 42 05 37 4c   .p.. ../...+B.7L
|   1456: 21 22 04 25 2b 01 14 45 3e 05 10 81 47 6c 81 11   !..%+..E>...Gl..
|   1472: 11 01 1e 78 04 12 18 0a 05 10 14 6b 05 0a 04 82   ...x.......k....
|   1488: 05 15 01 1e 05 23 4b 18 24 31 20 27 12 2e 81 0e   .....#K.$1 '....
|   1504: 31 18 18 01 10 55 7e 29 2a 06 19 65 38 02 01 30   1....U~)*..e8..0
|   1520: 09 02 14 02 01 31 02 04 84 00 02 01 36 06 04 84   .....1......6...
|   1536: 7a 02 01 61 07 04 83 71 02 01 62 05 04 83 10 03   z..a...q..b.....
|   1552: 02 34 02 02 63 6f 07 04 83 27 02 01 64 07 04 81   .4..co...'..d...
|   1568: 0c 03 04 81 55 03 01 6f 03 02 7e 02 01 69 02 04   ....U..o..~..i..
|   1584: 81 08 03 02 05 03 04 82 70 02 01 6a 05 02 41 03   ........p..j..A.
|   1600: 02 6f 30 04 02 5e 02 01 6b 02 04 82 13 02 01 6c   .o0..^..k......l
|   1616: 02 04 83 2d 08 04 81 20 02 01 6e 09 04 82 69 02   ...-... ..n...i.
|   1632: 02 6f 38 02 04 83 73 02 01 71 0a 04 81 4f 02 01   .o8...s..q...O..
|   1648: 74 09 04 83 2c 02 01 75 03 04 83 79 03 03 68 c2   t...,..u...y..h.
|   1664: b3 03 04 81 09 02 02 77 64 06 04 81 79 02 01 78   .......wd...y..x
|   1680: 03 04 83 41 03 02 19 02 01 79 02 04 82 1a 07 02   ...A.....y......
|   1696: 72 03 01 6a 06 04 83 1a 02 01 7a 05 04 84 6d 01   r..j......z...m.
|   1712: 04 81 24 02 03 c2 aa 75 0a 04 84 72 03 01 b3 04   ..$....u...r....
|   1728: 04 82 02 03 04 82 2c 03 01 ba 07 04 26 51 03 02   ......,.....&Q..
|   1744: bd 65 07 04 81 1a 03 01 be 09 02 44 02 02 ca 97   .e.........D....
|   1760: 02 04 84 30 02 03 d5 a7 6f 04 02 36 03 02 bd 72   ...0....o..6...r
|   1776: 07 04 81 03 02 05 f3 b2 a7 91 68 09 04 82 22 01   ..........h.....
|   1792: 01 67 01 16 81 41 81 1f 4c 0f 0d 0d 6f 3d 04 01   .g...A..L...o=..
|   1808: 18 12 08 5e 05 16 4f 42 61 22 45 3c 27 01 20 08   ...^..OBa.E<'. .
|   1824: 13 27 14 17 1f 08 3e 0d 41 81 1c 3e 06 1c 1e 01   .'....>.A..>....
|   1840: 16 0c 11 6b 26 54 05 14 03 81 6b 12 01 1a 36 41   ...k&T....k...6A
|   1856: 11 0b 0c 36 7c 08 0e 0c 52 4f 50 01 0c 81 0e 22   ...6|...ROP.....
|   1872: 3d 72 1f 01 22 07 0e 22 3c 4d 1c 09 03 2d 22 1e   =r......<M...-..
|   1888: 11 7e 45 2e 1e 29 01 16 44 07 06 03 81 08 75 81   .~E..)..D.....u.
|   1904: 67 16 12 01 16 22 5a 47 6f 37 0e 05 4d 1f 17 38   g.....ZGo7..M..8
|   1920: 01 14 81 3c 4c 79 07 31 0c 45 4d 2c 02 02 35 65   ...<Ly.1.EM,..5e
|   1936: 0a 04 83 79 02 02 36 75 01 04 84 6b 02 01 38 0a   ...y..6u...k..8.
|   1952: 04 81 6f 02 01 63 02 04 81 22 03 01 75 03 04 83   ..o..c......u...
|   1968: 33 02 01 64 04 04 81 6c 03 04 81 6e 02 01 65 06   3..d...l...n..e.
|   1984: 04 82 4b 02 04 81 7b 03 05 77 f7 98 85 82 02 04   ..K......w......
|   2000: 83 22 02 02 66 6d 07 04 83 5c 02 01 67 03 04 81   ....fm......g...
|   2016: 5e 02 01 69 02 04 84 1e 03 01 61 04 04 81 74 02   ^..i......a...t.
|   2032: 01 6a 01 04 84 50 07 04 84 22 02 04 81 11 02 01   .j...P..........
|   2048: 6b 03 04 83 1f 01 04 83 55 03 01 6f 02 02 49 03   k.......U..o..I.
|   2064: 01 71 0a 04 81 21 02 01 6e 07 04 81 64 02 01 71   .q...!..n...d..q
|   2080: 0a 04 84 0c 02 02 72 73 09 04 82 54 02 06 73 c2   ......rs...T..s.
|   2096: b9 c2 b9 73 08 04 83 3b 02 01 74 0a 04 84 7d 03   ...s...;..t.....
|   2112: 01 78 03 04 83 4c 02 02 75 78 03 04 83 56 04 02   .x...L..ux...V..
|   2128: c2 bd 07 04 81 72 02 01 76 03 04 83 4e 01 02 5d   .....r..v...N..]
|   2144: 05 04 84 1a 02 01 78 01 08 83 69 81 16 02 01 79   ......x...i....y
|   2160: 03 04 84 34 06 04 81 00 03 01 75 05 04 82 2f 02   ...4......u.../.
|   2176: 01 7a 05 02 35 02 02 c2 aa 0a 04 84 46 03 01 b9   .z..5.......F...
|   2192: 09 02 02 03 01 bd 06 04 82 5d 03 01 be 07 04 81   .........]......
|   2208: 7d 02 02 c6 bd 08 04 83 1e 02 03 ca a1 71 05 04   .............q..
|   2224: 81 19 02 02 d8 b9 01 02 25 02 04 ea a3 99 66 07   ........%.....f.
|   2240: 04 83 37 02 04 f0 9e a1 93 02 04 83 57 01 01 68   ..7.........W..h
|   2256: 01 1a 13 13 81 78 3b 46 08 14 38 44 21 04 13 01   .....x;F..8D!...
|   2272: 24 09 1b 2b 1a 18 17 0b 2f 0e 08 64 06 04 0b 1c   $..+..../..d....
|   2288: 2f 11 78 01 22 02 1a 46 58 18 37 0b 12 0a 18 36   /.x....FX.7....6
|   2304: 3a 23 57 18 16 09 01 14 26 3c 54 47 2b 3d 0d 81   :#W.....&<TG+=..
|   2320: 16 6e 01 16 1b 22 3a 53 15 5d 19 3c 81 1c 13 01   .n....:S.].<....
|   2336: 16 81 20 04 3c 26 74 51 5a 39 19 05 01 28 02 35   .. .<&tQZ9...(.5
|   2352: 26 0d 0c 0b 29 41 25 0e 05 81 0e 5c 14 11 1d 2a   &...)A%........*
|   2368: 22 09 01 16 05 82 02 0b 38 63 15 06 2b 37 13 01   ........8c..+7..
|   2384: 1e 09 6f 10 1b 81 2b 31 0b 31 20 3c 06 43 11 15   ..o...+1.1 <.C..
|   2400: 01 14 39 5f 0b 7e 10 1b 58 55 39 33 02 01 30 07   ..9_.~..XU93..0.
|   2416: 04 81 0a 02 03 35 73 7a 02 04 82 5d 02 02 36 36   .....5sz...]..66
|   2432: 02 04 81 2c 02 01 37 09 02 13 02 01 39 02 04 82   ...,..7.....9...
|   2448: 7c 01 04 83 17 02 01 63 07 02 6c 03 04 84 16 02   |......c..l.....
|   2464: 01 65 04 02 64 01 04 81 00 04 02 50 02 01 66 0a   .e..d......P..f.
|   2480: 04 81 32 02 01 67 09 02 3f 01 04 83 42 02 01 69   ..2..g..?...B..i
|   2496: 03 04 84 0e 02 02 6b 77 02 04 83 47 02 01 6c 03   ......kw...G..l.
|   2512: 02 22 02 04 83 3c 03 03 32 72 65 08 04 84 0e 03   .....<..2re.....
|   2528: 01 33 07 04 84 55 03 02 35 34 08 04 82 78 02 01   .3...U..54...x..
|   2544: 6e 04 04 82 57 02 01 6f 04 04 83 3c 03 03 67 c2   n...W..o...<..g.
|   2560: b3 06 04 82 41 03 01 72 02 02 35 02 01 75 02 08   ....A..r..5..u..
|   2576: 82 52 82 0e 04 04 84 3c 02 03 76 dc 95 09 04 83   .R.....<..v.....
|   2592: 1f 02 01 79 04 04 81 20 02 01 7a 04 02 6f 05 04   ...y... ..z..o..
|   2608: 81 41 02 02 c2 aa 06 04 82 57 04 02 78 6b 08 04   .A.......W..xk..
|   2624: 83 58 03 01 b2 07 04 83 4b 02 04 81 52 03 01 b3   .X......K...R...
|   2640: 01 04 81 3e 01 04 81 3f 03 01 bd 02 02 75 03 02   ...>...?.....u..
|   2656: be 6b 05 04 83 0c 02 04 c3 b8 66 70 01 04 82 2f   .k........fp.../
|   2672: 02 02 ce bc 08 04 81 04 02 03 cf a7 6b 06 04 82   ............k...
|   2688: 4d 02 03 d9 84 72 03 02 13 02 02 da 90 06 04 84   M....r..........
|   2704: 73 02 04 f0 ad 93 a0 06 02 09 01 01 69 01 20 37   s...........i. 7
|   2720: 4d 55 11 49 26 3c 17 0d 4a 26 03 05 0c 20 43 01   MU.I&<..J&... C.
|   2736: 10 59 08 37 5a 56 72 81 05 01 1a 16 33 32 0a 03   .Y.7ZVr.....32..
|   2752: 18 81 17 5f 59 27 37 08 01 24 0a 70 1f 07 40 3b   ..._Y'7..$.p..@;
|   2768: 15 20 09 15 30 0f 17 06 36 81 08 17 01 1c 32 0a   . ..0...6.....2.
|   2784: 05 1a 5f 1c 32 78 03 15 17 81 2b 1e 01 1a 04 03   .._.2x....+.....
|   2800: 2b 07 0c 38 43 6c 0f 81 77 0e 0e 01 1a 1c 3d 81   +..8Cl..w.....=.
|   2816: 0d 0d 17 1d 4c 63 44 2e 11 2b 01 18 2b 2d 49 72   ....LcD..+..+-Ir
|   2832: 1d 22 17 31 19 27 32 4c 01 1c 0b 67 27 20 81 1c   ...1.'2L...g' ..
|   2848: 47 31 29 0d 0b 12 4c 07 01 18 35 81 0b 08 0e 5f   G1)...L...5...._
|   2864: 11 18 37 81 09 09 02 01 30 09 02 19 02 02 31 63   ..7.....0.....1c
|   2880: 09 02 7f 02 01 32 04 02 2c 05 04 83 6e 02 01 35   .....2..,...n..5
|   2896: 09 04 83 7a 03 01 79 05 02 0f 02 02 36 73 05 04   ...z..y.....6s..
|   2912: 83 3d 02 03 38 6a 70 07 04 84 39 02 01 61 07 04   .=..8jp...9..a..
|   2928: 83 44 02 01 62 0a 04 84 37 02 01 64 01 04 85 00   .D..b...7..d....
|   2944: 07 04 82 36 03 02 cf a7 01 04 82 5f 02 01 66 06   ...6......._..f.
|   2960: 04 82 35 03 03 71 70 6e 04 04 82 14 02 02 67 7a   ..5..qpn......gz
|   2976: 02 04 82 00 02 01 68 01 02 14 02 01 69 05 02 48   ......h.....i..H
|   2992: 02 01 6a 01 04 83 7a 07 02 12 01 02 33 02 01 6d   ..j...z.....3..m
|   3008: 04 04 83 76 03 01 68 08 04 82 63 02 01 6f 03 06   ...v..h...c..o..
|   3024: 2c 81 52 06 04 81 4f 02 01 70 06 04 83 00 03 02   ,.R...O..p......
|   3040: c2 be 06 04 83 37 02 01 72 09 04 82 78 03 03 71   .....7..r...x..q
|   3056: 61 6c 0a 02 3e 03 02 c2 be 05 04 84 67 02 01 73   al..>.......g..s
|   3072: 09 04 81 0d 02 01 74 04 02 58 02 01 75 08 04 81   ......t..X..u...
|   3088: 17 02 01 76 04 04 83 4b 06 04 84 70 02 01 7a 02   ...v...K...p..z.
|   3104: 04 83 7e 02 02 c2 aa 03 02 61 03 01 b2 08 04 84   ..~......a......
|   3120: 13 03 04 b9 c2 b2 6a 01 02 19 03 02 bc 63 05 04   ......j......c..
|   3136: 84 12 02 02 c7 86 09 04 84 11 02 02 ce bc 02 02   ................
|   3152: 17 02 03 cf ab 6e 07 02 29 02 06 d5 b1 30 d1 bb   .....n..)....0..
|   3168: 6e 01 02 4e 02 03 eb 8b a7 08 04 81 6b 03 02 b5   n..N........k...
|   3184: bc 07 04 83 08 01 01 6a 01 14 81 07 79 0f 79 32   .......j....y.y2
|   3200: 33 13 81 16 01 16 2c 0a 81 1b 24 2f 05 81 19 19   3.....,...$/....
|   3216: 2d 01 16 81 4c 03 14 4f 81 08 2d 05 2f 21 01 18   -...L..O..-./!..
|   3232: 27 1f 0e 81 16 0c 82 4b 04 12 06 0e 01 1e 26 05   '......K......&.
|   3248: 22 14 55 05 09 81 16 21 05 19 37 74 32 01 1e 37   ..U....!..7t2..7
|   3264: 07 1e 03 10 81 2c 38 07 1a 2a 2b 81 0d 08 01 1e   .....,8..*+.....
|   3280: 2b 19 31 3c 4c 03 1a 14 04 1c 06 76 04 48 62 01   +.1<L......v.Hb.
|   3296: 1a 0d 44 38 13 31 52 52 1e 6d 57 12 03 19 01 12   ..D8.1RR.mW.....
|   3312: 17 81 24 2f 4e 32 2f 23 20 01 20 04 34 18 2a 3b   ..$/N2/# . .4.*;
|   3328: 2d 1b 73 0b 08 05 36 5d 1f 25 24 02 03 32 73 30   -.s...6].%$..2s0
|   3344: 08 04 82 16 02 01 33 02 04 82 54 02 01 34 07 04   ......3...T..4..
|   3360: 81 4b 03 01 6c 04 04 82 74 03 01 6d 03 04 82 26   .K..l...t..m...&
|   3376: 02 02 35 76 06 04 82 44 02 01 36 09 04 83 39 03   ..5v...D..6...9.
|   3392: 03 64 c2 ba 03 04 83 30 02 01 61 06 04 82 34 02   .d.....0..a...4.
|   3408: 02 62 69 03 02 23 02 01 63 03 04 82 6c 02 01 64   .bi..#..c...l..d
|   3424: 07 04 83 43 02 01 65 04 04 81 61 03 01 67 01 04   ...C..e...a..g..
|   3440: 82 03 03 01 74 0a 04 84 44 02 01 66 07 04 81 09   ....t...D..f....
|   3456: 03 02 2b 03 01 7a 03 04 82 79 02 01 67 01 04 82   ..+..z...y..g...
|   3472: 42 03 01 35 08 04 82 38 02 01 68 07 04 81 3b 02   B..5...8..h...;.
|   3488: 03 69 c2 b9 04 04 82 2b 02 01 6a 09 04 83 69 02   .i.....+..j...i.
|   3504: 03 6d 61 63 02 04 81 02 02 02 6e 74 03 04 81 32   .mac......nt...2
|   3520: 02 01 6f 0a 04 83 45 02 01 71 0a 04 82 47 02 01   ..o...E..q...G..
|   3536: 72 03 04 83 1a 03 01 78 04 04 82 44 02 01 73 04   r......x...D..s.
|   3552: 04 83 0e 03 02 70 74 0a 02 2e 03 01 78 04 04 83   .....pt.....x...
|   3568: 33 02 03 74 ce bc 09 04 84 25 02 01 75 01 02 33   3..t.....%..u..3
|   3584: 02 02 24 02 01 77 05 02 03 03 04 83 36 03 01 6b   ..$..w......6..k
|   3600: 0a 04 81 06 03 01 6f 05 02 4c 02 01 78 0a 04 83   ......o..L..x...
|   3616: 7b 03 05 72 6c c2 b9 6c 07 04 83 77 03 03 e2 b5   ...rl..l...w....
|   3632: b9 08 04 81 5d 02 01 79 06 04 84 68 03 04 32 64   ....]..y...h..2d
|   3648: c8 ab 08 02 4b 03 01 37 06 04 83 26 03 02 c2 ba   ....K..7...&....
|   3664: 0a 04 82 12 03 03 eb 81 9f 02 04 82 05 02 03 7a   ...............z
|   3680: d7 ac 02 04 81 7c 02 02 c2 b9 02 04 82 4c 01 04   .....|.......L..
|   3696: 84 13 03 05 bc 70 c2 ba 65 02 04 83 69 03 01 be   .....p..e...i...
|   3712: 02 04 82 15 02 02 ca 8b 02 02 47 01 01 6b 01 18   ..........G..k..
|   3728: 08 81 47 81 18 81 41 0d 0f 0d 14 25 01 14 68 3a   ..G...A....%..h:
|   3744: 4d 59 3e 2d 81 0a 11 16 01 1a 70 24 44 1a 14 62   MY>-......p$D..b
|   3760: 12 3b 50 15 34 03 16 01 0c 32 08 08 0a 0a 0b 07   .;P.4....2......
|   3776: 10 07 07 07 06 07 07 06 07 06 07 07 0a 08 0a 0b   ................
|   3792: 07 06 08 08 07 08 08 08 08 07 08 07 09 09 0a 81   ................
|   3808: 03 07 07 0f 07 07 0b 09 07 07 07 0c 07 07 07 07   ................
|   3824: 06 0f 0b 08 07 07 06 0a 08 07 07 06 0a 0d 07 0b   ................
|   3840: 11 07 07 07 08 08 0a 0a 09 0a 08 81 1e 07 0b 07   ................
|   3856: 07 0b 07 07 08 0b 07 0a 07 07 08 07 0a 08 07 0f   ................
|   3872: 08 0b 07 07 07 0e 07 08 0a 06 08 08 06 07 08 07   ................
|   3888: 09 09 0a 81 15 06 07 07 07 0a 08 0b 06 0e 06 07   ................
|   3904: 07 0b 07 08 07 07 07 09 08 0a 0a 07 0b 09 0b 07   ................
|   3920: 08 06 08 08 08 0b 81 0d 08 08 07 07 07 0b 0b 0b   ................
|   3936: 08 07 07 07 0f 0b 06 07 07 07 08 0c 07 07 08 08   ................
|   3952: 0e 09 0b 07 06 08 06 07 07 08 09 07 0a 0a 81 1f   ................
|   3968: 07 09 08 06 0b 0a 0d 07 0a 07 08 0a 09 07 08 07   ................
|   3984: 07 09 06 0d 09 07 0a 08 08 0b 0b 06 08 0a 08 09   ................
|   4000: 08 08 09 81 1c 06 07 0a 07 06 08 09 07 07 0b 08   ................
|   4016: 07 09 08 06 06 0d 07 07 0c 07 08 07 08 08 07 06   ................
|   4032: 07 0b 07 07 07 09 08 08 07 08 0b 09 08 81 16 09   ................
|   4048: 07 07 07 07 08 07 09 07 07 07 07 07 07 07 0a 07   ................
|   4064: 07 07 07 09 07 09 08 07 07 07 07 07 07 07 09 09   ................
|   4080: 0a 07 06 07 0b 09 07 09 07 08 09 09 0c 0b 07 07   ................
| page 22 offset 86016
|      0: 0d 00 00 00 01 00 24 00 00 24 00 00 00 00 00 00   ......$..$......
|     32: 00 00 00 00 9f 54 88 80 80 80 80 03 04 00 bf 2c   .....T.........,
|     48: 00 0a 0e 8b 61 42 11 82 12 4d 05 12 81 47 48 81   ....aB...M...GH.
|     64: 1c 3a 41 17 25 01 2a 42 21 1d 1f 07 44 65 2c 0f   .:A.%.*B!...De,.
|     80: 18 20 18 08 03 19 04 10 19 0b 17 26 01 1a 14 1f   . .........&....
|     96: 11 1f 2b 10 82 08 26 2b 76 0c 27 01 22 4c 23 06   ..+...&+v.'..L#.
|    112: 81 10 2e 2e 03 37 4b 13 14 14 1b 15 24 0d 01 18   .....7K.....$...
|    128: 3a 0e 4b 15 7b 2a 4a 13 24 81 10 0a 01 18 11 16   :.K..*J.$.......
|    144: 28 1f 57 54 15 16 6b 50 2f 04 04 30 6b 30 34 05   (.WT..kP/..0k04.
|    160: 04 83 1c 02 01 31 04 02 39 02 02 22 01 04 82 48   .....1..9......H
|    176: 02 01 32 09 04 81 25 02 01 34 01 04 81 1a 02 01   ..2...%..4......
|    192: 35 01 02 09 03 01 30 09 04 83 29 02 01 37 05 04   5.....0...)..7..
|    208: 82 70 02 01 38 06 04 83 2f 02 01 39 03 04 83 29   .p..8.../..9...)
|    224: 02 01 61 09 02 67 02 01 62 02 04 82 57 02 01 63   ..a..g..b...W..c
|    240: 01 04 82 24 02 02 64 33 09 04 84 06 02 01 65 09   ...$..d3......e.
|    256: 04 84 46 02 01 66 03 04 84 15 01 04 84 69 04 04   ..F..f.......i..
|    272: 84 36 02 01 67 06 04 84 7e 02 08 83 35 81 2c 02   .6..g...~...5.,.
|    288: 01 68 03 04 82 3a 05 08 81 2e 81 20 02 01 69 02   .h...:..... ..i.
|    304: 04 81 69 02 01 6a 06 02 46 01 08 82 1e 82 5b 02   ..i..j..F.....[.
|    320: 04 84 20 02 01 6b 09 04 81 2e 02 01 6c 08 04 84   .. ..k......l...
|    336: 56 03 01 62 0a 04 83 3f 02 02 6d 6a 01 04 82 15   V..b...?..mj....
|    352: 02 04 6f 69 72 33 01 04 82 25 02 01 72 01 02 44   ..oir3...%..r..D
|    368: 03 01 35 06 04 81 3b 02 02 74 74 04 04 81 79 02   ..5...;..tt...y.
|    384: 01 78 01 04 81 5b 02 02 7a 02 01 79 04 02 19 02   .x...[..z..y....
|    400: 03 7a 71 6b 03 04 83 37 02 02 c2 b3 01 02 31 04   .zqk...7......1.
|    416: 04 82 04 03 07 ba 6e f5 9a 8b 98 76 02 02 5b 02   ......n....v..[.
|    432: 02 cb 8f 06 04 84 28 02 02 ce bc 01 04 81 66 06   ......(.......f.
|    448: 04 81 1b 02 04 83 47 04 06 ce bc ce bf df bc 09   ......G.........
|    464: 04 82 4f 02 02 dd 9c 03 04 81 62 02 04 f2 86 b3   ..O.......b.....
|    480: bb 01 04 82 08 01 01 6c 01 12 81 34 81 00 0d 2a   .......l...4...*
|    496: 81 48 13 01 1a 0e 14 4f 81 17 14 12 10 75 68 36   .H.....O.....uh6
|    512: 0b 1d 01 16 12 22 23 51 1d 7c 25 08 20 4f 7a 01   ......#Q.|%. Oz.
|    528: 12 08 0b 81 7c 71 81 12 0b 0b 01 0e 4e 50 55 82   ....|q......NPU.
|    544: 1e 2e 23 01 1c 0f 10 24 07 33 06 81 0c 73 42 1d   ..#....$.3...sB.
|    560: 81 04 16 01 16 5e 62 6a 06 32 81 03 2f 0f 08 4e   .....^bj.2../..N
|    576: 01 06 81 2c 22 01 12 53 81 1e 6e 40 31 0b 1c 41   ...,...S..n@1..A
|    592: 01 18 79 14 11 17 13 81 0f 81 15 19 35 40 02 01   ..y.........5@..
|    608: 30 01 04 81 0d 03 04 83 6b 02 01 33 07 04 84 66   0.......k..3...f
|    624: 03 04 83 08 02 01 35 08 04 83 43 01 04 83 50 02   ......5...C...P.
|    640: 01 36 09 02 3b 02 01 37 07 04 84 38 02 01 61 0a   .6..;..7...8..a.
|    656: 04 83 17 03 04 e1 8d 93 69 01 04 81 0e 02 01 62   ........i......b
|    672: 03 04 84 16 04 04 83 0e 02 01 63 05 04 81 79 05   ..........c...y.
|    688: 04 84 5d 02 01 64 07 04 81 4a 03 02 6d 6e 08 02   ..]..d...J..mn..
|    704: 09 02 01 65 06 04 84 3e 03 02 76 7a 02 02 76 02   ...e...>..vz..v.
|    720: 01 66 0a 02 47 03 01 79 09 04 81 21 02 02 67 6f   .f..G..y...!..go
|    736: 05 02 38 02 02 68 77 03 04 82 27 02 01 69 02 02   ..8..hw...'..i..
|    752: 6f 04 02 6f 02 01 6b 07 04 82 61 02 01 6c 06 08   o..o..k...a..l..
|    768: 82 2e 81 5a 02 01 6d 01 04 84 25 03 04 83 31 02   ...Z..m...%...1.
|    784: 06 2f 82 2e 03 01 68 08 04 83 73 02 01 6e 09 04   ./....h...s..n..
|    800: 84 5a 02 01 6f 05 04 82 39 02 01 70 04 04 82 19   .Z..o...9..p....
|    816: 05 02 0f 02 01 71 07 04 83 39 03 02 63 71 06 04   .....q...9..cq..
|    832: 81 5e 03 01 67 07 04 83 73 03 01 70 08 04 84 6a   .^..g...s..p...j
|    848: 02 01 73 03 04 83 40 02 01 74 07 04 84 7c 03 06   ..s...@..t...|..
|    864: 35 69 7a 70 c2 bd 01 04 83 1a 02 01 75 01 08 82   5izp........u...
|    880: 2e 81 13 05 04 82 69 03 01 70 03 04 84 50 02 01   ......i..p...P..
|    896: 76 01 04 82 52 09 04 82 64 02 02 77 73 03 04 81   v...R...d..ws...
|    912: 27 02 01 78 08 02 1f 01 04 83 64 02 01 79 04 08   '..x......d..y..
|    928: 81 49 81 44 05 04 84 01 02 03 c2 aa 76 02 04 82   .I.D........v...
|    944: 67 03 01 b9 02 02 4f 06 02 31 03 01 bd 05 04 82   g.....O..1......
|    960: 3d 02 02 ce bc 01 02 2c 01 01 6d 01 12 0c 47 83   =......,..m...G.
|    976: 0a 07 52 16 41 05 01 18 50 05 74 25 21 81 16 16   ..R.A...P.t%!...
|    992: 05 24 16 6c 01 22 81 05 18 06 12 2a 59 09 1f 09   .$.l.......*Y...
|   1008: 3d 27 39 17 3a 1f 04 01 14 72 81 1a 24 81 38 20   ='9.:....r..$.8 
|   1024: 27 19 2b 01 18 81 2b 24 63 0b 11 5d 2d 0c 41 1a   '.+...+$c..]-.A.
|   1040: 30 01 1e 15 04 3c 3a 15 0e 28 18 06 56 81 37 20   0....<:..(..V.7 
|   1056: 0d 6b 01 1e 63 3f 42 73 0a 26 0c 6f 0f 15 13 0b   .k..c?Bs.&.o....
|   1072: 04 25 33 01 16 24 52 16 3a 21 1b 63 26 31 20 34   .%3..$R.:!.c&1 4
|   1088: 01 0e 1a 60 13 19 3d 82 1f 01 1e 5b 07 26 07 20   ...`..=....[.&. 
|   1104: 03 5a 69 6c 27 0b 22 24 20 0f 02 01 31 01 04 82   .Zil'..$ ...1...
|   1120: 6f 02 01 32 03 04 82 41 01 04 81 43 02 01 33 09   o..2...A...C..3.
|   1136: 04 81 23 03 05 7a 68 c2 bd 73 06 04 81 3a 02 01   ..#..zh..s...:..
|   1152: 35 07 04 83 6c 02 01 38 01 04 83 1c 02 02 62 6f   5...l..8......bo
|   1168: 06 04 83 16 02 01 63 07 02 5b 03 06 6e 31 cf af   ......c..[..n1..
|   1184: 61 71 0a 04 83 33 03 02 c2 be 03 04 83 2b 02 01   aq...3.......+..
|   1200: 64 09 04 81 19 01 04 83 09 03 01 62 0a 04 82 56   d..........b...V
|   1216: 03 01 6a 03 04 84 4e 02 01 65 05 04 82 3a 02 04   ..j...N..e...:..
|   1232: 82 53 02 01 66 09 04 82 7a 02 01 67 02 04 82 69   .S..f...z..g...i
|   1248: 08 04 81 35 02 01 68 09 04 83 2f 02 01 69 01 04   ...5..h.../..i..
|   1264: 81 62 02 01 6a 0a 04 81 59 02 01 6b 09 04 81 5f   .b..j...Y..k..._
|   1280: 02 01 6c 08 04 84 0d 02 01 6d 05 04 84 32 02 01   ..l......m...2..
|   1296: 6e 01 04 83 05 02 01 6f 07 04 82 6f 02 01 70 04   n......o...o..p.
|   1312: 04 83 60 03 04 82 0d 03 03 c2 b9 70 02 04 81 43   ..`........p...C
|   1328: 02 01 71 07 04 81 13 03 04 82 35 02 01 72 03 04   ..q.......5..r..
|   1344: 84 51 02 02 73 65 04 04 84 14 02 01 74 01 04 83   .Q..se......t...
|   1360: 5f 02 01 75 03 02 0b 03 02 c2 be 08 04 82 3a 02   _..u..........:.
|   1376: 01 76 06 04 84 43 02 01 77 01 04 82 18 01 04 81   .v...C..w.......
|   1392: 32 02 01 78 08 04 81 47 02 01 7a 01 04 82 44 02   2..x...G..z...D.
|   1408: 02 c2 b3 05 04 83 12 03 04 83 14 04 01 37 04 04   .............7..
|   1424: 83 6c 03 03 ba dd af 05 04 82 41 02 02 c3 9f 07   .l........A.....
|   1440: 04 82 34 02 03 c6 80 78 0a 04 83 14 02 02 ca 95   ..4....x........
|   1456: 07 04 83 0c 02 03 ce b0 67 03 02 6e 03 01 bc 05   ........g..n....
|   1472: 02 17 04 02 6c 02 03 e7 a4 94 05 04 82 51 01 01   ....l........Q..
|   1488: 6e 01 18 56 26 2f 54 29 5a 25 11 28 24 81 0f 01   n..V&/T)Z%.($...
|   1504: 1c 06 39 06 13 59 09 07 81 39 16 0c 39 27 4a 01   ..9..Y...9..9'J.
|   1520: 14 2a 03 53 23 81 0d 7d 5b 06 03 01 18 1e 03 81   .*.S#...[.......
|   1536: 02 34 37 29 15 34 81 30 36 01 1a 81 25 19 07 21   .47).4.06...%..!
|   1552: 07 33 12 82 02 45 04 05 01 12 82 0f 42 55 1d 08   .3...E......BU..
|   1568: 1a 44 3d 01 16 18 17 36 54 6e 1b 49 1f 30 09 1c   .D=....6Tn.I.0..
|   1584: 01 16 68 81 00 08 48 3a 13 50 3c 28 27 01 1c 28   ..h...H:.P<('..(
|   1600: 03 06 12 5b 06 30 38 04 65 54 1a 0b 4d 01 20 03   ...[.08.eT..M. .
|   1616: 09 3d 27 04 11 59 11 1a 0b 73 53 81 03 04 26 02   .='..Y...sS...&.
|   1632: 01 32 02 04 83 3e 02 01 36 01 02 73 09 04 81 14   .2...>..6..s....
|   1648: 02 01 37 0a 04 83 30 02 01 62 08 04 84 4d 02 02   ..7...0..b...M..
|   1664: 63 7a 0a 04 84 08 02 01 64 07 04 83 61 03 02 7a   cz......d...a..z
|   1680: 67 09 02 58 02 02 65 69 09 02 4e 02 05 67 eb 9b   g..X..ei..N..g..
|   1696: a1 72 09 04 81 06 02 01 68 01 04 82 13 02 01 69   .r......h......i
|   1712: 08 04 84 39 01 04 82 45 02 01 6a 0a 04 83 72 02   ...9...E..j...r.
|   1728: 02 6b 70 07 04 81 25 02 01 6c 0a 02 5a 02 01 6d   .kp...%..l..Z..m
|   1744: 03 08 82 58 81 11 01 04 84 2c 02 01 6e 07 02 74   ...X.....,..n..t
|   1760: 02 01 6f 05 04 82 7d 02 01 71 0a 02 7c 02 02 72   ..o......q..|..r
|   1776: 75 05 04 83 09 02 01 74 03 04 83 1d 02 01 75 07   u......t......u.
|   1792: 04 84 21 02 01 76 07 04 84 49 02 01 77 03 02 09   ..!..v...I..w...
|   1808: 02 04 81 01 02 01 78 06 04 81 0f 02 01 7a 04 04   ......x......z..
|   1824: 81 3e 02 04 c2 aa 64 6f 05 04 83 11 03 02 bc 64   .>....do.......d
|   1840: 09 04 81 7b 02 05 c6 80 39 63 64 01 04 83 62 03   ........9cd...b.
|   1856: 01 92 09 04 82 42 02 02 ce bc 09 02 4d 02 02 cf   .....B......M...
|   1872: 97 06 04 83 42 02 02 d1 8b 02 02 2d 02 05 dd b1   ....B......-....
|   1888: ca b2 70 01 02 1b 02 03 e6 b5 96 09 04 81 50 02   ..p...........P.
|   1904: 04 e8 b8 aa 6e 08 04 82 1a 02 05 f0 90 b2 b2 6c   ....n..........l
|   1920: 01 02 59 02 04 f1 8f 99 80 0a 04 83 25 01 01 6f   ..Y.........%..o
|   1936: 01 26 05 6b 0f 30 12 1f 16 5d 19 08 20 08 33 33   .&.k.0...].. .33
|   1952: 1e 12 31 31 06 01 16 04 63 33 67 24 2b 81 0a 5d   ..11....c3g$+..]
|   1968: 2c 0b 01 14 18 0f 36 82 49 0c 1c 08 27 4b 01 1a   ,.....6.I...'K..
|   1984: 4b 24 3a 13 64 07 14 0b 43 08 68 2e 3c 01 26 1a   K$:.d...C.h.<.&.
|   2000: 0b 06 58 10 3d 1b 0a 2f 3e 27 36 1b 1b 21 05 25   ..X.=../>'6..!.%
|   2016: 0d 41 01 12 81 16 4b 2e 7c 7d 32 1f 1e 01 1a 2e   .A....K.|.2.....
|   2032: 20 62 72 11 22 05 20 0a 2c 24 60 5e 01 2a 0e 5e    br... .,$`^.*.^
|   2048: 13 22 2d 1c 0c 1f 0c 10 0c 47 05 4e 03 15 06 33   ..-......G.N...3
|   2064: 1d 06 29 01 10 81 08 81 0b 81 48 53 11 01 20 14   ..).......HS.. .
|   2080: 25 81 17 10 08 08 47 2a 56 2b 2f 20 05 26 22 02   %.....G*V+/ .&..
|   2096: 01 30 0a 02 5e 03 02 39 76 08 04 82 5c 02 01 31   .0..^..9v......1
|   2112: 04 02 54 02 01 33 01 04 81 2d 02 02 36 37 09 02   ..T..3...-..67..
|   2128: 45 03 01 61 04 04 84 16 02 01 37 0a 04 84 5e 02   E..a......7...^.
|   2144: 03 39 c2 b3 01 04 83 2c 02 01 61 08 04 82 4b 02   .9.....,..a...K.
|   2160: 01 62 08 04 83 08 03 02 65 30 07 04 84 0d 02 01   .b......e0......
|   2176: 64 02 04 82 5e 02 04 81 07 02 05 65 70 6b 7a 35   d...^......epkz5
|   2192: 02 02 4e 03 03 db 8a 69 01 04 83 0b 02 01 66 05   ..N....i......f.
|   2208: 04 84 34 03 01 68 04 04 84 51 02 01 67 05 02 53   ..4..h...Q..g..S
|   2224: 02 04 82 78 02 01 68 09 04 83 6f 02 01 69 03 04   ...x..h...o..i..
|   2240: 81 42 02 01 6a 01 04 84 55 03 04 84 10 02 04 81   .B..j...U.......
|   2256: 56 03 02 72 74 06 04 83 20 02 02 6c 7a 01 04 83   V..rt... ..lz...
|   2272: 38 02 01 6e 01 02 15 02 01 6f 01 04 81 7c 01 02   8..n.....o...|..
|   2288: 27 02 01 73 01 02 36 04 02 2e 03 03 65 ce bc 08   '..s..6.....e...
|   2304: 04 82 43 02 01 74 09 04 82 7f 02 01 75 07 04 82   ..C..t......u...
|   2320: 13 03 01 66 07 04 83 21 03 02 6a 69 07 04 83 7e   ...f...!..ji...~
|   2336: 03 01 6b 01 04 84 26 02 01 76 0a 04 82 7f 03 05   ..k...&..v......
|   2352: 67 da b2 65 75 0a 04 84 13 03 06 c2 be c9 87 6b   g..eu..........k
|   2368: 61 07 04 81 5b 02 02 77 64 01 02 3c 02 01 7a 06   a...[..wd..<..z.
|   2384: 04 81 21 01 04 81 29 02 04 84 4b 03 02 79 30 09   ..!...)...K..y0.
|   2400: 04 83 7d 03 02 ce bc 02 04 81 6a 02 02 c2 aa 05   ..........j.....
|   2416: 02 50 03 01 b2 02 04 81 12 05 02 3e 04 01 63 07   .P.........>..c.
|   2432: 04 84 04 03 03 b3 62 61 01 04 84 3e 03 02 ba 6f   ......ba...>...o
|   2448: 02 04 84 51 02 02 c4 91 04 04 84 36 02 05 ce b9   ...Q.......6....
|   2464: 65 c9 97 07 04 83 76 02 04 ef 82 ac 6d 09 02 5d   e.....v.....m..]
|   2480: 02 05 f0 92 bd b3 6f 03 04 81 25 03 04 99 ba 8f   ......o...%.....
|   2496: 64 02 04 81 1f 02 05 f3 8a bd b1 6d 09 04 81 28   d..........m...(
|   2512: 01 01 70 01 18 46 7c 1f 14 0a 1b 2e 1c 2d 14 6b   ..p..F|......-.k
|   2528: 07 01 18 19 81 05 2e 28 40 11 2b 22 0b 07 18 01   .......(@.+.....
|   2544: 14 40 13 81 36 12 2d 7f 1f 1b 1a 01 12 82 76 1e   .@..6.-.......v.
|   2560: 1d 12 81 03 07 12 01 10 5a 81 38 19 36 52 26 18   ........Z.8.6R&.
|   2576: 01 12 64 5d 40 25 05 57 33 31 11 01 1e 36 36 25   ..d]@%.W31...66%
|   2592: 1b 28 07 22 42 13 0f 07 1c 5a 73 51 01 24 07 2d   .(..B....ZsQ.$.-
|   2608: 06 03 81 00 22 03 1d 19 18 26 2c 16 23 4f 76 08   .........&,.#Ov.
|   2624: 01 1c 11 1b 54 78 23 1a 81 13 75 04 0c 14 12 0c   ....Tx#...u.....
|   2640: 01 12 24 0d 81 4d 11 7f 22 35 2e 02 01 30 02 04   ..$..M...5...0..
|   2656: 83 5e 02 01 31 0a 04 81 47 03 05 e7 b2 a5 c3 9f   .^..1...G.......
|   2672: 04 04 83 16 02 01 35 08 02 35 02 02 36 79 09 04   ......5..5..6y..
|   2688: 82 24 02 01 37 01 04 81 30 03 02 6d 65 04 04 82   .$..7...0..me...
|   2704: 0e 02 02 38 63 06 02 41 03 02 c9 aa 06 04 84 5b   ...8c..A.......[
|   2720: 02 01 61 03 04 83 0b 03 04 84 4c 03 04 83 5f 03   ..a.......L..._.
|   2736: 01 6c 07 04 83 7f 02 01 63 04 04 84 7b 02 01 64   .l......c......d
|   2752: 04 04 83 5d 02 01 65 06 04 83 4c 03 01 74 08 04   ...]..e...L..t..
|   2768: 82 0b 02 01 68 03 02 06 03 04 71 e7 8e bb 08 04   ....h.....q.....
|   2784: 81 43 03 01 74 07 04 82 30 02 03 69 ce bc 07 04   .C..t...0..i....
|   2800: 81 3c 02 03 6a 62 6c 09 02 4b 02 01 6c 09 04 81   .<..jbl..K..l...
|   2816: 60 02 01 6d 05 04 82 6f 04 04 81 62 03 04 6c 74   `..m...o...b..lt
|   2832: c2 b9 07 04 85 08 03 02 c2 be 08 04 83 2b 02 02   .............+..
|   2848: 6e 73 08 04 81 1f 03 01 75 04 04 83 72 02 01 6f   ns......u...r..o
|   2864: 06 08 81 14 83 2f 03 02 ce bc 0a 04 83 67 03 03   ...../.......g..
|   2880: cf 80 66 07 02 28 02 01 70 01 04 82 2a 03 01 7a   ..f..(..p...*..z
|   2896: 08 04 81 0d 02 01 71 07 04 81 37 02 01 73 05 02   ......q...7..s..
|   2912: 59 03 01 6d 07 02 7a 02 01 74 05 04 82 62 02 02   Y..m..z..t...b..
|   2928: 75 6a 03 04 81 37 02 02 77 68 08 04 84 14 02 01   uj...7..wh......
|   2944: 78 01 04 83 6f 02 01 79 01 04 82 66 06 04 81 36   x...o..y...f...6
|   2960: 02 01 7a 0a 04 81 15 03 05 6f f0 99 8a a6 08 04   ..z......o......
|   2976: 82 06 02 02 c2 b2 04 04 83 38 03 03 b3 dd 9d 05   .........8......
|   2992: 04 83 6f 03 01 b9 06 04 83 66 03 01 ba 01 04 81   ..o......f......
|   3008: 0c 07 04 83 10 04 01 69 06 04 81 39 03 01 bd 04   .......i...9....
|   3024: 04 82 00 06 02 16 02 02 da 99 02 04 84 49 02 07   .............I..
|   3040: dd 9b 6e e6 89 a0 75 01 04 81 6e 02 09 f0 92 ab   ..n...u...n.....
|   3056: ab ec 8c 8d ca 81 01 04 81 46 01 01 71 01 1a 1a   .........F..q...
|   3072: 08 41 65 0b 22 18 69 2f 81 0e 13 05 01 18 08 2d   .Ae...i/.......-
|   3088: 07 04 81 70 23 18 20 1a 0c 74 01 16 1f 11 05 6b   ...p#. ..t.....k
|   3104: 2f 18 47 13 16 30 4c 01 22 12 05 2d 39 05 07 61   /.G..0L....-9..a
|   3120: 0b 06 0a 56 3f 56 2e 10 0d 50 01 16 1f 1f 3c 2b   ...V?V...P....<+
|   3136: 32 0c 43 4b 81 18 5a 01 18 16 0d 0e 32 40 42 1c   2.CK..Z.....2@B.
|   3152: 4a 24 12 17 13 01 20 03 6e 0e 1c 0f 04 0b 3b 05   J$.... .n.....;.
|   3168: 52 4e 0e 23 26 50 20 01 12 59 09 72 4f 47 44 15   RN.#&P ..Y.rOGD.
|   3184: 41 28 01 16 5e 36 24 0e 19 81 15 07 81 26 16 01   A(..^6$......&..
|   3200: 18 81 0e 0f 5e 81 01 04 04 1a 1a 44 50 02 02 31   ....^......DP..1
|   3216: 68 09 04 83 76 02 01 32 07 04 81 70 02 02 33 7a   h...v..2...p..3z
|   3232: 05 04 84 4a 02 01 34 08 04 81 02 03 01 69 08 04   ...J..4......i..
|   3248: 81 0b 03 01 76 02 04 81 62 02 01 37 04 04 81 78   ....v...b..7...x
|   3264: 05 04 82 51 01 02 15 02 03 38 75 77 06 04 82 1b   ...Q.....8uw....
|   3280: 02 01 39 04 02 20 03 04 84 03 03 01 74 03 04 81   ..9.. ......t...
|   3296: 60 02 01 61 04 02 24 01 04 83 63 02 01 62 09 02   `..a..$...c..b..
|   3312: 15 02 01 63 05 06 51 84 0e 03 03 c2 be 62 04 04   ...c..Q......b..
|   3328: 82 3d 02 02 64 70 03 04 83 36 02 01 66 06 04 82   .=..dp...6..f...
|   3344: 66 02 02 6a 38 02 04 84 0a 02 02 6d 61 05 04 81   f..j8......ma...
|   3360: 30 03 01 6e 08 04 83 71 02 01 6e 01 02 60 02 01   0..n...q..n..`..
|   3376: 70 02 04 82 43 02 01 71 05 06 82 48 49 02 01 73   p...C..q...HI..s
|   3392: 06 04 81 1f 02 01 74 09 04 81 70 02 01 75 05 04   ......t...p..u..
|   3408: 83 44 02 01 76 05 04 84 08 04 04 82 1d 02 01 77   .D..v..........w
|   3424: 09 02 69 02 02 78 69 08 04 82 79 02 01 7a 05 04   ..i..xi...y..z..
|   3440: 84 22 03 09 66 cf 9f 71 67 36 e2 b1 a5 02 04 81   ....f..qg6......
|   3456: 21 02 03 c2 aa 6a 01 04 81 12 03 01 b3 03 02 35   !....j.........5
|   3472: 02 04 84 1f 04 04 84 19 03 04 b9 d4 87 68 02 04   .............h..
|   3488: 81 42 03 01 ba 06 04 84 44 04 02 64 67 03 04 84   .B......D..dg...
|   3504: 4b 03 01 bc 04 04 81 42 03 01 be 01 02 48 02 02   K......B.....H..
|   3520: ce bc 0a 04 81 2e 02 02 cf a7 02 04 83 6e 02 04   .............n..
|   3536: e7 a4 ba 67 07 04 83 59 01 01 72 01 20 41 1d 3a   ...g...Y..r. A.:
|   3552: 0b 05 04 12 1f 3c 03 2f 81 05 81 2e 13 01 14 0c   .....<./........
|   3568: 81 3f 17 81 07 63 08 81 07 01 12 81 06 71 17 0b   .?...c.......q..
|   3584: 46 81 5a 13 01 18 02 81 06 0f 49 42 2d 39 2e 2c   F.Z.......IB-9.,
|   3600: 45 27 01 16 06 19 27 1d 3f 53 81 3a 45 0d 20 01   E'....'.?S.:E. .
|   3616: 14 1b 07 2a 76 37 36 09 82 4d 04 01 14 0c 30 2d   ...*v76..M....0-
|   3632: 2d 51 38 31 49 49 74 01 16 29 17 0a 2f 72 1d 4a   -Q81IIt..)../r.J
|   3648: 81 27 11 18 01 14 63 81 1c 5f 04 4d 38 19 18 0e   .'....c.._.M8...
|   3664: 01 1c 56 2f 25 5f 07 05 03 28 24 5d 2b 4d 42 13   ..V/%_...($]+MB.
|   3680: 02 02 30 71 01 04 84 03 02 01 33 08 04 83 16 01   ..0q......3.....
|   3696: 04 83 3d 02 01 35 03 02 58 02 01 37 04 04 83 0c   ..=..5..X..7....
|   3712: 03 01 64 04 04 84 46 02 02 38 61 0a 04 83 66 03   ..d...F..8a...f.
|   3728: 02 73 69 09 04 82 5f 02 01 39 09 04 84 17 02 02   .si..._..9......
|   3744: 61 6a 03 04 83 12 02 01 62 07 04 82 72 03 01 65   aj......b...r..e
|   3760: 09 04 83 14 04 01 68 07 04 82 24 6a 09 0d 07 07   ......h...$j....
|   3776: 06 07 07 07 07 06 07 07 08 07 0f 0d 0d 07 10 07   ................
|   3792: 07 07 08 0a 06 07 08 0a 06 09 0b 0c 08 10 0c 08   ................
|   3808: 0a 79 0b 0b 0b 06 07 07 0a 0b 0b 07 07 07 07 06   .y..............
|   3824: 07 07 08 09 07 09 10 07 07 07 0a 07 08 07 07 07   ................
|   3840: 07 0c 0d 07 0b 08 0a 0d 09 09 07 07 81 12 07 0b   ................
|   3856: 07 0b 07 07 08 06 0c 08 0b 07 07 0b 07 0b 07 07   ................
|   3872: 07 07 07 07 07 07 0b 09 0b 07 08 07 06 08 07 0b   ................
|   3888: 07 07 0c 07 09 08 09 08 08 09 09 81 11 07 0a 07   ................
|   3904: 07 08 07 07 07 0b 07 0b 07 08 06 0d 06 07 06 08   ................
|   3920: 07 07 07 0a 07 07 0a 08 0b 07 07 08 07 0a 09 0a   ................
|   3936: 0a 0a 81 22 06 08 06 07 07 07 07 09 07 07 08 0b   ................
|   3952: 0a 09 07 07 0a 07 07 0f 08 08 06 0a 09 09 07 07   ................
|   3968: 07 08 07 07 0b 0c 07 0f 08 08 07 0a 07 09 08 08   ................
|   3984: 0b 09 0b 0a 0b 81 0b 07 07 0b 06 08 07 08 07 08   ................
|   4000: 0f 07 07 07 07 07 06 0a 07 09 08 07 0b 0a 08 08   ................
|   4016: 07 09 08 08 07 07 07 06 06 07 08 08 07 0b 07 0b   ................
|   4032: 08 09 07 0b 07 0a 08 0d 0f 81 13 08 07 08 07 07   ................
|   4048: 07 0e 09 0a 07 0a 06 08 09 08 07 08 08 07 06 07   ................
|   4064: 08 07 07 07 0b 06 08 07 0f 09 0e 0a 07 08 07 06   ................
|   4080: 08 08 0a 81 08 08 0b 06 07 07 08 08 07 08 07 07   ................
| page 23 offset 90112
|      0: 0d 00 00 00 01 00 22 00 00 22 00 00 00 00 00 00   ................
|     32: 00 00 9f 56 88 80 80 80 80 04 04 00 bf 30 00 00   ...V.........0..
|     48: 0e 8c 03 30 72 64 04 04 81 24 02 01 66 06 04 81   ...0rd...$..f...
|     64: 05 02 04 81 0f 03 01 70 0a 04 82 45 02 01 67 01   .......p...E..g.
|     80: 04 84 1a 02 04 81 03 07 04 82 13 02 01 68 05 04   .............h..
|     96: 83 1d 02 01 6a 02 04 83 03 02 06 82 26 39 03 01   ....j.......&9..
|    112: 67 01 04 81 0a 02 02 6c 70 09 02 48 03 03 c9 be   g......lp..H....
|    128: 6e 05 04 83 58 02 01 6e 07 04 83 10 03 02 30 6d   n...X..n......0m
|    144: 07 04 84 20 02 03 6f d2 b1 09 04 84 43 02 01 70   ... ..o.....C..p
|    160: 07 02 24 01 02 7d 02 01 71 07 04 83 2f 03 04 81   ..$.....q.../...
|    176: 18 03 01 62 08 04 82 39 02 02 72 75 0a 04 81 24   ...b...9..ru...$
|    192: 02 01 75 02 04 81 4e 05 04 83 3d 02 01 76 03 02   ..u...N...=..v..
|    208: 64 03 02 6b 6c 08 04 82 2f 02 01 78 05 04 84 66   d..kl.../..x...f
|    224: 02 02 79 36 02 02 39 02 02 c2 b2 04 04 84 7c 04   ..y6..9.......|.
|    240: 02 dd ab 09 04 83 71 03 02 b3 31 09 04 82 33 03   ......q...1...3.
|    256: 01 bc 04 02 6e 03 01 bd 07 04 85 09 04 01 75 07   ....n.........u.
|    272: 02 0e 02 02 ce bc 07 02 6b 02 02 d1 9e 0a 04 84   ........k.......
|    288: 51 02 03 d5 b1 36 09 02 1e 02 04 e4 8d ac 38 01   Q....6........8.
|    304: 02 61 02 04 f0 96 85 81 09 04 83 5e 03 03 9a 87   .a.........^....
|    320: 8d 05 04 83 51 01 01 73 01 30 0f 1c 12 09 29 0d   ....Q..s.0....).
|    336: 07 2e 81 01 11 2a 22 1d 04 2e 0f 08 04 23 29 0b   .....*.......#).
|    352: 3b 15 01 16 2f 2f 81 20 81 07 13 56 26 3b 25 01   ;...//. ...V&;%.
|    368: 28 49 03 0a 61 04 08 2e 03 22 10 38 34 0c 09 29   (I..a......84..)
|    384: 0c 0c 34 28 0b 01 1e 0f 3c 5b 13 0a 34 11 5a 73   ..4(....<[..4.Zs
|    400: 1e 22 03 1a 54 03 01 22 08 06 3c 41 06 2c 2b 16   ....T.....<A.,+.
|    416: 10 58 52 08 0e 17 41 33 26 01 20 28 39 0b 0b 1e   .XR...A3&. (9...
|    432: 18 55 16 1e 73 29 0a 26 36 06 06 01 20 0f 04 30   .U..s).&6... ..0
|    448: 0e 5e 2f 21 23 78 1a 0c 25 81 1c 06 12 01 20 81   .^/!#x..%..... .
|    464: 06 32 08 19 30 23 30 04 6f 29 10 3d 0b 36 07 01   .2..0#0.o).=.6..
|    480: 10 0a 54 61 23 09 1e 22 11 01 16 06 14 0a 55 4a   ..Ta#.........UJ
|    496: 1e 63 2f 6c 7e 10 02 01 32 03 02 27 03 02 76 6c   .c/l~...2..'..vl
|    512: 0a 02 44 02 01 33 03 04 82 2d 07 08 81 07 82 6b   ..D..3...-.....k
|    528: 02 01 39 08 02 0a 02 01 61 04 02 33 02 01 62 08   ..9.....a..3..b.
|    544: 04 84 5b 02 01 63 04 04 84 22 06 02 5c 03 01 74   ..[..c.........t
|    560: 07 04 84 41 02 02 64 66 09 04 81 38 02 01 66 05   ...A..df...8..f.
|    576: 04 83 5a 03 04 83 22 02 02 0f 02 02 68 6d 06 04   ..Z.........hm..
|    592: 84 31 02 01 69 09 04 83 22 03 01 6e 04 04 81 00   .1..i......n....
|    608: 02 01 6a 05 04 83 17 01 04 84 5e 03 01 66 04 02   ..j.......^..f..
|    624: 1d 02 01 6b 08 04 82 6d 02 01 6d 09 02 2f 01 02   ...k...m..m../..
|    640: 02 02 01 6e 09 04 82 5d 02 01 6f 01 04 81 00 01   ...n...]..o.....
|    656: 04 84 46 02 01 70 04 04 82 6c 02 01 71 06 04 82   ..F..p...l..q...
|    672: 70 02 01 79 0a 04 82 79 02 02 c2 aa 07 04 82 08   p..y...y........
|    688: 03 04 83 37 03 01 b2 0a 04 81 43 03 01 b3 09 04   ...7......C.....
|    704: 84 58 03 01 ba 07 04 84 2b 03 01 bc 05 04 83 55   .X......+......U
|    720: 04 02 c2 b2 01 04 82 3b 02 03 c9 be 63 04 04 83   .......;....c...
|    736: 2a 02 02 ce bc 04 04 84 2e 02 02 d3 ad 0a 02 62   *..............b
|    752: 02 04 f2 b0 9a a2 08 04 83 11 01 01 74 01 1c 2e   ............t...
|    768: 03 12 0d 4e 81 40 06 81 00 4a 32 17 0e 01 1e 0b   ...N.@...J2.....
|    784: 15 5e 0f 71 12 46 1d 05 1c 05 35 39 36 17 01 1a   .^.q.F....596...
|    800: 05 81 19 09 6f 0f 06 1a 28 0c 4a 4c 5c 01 1a 16   ....o...(.JL....
|    816: 16 15 81 46 69 35 21 2b 05 14 81 08 01 16 0d 1d   ...Fi5!+........
|    832: 30 47 04 5d 40 10 51 81 05 01 16 31 7a 71 7d 21   0G.]@.Q....1zq.!
|    848: 29 1d 21 0b 3d 04 01 1a 39 1b 74 3f 48 23 23 0b   ).!.=...9.t?H##.
|    864: 05 34 21 19 50 01 0e 81 31 33 5b 43 76 6c 01 1a   .4!.P...13[Cvl..
|    880: 7b 4c 11 15 12 0e 06 12 1b 1a 81 1a 4f 01 1e 17   .L..........O...
|    896: 08 1d 1c 7e 27 0e 81 19 2a 04 0d 49 22 31 02 01   ...~'...*..I.1..
|    912: 31 08 04 83 34 02 01 35 03 04 83 10 02 01 39 0a   1...4..5......9.
|    928: 02 72 03 05 7a ec ab b1 66 06 04 82 62 02 02 61   .r..z...f...b..a
|    944: 70 05 04 83 28 02 01 62 09 02 6d 02 01 63 0a 04   p...(..b..m..c..
|    960: 81 64 03 04 76 32 35 6e 09 02 23 02 01 64 02 04   .d..v25n..#..d..
|    976: 84 4e 03 01 66 08 04 81 38 02 01 65 03 04 81 50   .N..f...8..e...P
|    992: 01 04 81 41 02 04 81 17 02 01 66 02 02 5d 02 04   ...A......f..]..
|   1008: 84 75 06 04 83 64 03 01 34 03 02 4b 02 01 67 06   .u...d..4..K..g.
|   1024: 04 83 56 02 04 83 3a 02 01 68 04 04 81 26 05 04   ..V...:..h...&..
|   1040: 83 3f 02 01 69 01 04 81 65 09 02 0c 02 06 6a 62   .?..i...e.....jb
|   1056: c2 aa 6e 6a 08 04 82 27 03 02 c2 bd 02 02 21 02   ..nj...'......!.
|   1072: 01 6b 07 02 17 03 01 39 02 02 30 02 03 6d 6b 79   .k.....9..0..mky
|   1088: 05 04 84 4e 02 01 6e 04 02 2e 02 03 72 c2 bd 07   ...N..n.....r...
|   1104: 02 32 02 01 74 08 04 83 5b 01 04 82 71 02 01 75   .2..t...[...q..u
|   1120: 01 02 4f 08 02 79 03 01 78 07 04 82 29 02 02 76   ..O..y..x...)..v
|   1136: 61 0a 04 83 1a 02 01 77 01 04 83 54 02 04 83 7e   a......w...T...~
|   1152: 07 04 83 32 02 01 78 05 04 83 25 03 04 83 2f 02   ...2..x...%.../.
|   1168: 01 7a 08 04 83 07 02 02 c2 b9 02 04 83 0b 04 04   .z..............
|   1184: 83 7e 04 02 6e 31 0a 04 82 1c 04 01 75 03 02 42   .~..n1......u..B
|   1200: 03 01 bc 0a 04 81 39 03 01 bd 07 04 83 20 02 03   ......9...... ..
|   1216: c6 83 67 04 04 84 19 02 02 c7 a3 06 04 82 7f 02   ..g.............
|   1232: 03 d3 86 34 07 04 81 6c 02 02 d6 84 08 02 40 02   ...4...l......@.
|   1248: 03 da 8f 39 01 04 84 51 02 04 ec a2 9b 6b 03 04   ...9...Q.....k..
|   1264: 81 2d 01 01 75 01 22 28 0f 43 09 31 1b 09 10 3f   .-..u..(.C.1...?
|   1280: 23 08 75 5d 08 48 07 11 01 1c 54 1a 11 1c 2d 0c   #.u].H....T...-.
|   1296: 30 0b 28 08 12 20 81 34 01 1a 3b 1c 10 40 81 5c   0.(.. .4..;..@..
|   1312: 04 1a 05 16 81 0d 18 01 18 3e 03 5e 62 74 47 37   .........>.^btG7
|   1328: 20 3d 07 20 0e 01 1e 10 69 42 48 08 04 08 56 08    =. ....iBH...V.
|   1344: 66 21 10 07 1a 34 01 18 1f 28 31 41 81 06 36 19   f!...4...(1A..6.
|   1360: 53 0d 0f 0c 01 1c 16 0a 0e 04 52 17 22 48 7b 43   S.........R..H.C
|   1376: 3e 04 47 44 01 1e 25 4b 0b 30 2c 0a 0c 6b 71 15   >.GD..%K.0,..kq.
|   1392: 03 4c 19 0f 16 01 22 2b 13 28 1d 24 4c 0f 46 0f   .L.....+.(.$L.F.
|   1408: 2f 0b 1c 03 0e 4a 4a 33 01 10 19 29 81 24 0a 82   /....JJ3...).$..
|   1424: 0c 46 02 01 30 05 04 82 5d 02 01 32 07 04 83 1f   .F..0...]..2....
|   1440: 02 02 33 6c 06 04 84 6f 02 01 35 08 02 33 02 06   ..3l...o..5..3..
|   1456: 37 6e 66 ef 98 bd 06 04 81 35 02 02 61 76 03 06   7nf......5..av..
|   1472: 82 12 73 02 01 63 02 02 57 02 04 83 09 03 01 69   ..s..c..W......i
|   1488: 05 02 66 02 01 64 06 04 81 01 02 01 65 06 02 3b   ..f..d......e..;
|   1504: 03 01 71 01 04 83 6c 02 01 66 01 04 84 7c 01 04   ..q...l..f...|..
|   1520: 83 5c 03 03 69 c2 b2 08 04 84 74 03 03 73 c2 bd   ....i.....t..s..
|   1536: 03 04 84 0a 02 01 67 06 08 82 1d 82 56 04 04 81   ......g.....V...
|   1552: 33 02 01 68 09 02 51 02 01 69 0a 02 08 02 01 6a   3..h..Q..i.....j
|   1568: 06 02 6c 03 01 6e 0a 04 81 2c 02 01 6c 08 04 83   ..l..n...,..l...
|   1584: 15 02 01 6d 04 04 84 24 03 01 33 01 04 81 3a 03   ...m...$..3...:.
|   1600: 03 6e c2 b9 07 04 81 6b 02 01 6f 06 04 83 28 02   .n.....k..o...(.
|   1616: 03 70 77 71 0a 04 81 2a 02 01 71 0a 04 84 34 02   .pwq...*..q...4.
|   1632: 01 73 05 04 81 7f 03 02 6a 73 01 04 83 08 02 01   .s......js......
|   1648: 74 02 04 81 60 01 04 83 5e 06 04 82 37 02 01 76   t...`...^...7..v
|   1664: 08 04 81 2d 02 01 77 01 04 82 12 01 02 46 02 03   ...-..w......F..
|   1680: 78 73 66 04 02 37 03 02 7a 62 02 04 83 1a 02 01   xsf..7..zb......
|   1696: 79 04 02 1a 03 04 84 2a 02 04 84 22 02 01 7a 05   y......*......z.
|   1712: 04 83 4d 02 02 c2 b2 09 04 83 04 03 01 b9 04 04   ..M.............
|   1728: 82 3e 03 02 bd 6c 07 04 84 06 03 02 be 73 0a 04   .>...l.......s..
|   1744: 83 5b 02 06 c9 82 71 c6 9a 61 05 02 7a 03 04 89   .[....q..a..z...
|   1760: e3 a1 be 04 04 83 05 02 04 ca aa 33 67 04 04 84   ...........3g...
|   1776: 61 02 03 d6 83 6b 08 04 81 77 02 02 da b0 0a 02   a....k...w......
|   1792: 32 03 01 b6 0a 02 13 02 03 e3 9a bb 04 04 84 42   2..............B
|   1808: 02 04 f0 b6 8e b7 06 04 83 5a 01 01 76 01 1a 7f   .........Z..v...
|   1824: 38 16 7c 3b 26 23 08 05 47 1c 19 20 01 1c 28 45   8.|;&#..G.. ..(E
|   1840: 20 0a 81 0a 45 15 44 05 03 1d 26 44 01 10 0c 3e    ...E.D...&D...>
|   1856: 26 3c 6d 82 43 04 01 1c 04 15 3a 56 62 39 16 03   &<m.C.....:Vb9..
|   1872: 30 52 24 0a 6f 14 01 16 20 81 3c 2a 53 0d 22 0f   0R$.o... .<*S...
|   1888: 29 1a 0a 01 1c 11 14 18 16 47 81 1f 54 04 0d 08   )........G..T...
|   1904: 4f 25 52 01 18 12 39 44 0f 39 3a 35 0d 81 63 39   O%R...9D.9:5..c9
|   1920: 24 01 18 1a 0b 19 5b 81 03 0a 3a 55 09 7c 41 01   $.....[...:U.|A.
|   1936: 16 18 4e 44 60 81 03 30 5a 04 21 34 01 18 50 17   ..ND`..0Z.!4..P.
|   1952: 12 0a 12 42 36 1b 34 11 2c 0b 02 01 32 01 04 84   ...B6.4.,...2...
|   1968: 0e 02 01 33 08 02 02 02 01 61 0a 08 81 63 82 5b   ...3.....a...c.[
|   1984: 02 01 62 03 02 3f 01 04 81 01 03 01 32 07 04 83   ..b..?......2...
|   2000: 02 02 02 64 38 07 04 84 72 03 01 64 07 04 81 02   ...d8...r..d....
|   2016: 02 01 65 04 04 81 0c 02 02 66 39 04 04 82 65 02   ..e......f9...e.
|   2032: 01 67 02 04 83 16 02 01 69 04 02 42 02 04 84 7d   .g......i..B....
|   2048: 04 02 12 02 01 6a 01 02 57 06 04 81 30 02 01 6b   .....j..W...0..k
|   2064: 03 04 84 22 03 02 61 6d 04 02 5b 02 01 6c 03 02   ......am..[..l..
|   2080: 04 03 04 81 45 02 01 6d 06 04 82 68 03 02 31 70   ....E..m...h..1p
|   2096: 03 04 83 7d 03 01 65 01 04 82 70 02 01 6e 05 04   ......e...p..n..
|   2112: 82 17 02 04 84 51 01 04 83 44 02 04 83 46 03 04   .....Q...D...F..
|   2128: 77 78 71 71 04 04 84 0c 03 02 d9 a0 03 04 83 54   wxqq...........T
|   2144: 02 03 6f d3 a1 08 02 06 02 02 70 72 07 04 84 71   ..o.......pr...q
|   2160: 02 02 72 69 06 04 84 55 02 01 74 03 04 82 54 02   ..ri...U..t...T.
|   2176: 03 77 6d 79 09 04 84 3e 02 04 78 71 67 32 08 04   .wmy...>..xqg2..
|   2192: 84 72 03 02 76 76 01 04 82 1f 02 03 79 75 6f 04   .r..vv......yuo.
|   2208: 04 84 77 03 04 f6 84 93 a8 05 04 83 6c 02 01 7a   ..w.........l..z
|   2224: 02 02 7c 02 04 83 21 05 04 83 07 02 02 c2 aa 01   ..|...!.........
|   2240: 04 81 2f 03 01 bc 0a 04 81 65 02 02 c3 be 01 04   ../......e......
|   2256: 82 04 02 02 df 94 07 04 82 5f 02 04 ea 80 84 6e   ........._.....n
|   2272: 04 04 84 73 03 03 84 b1 75 06 04 84 56 02 03 ef   ...s....u...V...
|   2288: 89 9e 07 04 83 7b 02 04 f0 92 ab 9a 0a 04 84 60   ...............`
|   2304: 01 01 77 01 18 49 1d 46 47 07 65 21 05 81 13 1a   ..w..I.FG.e!....
|   2320: 06 01 16 81 7e 5a 26 1b 12 05 0f 44 03 57 01 16   ....~Z&....D.W..
|   2336: 14 4d 31 81 0d 2c 2a 07 03 81 2c 01 14 23 0a 2a   .M1..,*...,..#.*
|   2352: 66 18 65 76 21 5a 5f 01 14 14 81 4c 11 10 24 81   f.ev!Z_....L..$.
|   2368: 49 48 28 01 16 7b 0a 4c 08 10 22 81 2d 03 69 38   IH(....L....-.i8
|   2384: 01 0e 3c 6e 1f 81 6a 2a 16 01 1a 3b 81 25 0d 28   ..<n..j*...;.%.(
|   2400: 0b 1a 0f 3f 24 38 04 25 01 20 31 2a 1d 5c 11 2f   ...?$8.%. 1*.../
|   2416: 05 33 28 0a 48 08 04 3d 11 45 01 18 3a 1b 1c 4c   .3(.H..=.E..:..L
|   2432: 14 63 08 05 73 81 1b 20 02 01 30 02 04 83 52 03   .c..s.. ..0...R.
|   2448: 02 c2 bd 01 04 83 73 02 02 31 6d 04 04 83 22 02   ......s..1m.....
|   2464: 01 32 05 04 82 4f 05 04 82 34 03 02 d4 87 0a 04   .2...O...4......
|   2480: 83 62 02 01 34 09 04 83 79 03 01 64 02 04 81 63   .b..4...y..d...c
|   2496: 03 02 c2 b2 03 04 82 34 02 01 37 06 04 83 19 04   .......4..7.....
|   2512: 04 82 31 02 01 38 09 04 81 1c 02 01 39 05 04 84   ..1..8......9...
|   2528: 07 03 04 82 56 02 01 61 01 04 81 1f 01 04 81 7d   ....V..a........
|   2544: 03 04 75 68 c2 be 02 04 81 2d 02 01 62 0a 04 83   ..uh.....-..b...
|   2560: 65 02 01 63 02 04 84 2c 03 01 6b 0a 04 84 58 02   e..c...,..k...X.
|   2576: 01 65 09 04 81 3e 03 01 64 03 04 83 2e 02 01 69   .e...>..d......i
|   2592: 06 04 83 60 03 01 35 0a 04 82 3d 02 01 6b 09 04   ...`..5...=..k..
|   2608: 83 34 03 01 70 05 04 81 6e 02 01 6c 09 04 83 28   .4..p...n..l...(
|   2624: 02 01 6d 04 04 82 6f 04 04 83 09 01 04 84 48 02   ..m...o.......H.
|   2640: 04 6e 79 68 31 03 04 83 4d 02 01 6f 03 02 2d 03   .nyh1...M..o..-.
|   2656: 01 6e 09 02 61 02 01 70 04 04 82 67 02 03 71 63   .n..a..p...g..qc
|   2672: 79 09 04 81 0b 03 02 c2 bc 0a 02 30 02 01 72 08   y..........0..r.
|   2688: 02 5e 02 01 73 08 04 81 07 02 01 75 05 02 6c 05   .^..s......u..l.
|   2704: 04 84 56 02 01 76 08 04 81 01 02 01 78 05 04 84   ..V..v......x...
|   2720: 61 02 04 84 6c 02 01 7a 0a 04 83 2e 02 02 c2 ba   a...l..z........
|   2736: 04 04 81 39 03 01 bc 01 04 83 23 02 02 c9 a8 03   ...9......#.....
|   2752: 04 83 38 02 04 ce bc 62 68 02 04 82 25 02 02 d4   ..8....bh...%...
|   2768: 85 08 04 82 2d 02 02 db 91 09 04 84 29 01 01 78   ....-.......)..x
|   2784: 01 0a 27 82 4d 5c 23 01 1c 11 62 38 15 17 67 05   ..'.M.#...b8..g.
|   2800: 3e 05 33 1b 29 1c 26 01 16 0d 81 33 0c 0c 09 61   >.3.).&....3...a
|   2816: 4e 1a 54 47 01 18 22 43 09 60 11 2a 08 1b 81 30   N.TG...C.`.*...0
|   2832: 27 44 01 24 2d 06 1c 19 2a 5e 22 24 04 2a 5c 0b   'D.$-...*^.$.*..
|   2848: 42 0d 0f 37 06 2d 01 1a 4c 28 2d 47 14 46 18 45   B..7.-..L(-G.F.E
|   2864: 0e 2c 04 81 1a 01 14 1d 33 75 70 62 32 75 26 2d   .,......3upb2u&-
|   2880: 08 01 18 41 0b 0a 0c 1f 17 27 61 81 37 3b 21 01   ...A.....'a.7;!.
|   2896: 1e 39 12 0e 1b 17 17 08 4c 04 81 18 0a 81 12 1a   .9......L.......
|   2912: 01 22 0d 11 30 32 1f 5d 31 08 1e 2e 23 3b 03 49   ....02.]1...#;.I
|   2928: 05 6d 03 02 01 30 01 04 81 47 04 02 22 03 02 65   .m...0...G.....e
|   2944: 77 0a 04 82 16 02 01 32 04 08 81 55 81 2e 01 06   w......2...U....
|   2960: 57 3a 73 02 01 36 0a 02 4f 03 01 7a 04 04 81 27   W:s..6..O..z...'
|   2976: 02 01 61 05 04 82 21 02 01 62 01 02 7e 02 01 63   ..a...!..b..~..c
|   2992: 05 04 81 0c 03 02 c2 b3 08 04 81 24 02 01 65 05   ...........$..e.
|   3008: 04 84 5e 01 04 81 04 01 04 82 3e 01 04 83 46 02   ..^.......>...F.
|   3024: 01 67 02 04 84 09 02 01 68 01 04 83 04 02 01 69   .g......h......i
|   3040: 04 04 82 31 04 04 82 5a 02 01 6a 01 04 81 21 02   ...1...Z..j...!.
|   3056: 01 6b 08 04 83 5e 03 02 68 7a 0a 04 84 67 03 04   .k...^..hz...g..
|   3072: 77 78 64 6f 04 04 81 4c 02 01 6d 04 04 83 03 03   wxdo...L..m.....
|   3088: 01 37 01 04 83 75 03 01 67 07 04 82 04 02 01 6e   .7...u..g......n
|   3104: 06 02 2c 04 04 83 52 02 01 6f 05 04 81 14 02 03   ..,...R..o......
|   3120: 70 6d 73 08 04 83 68 02 01 71 06 04 84 7c 02 01   pms...h..q...|..
|   3136: 72 02 04 84 20 03 04 83 33 01 04 82 13 02 04 82   r... ...3.......
|   3152: 17 03 01 69 04 04 81 1c 03 01 76 04 04 84 71 02   ...i......v...q.
|   3168: 01 73 04 04 82 53 02 01 75 01 04 81 3b 05 04 82   .s...S..u...;...
|   3184: 2a 02 01 77 03 04 82 4f 02 01 79 02 02 60 02 01   *..w...O..y..`..
|   3200: 7a 08 04 81 34 02 04 c2 aa 6b 61 04 04 82 7b 02   z...4....ka.....
|   3216: 02 c6 b4 0a 04 81 02 02 02 ca 83 03 02 5a 02 02   .............Z..
|   3232: d4 ae 04 04 81 45 02 02 d7 bb 0a 04 83 78 02 02   .....E.......x..
|   3248: dc 96 06 04 82 1f 02 02 df 95 05 04 82 11 02 03   ................
|   3264: ea b7 a6 07 04 83 6e 02 04 f0 93 a0 b9 06 04 82   ......n.........
|   3280: 6c 02 05 f5 af 82 82 73 07 02 41 01 01 79 01 1e   l......s..A..y..
|   3296: 07 21 30 08 81 04 17 25 0a 0c 81 17 27 81 25 01   .!0....%....'.%.
|   3312: 1a 03 5d 21 81 16 07 3f 27 16 3f 14 08 18 01 12   ..]!...?'.?.....
|   3328: 68 4f 0e 25 34 3a 3d 81 16 01 12 09 81 0a 3c 72   hO.%4:=.......<r
|   3344: 31 81 40 48 01 1c 5e 14 34 31 81 1b 10 51 25 3f   1.@H..^.41...Q%?
|   3360: 18 1e 0c 0e 01 12 6a 81 2f 30 7c 08 7f 09 24 01   ......j./0|...$.
|   3376: 12 5a 81 55 12 41 39 33 6c 0c 01 1c 81 30 1c 26   .Z.U.A93l....0.&
|   3392: 08 5d 11 2f 09 6b 0f 15 19 3d 01 14 04 71 81 17   .]./.k...=...q..
|   3408: 0c 04 16 50 7e 61 01 12 82 5d 0d 3c 81 01 06 16   ...P~a...].<....
|   3424: 32 02 01 31 06 04 85 00 02 01 34 01 02 06 03 04   2..1......4.....
|   3440: 81 52 02 04 84 37 02 01 35 0a 04 81 4b 02 01 62   .R...7..5...K..b
|   3456: 01 04 82 49 06 04 82 36 02 01 65 04 02 71 02 01   ...I...6..e..q..
|   3472: 66 04 04 1c 2b 02 04 82 29 02 05 69 62 c2 bc 70   f...+...)..ib..p
|   3488: 08 04 84 46 02 01 6d 02 04 81 4b 08 04 83 56 03   ...F..m...K...V.
|   3504: 01 6d 06 04 81 2c 03 02 74 67 03 04 81 5c 02 01   .m...,..tg......
|   3520: 6f 0a 04 81 5b 02 01 71 01 04 81 08 02 04 84 0c   o...[..q........
|   3536: 07 04 81 5c 03 01 7a 05 04 81 77 02 01 73 01 02   ......z...w..s..
|   3552: 12 03 02 32 70 09 04 81 44 03 01 6f 0a 04 84 17   ...2p...D..o....
|   3568: 03 03 c2 b9 76 04 04 81 50 02 01 74 01 04 82 3f   ....v...P..t...?
|   3584: 05 04 82 5a 02 01 76 09 02 54 01 04 83 5f 02 01   ...Z..v..T..._..
|   3600: 77 07 02 3d 02 01 78 03 04 83 0e 03 04 83 73 02   w..=..x.......s.
|   3616: 02 08 02 01 79 04 04 84 68 02 02 c2 ba 02 04 84   ....y...h.......
|   3632: 3e 03 01 bd 02 08 81 06 82 6e 04 01 74 04 04 84   >........n..t...
|   3648: 17 02 03 c5 a7 33 0a 04 84 55 02 02 c7 9d 04 04   .....3...U......
|   3664: 81 60 02 08 ca 81 30 68 f0 90 90 b2 09 04 84 2e   .`....0h........
|   3680: 03 01 b5 02 04 82 33 02 03 d1 9e 6c 02 04 81 1a   ......3....l....
|   3696: 02 02 d4 93 04 04 81 05 02 02 d8 ab 03 04 82 49   ...............I
|   3712: 03 02 b8 73 01 04 84 1d 02 03 e2 af 9d 07 02 4d   ...s...........M
|   3728: 02 03 ec 8f ad 03 04 84 47 01 01 7a 01 22 1d 42   ........G..z...B
|   3744: 10 5f 1b 08 63 1e 07 0a 30 07 0b 26 31 61 07 01   ._..c...0..&1a..
|   3760: 1c 0a 37 29 0a 68 40 38 0a 4a 04 08 0b 07 0f 07   ..7).h@8.J......
|   3776: 0c 07 07 09 07 08 09 09 0b 07 08 0b 06 08 07 07   ................
|   3792: 08 08 08 06 07 06 07 08 08 09 0a 09 81 31 06 07   .............1..
|   3808: 0d 06 06 07 0a 07 08 0e 08 07 07 0b 06 07 09 07   ................
|   3824: 0b 07 07 07 0c 07 07 07 07 08 09 08 07 0a 81 14   ................
|   3840: 07 07 06 0b 08 06 07 09 07 07 0f 0e 06 0b 0b 0a   ................
|   3856: 0c 07 06 06 09 06 08 0b 09 07 08 0f 0b 07 0c 08   ................
|   3872: 06 07 07 09 08 09 07 09 0a 81 20 07 07 08 06 0c   .......... .....
|   3888: 09 0a 06 07 06 07 0b 09 09 0d 06 06 06 07 07 07   ................
|   3904: 07 09 07 09 07 07 08 0f 07 0a 08 08 0e 07 08 07   ................
|   3920: 08 08 0b 0a 0a 09 07 06 09 0a 81 10 07 06 09 0a   ................
|   3936: 07 08 07 07 08 07 0d 0a 07 07 0a 07 08 07 13 0a   ................
|   3952: 08 08 08 08 07 09 0a 08 09 0a 0e 08 07 08 08 0a   ................
|   3968: 09 09 0a 81 08 07 08 08 0b 08 07 07 08 0b 07 0b   ................
|   3984: 0b 0a 07 07 07 07 07 07 07 07 07 07 0f 0a 06 06   ................
|   4000: 07 09 07 06 07 0a 07 0b 07 08 07 08 0a 08 08 81   ................
|   4016: 16 0a 08 0e 06 07 07 06 07 08 13 07 07 0b 07 07   ................
|   4032: 08 0a 07 07 07 0a 07 09 07 13 07 07 07 0b 07 06   ................
|   4048: 07 0a 08 07 08 08 08 08 09 0a 0a 81 06 07 0e 07   ................
|   4064: 0b 06 0b 0b 0b 07 08 07 0f 07 06 08 07 09 0b 0a   ................
|   4080: 06 0e 07 08 09 07 09 08 0e 07 09 08 08 08 08 09   ................
| page 24 offset 94208
|      0: 0d 00 00 00 01 00 28 00 00 28 00 00 00 00 00 00   ......(..(......
|     32: 00 00 00 00 00 00 00 00 9f 50 88 80 80 80 80 05   .........P......
|     48: 04 00 bf 24 00 09 0e 5b 14 06 1c 0d 12 03 18 37   ...$...[.......7
|     64: 1f 05 55 32 10 15 5a 81 07 4b 04 01 16 07 0e 5f   ..U2..Z..K....._
|     80: 0b 46 0b 22 81 41 24 23 01 28 2a 07 11 09 15 0b   .F...A$#.(*.....
|     96: 0f 0c 09 0a 1e 05 1f 5e 07 19 1c 1e 33 3e 01 18   .......^....3>..
|    112: 26 0c 1b 43 08 38 11 05 81 1b 5f 20 01 1e 06 1c   &..C.8...._ ....
|    128: 36 27 33 20 53 4f 06 03 1a 2f 2c 40 6d 01 18 72   6'3 SO.../,@m..r
|    144: 81 0d 20 3a 23 05 34 19 23 2b 36 01 12 2c 4d 0c   .. :#.4.#+6..,M.
|    160: 59 82 04 46 40 0f 01 1a 28 15 32 33 2e 52 0f 49   Y..F@...(.23.R.I
|    176: 04 09 81 33 26 03 30 7a 34 01 04 82 05 02 01 36   ...3&.0z4......6
|    192: 06 04 81 5a 02 04 37 ce bc 74 09 04 81 17 02 01   ...Z..7..t......
|    208: 38 01 04 83 79 03 03 dd 9a 73 02 04 84 12 02 01   8...y....s......
|    224: 61 04 04 82 1c 02 01 62 01 04 83 4e 07 04 82 5b   a......b...N...[
|    240: 02 01 63 0a 02 4e 02 01 64 04 04 84 7d 02 01 65   ..c..N..d......e
|    256: 01 04 84 2a 02 01 67 01 04 81 75 02 04 68 d0 bf   ...*..g...u..h..
|    272: 70 09 04 81 4a 02 01 69 01 04 84 34 05 04 82 48   p...J..i...4...H
|    288: 02 01 6a 02 02 1d 04 04 81 54 02 01 6b 03 04 81   ..j......T..k...
|    304: 0d 02 01 6c 09 04 83 54 02 01 6e 06 02 0b 01 04   ...l...T..n.....
|    320: 84 1c 02 01 6f 0a 02 26 03 01 6a 08 04 82 26 03   ....o..&..j...&.
|    336: 05 73 75 c2 bd 61 03 02 38 02 02 70 37 06 04 81   .su..a..8..p7...
|    352: 7e 02 01 71 01 04 83 67 03 01 65 06 04 84 08 02   ~..q...g..e.....
|    368: 01 72 0a 04 82 1e 02 01 74 01 04 82 6c 02 02 5d   .r......t...l..]
|    384: 04 04 84 17 03 04 82 77 02 01 75 04 08 82 22 82   .......w..u.....
|    400: 0b 02 02 76 6c 03 04 83 25 02 01 77 03 04 81 24   ...vl...%..w...$
|    416: 03 04 82 42 02 01 78 06 04 82 4a 03 02 c2 b2 02   ...B..x...J.....
|    432: 04 83 21 02 01 79 09 04 83 43 02 01 7a 04 02 51   ..!..y...C..z..Q
|    448: 02 02 c2 aa 02 02 51 03 01 b3 09 04 81 2a 03 01   ......Q......*..
|    464: b9 06 04 82 73 03 02 bd 73 04 02 4e 04 05 76 c2   ....s...s..N..v.
|    480: be 67 65 08 02 1d 04 03 78 de bc 02 04 83 6d 04   .ge.....x.....m.
|    496: 01 7a 09 04 84 1d 02 04 ca a2 36 32 07 04 83 2e   .z........62....
|    512: 02 02 d8 aa 04 04 84 31 02 02 df 8a 02 02 73 01   .......1......s.
|    528: 02 c2 aa 01 08 81 7f 82 01 01 06 56 83 70 02 06   ...........V.p..
|    544: 74 82 6d 01 06 81 5d 45 01 04 82 7b 01 0c 81 46   t.m...]E.......F
|    560: 13 6a 82 12 01 0c 82 24 63 15 35 74 01 12 81 14   .j.....$c.5t....
|    576: 81 24 1f 3d 7c 15 1c 01 0a 82 39 1a 81 6f 03 02   .$.=|.....9..o..
|    592: 30 65 07 04 83 3a 03 01 63 03 04 81 7d 03 01 65   0e...:..c......e
|    608: 09 02 03 03 01 66 01 02 6c 04 02 66 7a 03 04 82   .....f..l..fz...
|    624: 1c 03 01 6b 0a 04 82 46 03 01 7a 08 04 84 2d 03   ...k...F..z...-.
|    640: 03 c2 bd 73 0a 04 81 10 05 02 c2 bc 03 02 03 04   ...s............
|    656: 01 be 02 04 84 35 03 04 f0 9f ad ae 08 04 83 41   .....5.........A
|    672: 02 01 b2 01 0a 3e 77 21 82 5f 01 08 81 74 82 68   .....>w!._...t.h
|    688: 01 0e 39 81 0c 81 4b 1c 4e 01 0e 83 46 06 3b 1d   ..9...K.N...F.;.
|    704: 0e 38 01 0e 81 50 15 81 53 35 57 01 08 82 7d 26   .8...P..S5W....&
|    720: 1c 01 04 2f 0e 01 08 66 5d 83 24 01 0e 43 81 10   .../...f].$..C..
|    736: 24 82 77 04 01 0a 82 0a 81 61 1f 03 01 35 08 04   $.w......a...5..
|    752: 81 11 03 01 61 09 04 82 0b 03 01 64 07 04 81 7e   ....a......d...~
|    768: 03 01 66 05 04 82 29 03 01 67 03 04 84 17 03 04   ..f...)..g......
|    784: 69 34 d8 a1 05 04 82 42 03 01 73 04 04 84 3d 03   i4.....B..s...=.
|    800: 01 76 06 04 81 70 04 03 76 c2 ba 07 04 81 34 03   .v...p..v.....4.
|    816: 01 78 06 04 83 48 03 03 c2 b3 36 07 02 7f 03 02   .x...H....6.....
|    832: d4 85 04 04 81 2d 03 02 d9 bc 05 04 83 20 03 04   .....-....... ..
|    848: ee b5 9c 70 03 04 83 57 03 05 f6 80 80 bb 70 05   ...p...W......p.
|    864: 04 81 6a 02 01 b3 01 06 82 41 12 01 08 67 0d 82   ..j......A...g..
|    880: 69 01 0e 81 51 22 5c 7d 81 00 01 10 68 05 2f 81   i...Q.......h./.
|    896: 4e 81 78 03 01 0a 74 81 58 81 72 01 0c 4e 72 07   N.x...t.X.r..Nr.
|    912: 79 81 7d 01 10 44 3b 58 66 82 08 0c 2f 01 06 0c   y....D;Xf.../...
|    928: 65 36 01 04 81 02 01 08 5d 43 82 10 03 01 61 06   e6......]C....a.
|    944: 04 83 3c 03 01 63 07 04 82 32 03 01 68 03 04 82   ..<..c...2..h...
|    960: 76 03 03 6a 77 6d 0a 04 84 35 03 01 70 01 04 84   v..jwm...5..p...
|    976: 70 03 01 74 01 06 84 05 0a 06 02 47 04 04 6a 75   p..t.......G..ju
|    992: ce bc 07 04 82 4d 03 02 75 65 07 04 81 05 03 01   .....M..ue......
|   1008: 77 01 04 81 59 04 03 6f db 85 08 02 3d 03 04 c2   w...Y..o....=...
|   1024: be c2 b9 01 04 81 04 03 07 c4 a7 67 d5 bb 7a 68   ...........g..zh
|   1040: 06 04 84 05 03 02 c7 a5 02 04 81 10 02 01 b9 01   ................
|   1056: 0c 1e 81 43 0b 81 56 01 08 82 70 81 27 01 06 34   ...C..V...p.'..4
|   1072: 83 38 01 0c 81 0f 1d 04 81 74 01 06 82 58 65 01   .8.......t...Xe.
|   1088: 10 27 55 7a 4b 81 00 2c 29 01 0e 04 1f 24 09 83   .'UzK..,)....$..
|   1104: 44 04 01 08 65 2f 41 2b 01 0c 34 0c 81 17 83 0f   D...e/A+..4.....
|   1120: 01 04 82 69 03 02 61 73 02 02 4d 03 01 65 01 04   ...i..as..M..e..
|   1136: 81 2e 03 02 69 61 04 04 83 06 04 03 69 69 67 08   ....ia......iig.
|   1152: 02 1b 03 03 6b c2 ba 06 04 82 49 03 01 6d 04 04   ....k.....I..m..
|   1168: 84 67 03 01 6f 02 04 82 4b 03 01 70 06 04 84 34   .g..o...K..p...4
|   1184: 03 04 72 61 76 76 04 02 67 03 03 73 c2 be 07 04   ..ravv..g..s....
|   1200: 82 17 03 01 76 03 04 81 56 03 01 78 02 04 84 24   ....v...V..x...$
|   1216: 03 03 79 69 38 05 04 84 68 03 05 c2 aa 63 c2 b2   ..yi8...h....c..
|   1232: 08 02 69 04 01 b9 06 04 82 75 04 01 ba 01 04 81   ..i......u......
|   1248: 51 04 01 bc 0a 04 81 0f 03 02 c5 a7 0a 04 84 71   Q..............q
|   1264: 03 05 c9 99 ee 84 af 03 04 84 10 04 06 9f db a5   ................
|   1280: 30 71 68 07 04 82 46 03 05 ca 8b 64 78 66 0a 04   0qh...F....dxf..
|   1296: 84 01 03 02 dd 9b 0a 04 82 4e 03 02 de bd 08 04   .........N......
|   1312: 82 03 03 07 eb b1 bd f2 84 82 8d 04 04 84 23 02   ..............#.
|   1328: 01 ba 01 0c 2d 81 55 09 82 17 01 04 07 64 01 0e   ....-.U......d..
|   1344: 33 81 73 0e 36 81 63 01 0e 2f 60 82 09 5b 5f 2c   3.s.6.c../`..[_,
|   1360: 01 08 82 6d 81 69 01 0c 81 2d 3c 35 81 0b 01 10   ...m.i...-<5....
|   1376: 4f 81 08 03 82 4f 29 27 01 0c 0f 03 55 82 6d 10   O....O)'....U.m.
|   1392: 01 08 0d 82 16 1e 01 06 2c 82 56 03 01 33 05 04   ........,.V..3..
|   1408: 82 25 03 01 36 07 04 82 73 03 01 63 0a 02 48 03   .%..6...s..c..H.
|   1424: 02 66 6f 07 04 84 60 03 01 67 03 04 84 27 03 01   .fo...`..g...'..
|   1440: 6c 0a 02 63 03 01 6d 07 04 82 75 03 01 6f 08 04   l..c..m...u..o..
|   1456: 82 4d 04 04 61 74 d4 a5 02 04 83 3c 03 02 d9 a8   .M..at.....<....
|   1472: 04 04 83 4e 03 03 db 93 61 02 04 81 52 03 03 e1   ...N....a...R...
|   1488: bf a7 08 04 83 42 02 01 bc 01 06 81 6c 2f 01 06   .....B......l/..
|   1504: 81 31 32 01 06 30 81 02 01 0c 81 02 81 73 04 67   .12..0.......s.g
|   1520: 01 06 81 6c 20 01 0e 57 6d 04 81 1f 81 24 01 04   ...l ..Wm....$..
|   1536: 83 54 01 0c 70 49 81 59 81 11 01 0e 56 81 44 0d   .T..pI.Y....V.D.
|   1552: 3d 81 23 01 0a 83 15 81 6b 06 03 02 39 6d 0a 02   =.#.....k...9m..
|   1568: 59 03 03 62 c2 aa 03 04 82 2f 03 01 63 02 04 84   Y..b...../..c...
|   1584: 45 04 05 79 76 7a c2 ba 04 04 81 19 03 01 66 07   E..yvz........f.
|   1600: 04 81 74 03 01 69 08 04 83 59 03 02 6f 37 09 04   ..t..i...Y..o7..
|   1616: 84 38 03 01 72 04 04 81 3f 03 01 73 07 02 69 03   .8..r...?..s..i.
|   1632: 03 79 76 62 04 02 76 03 02 c2 b2 06 04 84 48 04   .yvb..v.......H.
|   1648: 03 b3 34 79 02 04 81 3d 04 01 bc 08 04 82 19 03   ..4y...=........
|   1664: 04 ce bc ce bc 01 04 84 4a 03 04 e7 a8 a1 79 01   ........J.....y.
|   1680: 02 03 02 01 bd 01 06 58 82 1d 01 0a 82 7b 81 02   .......X........
|   1696: 57 01 04 0a 6b 01 08 81 5f 70 13 01 12 0e 38 65   W...k..._p....8e
|   1712: 11 34 52 4c 5c 75 01 06 82 56 3e 01 02 23 01 0a   .4RL.u...V>..#..
|   1728: 81 29 08 83 2f 01 0c 81 43 81 48 2f 03 01 08 83   .)../...C.H/....
|   1744: 5a 76 3a 03 01 30 04 04 81 71 03 01 32 01 04 82   Zv:..0...q..2...
|   1760: 1d 03 01 36 02 04 84 34 03 01 61 09 04 82 41 03   ...6...4..a...A.
|   1776: 01 68 07 02 38 03 01 6a 08 04 84 15 03 01 6c 08   .h..8..j......l.
|   1792: 04 82 66 03 01 6d 08 04 82 69 03 01 6f 01 04 82   ..f..m...i..o...
|   1808: 40 02 04 84 2d 03 02 78 03 01 73 04 08 81 29 82   @...-..x..s...).
|   1824: 08 03 03 75 75 6b 06 04 84 21 03 01 78 05 04 83   ...uuk...!..x...
|   1840: 61 04 04 c2 be c2 bc 06 04 82 5c 03 01 79 01 04   a............y..
|   1856: 83 46 03 02 c2 b3 06 02 40 02 01 be 01 08 81 0f   .F......@.......
|   1872: 81 71 01 0e 81 25 60 81 39 1d 70 01 06 1b 83 53   .q...%`.9.p....S
|   1888: 01 06 83 37 52 01 10 6b 65 18 2a 81 4d 47 33 01   ...7R..ke.*.MG3.
|   1904: 06 82 79 07 01 02 46 01 08 03 13 81 64 01 0c 5a   ..y...F.....d..Z
|   1920: 65 76 82 33 04 01 08 82 61 82 19 03 02 35 64 01   ev.3....a....5d.
|   1936: 04 84 17 03 01 37 06 04 82 10 03 01 62 08 02 5b   .....7......b..[
|   1952: 03 01 66 07 04 83 04 03 01 67 06 02 36 03 01 6a   ..f......g..6..j
|   1968: 01 04 83 3e 08 04 83 59 03 01 71 01 04 82 47 03   ...>...Y..q...G.
|   1984: 01 72 08 06 81 73 32 03 01 75 09 04 82 35 03 02   .r...s2..u...5..
|   2000: 77 76 07 04 83 68 03 01 78 05 02 72 03 02 c2 b3   wv...h..x..r....
|   2016: 0a 04 81 7e 04 01 bd 05 04 84 35 03 02 cb 8a 03   ...~......5.....
|   2032: 04 84 46 03 02 ce bc 02 04 82 72 01 05 c3 9f ca   ..F.......r.....
|   2048: 83 74 03 04 81 58 02 01 a6 08 04 84 26 02 04 82   .t...X......&...
|   2064: 1d 02 01 be 06 04 81 4f 03 04 83 1d 01 02 c4 a7   .......O........
|   2080: 01 02 0e 05 04 81 7c 04 04 84 09 02 01 b3 01 04   ......|.........
|   2096: 81 43 09 04 82 70 03 02 67 72 07 04 83 06 02 01   .C...p..gr......
|   2112: b8 06 04 83 09 03 04 78 6d 77 75 07 04 82 69 01   .......xmwu...i.
|   2128: 02 c5 80 06 04 83 40 02 01 82 06 04 82 6a 03 04   ......@......j..
|   2144: 82 1a 02 01 89 07 08 81 39 81 6c 02 01 8b 06 04   ........9.l.....
|   2160: 81 1a 03 01 6a 02 02 26 02 01 93 04 04 83 49 03   ....j..&......I.
|   2176: 02 6e 70 03 02 0f 01 02 c6 83 01 04 82 5b 06 04   .np..........[..
|   2192: 83 6a 02 01 85 02 04 82 0d 03 01 31 09 02 41 03   .j.........1..A.
|   2208: 01 6b 0a 04 84 0d 02 01 88 04 06 82 16 7f 02 01   .k..............
|   2224: 95 06 04 81 50 02 04 84 18 01 04 84 3f 03 01 78   ....P.......?..x
|   2240: 06 04 84 11 02 01 99 05 04 83 38 01 04 81 4a 02   ..........8...J.
|   2256: 01 9a 04 04 81 16 02 02 9b 62 03 02 10 02 01 a3   .........b......
|   2272: 04 04 82 0d 01 04 84 64 02 01 a5 05 06 81 3d 61   .......d......=a
|   2288: 03 02 79 69 05 04 82 23 02 01 a8 09 04 83 44 02   ..yi...#......D.
|   2304: 01 ab 03 04 81 13 02 02 ad 75 06 04 82 07 02 01   .........u......
|   2320: b4 05 04 82 74 03 04 75 61 65 6c 05 04 82 68 02   ....t..uael...h.
|   2336: 01 b6 03 04 81 6b 02 01 ba 05 04 83 72 02 01 bd   .....k......r...
|   2352: 06 04 84 15 02 02 be 74 02 04 84 57 03 01 79 07   .......t...W..y.
|   2368: 04 82 5d 02 02 bf 67 09 04 81 42 03 01 72 03 04   ..]...g...B..r..
|   2384: 82 7a 03 01 77 0a 02 3c 01 02 c7 80 02 04 84 1d   .z..w..<........
|   2400: 03 01 31 04 04 83 1d 02 03 81 c9 ab 06 04 83 4d   ..1............M
|   2416: 02 01 82 09 04 83 25 02 03 86 d3 97 05 02 34 02   ......%.......4.
|   2432: 02 89 78 02 04 83 19 02 01 8c 03 02 56 02 04 81   ..x.........V...
|   2448: 3b 02 04 82 16 02 01 9c 03 04 82 55 04 04 81 08   ;..........U....
|   2464: 02 01 9d 07 04 81 1c 03 01 68 04 04 83 11 02 01   .........h......
|   2480: 9f 05 04 81 0e 02 01 a1 01 04 84 79 08 04 82 27   ...........y...'
|   2496: 02 01 a3 04 04 81 5c 06 02 33 02 02 a5 76 0a 04   .........3...v..
|   2512: 82 07 02 08 ad 7a c8 bf e0 a4 8a 64 04 04 81 03   .....z.....d....
|   2528: 02 01 af 05 04 84 25 02 01 b3 03 02 5c 02 01 bb   ......%.........
|   2544: 06 02 06 03 01 68 03 04 81 2c 03 01 71 04 04 81   .....h...,..q...
|   2560: 69 02 01 bd 03 06 81 7a 6f 02 04 84 2f 01 03 c8   i......zo.../...
|   2576: 9d 36 02 04 83 43 02 02 a1 70 01 04 82 4a 02 01   .6...C...p...J..
|   2592: a5 02 04 83 45 02 01 ad 01 04 81 10 02 01 b1 02   ....E...........
|   2608: 04 84 4c 07 04 84 03 02 01 bc 08 04 81 3b 03 01   ..L..........;..
|   2624: 31 03 04 83 45 02 01 bf 07 04 81 17 01 02 c9 80   1...E...........
|   2640: 01 02 3a 01 04 83 62 02 01 82 02 04 81 55 04 04   ..:...b......U..
|   2656: 84 6d 02 02 50 02 01 8f 02 04 84 16 06 04 83 57   .m..P..........W
|   2672: 02 01 91 04 04 83 4f 02 01 93 0a 04 81 1d 03 01   ......O.........
|   2688: 69 05 04 83 37 03 01 79 08 04 82 21 02 01 96 04   i...7..y...!....
|   2704: 04 82 13 04 02 6c 02 04 83 29 02 01 97 04 02 2d   .....l...).....-
|   2720: 02 03 99 6d 74 05 04 81 73 02 01 9f 09 04 84 63   ...mt...s......c
|   2736: 02 01 a0 05 02 6a 02 02 76 02 01 a2 02 02 2e 02   .....j..v.......
|   2752: 01 a3 01 04 82 16 02 01 a5 04 04 81 31 06 04 83   ............1...
|   2768: 0f 02 01 a8 03 04 83 47 02 01 a9 06 06 82 0d 49   .......G.......I
|   2784: 02 01 af 0a 04 83 1c 02 02 b2 34 04 04 81 3c 02   ..........4...<.
|   2800: 04 b5 74 c2 b2 03 04 81 28 02 01 ba 09 04 83 62   ..t.....(......b
|   2816: 02 01 bb 07 04 84 73 02 01 bc 06 04 81 2a 02 01   ......s......*..
|   2832: bd 04 04 81 68 02 01 be 09 04 83 67 03 01 73 08   ....h......g..s.
|   2848: 04 83 5f 01 02 ca 80 07 04 84 0b 03 01 77 02 04   .._..........w..
|   2864: 82 59 02 01 81 06 04 82 1c 02 01 83 08 04 83 1b   .Y..............
|   2880: 01 04 81 71 02 01 86 07 04 81 79 02 01 88 08 02   ...q......y.....
|   2896: 62 01 04 81 0a 02 01 89 04 04 81 62 02 01 8a 03   b..........b....
|   2912: 04 83 11 01 04 83 50 02 01 8c 06 04 84 2e 02 01   ......P.........
|   2928: 8e 03 04 82 3e 04 04 82 33 03 01 68 07 04 82 3b   ....>...3..h...;
|   2944: 02 01 8f 04 04 82 63 03 01 73 08 02 7e 02 01 90   ......c..s..~...
|   2960: 08 02 20 02 01 91 01 04 83 52 02 01 94 06 04 83   .. ......R......
|   2976: 36 02 02 95 7a 0a 02 51 02 04 99 75 73 73 03 02   6...z..Q...uss..
|   2992: 36 02 01 9c 06 04 81 27 02 01 a5 07 04 81 7b 03   6......'........
|   3008: 07 e0 a4 aa d5 b8 61 62 0a 02 77 02 02 a6 6f 07   ......ab..w...o.
|   3024: 04 81 07 03 03 ec b2 be 02 04 82 39 02 02 a7 33   ...........9...3
|   3040: 08 02 61 02 01 a9 03 04 84 07 02 01 b6 0a 04 84   ..a.............
|   3056: 02 02 01 b7 05 04 81 4a 03 03 6a 69 6a 05 04 81   .......J..jij...
|   3072: 48 02 01 b8 09 04 83 0a 03 04 c4 91 d8 bd 03 02   H...............
|   3088: 1c 02 01 b9 09 02 4c 02 04 ba c9 b1 37 07 04 81   ......L.....7...
|   3104: 4e 02 02 bb 70 01 04 84 4c 02 01 bc 01 04 83 0c   N...p...L.......
|   3120: 02 02 be 72 05 02 04 01 02 cb 80 0a 04 84 52 02   ...r..........R.
|   3136: 01 88 07 04 83 1d 02 01 8a 08 02 7c 02 01 a1 09   ...........|....
|   3152: 04 81 1b 03 01 30 06 04 81 52 03 01 6a 01 04 82   .....0...R..j...
|   3168: 34 02 01 a2 01 04 83 30 02 03 a3 71 64 04 02 7e   4......0...qd..~
|   3184: 02 01 a4 0a 04 83 34 02 01 ae 06 04 84 7f 03 01   ......4.........
|   3200: 6e 06 04 83 68 01 02 cd b1 02 04 82 55 03 01 6a   n...h.......U..j
|   3216: 01 04 83 5d 02 01 b7 08 04 81 58 03 01 75 07 04   ...]......X..u..
|   3232: 84 09 02 01 b8 01 04 82 0e 06 02 22 03 04 82 4f   ...............O
|   3248: 03 02 dd af 05 04 84 3f 02 01 bc 01 04 84 3b 02   .......?......;.
|   3264: 01 bd 09 04 81 61 01 04 83 3c 02 03 bf 64 67 02   .....a...<...dg.
|   3280: 04 82 0c 01 05 ce 81 66 da 94 01 02 10 03 01 6b   .......f.......k
|   3296: 0a 04 82 7e 02 01 8d 08 04 83 02 02 07 ad 69 f0   ...~..........i.
|   3312: 98 a6 a7 61 09 04 84 41 03 01 72 03 04 82 62 02   ...a...A..r...b.
|   3328: 01 ae 06 04 83 5d 02 04 81 44 03 01 37 06 04 81   .....]...D..7...
|   3344: 08 02 05 af 64 cf 8d 32 01 02 11 02 01 b1 05 04   ....d..2........
|   3360: 84 52 03 01 61 08 04 81 68 03 01 68 08 04 83 5a   .R..a...h..h...Z
|   3376: 02 01 b2 05 04 84 43 01 02 7e 03 04 83 23 02 04   ......C..~...#..
|   3392: b3 71 30 73 03 04 83 76 02 01 b5 02 04 82 04 02   .q0s...v........
|   3408: 01 b6 0a 04 84 6e 02 01 b7 03 04 81 36 02 01 b8   .....n......6...
|   3424: 01 04 84 60 02 02 3a 03 04 84 76 01 02 50 03 02   ...`..:...v..P..
|   3440: 32 6a 09 04 81 0c 03 01 68 03 02 11 02 01 b9 04   2j......h.......
|   3456: 04 84 0f 02 04 bb d2 b5 62 08 04 81 10 02 01 bc   ........b.......
|   3472: 01 0e 4d 81 25 3f 1b 81 54 01 0c 55 81 38 06 82   ..M.%?..T..U.8..
|   3488: 1b 01 08 21 82 66 37 01 08 65 09 83 3c 02 0a 82   ...!.f7..e..<...
|   3504: 21 08 81 52 01 08 83 4e 81 29 01 0e 47 15 81 21   !..R...N.)..G..!
|   3520: 81 0f 65 01 10 12 20 2d 38 81 00 81 73 01 10 0e   ..e... -8...s...
|   3536: 33 6c 2d 3e 81 4e 07 03 01 67 03 04 83 52 03 01   3l->.N...g...R..
|   3552: 6b 08 04 83 72 03 02 6c 32 02 04 81 51 03 03 6d   k...r..l2...Q..m
|   3568: 67 79 09 04 82 67 03 01 70 04 04 81 44 03 02 71   gy...g..p...D..q
|   3584: 6a 0a 04 81 6d 03 01 79 01 04 81 5e 03 02 c2 bd   j...m..y...^....
|   3600: 07 04 81 3a 04 01 be 08 02 18 03 02 ce bc 07 02   ...:............
|   3616: 34 02 01 bd 03 02 28 03 01 67 04 04 82 09 03 02   4.....(..g......
|   3632: 6e 6c 01 02 22 03 01 78 02 04 83 5f 02 01 bf 02   nl.....x..._....
|   3648: 02 16 03 01 7a 06 04 82 05 01 02 cf 80 03 02 69   ....z..........i
|   3664: 03 01 6e 05 04 83 40 02 02 81 6c 06 04 84 5d 03   ..n...@...l...].
|   3680: 02 ca ab 04 04 81 5d 02 01 84 03 04 81 2e 03 04   ......].........
|   3696: 82 6e 02 01 85 06 04 82 40 02 01 88 04 02 62 02   .n......@.....b.
|   3712: 03 8a 75 6a 03 04 83 50 02 01 8b 05 04 82 60 81   ..uj...P......`.
|   3728: 01 08 07 0a 07 09 07 0b 06 07 07 07 0a 0b 0a 07   ................
|   3744: 07 0a 06 07 0a 08 07 07 07 12 09 08 0b 07 08 07   ................
|   3760: 06 07 07 07 07 0a 09 07 0a 08 07 3f 08 07 06 06   ...........?....
|   3776: 08 07 07 09 07 07 0a 4b 07 07 07 07 07 0a 07 07   .......K........
|   3792: 09 07 08 08 08 0a 0b 49 07 07 07 09 07 0b 0a 08   .......I........
|   3808: 07 08 0a 0d 08 48 07 07 08 08 09 07 07 07 09 09   .....H..........
|   3824: 07 07 09 0a 07 07 07 08 0b 0c 0b 08 08 0d 4c 07   ..............L.
|   3840: 07 06 08 07 06 07 07 0a 08 09 09 44 07 09 07 0b   ...........D....
|   3856: 07 07 08 07 06 08 08 09 07 0a 09 41 07 07 07 07   ...........A....
|   3872: 06 07 07 07 0e 09 09 07 0a 07 07 42 08 07 06 07   ...........B....
|   3888: 06 0b 07 08 07 08 06 08 07 08 08 0b 0b 0b 0f 0b   ................
|   3904: 08 07 0a 08 0b 09 07 06 07 07 0c 07 06 07 08 0f   ................
|   3920: 07 0b 07 07 0b 08 08 07 07 08 07 0a 07 07 07 08   ................
|   3936: 07 08 07 06 08 07 09 07 08 08 0e 0b 07 07 07 0b   ................
|   3952: 0a 08 0e 07 06 06 07 07 0c 09 08 07 07 0b 07 07   ................
|   3968: 07 0b 0e 0b 07 07 07 07 0e 06 09 07 09 06 07 0b   ................
|   3984: 07 08 07 08 0a 07 07 07 07 07 07 08 07 07 0b 07   ................
|   4000: 0a 07 0b 07 0b 07 07 06 06 07 07 07 09 07 07 0c   ................
|   4016: 08 09 07 07 07 07 09 07 09 06 0a 08 07 07 08 07   ................
|   4032: 06 07 07 07 07 08 07 07 07 08 07 07 07 0e 08 07   ................
|   4048: 0b 09 0a 07 07 0d 07 0b 07 0a 07 07 07 0e 0a 07   ................
|   4064: 07 07 11 08 06 07 0a 4a 07 07 08 09 07 08 07 08   .......J........
|   4080: 06 07 06 07 07 07 06 07 07 07 08 08 0b 07 06 09   ................
| page 25 offset 98304
|      0: 0d 00 00 00 01 00 29 00 00 29 00 00 00 00 00 00   ......)..)......
|     32: 00 00 00 00 00 00 00 00 00 9f 4f 88 80 80 80 80   ..........O.....
|     48: 06 04 00 bf 22 00 00 0e 17 04 30 cf 8c 70 03 02   ..........0..p..
|     64: 0e 02 01 8d 05 04 82 5c 03 01 63 07 04 84 19 02   ..........c.....
|     80: 01 8e 09 02 66 02 01 93 06 04 83 30 02 01 99 06   ....f......0....
|     96: 04 84 75 04 04 84 07 03 02 c6 a3 05 04 84 01 02   ..u.............
|    112: 01 9b 08 02 42 02 01 9d 07 02 30 03 02 0b 02 01   ....B.....0.....
|    128: 9f 06 04 81 06 03 02 da a9 07 02 66 02 01 a5 09   ...........f....
|    144: 02 0c 02 01 ab 02 04 81 39 02 01 ad 01 02 6d 03   ........9.....m.
|    160: 04 82 62 02 01 b2 0a 04 83 36 02 03 b3 d6 88 07   ..b......6......
|    176: 04 84 78 02 01 b8 05 04 84 02 05 04 81 5d 01 02   ..x..........]..
|    192: d0 b1 0a 02 5f 03 01 7a 03 02 76 02 02 b5 35 08   ...._..z..v...5.
|    208: 04 83 63 03 01 75 07 04 84 35 02 04 b8 71 61 61   ..c..u...5...qaa
|    224: 0a 04 81 6b 02 01 bb 08 04 84 4a 02 01 bd 0a 06   ...k......J.....
|    240: 6f 83 6d 01 02 d1 80 06 04 83 65 02 01 84 07 04   o.m.......e.....
|    256: 82 1b 02 01 85 09 04 82 3f 02 02 86 6f 08 04 82   ........?...o...
|    272: 5f 02 01 88 03 04 81 29 02 01 89 02 04 83 14 08   _......)........
|    288: 04 84 6f 03 01 63 02 04 84 1c 02 01 8a 0a 06 82   ..o..c..........
|    304: 14 2d 03 02 6c 69 04 04 83 57 02 01 8e 07 04 84   .-..li...W......
|    320: 48 02 06 90 e1 91 8f 6a 7a 05 04 83 46 02 03 91   H......jz...F...
|    336: 64 37 03 04 82 01 02 01 93 0a 04 82 1f 02 01 98   d7..............
|    352: 05 04 84 30 02 03 9b 63 66 05 04 81 55 02 05 9f   ...0...cf...U...
|    368: 78 6a d1 87 09 04 81 4d 02 02 a3 78 06 02 07 02   xj.....M...x....
|    384: 04 a5 e1 a9 8f 06 02 10 02 02 af 76 09 04 83 13   ...........v....
|    400: 03 02 7a 33 07 04 84 1f 02 01 b1 05 04 84 0e 02   ..z3............
|    416: 02 b7 71 0a 04 82 7b 02 02 bf 62 0a 04 83 6f 01   ..q.......b...o.
|    432: 04 d2 8b 67 73 06 04 83 2b 02 04 97 e3 86 b2 07   ...gs...+.......
|    448: 04 84 12 02 01 9f 02 04 81 05 03 02 24 02 01 a7   ............$...
|    464: 04 04 84 1f 02 01 a9 04 04 81 47 06 06 23 82 23   ..........G..#.#
|    480: 02 02 b1 78 06 02 43 02 01 b9 02 04 82 44 02 01   ...x..C......D..
|    496: bd 02 04 83 3d 08 04 81 76 02 01 bf 0a 04 85 04   ....=...v.......
|    512: 01 02 d3 8e 06 04 85 02 02 02 8f 68 03 02 75 02   ...........h..u.
|    528: 01 91 08 02 28 02 01 93 05 02 16 02 01 9d 06 04   ....(...........
|    544: 82 5e 02 02 9f 33 06 04 83 78 02 03 a7 6c 78 06   .^...3...x...lx.
|    560: 04 83 33 03 09 da a9 ec 82 b2 e1 87 90 71 06 04   ..3..........q..
|    576: 84 7b 02 01 ab 06 04 83 27 02 01 ad 03 02 72 02   ........'.....r.
|    592: 01 af 03 04 82 0c 02 01 b5 0a 04 81 7d 02 01 bb   ................
|    608: 0a 02 58 03 01 6a 03 04 81 70 01 02 d4 81 04 04   ..X..j...p......
|    624: 84 0d 02 01 85 06 04 81 3d 02 02 8b 35 07 04 83   ........=...5...
|    640: 50 02 02 8d 77 03 02 79 02 01 95 0a 04 84 5c 02   P...w..y........
|    656: 03 97 6a 6c 0a 04 83 7a 02 01 99 09 04 82 26 02   ..jl...z......&.
|    672: 02 9b 71 05 04 82 01 02 02 9d 67 04 04 84 5f 02   ..q.......g..._.
|    688: 01 a7 04 04 82 4a 01 02 d5 a3 0a 04 81 00 03 01   .....J..........
|    704: 39 06 04 81 51 02 01 a5 06 02 5e 03 01 67 02 04   9...Q.....^..g..
|    720: 81 0d 02 01 a9 08 04 84 1e 01 02 75 02 01 aa 04   ...........u....
|    736: 04 81 0a 02 01 ab 03 04 83 21 02 01 ac 06 02 08   .........!......
|    752: 02 01 ad 0a 02 57 02 02 b3 74 0a 04 84 40 02 03   .....W...t...@..
|    768: b4 61 6e 08 04 83 1a 03 02 6d 76 02 04 81 0a 02   .an......mv.....
|    784: 01 ba 06 04 83 51 02 01 bb 03 04 82 61 03 01 67   .....Q......a..g
|    800: 08 04 83 28 02 01 bc 01 02 62 01 02 d6 80 01 04   ...(.....b......
|    816: 84 53 02 02 82 7a 08 02 7f 02 01 83 06 02 50 02   .S...z........P.
|    832: 04 81 32 02 01 86 09 04 82 52 02 01 87 09 04 83   ..2......R......
|    848: 7b 02 01 8c 03 04 83 19 01 03 d7 89 74 0a 04 82   ............t...
|    864: 37 02 01 92 07 04 81 23 02 01 93 0a 04 81 12 02   7......#........
|    880: 01 9a 07 02 58 02 01 9e 03 04 81 19 02 01 a0 0a   ....X...........
|    896: 04 82 5e 03 01 6c 01 02 0a 03 04 78 c2 b9 63 05   ..^..l.....x..c.
|    912: 02 02 02 01 a8 0a 02 07 02 01 ab 01 04 81 01 02   ................
|    928: 03 af c3 b0 05 04 82 4e 02 04 b7 69 c2 be 04 04   .......N...i....
|    944: 84 44 02 05 bd e4 98 a5 6c 03 04 83 51 01 03 d8   .D......l...Q...
|    960: 9c 38 08 04 84 73 02 02 9d 73 0a 04 83 0b 02 01   .8...s...s......
|    976: aa 02 04 84 56 02 02 ab 7a 03 04 82 7f 02 01 ac   ....V...z.......
|    992: 09 04 82 40 02 02 ad 61 03 04 81 14 03 03 c6 8c   ...@...a........
|   1008: 71 09 04 82 56 02 02 b7 69 0a 04 82 5c 02 03 b8   q...V...i.......
|   1024: 66 66 05 04 81 11 03 01 7a 05 04 82 7a 02 01 be   ff......z...z...
|   1040: 05 04 81 2a 02 02 bf 76 0a 02 76 01 02 d9 81 01   ...*...v..v.....
|   1056: 04 83 76 02 01 83 02 02 3c 03 01 36 05 04 81 54   ..v.....<..6...T
|   1072: 02 01 85 09 04 82 73 02 01 86 06 04 84 53 02 03   ......s......S..
|   1088: a7 6a 61 01 04 82 0f 02 01 a8 04 02 38 02 01 b1   .ja.........8...
|   1104: 01 04 83 21 03 03 dc 94 6a 02 02 2b 02 01 b2 07   ...!....j..+....
|   1120: 02 1a 02 01 b6 04 04 82 17 02 01 ba 04 04 83 7b   ................
|   1136: 03 01 71 03 04 82 77 02 01 bd 09 04 84 4f 01 04   ..q...w......O..
|   1152: 82 49 01 07 da 80 e8 b6 8a 67 68 05 04 83 04 02   .I.......gh.....
|   1168: 03 85 d1 9c 06 04 81 59 02 01 8f 05 04 81 2c 02   .......Y......,.
|   1184: 01 93 01 04 83 3d 02 04 9a ed 90 8b 01 04 83 44   .....=.........D
|   1200: 02 02 9c 73 09 04 83 21 02 01 a0 0a 04 85 03 02   ...s...!........
|   1216: 01 a6 05 02 7e 03 04 81 19 02 02 a9 77 05 04 82   ....~.......w...
|   1232: 69 02 01 ac 03 02 4f 04 04 82 76 03 03 67 c2 bc   i.....O...v..g..
|   1248: 07 04 83 38 02 01 b7 03 04 82 5b 02 01 bf 09 02   ...8......[.....
|   1264: 6a 01 02 db 83 08 04 84 55 02 02 93 70 02 04 81   j.......U...p...
|   1280: 47 02 01 a5 05 04 82 12 02 01 a6 01 02 52 01 02   G............R..
|   1296: dc 8e 01 02 6a 02 02 96 6b 06 04 84 29 02 01 9a   ....j...k...)...
|   1312: 05 04 84 05 03 04 82 3e 02 01 9f 09 04 81 64 02   .......>......d.
|   1328: 03 a4 76 77 0a 04 84 0f 02 01 a6 06 04 83 52 02   ..vw..........R.
|   1344: 01 aa 01 04 83 70 02 01 ae 01 04 83 33 01 02 dd   .....p......3...
|   1360: 8c 03 04 82 1f 02 02 90 78 09 04 82 4b 02 01 96   ........x...K...
|   1376: 05 04 81 10 03 01 6c 06 04 83 24 02 02 9c 6a 04   ......l...$...j.
|   1392: 04 82 1b 02 05 a0 79 c9 a8 75 01 02 34 02 01 a8   ......y..u..4...
|   1408: 05 02 2c 02 01 b2 06 04 84 3f 02 02 ba 67 03 02   ..,......?...g..
|   1424: 2f 02 05 bf e0 a6 ad 77 08 02 2f 01 02 de 83 05   /......w../.....
|   1440: 02 65 02 01 84 06 04 81 00 02 01 85 01 04 82 60   .e.............`
|   1456: 01 04 81 57 02 01 8f 03 04 83 3b 02 01 90 03 02   ...W......;.....
|   1472: 7b 02 01 91 07 04 83 5d 02 03 9c 78 61 07 04 81   .......]...xa...
|   1488: 00 02 01 9e 08 04 82 00 02 02 9f 6f 04 04 83 51   ...........o...Q
|   1504: 02 01 a3 04 04 81 2f 02 02 a5 73 0a 04 84 7a 02   ....../...s...z.
|   1520: 02 b1 66 08 04 81 5a 02 02 b7 78 02 02 78 02 01   ..f...Z...x..x..
|   1536: b9 05 04 83 08 02 01 ba 0a 04 84 76 02 01 bb 07   ...........v....
|   1552: 02 5c 02 01 bc 08 02 13 02 01 bf 08 02 2a 01 03   .............*..
|   1568: df 82 66 08 04 82 2c 02 01 87 01 04 83 0a 02 01   ..f...,.........
|   1584: 8d 05 04 84 0c 02 05 91 72 6b 69 61 03 02 45 02   ........rkia..E.
|   1600: 03 97 de a4 09 04 82 6b 02 02 98 62 06 04 81 18   .......k...b....
|   1616: 02 01 a0 0a 04 82 4a 02 01 bf 05 02 39 01 06 e0   ......J.....9...
|   1632: a7 9d 31 76 63 05 04 83 00 02 02 af aa 02 04 81   ..1vc...........
|   1648: 2b 02 03 b7 ae 65 01 04 84 36 02 02 bb 98 0a 04   +....e...6......
|   1664: 82 23 01 04 e1 80 88 63 06 04 83 5c 03 01 a2 04   .#.....c........
|   1680: 02 5c 02 02 85 9b 05 04 81 3e 02 04 8b b3 db 8f   .........>......
|   1696: 07 02 56 02 04 91 b8 64 66 08 04 82 49 02 02 95   ..V....df...I...
|   1712: 9d 08 04 81 4e 03 01 a2 03 04 81 77 02 02 9a a0   ....N......w....
|   1728: 01 04 82 39 02 03 9d 90 69 03 02 41 02 03 a6 9a   ...9....i..A....
|   1744: 68 04 02 4c 02 05 a7 9c c7 ad 6e 06 04 83 7b 02   h..L......n.....
|   1760: 03 a8 b2 38 04 02 5f 02 02 af 88 07 02 19 02 03   ...8.._.........
|   1776: bd 96 71 03 04 81 11 01 03 e2 83 80 05 02 5f 02   ..q..........._.
|   1792: 02 b1 a6 01 04 83 34 01 04 84 06 02 02 b3 9d 01   ......4.........
|   1808: 04 83 0f 02 03 ba 9a 64 01 04 84 4f 01 03 e3 81   .......d...O....
|   1824: 81 0a 02 21 02 02 84 8c 03 04 81 10 02 02 90 a1   ...!............
|   1840: 02 04 81 1b 02 02 9c a3 02 04 82 2e 02 02 a5 89   ................
|   1856: 04 04 82 23 02 02 a6 98 07 04 83 00 02 09 ab a8   ...#............
|   1872: 77 31 63 6a c2 aa 35 04 04 81 38 03 01 aa 01 04   w1cj..5...8.....
|   1888: 82 1e 02 02 ac a4 02 02 37 02 05 b9 8e 70 34 79   ........7....p4y
|   1904: 0a 04 84 30 02 02 bd bf 01 04 83 19 01 05 e4 80   ...0............
|   1920: 83 79 69 04 04 83 15 03 01 bb 01 02 63 02 03 8a   .yi.........c...
|   1936: 8d 36 0a 04 84 57 02 05 8c 88 d0 b1 63 09 04 84   .6...W......c...
|   1952: 49 02 02 90 8e 02 04 84 60 02 02 a1 98 03 04 84   I.......`.......
|   1968: 0f 02 02 b1 a2 08 04 83 30 01 04 e5 85 87 68 02   ........0.....h.
|   1984: 04 84 19 02 03 8a a8 39 0a 02 6e 02 03 8d be 38   .......9..n....8
|   2000: 09 04 81 78 02 04 8f 85 68 30 05 04 84 5a 03 01   ...x....h0...Z..
|   2016: a7 09 04 82 09 02 03 92 8e 7a 04 02 28 02 02 95   .........z..(...
|   2032: 89 01 02 38 03 01 be 07 04 84 4d 02 08 9e 9e f4   ...8......M.....
|   2048: 95 95 98 68 71 07 04 84 13 02 02 9f 9f 04 04 84   ...hq...........
|   2064: 35 02 02 a0 a2 02 02 24 03 05 b4 f0 90 b1 92 0a   5......$........
|   2080: 04 82 15 02 03 a3 a1 64 07 04 84 22 02 02 a6 bb   .......d........
|   2096: 04 04 84 52 02 05 a8 af 75 c2 bd 01 04 81 25 02   ...R....u.....%.
|   2112: 02 aa b3 06 04 81 66 02 03 ae be 7a 0a 02 4d 02   ......f....z..M.
|   2128: 08 af 96 66 6b f3 93 af 8f 04 04 83 02 02 03 bd   ...fk...........
|   2144: aa 6a 07 02 62 01 04 e6 80 83 69 08 04 84 19 02   .j..b.....i.....
|   2160: 02 81 bc 0a 04 81 25 02 04 86 aa 32 75 06 04 82   ......%....2u...
|   2176: 65 02 05 96 b7 69 35 30 07 02 78 02 03 9d 98 73   e....i50..x....s
|   2192: 06 02 7f 02 02 a3 97 02 04 81 7f 02 05 a5 80 e7   ................
|   2208: a0 b6 01 04 81 37 03 01 87 08 04 82 61 02 02 b3   .....7......a...
|   2224: b2 03 04 83 1e 02 02 b8 a0 0a 04 84 2e 02 02 bc   ................
|   2240: af 0a 04 83 71 02 02 bf 91 09 04 84 42 01 03 e7   ....q.......B...
|   2256: 81 b4 07 04 84 5e 02 02 86 8e 01 04 84 2c 02 02   .....^.......,..
|   2272: 8b a9 09 04 82 02 02 03 8d 9d 30 05 04 84 1a 02   ..........0.....
|   2288: 02 8e b6 08 04 83 60 02 02 91 99 0a 04 82 05 02   ......`.........
|   2304: 02 92 af 08 04 81 1c 02 02 94 b9 05 04 81 45 02   ..............E.
|   2320: 02 9c 8f 06 02 14 02 02 9e a2 07 04 83 78 02 02   .............x..
|   2336: a0 83 06 04 83 08 02 02 a1 a8 01 02 78 02 02 ae   ............x...
|   2352: ae 04 04 81 0e 02 02 b5 8c 06 04 84 6c 02 02 bf   ............l...
|   2368: 80 09 04 83 1e 01 04 e8 83 93 73 0a 04 83 57 02   ..........s...W.
|   2384: 02 88 a8 0a 04 84 50 02 02 89 a0 09 04 83 70 02   ......P.......p.
|   2400: 02 8a ad 05 04 83 18 02 02 95 84 04 02 3b 03 01   .............;..
|   2416: b5 06 04 81 26 02 08 a0 91 65 ce bb 6a d7 96 09   ....&....e..j...
|   2432: 04 82 05 02 02 a7 bf 02 04 84 47 02 02 b5 bb 05   ..........G.....
|   2448: 02 0a 02 04 bf 88 6a 6b 03 04 84 2a 01 04 e9 80   ......jk...*....
|   2464: 97 65 09 04 83 26 02 02 9a 89 04 04 83 29 02 02   .e...&.......)..
|   2480: a4 b8 05 04 82 7f 02 05 ba 83 69 76 6c 04 02 3a   ..........ivl..:
|   2496: 03 01 87 03 02 3c 02 02 be b6 06 04 84 25 01 06   .....<.......%..
|   2512: ea 81 98 64 39 79 03 04 84 12 02 02 88 bc 09 04   ...d9y..........
|   2528: 84 40 02 03 8c b5 39 01 04 83 11 02 02 91 ab 05   .@....9.........
|   2544: 04 83 01 02 03 9d 97 63 05 04 83 07 02 02 9e a3   .......c........
|   2560: 04 04 82 04 02 02 ae a3 03 04 81 20 02 02 b2 a1   ........... ....
|   2576: 04 02 66 02 04 b4 9d 65 6b 02 02 29 02 03 ba bd   ..f....ek..)....
|   2592: 72 08 04 83 75 02 03 bc a7 37 09 04 81 55 01 03   r...u....7...U..
|   2608: eb 84 9d 07 02 60 02 06 8f aa 6f 69 6b 68 03 02   .....`....oikh..
|   2624: 29 02 02 92 90 0a 04 81 30 02 04 99 ba 6e 65 02   ).......0....ne.
|   2640: 04 82 1e 02 02 b8 8f 05 04 81 52 02 02 bd 80 08   ..........R.....
|   2656: 04 84 23 02 02 be bc 08 02 2e 02 02 bf bc 01 04   ..#.............
|   2672: 82 6b 01 04 ec 85 b8 76 05 04 81 76 02 03 99 ad   .k.....v...v....
|   2688: 74 07 02 7e 02 02 a3 80 06 04 81 37 02 04 ac a9   t..~.......7....
|   2704: 79 75 01 02 6f 02 02 b9 89 06 02 66 01 03 ed 8a   yu..o......f....
|   2720: 8a 05 02 3f 02 02 96 b6 05 02 63 01 04 ee 8d 91   ...?......c.....
|   2736: 7a 02 04 82 2a 02 02 92 af 03 04 84 06 02 03 98   z...*...........
|   2752: be 78 01 04 81 50 02 03 99 82 71 06 02 13 02 04   .x...P....q.....
|   2768: 9c 8d 68 61 09 04 83 1b 02 02 a4 bd 06 04 82 24   ..ha...........$
|   2784: 02 02 ad a9 06 04 81 5d 02 02 b4 b9 09 04 81 75   .......].......u
|   2800: 02 02 bb 8d 05 04 84 39 01 03 ef af 90 03 04 82   .......9........
|   2816: 3d 03 02 a3 61 03 04 83 02 02 02 b4 ae 0a 04 82   =...a...........
|   2832: 0e 02 02 b5 b1 06 02 47 02 02 b7 a9 02 04 84 42   .......G.......B
|   2848: 01 05 f0 90 8e bf 34 03 04 81 40 03 04 ad b0 33   ......4...@....3
|   2864: 38 05 04 84 19 03 02 ae 89 07 04 81 68 03 03 af   8...........h...
|   2880: b7 61 0a 04 82 2f 02 03 91 81 a7 02 04 81 04 03   .a.../..........
|   2896: 02 89 ac 08 04 83 62 03 02 97 a6 08 04 82 64 03   ......b.......d.
|   2912: 02 af bc 07 04 83 14 03 02 b1 b3 05 04 81 34 03   ..............4.
|   2928: 02 b7 ad 07 04 82 35 03 03 bb 9f 64 07 04 84 4c   ......5....d...L
|   2944: 02 03 92 8d a5 05 04 82 7b 03 03 98 ab 62 09 04   .............b..
|   2960: 81 2f 03 02 b7 99 05 04 82 43 02 04 93 85 98 6b   ./.......C.....k
|   2976: 0a 02 1e 03 02 a9 90 01 04 84 62 03 05 b6 b0 74   ..........b....t
|   2992: c2 b3 07 04 82 55 02 03 95 8e a5 06 04 83 2a 03   .....U........*.
|   3008: 02 96 95 09 04 83 0c 03 02 97 8b 06 04 84 60 03   ..............`.
|   3024: 02 b5 bd 07 04 82 56 03 02 b7 9c 06 04 82 2d 02   ......V.......-.
|   3040: 04 96 a0 80 6e 01 04 83 7f 03 02 a5 ad 03 04 83   ....n...........
|   3056: 3c 03 02 ad ac 07 02 72 02 04 97 87 b5 35 07 02   <......r.....5..
|   3072: 5f 04 01 bc 07 02 53 03 02 8f 90 02 02 70 02 06   _.....S......p..
|   3088: 98 8f 88 73 7a 78 06 02 35 04 01 ba 02 02 23 03   ...szx..5.....#.
|   3104: 06 a2 92 ca 8a 36 6d 07 04 82 06 02 04 99 8b 93   .....6m.........
|   3120: 7a 09 04 84 6b 03 03 8c 82 72 07 04 81 7a 03 02   z...k....r...z..
|   3136: 94 ba 04 04 82 3c 03 02 a1 92 0a 04 84 31 03 02   .....<.......1..
|   3152: a8 b7 08 04 84 16 03 02 b1 ac 03 04 84 28 02 05   .............(..
|   3168: 9a 99 8d d7 b5 01 04 84 65 03 03 9d 86 7a 09 04   ........e....z..
|   3184: 84 07 03 03 ac 80 37 09 04 84 24 02 03 9b 87 93   ......7...$.....
|   3200: 04 04 82 60 03 02 91 8b 05 04 84 6c 03 02 a0 b9   ...`.......l....
|   3216: 05 04 82 13 03 03 a5 81 70 06 04 83 6e 03 02 b6   ........p...n...
|   3232: 9a 03 04 82 00 02 03 9c 8a a3 04 04 83 7e 03 02   .............~..
|   3248: 96 b7 01 04 83 5b 03 02 a8 88 02 04 83 7a 03 03   .....[.......z..
|   3264: a9 98 77 02 04 81 38 03 02 b1 b2 04 02 46 03 03   ..w...8......F..
|   3280: b6 bb 72 03 04 82 1a 03 02 be a9 04 04 83 73 02   ..r...........s.
|   3296: 04 9d 8a 9a 6a 01 02 32 03 02 96 9c 03 02 6f 03   ....j..2......o.
|   3312: 02 a6 b2 04 04 83 35 03 02 b4 a6 05 02 43 03 02   ......5......C..
|   3328: bc 98 05 02 4a 02 03 9e 8f 98 0a 04 81 08 03 03   ....J...........
|   3344: 90 8c 6d 07 04 84 64 03 03 b4 9f 6e 03 04 84 35   ..m...d....n...5
|   3360: 02 04 9f a1 a9 69 07 04 84 43 02 03 a7 85 b6 06   .....i...C......
|   3376: 02 60 02 03 ad ba b7 06 02 2b 02 03 bc b6 b6 01   .`.......+......
|   3392: 04 81 31 01 04 f1 92 a9 98 06 02 0c 03 03 b1 9d   ..1.............
|   3408: 69 08 04 84 65 02 06 9e 91 a5 ea b0 98 07 04 82   i...e...........
|   3424: 43 02 03 a1 b7 be 02 04 81 13 02 03 b4 af 9e 0a   C...............
|   3440: 04 84 1d 02 05 b5 92 84 69 6e 07 04 82 52 01 05   ........in...R..
|   3456: f2 90 9a 83 73 03 04 82 45 02 03 91 ac 81 07 04   ....s...E.......
|   3472: 82 7a 03 02 be 94 02 04 81 46 02 03 94 89 ac 04   .z.......F......
|   3488: 04 81 4a 02 04 95 b4 ae 39 08 04 82 2a 02 05 a0   ..J.....9...*...
|   3504: 90 b5 66 34 04 04 82 46 02 05 a6 91 b7 d5 bf 06   ..f4...F........
|   3520: 04 81 7b 02 03 ab a0 93 05 02 2b 02 04 b2 8c 80   ..........+.....
|   3536: 6a 07 04 84 1a 03 02 9c a9 0a 04 81 36 03 02 aa   j...........6...
|   3552: bf 04 04 84 34 01 05 f3 82 84 8d 66 0a 04 83 75   ....4......f...u
|   3568: 02 03 88 a7 b4 06 04 83 38 02 03 ab bf a6 02 04   ........8.......
|   3584: 81 65 02 05 b0 ae a8 73 70 0a 02 10 02 04 b8 a6   .e.....sp.......
|   3600: b6 75 05 04 83 4e 02 03 bd b2 84 08 04 83 50 01   .u...N........P.
|   3616: 04 f4 82 91 84 06 04 81 6a 02 03 8c b4 be 06 02   ........j.......
|   3632: 24 02 03 9b b2 83 01 04 84 4b 02 03 a0 87 b0 05   $........K......
|   3648: 04 83 2f 03 03 ae ba 61 05 04 82 1b 04 08 07 07   ../....a........
|   3664: 06 07 0b 08 06 09 07 07 06 07 0a 07 09 0b 07 06   ................
|   3680: 08 07 0a 07 08 08 07 07 08 07 0b 07 08 08 07 0c   ................
|   3696: 09 07 07 09 0b 07 09 08 08 07 08 08 0a 0a 0a 07   ................
|   3712: 0c 07 07 0b 07 08 07 06 06 07 08 09 0f 07 06 07   ................
|   3728: 07 06 07 08 07 08 07 07 09 07 08 08 07 08 07 06   ................
|   3744: 07 0a 07 07 06 06 08 09 08 07 07 07 06 08 07 0a   ................
|   3760: 07 07 07 09 07 07 06 07 07 06 09 06 07 09 0a 0b   ................
|   3776: 09 08 07 08 07 08 09 08 09 07 07 07 08 06 07 07   ................
|   3792: 07 09 06 07 08 06 07 07 07 0b 0d 09 07 07 0a 08   ................
|   3808: 07 0a 08 0a 09 07 06 08 08 07 06 07 08 0b 07 09   ................
|   3824: 07 07 07 08 08 07 07 08 0a 06 07 07 0a 07 07 0b   ................
|   3840: 07 06 07 09 07 08 07 08 08 07 07 07 06 06 06 09   ................
|   3856: 07 07 0a 09 08 07 06 0c 08 09 08 0a 06 08 09 0a   ................
|   3872: 08 07 08 08 08 0b 08 07 09 08 0c 08 09 08 08 08   ................
|   3888: 08 08 08 0f 07 07 0b 08 0b 06 09 0b 08 08 08 0a   ................
|   3904: 08 09 0a 07 08 07 07 0e 08 07 0b 09 08 0b 08 08   ................
|   3920: 0e 08 0a 08 0a 0a 08 08 0b 07 08 08 08 08 09 08   ................
|   3936: 08 09 08 08 08 08 07 08 08 07 08 08 08 0a 08 08   ................
|   3952: 08 07 07 0e 08 07 0a 0a 08 08 0a 06 08 0c 08 09   ................
|   3968: 08 09 08 08 07 09 09 09 08 0b 08 0a 08 08 07 08   ................
|   3984: 0a 08 08 09 07 08 07 0a 08 09 08 0a 08 08 08 08   ................
|   4000: 09 08 08 07 08 0b 0a 08 09 09 08 08 08 08 08 09   ................
|   4016: 09 09 08 09 08 0b 09 08 08 08 08 0a 08 07 09 06   ................
|   4032: 07 0b 06 0c 0a 09 08 08 08 08 0b 09 09 09 08 08   ................
|   4048: 09 08 09 08 08 09 07 09 08 09 07 08 07 07 09 09   ................
|   4064: 09 0a 08 08 09 09 09 0c 09 09 0b 0b 09 08 09 0a   ................
|   4080: 0b 0b 08 0a 08 08 0b 09 09 0a 0a 09 0a 08 09 09   ................
| page 26 offset 102400
|      0: 0d 00 00 00 01 0e a7 00 0e a7 00 00 00 00 00 00   ................
|   3744: 00 00 00 00 00 00 00 82 51 88 80 80 80 80 07 04   ........Q.......
|   3760: 00 85 26 00 00 01 2d 05 30 f4 a3 b5 8c 0a 02 1b   ..&...-.0.......
|   3776: 02 03 b4 91 a9 02 04 82 1b 02 04 b7 b5 89 67 06   ..............g.
|   3792: 04 84 2f 01 04 f5 86 a9 bd 01 04 81 13 02 06 91   ../.............
|   3808: be ae ca 9e 78 04 04 81 1d 02 05 99 9b b2 6f 65   ....x.........oe
|   3824: 02 04 84 07 02 03 9e 99 8b 02 02 15 02 03 a1 ab   ................
|   3840: b6 02 04 83 0f 02 03 a3 96 8c 02 04 82 20 02 03   ............. ..
|   3856: ac a3 8d 08 02 55 02 03 b0 80 82 02 04 81 18 02   .....U..........
|   3872: 03 b1 9c bb 08 02 67 02 03 b5 be 81 07 04 83 79   ......g........y
|   3888: 02 04 bf 81 9d 71 07 04 81 7c 01 04 f6 83 ab 80   .....q...|......
|   3904: 01 04 81 2a 02 04 89 8c a8 61 01 04 82 30 02 03   ...*.....a...0..
|   3920: 8e ae 81 07 04 84 05 02 04 8f bd b0 6a 09 04 82   ............j...
|   3936: 1e 02 04 92 95 9c 6c 07 04 82 64 03 02 b4 9f 09   ......l...d.....
|   3952: 04 83 65 02 04 9a a9 9f 34 06 04 83 70 02 03 a4   ..e.....4...p...
|   3968: ad af 01 02 02 02 03 b4 9a 90 07 04 83 5e 01 04   .............^..
|   3984: f7 87 a5 9d 04 04 84 62 02 03 89 83 8e 0a 04 82   .......b........
|   4000: 2e 02 03 98 bd 8e 01 04 84 06 02 03 99 a7 8e 02   ................
|   4016: 04 83 7d 02 03 a0 a1 bb 01 04 81 4e 02 04 a8 86   ...........N....
|   4032: b8 64 0a 02 34 02 03 b2 9a 9e 05 04 83 16 02 04   .d..4...........
|   4048: b4 a7 93 36 06 04 83 7d 03 02 ba 9c 02 04 83 07   ...6............
|   4064: 04 09 09 0a 0a 0c 0b 08 09 09 08 09 08 09 0a 0a   ................
|   4080: 0a 09 0a 0a 08 0a 08 09 0a 09 09 09 09 09 09 0a   ................
| end x.db
}]} {}

do_catchsql_test 74.1 {
  SELECT rowid, quote(matchinfo(t1,'p�xyb<s')) FROM t1 WHERE t1 MATCH 'e*';
} {1 {unable to use function matchinfo in the requested context}}



sqlite3_fts5_may_be_corrupt 0
finish_test

Changes to ext/fts5/test/fts5corrupt4.test.
24
25
26
27
28
29
30


31
32
33
34
35
36
37
do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE ttt USING fts5(a, b); 
  INSERT INTO ttt 
     VALUES('e ee eee e ee eee e ee eee', 'eee ee e e e ee eee ee ee');
  INSERT INTO ttt SELECT a||a, b||b FROM ttt;   
  INSERT INTO ttt SELECT a||a, b||b FROM ttt;   
}



proc mutate {blob i} {
  set o [expr {$i % [string length $blob]}]
  set a [string range $blob 0 $o-1]
  set b [string range $blob $o+1 end]
  set v [expr int(rand()*255) - 127]
  return "$a[binary format c $v]$b"







>
>







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE ttt USING fts5(a, b); 
  INSERT INTO ttt 
     VALUES('e ee eee e ee eee e ee eee', 'eee ee e e e ee eee ee ee');
  INSERT INTO ttt SELECT a||a, b||b FROM ttt;   
  INSERT INTO ttt SELECT a||a, b||b FROM ttt;   
}

expr srand(1)

proc mutate {blob i} {
  set o [expr {$i % [string length $blob]}]
  set a [string range $blob 0 $o-1]
  set b [string range $blob $o+1 end]
  set v [expr int(rand()*255) - 127]
  return "$a[binary format c $v]$b"
Changes to ext/fts5/test/fts5delete.test.
87
88
89
90
91
92
93






94



95











96

  INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 123, 'one');
}

do_catchsql_test 2.4 {
  SELECT rowid FROM test_idx WHERE test_idx MATCH 'two' ORDER BY rank;
} {1 {database disk image is malformed}}























finish_test








>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>

>
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
  INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 123, 'one');
}

do_catchsql_test 2.4 {
  SELECT rowid FROM test_idx WHERE test_idx MATCH 'two' ORDER BY rank;
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 3.0 {
  CREATE VIRTUAL TABLE tx USING fts5(a, b, c, d, content=);
  INSERT INTO tx(rowid, a, c) VALUES(1, 'abc def', 'a b c');
  INSERT INTO tx(rowid, a, c) VALUES(5, 'a b c', 'a b d def');
}
do_execsql_test 3.1 {
  INSERT INTO tx(tx, rowid, a, b, c, d) 
    VALUES('delete', 5, 'a b c', NULL, 'a b d def', NULL);
}
do_execsql_test 3.2 {
  INSERT INTO tx(tx) VALUES('integrity-check');
}
do_execsql_test 3.3 {
  INSERT INTO tx(tx, rowid, a, b, c, d) 
    VALUES('delete', 1, 'abc def', NULL, 'a b c', NULL);
}
do_execsql_test 3.4 {
  INSERT INTO tx(tx) VALUES('integrity-check');
}

finish_test

Added ext/fts5/test/fts5prefix2.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
# 2020 Dec 3
#
# 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 focused on prefix indexes.
#

source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5prefix2

# If SQLITE_ENABLE_FTS5 is defined, omit this file.
ifcapable !fts5 {
  finish_test
  return
}

foreach p {3 2 1} {
  reset_db
    do_execsql_test 1.$p.0 "
    CREATE VIRTUAL TABLE t1 USING fts5(xyz, prefix=$p);
  "
  do_execsql_test 1.$p.1 {
    INSERT INTO t1 VALUES
      ('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 f.');
  }

  do_execsql_test 1.$p.2 {
    SELECT highlight(t1, 0, '[', ']') FROM t1('f*');
  } {
    {May you [find] [forgiveness] [for] yourself and [forgive] others.}
    {May you share [freely], never taking more than you give [f].}
  }
}

do_execsql_test 2.0 {
  CREATE VIRTUAL TABLE t2 USING fts5(one, prefix=3);
  INSERT INTO t2 VALUES('top');
  INSERT INTO t2 VALUES('to');
  INSERT INTO t2 VALUES('tommy');
}

do_execsql_test 2.1 {
  SELECT * FROM t2('to*');
} {top to tommy}



finish_test
Changes to ext/misc/appendvfs.c.
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
**
******************************************************************************
**
** This file implements a VFS shim that allows an SQLite database to be
** appended onto the end of some other file, such as an executable.
**
** A special record must appear at the end of the file that identifies the
** file as an appended database and provides an offset to page 1.  For

** best performance page 1 should be located at a disk page boundary, though
** that is not required.
**
** When opening a database using this VFS, the connection might treat
** the file as an ordinary SQLite database, or it might treat is as a
** database appended onto some other file.  Here are the rules:
**
**  (1)  When opening a new empty file, that file is treated as an ordinary
**       database.
**
**  (2)  When opening a file that begins with the standard SQLite prefix
**       string "SQLite format 3", that file is treated as an ordinary
**       database.
**
**  (3)  When opening a file that ends with the appendvfs trailer string
**       "Start-Of-SQLite3-NNNNNNNN" that file is treated as an appended


**       database.
**
**  (4)  If none of the above apply and the SQLITE_OPEN_CREATE flag is
**       set, then a new database is appended to the already existing file.
**
**  (5)  Otherwise, SQLITE_CANTOPEN is returned.
**
** To avoid unnecessary complications with the PENDING_BYTE, the size of
** the file containing the database is limited to 1GB.  This VFS will refuse
** to read or write past the 1GB mark.  This restriction might be lifted in
** future versions.  For now, if you need a large database, then keep the
** database in a separate file.
**
** If the file being opened is not an appended database, then this shim is
** a pass-through into the default underlying VFS.
**/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <string.h>
#include <assert.h>

/* The append mark at the end of the database is:
**
**     Start-Of-SQLite3-NNNNNNNN
**     123456789 123456789 12345
**
** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is
** the offset to page 1.
*/
#define APND_MARK_PREFIX     "Start-Of-SQLite3-"
#define APND_MARK_PREFIX_SZ  17

#define APND_MARK_SIZE       25

/*
** Maximum size of the combined prefix + database + append-mark.  This
** must be less than 0x40000000 to avoid locking issues on Windows.
*/
#define APND_MAX_SIZE  (65536*15259)








/*
** Forward declaration of objects used by this utility
*/
typedef struct sqlite3_vfs ApndVfs;
typedef struct ApndFile ApndFile;

/* Access to a lower-level VFS that (might) implement dynamic loading,
** access to randomness, etc.
*/
#define ORIGVFS(p)  ((sqlite3_vfs*)((p)->pAppData))
#define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1))









/* An open file */

















struct ApndFile {

  sqlite3_file base;              /* IO methods */

  sqlite3_int64 iPgOne;           /* File offset to page 1 */

  sqlite3_int64 iMark;            /* Start of the append-mark */
};

/*
** Methods for ApndFile
*/
static int apndClose(sqlite3_file*);
static int apndRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);







|
>
|
|


|
|
|
<
<

<
|
<

|
|
>
>
|







|
|
|
|

|
|












|



>
|







>
>
>
>
>
>
>












>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
|
>
|
>
|







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
**
******************************************************************************
**
** This file implements a VFS shim that allows an SQLite database to be
** appended onto the end of some other file, such as an executable.
**
** A special record must appear at the end of the file that identifies the
** file as an appended database and provides the offset to the first page
** of the exposed content. (Or, it is the length of the content prefix.)
** For best performance page 1 should be located at a disk page boundary,
** though that is not required.
**
** When opening a database using this VFS, the connection might treat
** the file as an ordinary SQLite database, or it might treat it as a
** database appended onto some other file.  The decision is made by
** applying the following rules in order:


**

**  (1)  An empty file is an ordinary database.

**
**  (2)  If the file ends with the appendvfs trailer string
**       "Start-Of-SQLite3-NNNNNNNN" that file is an appended database.
**
**  (3)  If the file begins with the standard SQLite prefix string
**       "SQLite format 3", that file is an ordinary database.
**
**  (4)  If none of the above apply and the SQLITE_OPEN_CREATE flag is
**       set, then a new database is appended to the already existing file.
**
**  (5)  Otherwise, SQLITE_CANTOPEN is returned.
**
** To avoid unnecessary complications with the PENDING_BYTE, the size of
** the file containing the database is limited to 1GB. (1000013824 bytes)
** This VFS will not read or write past the 1GB mark.  This restriction
** might be lifted in future versions.  For now, if you need a larger
** database, then keep it in a separate file.
**
** If the file being opened is a plain database (not an appended one), then
** this shim is a pass-through into the default underlying VFS. (rule 3)
**/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <string.h>
#include <assert.h>

/* The append mark at the end of the database is:
**
**     Start-Of-SQLite3-NNNNNNNN
**     123456789 123456789 12345
**
** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is
** the offset to page 1, and also the length of the prefix content.
*/
#define APND_MARK_PREFIX     "Start-Of-SQLite3-"
#define APND_MARK_PREFIX_SZ  17
#define APND_MARK_FOS_SZ      8
#define APND_MARK_SIZE       (APND_MARK_PREFIX_SZ+APND_MARK_FOS_SZ)

/*
** Maximum size of the combined prefix + database + append-mark.  This
** must be less than 0x40000000 to avoid locking issues on Windows.
*/
#define APND_MAX_SIZE  (65536*15259)

/*
** Size of storage page upon which to align appendvfs portion.
*/
#ifndef APND_ROUNDUP_BITS
#define APND_ROUNDUP_BITS 12
#endif

/*
** Forward declaration of objects used by this utility
*/
typedef struct sqlite3_vfs ApndVfs;
typedef struct ApndFile ApndFile;

/* Access to a lower-level VFS that (might) implement dynamic loading,
** access to randomness, etc.
*/
#define ORIGVFS(p)  ((sqlite3_vfs*)((p)->pAppData))
#define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1))

/* Invariants for an open appendvfs file:
 * Once an appendvfs file is opened, it will be in one of three states:
 * State 0: Never written. Underlying file (if any) is unaltered.
 * State 1: Append mark is persisted, content write is in progress.
 * State 2: Append mark is persisted, content writes are complete.
 * 
 * State 0 is persistent in the sense that nothing will have been done
 * to the underlying file, including any attempt to convert it to an
 * appendvfs file.
 *
 * State 1 is normally transitory. However, if a write operation ends
 * abnormally (disk full, power loss, process kill, etc.), then State 1
 * may be persistent on disk with an incomplete content write-out. This
 * is logically equivalent to an interrupted write to an ordinary file,
 * where some unknown portion of to-be-written data is persisted while
 * the remainder is not. Database integrity in such cases is maintained
 * (or not) by the same measures available for ordinary file access.
 *
 * State 2 is persistent under normal circumstances (when there is no
 * abnormal termination of a write operation such that data provided
 * to the underlying VFS write method has not yet reached storage.)
 *
 * In order to maintain the state invariant, the append mark is written
 * in advance of content writes where any part of such content would
 * overwrite an existing (or yet to be written) append mark.
 */
struct ApndFile {
  /* Access to IO methods of the underlying file */
  sqlite3_file base;
  /* File offset to beginning of appended content (unchanging) */
  sqlite3_int64 iPgOne;
  /* File offset of written append-mark, or -1 if unwritten */
  sqlite3_int64 iMark;
};

/*
** Methods for ApndFile
*/
static int apndClose(sqlite3_file*);
static int apndRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
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
  apndShmLock,                    /* xShmLock */
  apndShmBarrier,                 /* xShmBarrier */
  apndShmUnmap,                   /* xShmUnmap */
  apndFetch,                      /* xFetch */
  apndUnfetch                     /* xUnfetch */
};



/*
** Close an apnd-file.
*/
static int apndClose(sqlite3_file *pFile){
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xClose(pFile);
}

/*
** Read data from an apnd-file.
*/
static int apndRead(
  sqlite3_file *pFile, 
  void *zBuf, 
  int iAmt, 
  sqlite_int64 iOfst
){
  ApndFile *p = (ApndFile *)pFile;
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xRead(pFile, zBuf, iAmt, iOfst+p->iPgOne);
}

/*
** Add the append-mark onto the end of the file.


*/
static int apndWriteMark(ApndFile *p, sqlite3_file *pFile){


  int i;


  unsigned char a[APND_MARK_SIZE];



  memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ);
  for(i=0; i<8; i++){

    a[APND_MARK_PREFIX_SZ+i] = (p->iPgOne >> (56 - i*8)) & 0xff;

  }


  return pFile->pMethods->xWrite(pFile, a, APND_MARK_SIZE, p->iMark);



}

/*
** Write data to an apnd-file.
*/
static int apndWrite(
  sqlite3_file *pFile,
  const void *zBuf,
  int iAmt,
  sqlite_int64 iOfst
){
  int rc;
  ApndFile *p = (ApndFile *)pFile;


  pFile = ORIGFILE(pFile);
  if( iOfst+iAmt>=APND_MAX_SIZE ) return SQLITE_FULL;
  rc = pFile->pMethods->xWrite(pFile, zBuf, iAmt, iOfst+p->iPgOne);
  if( rc==SQLITE_OK &&  iOfst + iAmt + p->iPgOne > p->iMark ){
    sqlite3_int64 sz = 0;
    rc = pFile->pMethods->xFileSize(pFile, &sz);
    if( rc==SQLITE_OK ){
      p->iMark = sz - APND_MARK_SIZE;
      if( iOfst + iAmt + p->iPgOne > p->iMark ){
        p->iMark = p->iPgOne + iOfst + iAmt;
        rc = apndWriteMark(p, pFile);
      }
    }
  }
  return rc;
}

/*
** Truncate an apnd-file.
*/
static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){
  int rc;
  ApndFile *p = (ApndFile *)pFile;
  pFile = ORIGFILE(pFile);
  rc = pFile->pMethods->xTruncate(pFile, size+p->iPgOne+APND_MARK_SIZE);
  if( rc==SQLITE_OK ){
    p->iMark = p->iPgOne+size;

    rc = apndWriteMark(p, pFile);
  }
  return rc;


}

/*
** Sync an apnd-file.
*/
static int apndSync(sqlite3_file *pFile, int flags){
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xSync(pFile, flags);
}

/*
** Return the current file-size of an apnd-file.

*/
static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
  ApndFile *p = (ApndFile *)pFile;
  int rc;
  pFile = ORIGFILE(p);
  rc = pFile->pMethods->xFileSize(pFile, pSize);
  if( rc==SQLITE_OK && p->iPgOne ){
    *pSize -= p->iPgOne + APND_MARK_SIZE;
  }
  return rc;
}

/*
** Lock an apnd-file.
*/
static int apndLock(sqlite3_file *pFile, int eLock){
  pFile = ORIGFILE(pFile);







<
<

















|

|



|
>
>

|
>
>
|
>
>

>
>
>

<
>
|
>

>
>
|
>
>
>











<
|
>
>

<
|
|
<
|
|
<
<
<
|
|
<
<
|






<
|

<
<
<
>
|
<
|
>
>












>


|
<
<
<
<
|
<
|







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
  apndShmLock,                    /* xShmLock */
  apndShmBarrier,                 /* xShmBarrier */
  apndShmUnmap,                   /* xShmUnmap */
  apndFetch,                      /* xFetch */
  apndUnfetch                     /* xUnfetch */
};



/*
** Close an apnd-file.
*/
static int apndClose(sqlite3_file *pFile){
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xClose(pFile);
}

/*
** Read data from an apnd-file.
*/
static int apndRead(
  sqlite3_file *pFile, 
  void *zBuf, 
  int iAmt, 
  sqlite_int64 iOfst
){
  ApndFile *paf = (ApndFile *)pFile;
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xRead(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
}

/*
** Add the append-mark onto what should become the end of the file.
*  If and only if this succeeds, internal ApndFile.iMark is updated.
*  Parameter iWriteEnd is the appendvfs-relative offset of the new mark.
*/
static int apndWriteMark(
  ApndFile *paf,
  sqlite3_file *pFile,
  sqlite_int64 iWriteEnd
){
  sqlite_int64 iPgOne = paf->iPgOne;
  unsigned char a[APND_MARK_SIZE];
  int i = APND_MARK_FOS_SZ;
  int rc;
  assert(pFile == ORIGFILE(paf));
  memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ);

  while (--i >= 0) {
    a[APND_MARK_PREFIX_SZ+i] = (unsigned char)(iPgOne & 0xff);
    iPgOne >>= 8;
  }
  iWriteEnd += paf->iPgOne;
  if( SQLITE_OK==(rc = pFile->pMethods->xWrite
                  (pFile, a, APND_MARK_SIZE, iWriteEnd)) ){
    paf->iMark = iWriteEnd;
  }
  return rc;
}

/*
** Write data to an apnd-file.
*/
static int apndWrite(
  sqlite3_file *pFile,
  const void *zBuf,
  int iAmt,
  sqlite_int64 iOfst
){

  ApndFile *paf = (ApndFile *)pFile;
  sqlite_int64 iWriteEnd = iOfst + iAmt;
  if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL;
  pFile = ORIGFILE(pFile);

  /* If append-mark is absent or will be overwritten, write it. */
  if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){

    int rc = apndWriteMark(paf, pFile, iWriteEnd);
    if( SQLITE_OK!=rc )



      return rc;
  }


  return pFile->pMethods->xWrite(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
}

/*
** Truncate an apnd-file.
*/
static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){

  ApndFile *paf = (ApndFile *)pFile;
  pFile = ORIGFILE(pFile);



  /* The append mark goes out first so truncate failure does not lose it. */
  if( SQLITE_OK!=apndWriteMark(paf, pFile, size) )

    return SQLITE_IOERR;
  /* Truncate underlying file just past append mark */
  return pFile->pMethods->xTruncate(pFile, paf->iMark+APND_MARK_SIZE);
}

/*
** Sync an apnd-file.
*/
static int apndSync(sqlite3_file *pFile, int flags){
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xSync(pFile, flags);
}

/*
** Return the current file-size of an apnd-file.
** If the append mark is not yet there, the file-size is 0.
*/
static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
  ApndFile *paf = (ApndFile *)pFile;




  *pSize = ( paf->iMark >= 0 )? (paf->iMark - paf->iPgOne) : 0;

  return SQLITE_OK;
}

/*
** Lock an apnd-file.
*/
static int apndLock(sqlite3_file *pFile, int eLock){
  pFile = ORIGFILE(pFile);
304
305
306
307
308
309
310
311
312
313

314
315
316
317
318
319
320
321
322
323
  return pFile->pMethods->xCheckReservedLock(pFile, pResOut);
}

/*
** File control method. For custom operations on an apnd-file.
*/
static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){
  ApndFile *p = (ApndFile *)pFile;
  int rc;
  pFile = ORIGFILE(pFile);

  rc = pFile->pMethods->xFileControl(pFile, op, pArg);
  if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
    *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", p->iPgOne, *(char**)pArg);
  }
  return rc;
}

/*
** Return the sector-size in bytes for an apnd-file.
*/







|


>


|







340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
  return pFile->pMethods->xCheckReservedLock(pFile, pResOut);
}

/*
** File control method. For custom operations on an apnd-file.
*/
static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){
  ApndFile *paf = (ApndFile *)pFile;
  int rc;
  pFile = ORIGFILE(pFile);
  if( op==SQLITE_FCNTL_SIZE_HINT ) *(sqlite3_int64*)pArg += paf->iPgOne;
  rc = pFile->pMethods->xFileControl(pFile, op, pArg);
  if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
    *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", paf->iPgOne,*(char**)pArg);
  }
  return rc;
}

/*
** Return the sector-size in bytes for an apnd-file.
*/
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
static int apndFetch(
  sqlite3_file *pFile,
  sqlite3_int64 iOfst,
  int iAmt,
  void **pp
){
  ApndFile *p = (ApndFile *)pFile;


  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp);
}

/* Release a memory-mapped page */
static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
  ApndFile *p = (ApndFile *)pFile;
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage);
}

/*
** Check to see if the file is an ordinary SQLite database file.
*/
static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){
  int rc;
  char zHdr[16];
  static const char aSqliteHdr[] = "SQLite format 3";
  if( sz<512 ) return 0;
  rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0);
  if( rc ) return 0;
  return memcmp(zHdr, aSqliteHdr, sizeof(zHdr))==0;
}

/*
** Try to read the append-mark off the end of a file.  Return the
** start of the appended database if the append-mark is present.  If
** there is no append-mark, return -1;




*/
static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){
  int rc, i;
  sqlite3_int64 iMark;

  unsigned char a[APND_MARK_SIZE];

  if( sz<=APND_MARK_SIZE ) return -1;
  rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE);
  if( rc ) return -1;
  if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1;
  iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ]&0x7f))<<56;
  for(i=1; i<8; i++){    

    iMark += (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<(56-8*i);
  }


  return iMark;
}













































/*
** Open an apnd file handle.
*/
static int apndOpen(
  sqlite3_vfs *pVfs,
  const char *zName,
  sqlite3_file *pFile,
  int flags,
  int *pOutFlags
){
  ApndFile *p;
  sqlite3_file *pSubFile;
  sqlite3_vfs *pSubVfs;
  int rc;
  sqlite3_int64 sz;
  pSubVfs = ORIGVFS(pVfs);
  if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){

    return pSubVfs->xOpen(pSubVfs, zName, pFile, flags, pOutFlags);
  }
  p = (ApndFile*)pFile;
  memset(p, 0, sizeof(*p));
  pSubFile = ORIGFILE(pFile);
  pFile->pMethods = &apnd_io_methods;
  rc = pSubVfs->xOpen(pSubVfs, zName, pSubFile, flags, pOutFlags);
  if( rc ) goto apnd_open_done;
  rc = pSubFile->pMethods->xFileSize(pSubFile, &sz);
  if( rc ){
    pSubFile->pMethods->xClose(pSubFile);
    goto apnd_open_done;
  }
  if( apndIsOrdinaryDatabaseFile(sz, pSubFile) ){
    memmove(pFile, pSubFile, pSubVfs->szOsFile);
    return SQLITE_OK;
  }

  p->iMark = 0;
  p->iPgOne = apndReadMark(sz, pFile);
  if( p->iPgOne>0 ){


    return SQLITE_OK;
  }
  if( (flags & SQLITE_OPEN_CREATE)==0 ){
    pSubFile->pMethods->xClose(pSubFile);
    rc = SQLITE_CANTOPEN;
  }





  p->iPgOne = (sz+0xfff) & ~(sqlite3_int64)0xfff;
apnd_open_done:
  if( rc ) pFile->pMethods = 0;
  return rc;
}

/*
** All other VFS methods are pass-thrus.



*/
static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
  return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync);
}




static int apndAccess(
  sqlite3_vfs *pVfs, 
  const char *zPath, 
  int flags, 
  int *pResOut
){
  return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut);







>
>












<
<
<
<
<
<
<
<
<
<
<
<
<

|
|
>
>
>
>




>


|



|
|
>
|

>
>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

















>

















>
|

|
>
>






>
>
>
>
>
|






|
>
>
>




>
>
>
>







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
static int apndFetch(
  sqlite3_file *pFile,
  sqlite3_int64 iOfst,
  int iAmt,
  void **pp
){
  ApndFile *p = (ApndFile *)pFile;
  if( p->iMark < 0 || iOfst+iAmt > p->iMark)
    return SQLITE_IOERR; /* Cannot read what is not yet there. */
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp);
}

/* Release a memory-mapped page */
static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
  ApndFile *p = (ApndFile *)pFile;
  pFile = ORIGFILE(pFile);
  return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage);
}

/*













** Try to read the append-mark off the end of a file.  Return the
** start of the appended database if the append-mark is present.
** If there is no valid append-mark, return -1;
**
** An append-mark is only valid if the NNNNNNNN start-of-database offset
** indicates that the appended database contains at least one page.  The
** start-of-database value must be a multiple of 512.
*/
static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){
  int rc, i;
  sqlite3_int64 iMark;
  int msbs = 8 * (APND_MARK_FOS_SZ-1);
  unsigned char a[APND_MARK_SIZE];

  if( APND_MARK_SIZE!=(sz & 0x1ff) ) return -1;
  rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE);
  if( rc ) return -1;
  if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1;
  iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ] & 0x7f)) << msbs;
  for(i=1; i<8; i++){
    msbs -= 8;
    iMark |= (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<msbs;
  }
  if( iMark > (sz - APND_MARK_SIZE - 512) ) return -1;
  if( iMark & 0x1ff ) return -1;
  return iMark;
}

static const char apvfsSqliteHdr[] = "SQLite format 3";
/*
** Check to see if the file is an appendvfs SQLite database file.
** Return true iff it is such. Parameter sz is the file's size.
*/
static int apndIsAppendvfsDatabase(sqlite3_int64 sz, sqlite3_file *pFile){
  int rc;
  char zHdr[16];
  sqlite3_int64 iMark = apndReadMark(sz, pFile);
  if( iMark>=0 ){
    /* If file has right end-marker, the expected odd size, and the
     * SQLite DB type marker where the end-marker puts it, then it
     * is an appendvfs database (to be treated as such.)
     */
    rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), iMark);
    if( SQLITE_OK==rc && memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))==0
        && (sz & 0x1ff)== APND_MARK_SIZE && sz>=512+APND_MARK_SIZE )
      return 1; /* It's an appendvfs database */
  }
  return 0;
}

/*
** Check to see if the file is an ordinary SQLite database file.
** Return true iff so. Parameter sz is the file's size.
*/
static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){
  char zHdr[16];
  if( apndIsAppendvfsDatabase(sz, pFile) /* rule 2 */
   || (sz & 0x1ff) != 0
   || SQLITE_OK!=pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0)
   || memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))!=0
  ){
    return 0;
  }else{
    return 1;
  }
}

/* Round-up used to get appendvfs portion to begin at a page boundary. */
#define APND_ALIGN_MASK(nbits) ((1<<nbits)-1)
#define APND_START_ROUNDUP(fsz, nbits) \
 ( ((fsz)+APND_ALIGN_MASK(nbits)) & ~(sqlite3_int64)APND_ALIGN_MASK(nbits) )

/*
** Open an apnd file handle.
*/
static int apndOpen(
  sqlite3_vfs *pVfs,
  const char *zName,
  sqlite3_file *pFile,
  int flags,
  int *pOutFlags
){
  ApndFile *p;
  sqlite3_file *pSubFile;
  sqlite3_vfs *pSubVfs;
  int rc;
  sqlite3_int64 sz;
  pSubVfs = ORIGVFS(pVfs);
  if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
    /* The appendvfs is not to be used for transient or temporary databases. */
    return pSubVfs->xOpen(pSubVfs, zName, pFile, flags, pOutFlags);
  }
  p = (ApndFile*)pFile;
  memset(p, 0, sizeof(*p));
  pSubFile = ORIGFILE(pFile);
  pFile->pMethods = &apnd_io_methods;
  rc = pSubVfs->xOpen(pSubVfs, zName, pSubFile, flags, pOutFlags);
  if( rc ) goto apnd_open_done;
  rc = pSubFile->pMethods->xFileSize(pSubFile, &sz);
  if( rc ){
    pSubFile->pMethods->xClose(pSubFile);
    goto apnd_open_done;
  }
  if( apndIsOrdinaryDatabaseFile(sz, pSubFile) ){
    memmove(pFile, pSubFile, pSubVfs->szOsFile);
    return SQLITE_OK;
  }
  /* Record that append mark has not been written until seen otherwise. */
  p->iMark = -1;
  p->iPgOne = apndReadMark(sz, pFile);
  if( p->iPgOne>=0 ){
    /* Append mark was found, infer its offset */
    p->iMark = sz - p->iPgOne - APND_MARK_SIZE;
    return SQLITE_OK;
  }
  if( (flags & SQLITE_OPEN_CREATE)==0 ){
    pSubFile->pMethods->xClose(pSubFile);
    rc = SQLITE_CANTOPEN;
  }
  /* Round newly added appendvfs location to #define'd page boundary. 
   * Note that nothing has yet been written to the underlying file.
   * The append mark will be written along with first content write.
   * Until then, the p->iMark value indicates it is not yet written.
   */
  p->iPgOne = APND_START_ROUNDUP(sz, APND_ROUNDUP_BITS);
apnd_open_done:
  if( rc ) pFile->pMethods = 0;
  return rc;
}

/*
** Delete an apnd file.
** For an appendvfs, this could mean delete the appendvfs portion,
** leaving the appendee as it was before it gained an appendvfs.
** For now, this code deletes the underlying file too.
*/
static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
  return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync);
}

/*
** All other VFS methods are pass-thrus.
*/
static int apndAccess(
  sqlite3_vfs *pVfs, 
  const char *zPath, 
  int flags, 
  int *pResOut
){
  return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut);
Changes to ext/misc/cksumvfs.c.
352
353
354
355
356
357
358



































359
360
361
362
363
364
365
  if( sqlite3_value_type(argv[0])!=SQLITE_BLOB ) return;
  nByte = sqlite3_value_bytes(argv[0]);
  if( nByte<512 || nByte>65536 || (nByte & (nByte-1))!=0 ) return;
  cksmCompute(data, nByte-8, cksum);
  sqlite3_result_int(context, memcmp(data+nByte-8,cksum,8)==0);
}




































/*
** Close a cksm-file.
*/
static int cksmClose(sqlite3_file *pFile){
  CksmFile *p = (CksmFile *)pFile;
  if( p->pPartner ){
    assert( p->pPartner->pPartner==p );







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
  if( sqlite3_value_type(argv[0])!=SQLITE_BLOB ) return;
  nByte = sqlite3_value_bytes(argv[0]);
  if( nByte<512 || nByte>65536 || (nByte & (nByte-1))!=0 ) return;
  cksmCompute(data, nByte-8, cksum);
  sqlite3_result_int(context, memcmp(data+nByte-8,cksum,8)==0);
}

#ifdef SQLITE_CKSUMVFS_INIT_FUNCNAME
/*
** SQL function:    initialize_cksumvfs(SCHEMANAME)
**
** This SQL functions (whose name is actually determined at compile-time
** by the value of the SQLITE_CKSUMVFS_INIT_FUNCNAME macro) invokes:
**
**   sqlite3_file_control(db, SCHEMANAME, SQLITE_FCNTL_RESERVE_BYTE, &n);
**
** In order to set the reserve bytes value to 8, so that cksumvfs will
** operation.  This feature is provided (if and only if the
** SQLITE_CKSUMVFS_INIT_FUNCNAME compile-time option is set to a string
** which is the name of the SQL function) so as to provide the ability
** to invoke the file-control in programming languages that lack
** direct access to the sqlite3_file_control() interface (ex: Java).
**
** This interface is undocumented, apart from this comment.  Usage
** example:
**
**    1.  Compile with -DSQLITE_CKSUMVFS_INIT_FUNCNAME="ckvfs_init"
**    2.  Run:  "SELECT cksum_init('main'); VACUUM;"
*/
static void cksmInitFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int nByte = 8;
  const char *zSchemaName = (const char*)sqlite3_value_text(argv[0]);
  sqlite3 *db = sqlite3_context_db_handle(context);
  sqlite3_file_control(db, zSchemaName, SQLITE_FCNTL_RESERVE_BYTES, &nByte);
  /* Return NULL */
}
#endif /* SQLITE_CKSUMBFS_INIT_FUNCNAME */

/*
** Close a cksm-file.
*/
static int cksmClose(sqlite3_file *pFile){
  CksmFile *p = (CksmFile *)pFile;
  if( p->pPartner ){
    assert( p->pPartner->pPartner==p );
711
712
713
714
715
716
717



718







719
720
721
722
723
724
725
static int cksmCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
  return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
}
static int cksmGetLastError(sqlite3_vfs *pVfs, int a, char *b){
  return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
}
static int cksmCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){



  return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);







}
static int cksmSetSystemCall(
  sqlite3_vfs *pVfs,
  const char *zName,
  sqlite3_syscall_ptr pCall
){
  return ORIGVFS(pVfs)->xSetSystemCall(ORIGVFS(pVfs),zName,pCall);







>
>
>
|
>
>
>
>
>
>
>







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
static int cksmCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
  return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
}
static int cksmGetLastError(sqlite3_vfs *pVfs, int a, char *b){
  return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
}
static int cksmCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
  sqlite3_vfs *pOrig = ORIGVFS(pVfs);
  int rc;
  assert( pOrig->iVersion>=2 );
  if( pOrig->xCurrentTimeInt64 ){
    rc = pOrig->xCurrentTimeInt64(pOrig, p);
  }else{
    double r;
    rc = pOrig->xCurrentTime(pOrig, &r);
    *p = (sqlite3_int64)(r*86400000.0);
  }
  return rc;
}
static int cksmSetSystemCall(
  sqlite3_vfs *pVfs,
  const char *zName,
  sqlite3_syscall_ptr pCall
){
  return ORIGVFS(pVfs)->xSetSystemCall(ORIGVFS(pVfs),zName,pCall);
742
743
744
745
746
747
748





749
750
751
752
753
754
755
  const sqlite3_api_routines *pApi
){
  int rc;
  if( db==0 ) return SQLITE_OK;
  rc = sqlite3_create_function(db, "verify_checksum", 1,
                   SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
                   0, cksmVerifyFunc, 0, 0);





  return rc;
}

/*
** Register the cksum VFS as the default VFS for the system.
** Also make arrangements to automatically register the "verify_checksum()"
** SQL function on each new database connection.







>
>
>
>
>







787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
  const sqlite3_api_routines *pApi
){
  int rc;
  if( db==0 ) return SQLITE_OK;
  rc = sqlite3_create_function(db, "verify_checksum", 1,
                   SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
                   0, cksmVerifyFunc, 0, 0);
#ifdef SQLITE_CKSUMVFS_INIT_FUNCNAME
  (void)sqlite3_create_function(db, SQLITE_CKSUMVFS_INIT_FUNCNAME, 1,
                   SQLITE_UTF8|SQLITE_DIRECTONLY,
                   0, cksmInitFunc, 0, 0);
#endif
  return rc;
}

/*
** Register the cksum VFS as the default VFS for the system.
** Also make arrangements to automatically register the "verify_checksum()"
** SQL function on each new database connection.
Changes to ext/misc/ieee754.c.
163
164
165
166
167
168
169








170
171
172
173
174
175
176
    }
  }else{
    sqlite3_int64 m, e, a;
    double r;
    int isNeg = 0;
    m = sqlite3_value_int64(argv[0]);
    e = sqlite3_value_int64(argv[1]);








    if( m<0 ){
      isNeg = 1;
      m = -m;
      if( m<0 ) return;
    }else if( m==0 && e>-1000 && e<1000 ){
      sqlite3_result_double(context, 0.0);
      return;







>
>
>
>
>
>
>
>







163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
    }
  }else{
    sqlite3_int64 m, e, a;
    double r;
    int isNeg = 0;
    m = sqlite3_value_int64(argv[0]);
    e = sqlite3_value_int64(argv[1]);

    /* Limit the range of e.  Ticket 22dea1cfdb9151e4 2021-03-02 */
    if( e>10000 ){
      e = 10000;
    }else if( e<-10000 ){
      e = -10000;
    }

    if( m<0 ){
      isNeg = 1;
      m = -m;
      if( m<0 ) return;
    }else if( m==0 && e>-1000 && e<1000 ){
      sqlite3_result_double(context, 0.0);
      return;
Changes to ext/misc/series.c.
243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
** is a bitmask showing which constraints are available:
**
**    1:    start=VALUE
**    2:    stop=VALUE
**    4:    step=VALUE
**
** Also, if bit 8 is set, that means that the series should be output
** in descending order rather than in ascending order.

**
** This routine should initialize the cursor and position it so that it
** is pointing at the first row, or pointing off the end of the table
** (so that seriesEof() will return true) if the table is empty.
*/
static int seriesFilter(
  sqlite3_vtab_cursor *pVtabCursor, 







|
>







243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
** is a bitmask showing which constraints are available:
**
**    1:    start=VALUE
**    2:    stop=VALUE
**    4:    step=VALUE
**
** Also, if bit 8 is set, that means that the series should be output
** in descending order rather than in ascending order.  If bit 16 is
** set, then output must appear in ascending order.
**
** This routine should initialize the cursor and position it so that it
** is pointing at the first row, or pointing off the end of the table
** (so that seriesEof() will return true) if the table is empty.
*/
static int seriesFilter(
  sqlite3_vtab_cursor *pVtabCursor, 
269
270
271
272
273
274
275
276





277
278
279
280
281
282
283
  if( idxNum & 2 ){
    pCur->mxValue = sqlite3_value_int64(argv[i++]);
  }else{
    pCur->mxValue = 0xffffffff;
  }
  if( idxNum & 4 ){
    pCur->iStep = sqlite3_value_int64(argv[i++]);
    if( pCur->iStep<1 ) pCur->iStep = 1;





  }else{
    pCur->iStep = 1;
  }
  for(i=0; i<argc; i++){
    if( sqlite3_value_type(argv[i])==SQLITE_NULL ){
      /* If any of the constraints have a NULL value, then return no rows.
      ** See ticket https://www.sqlite.org/src/info/fac496b61722daf2 */







|
>
>
>
>
>







270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
  if( idxNum & 2 ){
    pCur->mxValue = sqlite3_value_int64(argv[i++]);
  }else{
    pCur->mxValue = 0xffffffff;
  }
  if( idxNum & 4 ){
    pCur->iStep = sqlite3_value_int64(argv[i++]);
    if( pCur->iStep==0 ){
      pCur->iStep = 1;
    }else if( pCur->iStep<0 ){
      pCur->iStep = -pCur->iStep;
      if( (idxNum & 16)==0 ) idxNum |= 8;
    }
  }else{
    pCur->iStep = 1;
  }
  for(i=0; i<argc; i++){
    if( sqlite3_value_type(argv[i])==SQLITE_NULL ){
      /* If any of the constraints have a NULL value, then return no rows.
      ** See ticket https://www.sqlite.org/src/info/fac496b61722daf2 */
363
364
365
366
367
368
369
370




371
372
373
374
375
376
377
  }
  if( (idxNum & 3)==3 ){
    /* Both start= and stop= boundaries are available.  This is the 
    ** the preferred case */
    pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0));
    pIdxInfo->estimatedRows = 1000;
    if( pIdxInfo->nOrderBy==1 ){
      if( pIdxInfo->aOrderBy[0].desc ) idxNum |= 8;




      pIdxInfo->orderByConsumed = 1;
    }
  }else{
    /* If either boundary is missing, we have to generate a huge span
    ** of numbers.  Make this case very expensive so that the query
    ** planner will work hard to avoid it. */
    pIdxInfo->estimatedRows = 2147483647;







|
>
>
>
>







369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
  }
  if( (idxNum & 3)==3 ){
    /* Both start= and stop= boundaries are available.  This is the 
    ** the preferred case */
    pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0));
    pIdxInfo->estimatedRows = 1000;
    if( pIdxInfo->nOrderBy==1 ){
      if( pIdxInfo->aOrderBy[0].desc ){
        idxNum |= 8;
      }else{
        idxNum |= 16;
      }
      pIdxInfo->orderByConsumed = 1;
    }
  }else{
    /* If either boundary is missing, we have to generate a huge span
    ** of numbers.  Make this case very expensive so that the query
    ** planner will work hard to avoid it. */
    pIdxInfo->estimatedRows = 2147483647;
Changes to ext/misc/shathree.c.
27
28
29
30
31
32
33


34

35
36
37
38
39
40
41
** 384, or 512, to determine SHA3 hash variant that is computed.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
#include <stdarg.h>


typedef sqlite3_uint64 u64;


/******************************************************************************
** The Hash Engine
*/
/*
** Macros to determine whether the machine is big or little endian,
** and whether or not that determination is run-time or compile-time.







>
>

>







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
** 384, or 512, to determine SHA3 hash variant that is computed.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
#include <stdarg.h>

#ifndef SQLITE_AMALGAMATION
typedef sqlite3_uint64 u64;
#endif /* SQLITE_AMALGAMATION */

/******************************************************************************
** The Hash Engine
*/
/*
** Macros to determine whether the machine is big or little endian,
** and whether or not that determination is run-time or compile-time.
617
618
619
620
621
622
623

624
625
626

627
628
629
630
631
632
633
      sqlite3_finalize(pStmt);
      sqlite3_result_error(context, zMsg, -1);
      sqlite3_free(zMsg);
      return;
    }
    nCol = sqlite3_column_count(pStmt);
    z = sqlite3_sql(pStmt);

    n = (int)strlen(z);
    hash_step_vformat(&cx,"S%d:",n);
    SHA3Update(&cx,(unsigned char*)z,n);


    /* Compute a hash over the result of the query */
    while( SQLITE_ROW==sqlite3_step(pStmt) ){
      SHA3Update(&cx,(const unsigned char*)"R",1);
      for(i=0; i<nCol; i++){
        switch( sqlite3_column_type(pStmt,i) ){
          case SQLITE_NULL: {







>
|
|
|
>







620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
      sqlite3_finalize(pStmt);
      sqlite3_result_error(context, zMsg, -1);
      sqlite3_free(zMsg);
      return;
    }
    nCol = sqlite3_column_count(pStmt);
    z = sqlite3_sql(pStmt);
    if( z ){
      n = (int)strlen(z);
      hash_step_vformat(&cx,"S%d:",n);
      SHA3Update(&cx,(unsigned char*)z,n);
    }

    /* Compute a hash over the result of the query */
    while( SQLITE_ROW==sqlite3_step(pStmt) ){
      SHA3Update(&cx,(const unsigned char*)"R",1);
      for(i=0; i<nCol; i++){
        switch( sqlite3_column_type(pStmt,i) ){
          case SQLITE_NULL: {
Changes to ext/rbu/rbu.c.
178
179
180
181
182
183
184







185
186
187
188
      fprintf(stdout, "%s", zBuf);
      break;

    default:
      fprintf(stderr, "error=%d: %s\n", rc, zErrmsg);
      break;
  }








  sqlite3_free(zErrmsg);
  return (rc==SQLITE_OK || rc==SQLITE_DONE) ? 0 : 1;
}







>
>
>
>
>
>
>




178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
      fprintf(stdout, "%s", zBuf);
      break;

    default:
      fprintf(stderr, "error=%d: %s\n", rc, zErrmsg);
      break;
  }

  if( nStatStep>0 ){
    sqlite3_int64 nUsed;
    sqlite3_int64 nHighwater;
    sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &nUsed, &nHighwater, 0);
    fprintf(stdout, "memory used=%lld highwater=%lld\n", nUsed, nHighwater);
  }

  sqlite3_free(zErrmsg);
  return (rc==SQLITE_OK || rc==SQLITE_DONE) ? 0 : 1;
}
Changes to ext/rbu/sqlite3rbu.c.
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
  int rc = SQLITE_OK;

#ifdef SQLITE_AMALGAMATION
    assert( WAL_CKPT_LOCK==1 );
#endif

  assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );


  if( pRbu && (pRbu->eStage==RBU_STAGE_OAL || pRbu->eStage==RBU_STAGE_MOVE) ){


    /* Magic number 1 is the WAL_CKPT_LOCK lock. Preventing SQLite from
    ** taking this lock also prevents any checkpoints from occurring. 
    ** todo: really, it's not clear why this might occur, as 
    ** wal_autocheckpoint ought to be turned off.  */


    if( ofst==WAL_LOCK_CKPT && n==1 ) rc = SQLITE_BUSY;
  }else{
    int bCapture = 0;
    if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){
      bCapture = 1;
    }

    if( bCapture==0 || 0==(flags & SQLITE_SHM_UNLOCK) ){
      rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
      if( bCapture && rc==SQLITE_OK ){
        pRbu->mLock |= (1 << ofst);
      }
    }
  }

  return rc;
}








>
>
|
>
>
|
<
<
<
>
>






<



|







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
  int rc = SQLITE_OK;

#ifdef SQLITE_AMALGAMATION
    assert( WAL_CKPT_LOCK==1 );
#endif

  assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
  if( pRbu && (
       pRbu->eStage==RBU_STAGE_OAL 
    || pRbu->eStage==RBU_STAGE_MOVE 
    || pRbu->eStage==RBU_STAGE_DONE
  )){
    /* Prevent SQLite from taking a shm-lock on the target file when it 



    ** is supplying heap memory to the upper layer in place of *-shm 
    ** segments. */
    if( ofst==WAL_LOCK_CKPT && n==1 ) rc = SQLITE_BUSY;
  }else{
    int bCapture = 0;
    if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){
      bCapture = 1;
    }

    if( bCapture==0 || 0==(flags & SQLITE_SHM_UNLOCK) ){
      rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
      if( bCapture && rc==SQLITE_OK ){
        pRbu->mLock |= ((1<<n) - 1) << ofst;
      }
    }
  }

  return rc;
}

Changes to ext/session/session2.test.
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

##########################################################################
# End of proc definitions. Start of tests.
##########################################################################

test_reset
do_execsql_test 1.0 { 
  CREATE TABLE t1(a PRIMARY KEY, b);
  INSERT INTO t1 VALUES('i', 'one');
}
do_iterator_test 1.1 t1 {
  DELETE FROM t1 WHERE a = 'i';
  INSERT INTO t1 VALUES('ii', 'two');
} {
  {DELETE t1 0 X. {t i t one} {}} 







|







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

##########################################################################
# End of proc definitions. Start of tests.
##########################################################################

test_reset
do_execsql_test 1.0 { 
  CREATE TABLE t1(a INT PRIMARY KEY, b);
  INSERT INTO t1 VALUES('i', 'one');
}
do_iterator_test 1.1 t1 {
  DELETE FROM t1 WHERE a = 'i';
  INSERT INTO t1 VALUES('ii', 'two');
} {
  {DELETE t1 0 X. {t i t one} {}} 
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
    DELETE FROM t1;
    INSERT INTO t1 VALUES('', NULL);
  }
}

test_reset
do_common_sql {
  CREATE TABLE t1(a PRIMARY KEY, b);
  CREATE TABLE t2(a, b INTEGER PRIMARY KEY);
  CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b));
  CREATE TABLE t4(a, b, PRIMARY KEY(b, a));
}

foreach {tn sql} [string map {%T1% t1 %T2% t2 %T3% t3 %T4% t4} $set_of_tests] {
  do_then_apply_sql $sql







|







180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
    DELETE FROM t1;
    INSERT INTO t1 VALUES('', NULL);
  }
}

test_reset
do_common_sql {
  CREATE TABLE t1(a int PRIMARY KEY, b);
  CREATE TABLE t2(a, b INTEGER PRIMARY KEY);
  CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b));
  CREATE TABLE t4(a, b, PRIMARY KEY(b, a));
}

foreach {tn sql} [string map {%T1% t1 %T2% t2 %T3% t3 %T4% t4} $set_of_tests] {
  do_then_apply_sql $sql
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
#
test_reset
forcedelete test.db3
sqlite3 db3 test.db3
do_test 3.0 {
  execsql {
    ATTACH 'test.db3' AS 'aux';
    CREATE TABLE t1(a, b PRIMARY KEY);
    CREATE TABLE t2(x, y, z);
    CREATE TABLE t3(a);

    CREATE TABLE aux.t1(a PRIMARY KEY, b);
    CREATE TABLE aux.t2(a, b INTEGER PRIMARY KEY);
    CREATE TABLE aux.t3(a, b, c, PRIMARY KEY(a, b));
    CREATE TABLE aux.t4(a, b, PRIMARY KEY(b, a));
  }
  execsql {
    CREATE TABLE t1(a PRIMARY KEY, b);
    CREATE TABLE t2(a, b INTEGER PRIMARY KEY);
    CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b));
    CREATE TABLE t4(a, b, PRIMARY KEY(b, a));
  } db2
} {}

proc xTrace {args} { puts $args }







|



|





|







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
#
test_reset
forcedelete test.db3
sqlite3 db3 test.db3
do_test 3.0 {
  execsql {
    ATTACH 'test.db3' AS 'aux';
    CREATE TABLE t1(a int, b PRIMARY KEY);
    CREATE TABLE t2(x, y, z);
    CREATE TABLE t3(a);

    CREATE TABLE aux.t1(a int PRIMARY KEY, b);
    CREATE TABLE aux.t2(a, b INTEGER PRIMARY KEY);
    CREATE TABLE aux.t3(a, b, c, PRIMARY KEY(a, b));
    CREATE TABLE aux.t4(a, b, PRIMARY KEY(b, a));
  }
  execsql {
    CREATE TABLE t1(a int PRIMARY KEY, b);
    CREATE TABLE t2(a, b INTEGER PRIMARY KEY);
    CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b));
    CREATE TABLE t4(a, b, PRIMARY KEY(b, a));
  } db2
} {}

proc xTrace {args} { puts $args }
583
584
585
586
587
588
589
590
















































591
do_execsql_test 10.2 {
  SELECT enable(0);
  SELECT enable(-1);
  SELECT enable(1);
  SELECT enable(-1);
} {0 0 1 1}
S delete

















































finish_test








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

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
do_execsql_test 10.2 {
  SELECT enable(0);
  SELECT enable(-1);
  SELECT enable(1);
  SELECT enable(-1);
} {0 0 1 1}
S delete

#-------------------------------------------------------------------------
test_reset
do_common_sql {
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d, e, f);
  WITH s(i) AS (
    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<32
  )
  INSERT INTO t1 SELECT NULL, 0, 0, 0, 0, 0 FROM s
}

do_then_apply_sql {
  UPDATE t1 SET                             f=f+1 WHERE a=1;
  UPDATE t1 SET                      e=e+1        WHERE a=2;
  UPDATE t1 SET                      e=e+1, f=f+1 WHERE a=3;
  UPDATE t1 SET               d=d+1               WHERE a=4;
  UPDATE t1 SET               d=d+1,        f=f+1 WHERE a=5;
  UPDATE t1 SET               d=d+1, e=e+1        WHERE a=6;
  UPDATE t1 SET               d=d+1, e=e+1, f=f+1 WHERE a=7;
  UPDATE t1 SET        c=c+1                      WHERE a=8;
  UPDATE t1 SET        c=c+1,               f=f+1 WHERE a=9;
  UPDATE t1 SET        c=c+1,        e=e+1        WHERE a=10;
  UPDATE t1 SET        c=c+1,        e=e+1, f=f+1 WHERE a=11;
  UPDATE t1 SET        c=c+1, d=d+1               WHERE a=12;
  UPDATE t1 SET        c=c+1, d=d+1,        f=f+1 WHERE a=13;
  UPDATE t1 SET        c=c+1, d=d+1, e=e+1        WHERE a=14;
  UPDATE t1 SET        c=c+1, d=d+1, e=e+1, f=f+1 WHERE a=15;
  UPDATE t1 SET d=d+1                             WHERE a=16;
  UPDATE t1 SET d=d+1,                      f=f+1 WHERE a=17;
  UPDATE t1 SET d=d+1,               e=e+1        WHERE a=18;
  UPDATE t1 SET d=d+1,               e=e+1, f=f+1 WHERE a=19;
  UPDATE t1 SET d=d+1,        d=d+1               WHERE a=20;
  UPDATE t1 SET d=d+1,        d=d+1,        f=f+1 WHERE a=21;
  UPDATE t1 SET d=d+1,        d=d+1, e=e+1        WHERE a=22;
  UPDATE t1 SET d=d+1,        d=d+1, e=e+1, f=f+1 WHERE a=23;
  UPDATE t1 SET d=d+1, c=c+1                      WHERE a=24;
  UPDATE t1 SET d=d+1, c=c+1,               f=f+1 WHERE a=25;
  UPDATE t1 SET d=d+1, c=c+1,        e=e+1        WHERE a=26;
  UPDATE t1 SET d=d+1, c=c+1,        e=e+1, f=f+1 WHERE a=27;
  UPDATE t1 SET d=d+1, c=c+1, d=d+1               WHERE a=28;
  UPDATE t1 SET d=d+1, c=c+1, d=d+1,        f=f+1 WHERE a=29;
  UPDATE t1 SET d=d+1, c=c+1, d=d+1, e=e+1        WHERE a=30;
  UPDATE t1 SET d=d+1, c=c+1, d=d+1, e=e+1, f=f+1 WHERE a=31;
}

do_test 11.0 {
  compare_db db db2
} {}

finish_test
Changes to ext/session/sessionH.test.
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
  do_common_sql {
    CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b));
  }
  do_then_apply_sql {
    WITH s(i) AS (
      VALUES(1) UNION ALL SELECT i+1 FROM s WHERe i<10000
    )
    INSERT INTO t1 SELECT 'abcde', randomblob(16), i FROM s;
  }
  compare_db db db2
} {}

#------------------------------------------------------------------------
db2 close
reset_db







|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
  do_common_sql {
    CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b));
  }
  do_then_apply_sql {
    WITH s(i) AS (
      VALUES(1) UNION ALL SELECT i+1 FROM s WHERe i<10000
    )
    INSERT INTO t1 SELECT 'abcde', randomblob(18), i FROM s;
  }
  compare_db db db2
} {}

#------------------------------------------------------------------------
db2 close
reset_db
Added ext/session/sessionmem.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
# 2020 December 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 the SQLite sessions module
# Specifically, for the sqlite3session_memory_used() API.
#

if {![info exists testdir]} {
  set testdir [file join [file dirname [info script]] .. .. test]
} 
source [file join [file dirname [info script]] session_common.tcl]
source $testdir/tester.tcl
ifcapable !session {finish_test; return}

set testprefix sessionmem

do_execsql_test 1.0 {
  CREATE TABLE t1(i INTEGER PRIMARY KEY, x, y);
  CREATE TABLE t2(i INTEGER, x, y, PRIMARY KEY(x, y));
}

do_test 1.1 {
  sqlite3session S db main
  S attach *
} {}

foreach {tn sql eRes} {
  1 { INSERT INTO t1 VALUES(1, 2, 3) } 1
  2 { UPDATE t1 SET x=5 }                    0
  3 { UPDATE t1 SET i=5 }                    1
  4 { DELETE FROM t1 }                       0
  5 { INSERT INTO t1 VALUES(1, 2, 3) }       0
  6 { INSERT INTO t1 VALUES(5, 2, 3) }       0
  7 { INSERT INTO t2 VALUES('a', 'b', 'c') } 1
  8 { INSERT INTO t2 VALUES('d', 'e', 'f') } 1
  9 { UPDATE t2 SET i='e' }                  0
} {
  set mem1 [S memory_used]
  do_test 1.2.$tn.(mu=$mem1) {
    execsql $sql
    set mem2 [S memory_used]
    expr {$mem2 > $mem1}
  } $eRes
}

do_test 1.3 {
  S delete
} {}

finish_test
Added ext/session/sessionnoop.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
# 2021 Februar 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.
#

if {![info exists testdir]} {
  set testdir [file join [file dirname [info script]] .. .. test]
} 
source [file join [file dirname [info script]] session_common.tcl]
source $testdir/tester.tcl
ifcapable !session {finish_test; return}

set testprefix sessionnoop

#-------------------------------------------------------------------------
# Test plan:
#
#   1.*: Test that concatenating changesets cannot produce a noop UPDATE.
#   2.*: Test that rebasing changesets cannot produce a noop UPDATE.
#   3.*: Test that sqlite3changeset_apply() ignores noop UPDATE changes.
#

do_execsql_test 1.0 {
  CREATE TABLE t1(a PRIMARY KEY, b, c, d);
  INSERT INTO t1 VALUES(1, 1, 1, 1);
  INSERT INTO t1 VALUES(2, 2, 2, 2);
  INSERT INTO t1 VALUES(3, 3, 3, 3);
}

proc do_concat_test {tn sql1 sql2 res} {
  uplevel [list do_test $tn [subst -nocommands {
    set C1 [changeset_from_sql {$sql1}]
    set C2 [changeset_from_sql {$sql2}]
    set C3 [sqlite3changeset_concat [set C1] [set C2]]
    set got [list]
    sqlite3session_foreach elem [set C3] { lappend got [set elem] }
    set got
  }] [list {*}$res]]
}

do_concat_test 1.1 {
  UPDATE t1 SET c=c+1;
} {
  UPDATE t1 SET c=c-1;
} {
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
  CREATE TABLE t1(a PRIMARY KEY, b, c);
  INSERT INTO t1 VALUES(1, 1, 1);
  INSERT INTO t1 VALUES(2, 2, 2);
  INSERT INTO t1 VALUES(3, 3, 3);
}

proc do_rebase_test {tn sql_local sql_remote conflict_res expected} {
  proc xConflict {args} [list return $conflict_res]

  uplevel [list \
    do_test $tn [subst -nocommands {
      execsql BEGIN
        set c_remote [changeset_from_sql {$sql_remote}]
      execsql ROLLBACK

      execsql BEGIN
        set c_local [changeset_from_sql {$sql_local}]
        set base [sqlite3changeset_apply_v2 db [set c_remote] xConflict]
      execsql ROLLBACK

      sqlite3rebaser_create R
      R config [set base]
      set res [list]
      sqlite3session_foreach elem [R rebase [set c_local]] { 
        lappend res [set elem] 
      }
      R delete
      set res
    }] [list {*}$expected]
  ]
}

do_rebase_test 2.1 {
  UPDATE t1 SET c=2 WHERE a=1;              -- local
} {
  UPDATE t1 SET c=3 WHERE a=1;              -- remote
} OMIT {
  {UPDATE t1 0 X.. {i 1 {} {} i 3} {{} {} {} {} i 2}}
}

do_rebase_test 2.2 {
  UPDATE t1 SET c=2 WHERE a=1;              -- local
} {
  UPDATE t1 SET c=3 WHERE a=1;              -- remote
} REPLACE {
}

do_rebase_test 2.3.1 {
  UPDATE t1 SET c=4 WHERE a=1;              -- local
} {
  UPDATE t1 SET c=4 WHERE a=1               -- remote
} OMIT {
  {UPDATE t1 0 X.. {i 1 {} {} i 4} {{} {} {} {} i 4}}
}

do_rebase_test 2.3.2 {
  UPDATE t1 SET c=5 WHERE a=1;              -- local
} {
  UPDATE t1 SET c=5 WHERE a=1               -- remote
} REPLACE {
}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 3.0 {
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
  INSERT INTO t1 VALUES(1, 1, 1);
  INSERT INTO t1 VALUES(2, 2, 2);
  INSERT INTO t1 VALUES(3, 3, 3);
  INSERT INTO t1 VALUES(4, 4, 4);
}

# Arg $pkstr contains one character for each column in the table. An
# "X" for PK column, or a "." for a non-PK.
#
proc mk_tbl_header {name pkstr} {
  set ret [binary format H2c 54 [string length $pkstr]]
  foreach i [split $pkstr {}] {
    if {$i=="X"} {
      append ret [binary format H2 01]
    } else {
      if {$i!="."} {error "bad pkstr: $pkstr ($i)"}
      append ret [binary format H2 00]
    }
  }
  append ret $name
  append ret [binary format H2 00]
  set ret
}

proc mk_update_change {args} {
  set ret [binary format H2H2 17 00]
  foreach a $args {
    if {$a==""} {
      append ret [binary format H2 00]
    } else {
      append ret [binary format H2W 01 $a]
    }
  }
  set ret
}

proc xConflict {args} { return "ABORT" }
do_test 3.1 {
  set    C [mk_tbl_header t1 X..]
  append C [mk_update_change    1 {} 1   {} {}  500]
  append C [mk_update_change    2 {} {}  {} {}  {}]
  append C [mk_update_change    3 3  {}  {} 600 {}]
  append C [mk_update_change    4 {} {}  {} {}  {}]

  sqlite3changeset_apply_v2 db $C xConflict
} {}
do_execsql_test 3.2 {
  SELECT * FROM t1
} {
  1 1 500
  2 2 2
  3 600 3
  4 4 4
}






finish_test

Changes to ext/session/sessionwor.test.
65
66
67
68
69
70
71
72


73
74
75
76
77
78
79

foreach {tn wo} {
  1 ""
  2 "WITHOUT ROWID"
} {
  reset_db

  do_execsql_test 2.$tn.0 "CREATE TABLE t1(a INTEGER PRIMARY KEY, b) $wo ;"


  
  do_iterator_test 1.1 t1 {
    INSERT INTO t1 VALUES(1, 'two');
  } {
    {INSERT t1 0 X. {} {i 1 t two}}
  }
  







|
>
>







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

foreach {tn wo} {
  1 ""
  2 "WITHOUT ROWID"
} {
  reset_db

  do_execsql_test 2.$tn.0.1 "CREATE TABLE t1(a INTEGER PRIMARY KEY, b) $wo ;"
  do_execsql_test 2.$tn.0.2 "CREATE TABLE t2(a INTEGER PRIMARY KEY, b) $wo ;"
  do_execsql_test 2.$tn.0.3 "CREATE TABLE t3(a INTEGER PRIMARY KEY, b) $wo ;"
  
  do_iterator_test 1.1 t1 {
    INSERT INTO t1 VALUES(1, 'two');
  } {
    {INSERT t1 0 X. {} {i 1 t two}}
  }
  
90
91
92
93
94
95
96





















97
98
99
100
  }
  
  do_iterator_test 2.$tn.4 t1 {
    DELETE FROM t1;
  } {
    {DELETE t1 0 X. {i 1 t four} {}}
  }





















}

finish_test








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




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
  }
  
  do_iterator_test 2.$tn.4 t1 {
    DELETE FROM t1;
  } {
    {DELETE t1 0 X. {i 1 t four} {}}
  }

  do_execsql_test 2.$tn.5 {
    INSERT INTO t1 VALUES(1, 'one');
    INSERT INTO t1 VALUES(2, 'two');
    INSERT INTO t1 VALUES(3, 'three');
  }

  do_iterator_test 2.$tn.6 t2 {
    INSERT INTO t2 SELECT a, b FROM t1
  } {
    {INSERT t2 0 X. {} {i 1 t one}} 
    {INSERT t2 0 X. {} {i 2 t two}}
    {INSERT t2 0 X. {} {i 3 t three}}
  }
  do_iterator_test 2.$tn.7 t3 {
    INSERT INTO t3 SELECT * FROM t1
  } {
    {INSERT t3 0 X. {} {i 1 t one}} 
    {INSERT t3 0 X. {} {i 2 t two}}
    {INSERT t3 0 X. {} {i 3 t three}}
  }
}

finish_test

Changes to ext/session/sqlite3session.c.
51
52
53
54
55
56
57

58
59
60
61
62
63
64
  char *zDb;                      /* Name of database session is attached to */
  int bEnable;                    /* True if currently recording */
  int bIndirect;                  /* True if all changes are indirect */
  int bAutoAttach;                /* True to auto-attach tables */
  int rc;                         /* Non-zero if an error has occurred */
  void *pFilterCtx;               /* First argument to pass to xTableFilter */
  int (*xTableFilter)(void *pCtx, const char *zTab);

  sqlite3_value *pZeroBlob;       /* Value containing X'' */
  sqlite3_session *pNext;         /* Next session object on same db. */
  SessionTable *pTable;           /* List of attached tables */
  SessionHook hook;               /* APIs to grab new and old data with */
};

/*







>







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
  char *zDb;                      /* Name of database session is attached to */
  int bEnable;                    /* True if currently recording */
  int bIndirect;                  /* True if all changes are indirect */
  int bAutoAttach;                /* True to auto-attach tables */
  int rc;                         /* Non-zero if an error has occurred */
  void *pFilterCtx;               /* First argument to pass to xTableFilter */
  int (*xTableFilter)(void *pCtx, const char *zTab);
  i64 nMalloc;                    /* Number of bytes of data allocated */
  sqlite3_value *pZeroBlob;       /* Value containing X'' */
  sqlite3_session *pNext;         /* Next session object on same db. */
  SessionTable *pTable;           /* List of attached tables */
  SessionHook hook;               /* APIs to grab new and old data with */
};

/*
93
94
95
96
97
98
99

100
101
102
103
104
105
106
** Structure for changeset iterators.
*/
struct sqlite3_changeset_iter {
  SessionInput in;                /* Input buffer or stream */
  SessionBuffer tblhdr;           /* Buffer to hold apValue/zTab/abPK/ */
  int bPatchset;                  /* True if this is a patchset */
  int bInvert;                    /* True to invert changeset */

  int rc;                         /* Iterator error code */
  sqlite3_stmt *pConflict;        /* Points to conflicting row, if any */
  char *zTab;                     /* Current table */
  int nCol;                       /* Number of columns in zTab */
  int op;                         /* Current operation */
  int bIndirect;                  /* True if current change was indirect */
  u8 *abPK;                       /* Primary key array */







>







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
** Structure for changeset iterators.
*/
struct sqlite3_changeset_iter {
  SessionInput in;                /* Input buffer or stream */
  SessionBuffer tblhdr;           /* Buffer to hold apValue/zTab/abPK/ */
  int bPatchset;                  /* True if this is a patchset */
  int bInvert;                    /* True to invert changeset */
  int bSkipEmpty;                 /* Skip noop UPDATE changes */
  int rc;                         /* Iterator error code */
  sqlite3_stmt *pConflict;        /* Points to conflicting row, if any */
  char *zTab;                     /* Current table */
  int nCol;                       /* Number of columns in zTab */
  int op;                         /* Current operation */
  int bIndirect;                  /* True if current change was indirect */
  u8 *abPK;                       /* Primary key array */
434
435
436
437
438
439
440




















441
442
443
444
445
446
447
    if( aBuf ) aBuf[0] = '\0';
  }

  if( pnWrite ) *pnWrite += nByte;
  return SQLITE_OK;
}






















/*
** This macro is used to calculate hash key values for data structures. In
** order to use this macro, the entire data structure must be represented
** as a series of unsigned integers. In order to calculate a hash-key value
** for a data structure represented as three such integers, the macro may
** then be used as follows:







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    if( aBuf ) aBuf[0] = '\0';
  }

  if( pnWrite ) *pnWrite += nByte;
  return SQLITE_OK;
}

/*
** Allocate and return a pointer to a buffer nByte bytes in size. If
** pSession is not NULL, increase the sqlite3_session.nMalloc variable
** by the number of bytes allocated.
*/
static void *sessionMalloc64(sqlite3_session *pSession, i64 nByte){
  void *pRet = sqlite3_malloc64(nByte);
  if( pSession ) pSession->nMalloc += sqlite3_msize(pRet);
  return pRet;
}

/*
** Free buffer pFree, which must have been allocated by an earlier
** call to sessionMalloc64(). If pSession is not NULL, decrease the
** sqlite3_session.nMalloc counter by the number of bytes freed.
*/
static void sessionFree(sqlite3_session *pSession, void *pFree){
  if( pSession ) pSession->nMalloc -= sqlite3_msize(pFree);
  sqlite3_free(pFree);
}

/*
** This macro is used to calculate hash key values for data structures. In
** order to use this macro, the entire data structure must be represented
** as a series of unsigned integers. In order to calculate a hash-key value
** for a data structure represented as three such integers, the macro may
** then be used as follows:
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
** SQLITE_OK.
**
** It is possible that a non-fatal OOM error occurs in this function. In
** that case the hash-table does not grow, but SQLITE_OK is returned anyway.
** Growing the hash table in this case is a performance optimization only,
** it is not required for correct operation.
*/
static int sessionGrowHash(int bPatchset, SessionTable *pTab){




  if( pTab->nChange==0 || pTab->nEntry>=(pTab->nChange/2) ){
    int i;
    SessionChange **apNew;
    sqlite3_int64 nNew = 2*(sqlite3_int64)(pTab->nChange ? pTab->nChange : 128);

    apNew = (SessionChange **)sqlite3_malloc64(sizeof(SessionChange *) * nNew);


    if( apNew==0 ){
      if( pTab->nChange==0 ){
        return SQLITE_ERROR;
      }
      return SQLITE_OK;
    }
    memset(apNew, 0, sizeof(SessionChange *) * nNew);

    for(i=0; i<pTab->nChange; i++){
      SessionChange *p;
      SessionChange *pNext;
      for(p=pTab->apChange[i]; p; p=pNext){
        int bPkOnly = (p->op==SQLITE_DELETE && bPatchset);
        int iHash = sessionChangeHash(pTab, bPkOnly, p->aRecord, nNew);
        pNext = p->pNext;
        p->pNext = apNew[iHash];
        apNew[iHash] = p;
      }
    }

    sqlite3_free(pTab->apChange);
    pTab->nChange = nNew;
    pTab->apChange = apNew;
  }

  return SQLITE_OK;
}








|
>
>
>
>





|
>
>




















|







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
** SQLITE_OK.
**
** It is possible that a non-fatal OOM error occurs in this function. In
** that case the hash-table does not grow, but SQLITE_OK is returned anyway.
** Growing the hash table in this case is a performance optimization only,
** it is not required for correct operation.
*/
static int sessionGrowHash(
  sqlite3_session *pSession,      /* For memory accounting. May be NULL */
  int bPatchset, 
  SessionTable *pTab
){
  if( pTab->nChange==0 || pTab->nEntry>=(pTab->nChange/2) ){
    int i;
    SessionChange **apNew;
    sqlite3_int64 nNew = 2*(sqlite3_int64)(pTab->nChange ? pTab->nChange : 128);

    apNew = (SessionChange**)sessionMalloc64(
        pSession, sizeof(SessionChange*) * nNew
    );
    if( apNew==0 ){
      if( pTab->nChange==0 ){
        return SQLITE_ERROR;
      }
      return SQLITE_OK;
    }
    memset(apNew, 0, sizeof(SessionChange *) * nNew);

    for(i=0; i<pTab->nChange; i++){
      SessionChange *p;
      SessionChange *pNext;
      for(p=pTab->apChange[i]; p; p=pNext){
        int bPkOnly = (p->op==SQLITE_DELETE && bPatchset);
        int iHash = sessionChangeHash(pTab, bPkOnly, p->aRecord, nNew);
        pNext = p->pNext;
        p->pNext = apNew[iHash];
        apNew[iHash] = p;
      }
    }

    sessionFree(pSession, pTab->apChange);
    pTab->nChange = nNew;
    pTab->apChange = apNew;
  }

  return SQLITE_OK;
}

962
963
964
965
966
967
968

969
970
971
972
973
974
975
**     *pazCol = {"w", "x", "y", "z"}
**     *pabPK  = {1, 0, 0, 1}
**
** All returned buffers are part of the same single allocation, which must
** be freed using sqlite3_free() by the caller
*/
static int sessionTableInfo(

  sqlite3 *db,                    /* Database connection */
  const char *zDb,                /* Name of attached database (e.g. "main") */
  const char *zThis,              /* Table name */
  int *pnCol,                     /* OUT: number of columns */
  const char **pzTab,             /* OUT: Copy of zThis */
  const char ***pazCol,           /* OUT: Array of column names for table */
  u8 **pabPK                      /* OUT: Array of booleans - true for PK col */







>







990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
**     *pazCol = {"w", "x", "y", "z"}
**     *pabPK  = {1, 0, 0, 1}
**
** All returned buffers are part of the same single allocation, which must
** be freed using sqlite3_free() by the caller
*/
static int sessionTableInfo(
  sqlite3_session *pSession,      /* For memory accounting. May be NULL */
  sqlite3 *db,                    /* Database connection */
  const char *zDb,                /* Name of attached database (e.g. "main") */
  const char *zThis,              /* Table name */
  int *pnCol,                     /* OUT: number of columns */
  const char **pzTab,             /* OUT: Copy of zThis */
  const char ***pazCol,           /* OUT: Array of column names for table */
  u8 **pabPK                      /* OUT: Array of booleans - true for PK col */
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
    nByte += sqlite3_column_bytes(pStmt, 1);
    nDbCol++;
  }
  rc = sqlite3_reset(pStmt);

  if( rc==SQLITE_OK ){
    nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1);
    pAlloc = sqlite3_malloc64(nByte);
    if( pAlloc==0 ){
      rc = SQLITE_NOMEM;
    }
  }
  if( rc==SQLITE_OK ){
    azCol = (char **)pAlloc;
    pAlloc = (u8 *)&azCol[nDbCol];







|







1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
    nByte += sqlite3_column_bytes(pStmt, 1);
    nDbCol++;
  }
  rc = sqlite3_reset(pStmt);

  if( rc==SQLITE_OK ){
    nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1);
    pAlloc = sessionMalloc64(pSession, nByte);
    if( pAlloc==0 ){
      rc = SQLITE_NOMEM;
    }
  }
  if( rc==SQLITE_OK ){
    azCol = (char **)pAlloc;
    pAlloc = (u8 *)&azCol[nDbCol];
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
    *pabPK = abPK;
    *pnCol = nDbCol;
  }else{
    *pazCol = 0;
    *pabPK = 0;
    *pnCol = 0;
    if( pzTab ) *pzTab = 0;
    sqlite3_free(azCol);
  }
  sqlite3_finalize(pStmt);
  return rc;
}

/*
** This function is only called from within a pre-update handler for a







|







1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
    *pabPK = abPK;
    *pnCol = nDbCol;
  }else{
    *pazCol = 0;
    *pabPK = 0;
    *pnCol = 0;
    if( pzTab ) *pzTab = 0;
    sessionFree(pSession, azCol);
  }
  sqlite3_finalize(pStmt);
  return rc;
}

/*
** This function is only called from within a pre-update handler for a
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
** indicate that updates on this table should be ignored. SessionTable.abPK 
** is set to NULL in this case.
*/
static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){
  if( pTab->nCol==0 ){
    u8 *abPK;
    assert( pTab->azCol==0 || pTab->abPK==0 );
    pSession->rc = sessionTableInfo(pSession->db, pSession->zDb, 
        pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK
    );
    if( pSession->rc==SQLITE_OK ){
      int i;
      for(i=0; i<pTab->nCol; i++){
        if( abPK[i] ){
          pTab->abPK = abPK;







|







1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
** indicate that updates on this table should be ignored. SessionTable.abPK 
** is set to NULL in this case.
*/
static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){
  if( pTab->nCol==0 ){
    u8 *abPK;
    assert( pTab->azCol==0 || pTab->abPK==0 );
    pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb, 
        pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK
    );
    if( pSession->rc==SQLITE_OK ){
      int i;
      for(i=0; i<pTab->nCol; i++){
        if( abPK[i] ){
          pTab->abPK = abPK;
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
  ** number of columns in the table.  */
  if( pTab->nCol!=pSession->hook.xCount(pSession->hook.pCtx) ){
    pSession->rc = SQLITE_SCHEMA;
    return;
  }

  /* Grow the hash table if required */
  if( sessionGrowHash(0, pTab) ){
    pSession->rc = SQLITE_NOMEM;
    return;
  }

  if( pTab->bStat1 ){
    stat1.hook = pSession->hook;
    stat1.pSession = pSession;







|







1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
  ** number of columns in the table.  */
  if( pTab->nCol!=pSession->hook.xCount(pSession->hook.pCtx) ){
    pSession->rc = SQLITE_SCHEMA;
    return;
  }

  /* Grow the hash table if required */
  if( sessionGrowHash(pSession, 0, pTab) ){
    pSession->rc = SQLITE_NOMEM;
    return;
  }

  if( pTab->bStat1 ){
    stat1.hook = pSession->hook;
    stat1.pSession = pSession;
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
        /* This may fail if SQLite value p contains a utf-16 string that must
        ** be converted to utf-8 and an OOM error occurs while doing so. */
        rc = sessionSerializeValue(0, p, &nByte);
        if( rc!=SQLITE_OK ) goto error_out;
      }
  
      /* Allocate the change object */
      pChange = (SessionChange *)sqlite3_malloc64(nByte);
      if( !pChange ){
        rc = SQLITE_NOMEM;
        goto error_out;
      }else{
        memset(pChange, 0, sizeof(SessionChange));
        pChange->aRecord = (u8 *)&pChange[1];
      }







|







1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
        /* This may fail if SQLite value p contains a utf-16 string that must
        ** be converted to utf-8 and an OOM error occurs while doing so. */
        rc = sessionSerializeValue(0, p, &nByte);
        if( rc!=SQLITE_OK ) goto error_out;
      }
  
      /* Allocate the change object */
      pChange = (SessionChange *)sessionMalloc64(pSession, nByte);
      if( !pChange ){
        rc = SQLITE_NOMEM;
        goto error_out;
      }else{
        memset(pChange, 0, sizeof(SessionChange));
        pChange->aRecord = (u8 *)&pChange[1];
      }
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
    /* Check the table schemas match */
    if( rc==SQLITE_OK ){
      int bHasPk = 0;
      int bMismatch = 0;
      int nCol;                   /* Columns in zFrom.zTbl */
      u8 *abPK;
      const char **azCol = 0;
      rc = sessionTableInfo(db, zFrom, zTbl, &nCol, 0, &azCol, &abPK);
      if( rc==SQLITE_OK ){
        if( pTo->nCol!=nCol ){
          bMismatch = 1;
        }else{
          int i;
          for(i=0; i<nCol; i++){
            if( pTo->abPK[i]!=abPK[i] ) bMismatch = 1;







|







1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
    /* Check the table schemas match */
    if( rc==SQLITE_OK ){
      int bHasPk = 0;
      int bMismatch = 0;
      int nCol;                   /* Columns in zFrom.zTbl */
      u8 *abPK;
      const char **azCol = 0;
      rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, &abPK);
      if( rc==SQLITE_OK ){
        if( pTo->nCol!=nCol ){
          bMismatch = 1;
        }else{
          int i;
          for(i=0; i<nCol; i++){
            if( pTo->abPK[i]!=abPK[i] ) bMismatch = 1;
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
  return SQLITE_OK;
}

/*
** Free the list of table objects passed as the first argument. The contents
** of the changed-rows hash tables are also deleted.
*/
static void sessionDeleteTable(SessionTable *pList){
  SessionTable *pNext;
  SessionTable *pTab;

  for(pTab=pList; pTab; pTab=pNext){
    int i;
    pNext = pTab->pNext;
    for(i=0; i<pTab->nChange; i++){
      SessionChange *p;
      SessionChange *pNextChange;
      for(p=pTab->apChange[i]; p; p=pNextChange){
        pNextChange = p->pNext;
        sqlite3_free(p);
      }
    }
    sqlite3_free((char*)pTab->azCol);  /* cast works around VC++ bug */
    sqlite3_free(pTab->apChange);
    sqlite3_free(pTab);
  }
}

/*
** Delete a session object previously allocated using sqlite3session_create().
*/
void sqlite3session_delete(sqlite3_session *pSession){







|











|


|
|
|







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
  return SQLITE_OK;
}

/*
** Free the list of table objects passed as the first argument. The contents
** of the changed-rows hash tables are also deleted.
*/
static void sessionDeleteTable(sqlite3_session *pSession, SessionTable *pList){
  SessionTable *pNext;
  SessionTable *pTab;

  for(pTab=pList; pTab; pTab=pNext){
    int i;
    pNext = pTab->pNext;
    for(i=0; i<pTab->nChange; i++){
      SessionChange *p;
      SessionChange *pNextChange;
      for(p=pTab->apChange[i]; p; p=pNextChange){
        pNextChange = p->pNext;
        sessionFree(pSession, p);
      }
    }
    sessionFree(pSession, (char*)pTab->azCol);  /* cast works around VC++ bug */
    sessionFree(pSession, pTab->apChange);
    sessionFree(pSession, pTab);
  }
}

/*
** Delete a session object previously allocated using sqlite3session_create().
*/
void sqlite3session_delete(sqlite3_session *pSession){
1755
1756
1757
1758
1759
1760
1761
1762
1763

1764

1765
1766
1767
1768
1769
1770
1771
    }
  }
  sqlite3_mutex_leave(sqlite3_db_mutex(db));
  sqlite3ValueFree(pSession->pZeroBlob);

  /* Delete all attached table objects. And the contents of their 
  ** associated hash-tables. */
  sessionDeleteTable(pSession->pTable);


  /* Free the session object itself. */

  sqlite3_free(pSession);
}

/*
** Set a table filter on a Session Object.
*/
void sqlite3session_table_filter(







|

>
|
>







1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
    }
  }
  sqlite3_mutex_leave(sqlite3_db_mutex(db));
  sqlite3ValueFree(pSession->pZeroBlob);

  /* Delete all attached table objects. And the contents of their 
  ** associated hash-tables. */
  sessionDeleteTable(pSession, pSession->pTable);

  /* Assert that all allocations have been freed and then free the 
  ** session object itself. */
  assert( pSession->nMalloc==0 );
  sqlite3_free(pSession);
}

/*
** Set a table filter on a Session Object.
*/
void sqlite3session_table_filter(
1804
1805
1806
1807
1808
1809
1810
1811

1812
1813
1814
1815
1816
1817
1818
    nName = sqlite3Strlen30(zName);
    for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){
      if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ) break;
    }

    if( !pTab ){
      /* Allocate new SessionTable object. */
      pTab = (SessionTable *)sqlite3_malloc64(sizeof(SessionTable) + nName + 1);

      if( !pTab ){
        rc = SQLITE_NOMEM;
      }else{
        /* Populate the new SessionTable object and link it into the list.
        ** The new object must be linked onto the end of the list, not 
        ** simply added to the start of it in order to ensure that tables
        ** appear in the correct order when a changeset or patchset is







|
>







1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
    nName = sqlite3Strlen30(zName);
    for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){
      if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ) break;
    }

    if( !pTab ){
      /* Allocate new SessionTable object. */
      int nByte = sizeof(SessionTable) + nName + 1;
      pTab = (SessionTable*)sessionMalloc64(pSession, nByte);
      if( !pTab ){
        rc = SQLITE_NOMEM;
      }else{
        /* Populate the new SessionTable object and link it into the list.
        ** The new object must be linked onto the end of the list, not 
        ** simply added to the start of it in order to ensure that tables
        ** appear in the correct order when a changeset or patchset is
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
      const char **azCol = 0;     /* Table columns */
      int i;                      /* Used to iterate through hash buckets */
      sqlite3_stmt *pSel = 0;     /* SELECT statement to query table pTab */
      int nRewind = buf.nBuf;     /* Initial size of write buffer */
      int nNoop;                  /* Size of buffer after writing tbl header */

      /* Check the table schema is still Ok. */
      rc = sessionTableInfo(db, pSession->zDb, zName, &nCol, 0, &azCol, &abPK);
      if( !rc && (pTab->nCol!=nCol || memcmp(abPK, pTab->abPK, nCol)) ){
        rc = SQLITE_SCHEMA;
      }

      /* Write a table header */
      sessionAppendTableHdr(&buf, ePatchset, pTab, &rc);








|







2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
      const char **azCol = 0;     /* Table columns */
      int i;                      /* Used to iterate through hash buckets */
      sqlite3_stmt *pSel = 0;     /* SELECT statement to query table pTab */
      int nRewind = buf.nBuf;     /* Initial size of write buffer */
      int nNoop;                  /* Size of buffer after writing tbl header */

      /* Check the table schema is still Ok. */
      rc = sessionTableInfo(0, db, pSession->zDb, zName, &nCol, 0,&azCol,&abPK);
      if( !rc && (pTab->nCol!=nCol || memcmp(abPK, pTab->abPK, nCol)) ){
        rc = SQLITE_SCHEMA;
      }

      /* Write a table header */
      sessionAppendTableHdr(&buf, ePatchset, pTab, &rc);

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
  for(pTab=pSession->pTable; pTab && ret==0; pTab=pTab->pNext){
    ret = (pTab->nEntry>0);
  }
  sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));

  return (ret==0);
}








/*
** Do the work for either sqlite3changeset_start() or start_strm().
*/
static int sessionChangesetStart(
  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
  int (*xInput)(void *pIn, void *pData, int *pnData),
  void *pIn,
  int nChangeset,                 /* Size of buffer pChangeset in bytes */
  void *pChangeset,               /* Pointer to buffer containing changeset */
  int bInvert                     /* True to invert changeset */

){
  sqlite3_changeset_iter *pRet;   /* Iterator to return */
  int nByte;                      /* Number of bytes to allocate for iterator */

  assert( xInput==0 || (pChangeset==0 && nChangeset==0) );

  /* Zero the output variable in case an error occurs. */
  *pp = 0;

  /* Allocate and initialize the iterator structure. */
  nByte = sizeof(sqlite3_changeset_iter);
  pRet = (sqlite3_changeset_iter *)sqlite3_malloc(nByte);
  if( !pRet ) return SQLITE_NOMEM;
  memset(pRet, 0, sizeof(sqlite3_changeset_iter));
  pRet->in.aData = (u8 *)pChangeset;
  pRet->in.nData = nChangeset;
  pRet->in.xInput = xInput;
  pRet->in.pIn = pIn;
  pRet->in.bEof = (xInput ? 0 : 1);
  pRet->bInvert = bInvert;


  /* Populate the output variable and return success. */
  *pp = pRet;
  return SQLITE_OK;
}

/*
** Create an iterator used to iterate through the contents of a changeset.
*/
int sqlite3changeset_start(
  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
  int nChangeset,                 /* Size of buffer pChangeset in bytes */
  void *pChangeset                /* Pointer to buffer containing changeset */
){
  return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0);
}
int sqlite3changeset_start_v2(
  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
  int nChangeset,                 /* Size of buffer pChangeset in bytes */
  void *pChangeset,               /* Pointer to buffer containing changeset */
  int flags
){
  int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
  return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert);
}

/*
** Streaming version of sqlite3changeset_start().
*/
int sqlite3changeset_start_strm(
  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
  int (*xInput)(void *pIn, void *pData, int *pnData),
  void *pIn
){
  return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0);
}
int sqlite3changeset_start_v2_strm(
  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
  int (*xInput)(void *pIn, void *pData, int *pnData),
  void *pIn,
  int flags
){
  int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
  return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert);
}

/*
** If the SessionInput object passed as the only argument is a streaming
** object and the buffer is full, discard some data to free up space.
*/
static void sessionDiscardData(SessionInput *pIn){







>
>
>
>
>
>
>










|
>




















>














|








|










|








|







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
  for(pTab=pSession->pTable; pTab && ret==0; pTab=pTab->pNext){
    ret = (pTab->nEntry>0);
  }
  sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db));

  return (ret==0);
}

/*
** Return the amount of heap memory in use.
*/
sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession){
  return pSession->nMalloc;
}

/*
** Do the work for either sqlite3changeset_start() or start_strm().
*/
static int sessionChangesetStart(
  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
  int (*xInput)(void *pIn, void *pData, int *pnData),
  void *pIn,
  int nChangeset,                 /* Size of buffer pChangeset in bytes */
  void *pChangeset,               /* Pointer to buffer containing changeset */
  int bInvert,                    /* True to invert changeset */
  int bSkipEmpty                  /* True to skip empty UPDATE changes */
){
  sqlite3_changeset_iter *pRet;   /* Iterator to return */
  int nByte;                      /* Number of bytes to allocate for iterator */

  assert( xInput==0 || (pChangeset==0 && nChangeset==0) );

  /* Zero the output variable in case an error occurs. */
  *pp = 0;

  /* Allocate and initialize the iterator structure. */
  nByte = sizeof(sqlite3_changeset_iter);
  pRet = (sqlite3_changeset_iter *)sqlite3_malloc(nByte);
  if( !pRet ) return SQLITE_NOMEM;
  memset(pRet, 0, sizeof(sqlite3_changeset_iter));
  pRet->in.aData = (u8 *)pChangeset;
  pRet->in.nData = nChangeset;
  pRet->in.xInput = xInput;
  pRet->in.pIn = pIn;
  pRet->in.bEof = (xInput ? 0 : 1);
  pRet->bInvert = bInvert;
  pRet->bSkipEmpty = bSkipEmpty;

  /* Populate the output variable and return success. */
  *pp = pRet;
  return SQLITE_OK;
}

/*
** Create an iterator used to iterate through the contents of a changeset.
*/
int sqlite3changeset_start(
  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
  int nChangeset,                 /* Size of buffer pChangeset in bytes */
  void *pChangeset                /* Pointer to buffer containing changeset */
){
  return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0, 0);
}
int sqlite3changeset_start_v2(
  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
  int nChangeset,                 /* Size of buffer pChangeset in bytes */
  void *pChangeset,               /* Pointer to buffer containing changeset */
  int flags
){
  int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
  return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert, 0);
}

/*
** Streaming version of sqlite3changeset_start().
*/
int sqlite3changeset_start_strm(
  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
  int (*xInput)(void *pIn, void *pData, int *pnData),
  void *pIn
){
  return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0, 0);
}
int sqlite3changeset_start_v2_strm(
  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
  int (*xInput)(void *pIn, void *pData, int *pnData),
  void *pIn,
  int flags
){
  int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
  return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert, 0);
}

/*
** If the SessionInput object passed as the only argument is a streaming
** object and the buffer is full, discard some data to free up space.
*/
static void sessionDiscardData(SessionInput *pIn){
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
** If an error occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
** The apOut[] array may have been partially populated in this case.
*/
static int sessionReadRecord(
  SessionInput *pIn,              /* Input data */
  int nCol,                       /* Number of values in record */
  u8 *abPK,                       /* Array of primary key flags, or NULL */
  sqlite3_value **apOut           /* Write values to this array */

){
  int i;                          /* Used to iterate through columns */
  int rc = SQLITE_OK;



  for(i=0; i<nCol && rc==SQLITE_OK; i++){
    int eType = 0;                /* Type of value (SQLITE_NULL, TEXT etc.) */
    if( abPK && abPK[i]==0 ) continue;
    rc = sessionInputBuffer(pIn, 9);
    if( rc==SQLITE_OK ){
      if( pIn->iNext>=pIn->nData ){
        rc = SQLITE_CORRUPT_BKPT;
      }else{
        eType = pIn->aData[pIn->iNext++];
        assert( apOut[i]==0 );
        if( eType ){

          apOut[i] = sqlite3ValueNew(0);
          if( !apOut[i] ) rc = SQLITE_NOMEM;
        }
      }
    }

    if( rc==SQLITE_OK ){







|
>




>
>











>







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
** If an error occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
** The apOut[] array may have been partially populated in this case.
*/
static int sessionReadRecord(
  SessionInput *pIn,              /* Input data */
  int nCol,                       /* Number of values in record */
  u8 *abPK,                       /* Array of primary key flags, or NULL */
  sqlite3_value **apOut,          /* Write values to this array */
  int *pbEmpty
){
  int i;                          /* Used to iterate through columns */
  int rc = SQLITE_OK;

  assert( pbEmpty==0 || *pbEmpty==0 );
  if( pbEmpty ) *pbEmpty = 1;
  for(i=0; i<nCol && rc==SQLITE_OK; i++){
    int eType = 0;                /* Type of value (SQLITE_NULL, TEXT etc.) */
    if( abPK && abPK[i]==0 ) continue;
    rc = sessionInputBuffer(pIn, 9);
    if( rc==SQLITE_OK ){
      if( pIn->iNext>=pIn->nData ){
        rc = SQLITE_CORRUPT_BKPT;
      }else{
        eType = pIn->aData[pIn->iNext++];
        assert( apOut[i]==0 );
        if( eType ){
          if( pbEmpty ) *pbEmpty = 0;
          apOut[i] = sqlite3ValueNew(0);
          if( !apOut[i] ) rc = SQLITE_NOMEM;
        }
      }
    }

    if( rc==SQLITE_OK ){
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
    p->abPK = (u8*)&p->apValue[p->nCol*2];
    p->zTab = p->abPK ? (char*)&p->abPK[p->nCol] : 0;
  }
  return (p->rc = rc);
}

/*
** Advance the changeset iterator to the next change.
**
** If both paRec and pnRec are NULL, then this function works like the public
** API sqlite3changeset_next(). If SQLITE_ROW is returned, then the
** sqlite3changeset_new() and old() APIs may be used to query for values.
**
** Otherwise, if paRec and pnRec are not NULL, then a pointer to the change
** record is written to *paRec before returning and the number of bytes in
** the record to *pnRec.

**
** Either way, this function returns SQLITE_ROW if the iterator is 
** successfully advanced to the next change in the changeset, an SQLite 
** error code if an error occurs, or SQLITE_DONE if there are no further 
** changes in the changeset.
*/
static int sessionChangesetNext(
  sqlite3_changeset_iter *p,      /* Changeset iterator */
  u8 **paRec,                     /* If non-NULL, store record pointer here */
  int *pnRec,                     /* If non-NULL, store size of record here */
  int *pbNew                      /* If non-NULL, true if new table */

){
  int i;
  u8 op;

  assert( (paRec==0 && pnRec==0) || (paRec && pnRec) );


  /* If the iterator is in the error-state, return immediately. */
  if( p->rc!=SQLITE_OK ) return p->rc;

  /* Free the current contents of p->apValue[], if any. */
  if( p->apValue ){
    for(i=0; i<p->nCol*2; i++){







|
<
|
<
<

|
<
<
>

|
<
<
|

|



|
>





>







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
    p->abPK = (u8*)&p->apValue[p->nCol*2];
    p->zTab = p->abPK ? (char*)&p->abPK[p->nCol] : 0;
  }
  return (p->rc = rc);
}

/*
** Advance the changeset iterator to the next change. The differences between

** this function and sessionChangesetNext() are that


**
**   * If pbEmpty is not NULL and the change is a no-op UPDATE (an UPDATE


**     that modifies no columns), this function sets (*pbEmpty) to 1.
**
**   * If the iterator is configured to skip no-op UPDATEs,


**     sessionChangesetNext() does that. This function does not.
*/
static int sessionChangesetNextOne(
  sqlite3_changeset_iter *p,      /* Changeset iterator */
  u8 **paRec,                     /* If non-NULL, store record pointer here */
  int *pnRec,                     /* If non-NULL, store size of record here */
  int *pbNew,                     /* If non-NULL, true if new table */
  int *pbEmpty
){
  int i;
  u8 op;

  assert( (paRec==0 && pnRec==0) || (paRec && pnRec) );
  assert( pbEmpty==0 || *pbEmpty==0 );

  /* If the iterator is in the error-state, return immediately. */
  if( p->rc!=SQLITE_OK ) return p->rc;

  /* Free the current contents of p->apValue[], if any. */
  if( p->apValue ){
    for(i=0; i<p->nCol*2; i++){
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
  }else{
    sqlite3_value **apOld = (p->bInvert ? &p->apValue[p->nCol] : p->apValue);
    sqlite3_value **apNew = (p->bInvert ? p->apValue : &p->apValue[p->nCol]);

    /* If this is an UPDATE or DELETE, read the old.* record. */
    if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){
      u8 *abPK = p->bPatchset ? p->abPK : 0;
      p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld);
      if( p->rc!=SQLITE_OK ) return p->rc;
    }

    /* If this is an INSERT or UPDATE, read the new.* record. */
    if( p->op!=SQLITE_DELETE ){
      p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew);
      if( p->rc!=SQLITE_OK ) return p->rc;
    }

    if( (p->bPatchset || p->bInvert) && p->op==SQLITE_UPDATE ){
      /* If this is an UPDATE that is part of a patchset, then all PK and
      ** modified fields are present in the new.* record. The old.* record
      ** is currently completely empty. This block shifts the PK fields from







|





|







3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
  }else{
    sqlite3_value **apOld = (p->bInvert ? &p->apValue[p->nCol] : p->apValue);
    sqlite3_value **apNew = (p->bInvert ? p->apValue : &p->apValue[p->nCol]);

    /* If this is an UPDATE or DELETE, read the old.* record. */
    if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){
      u8 *abPK = p->bPatchset ? p->abPK : 0;
      p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld, 0);
      if( p->rc!=SQLITE_OK ) return p->rc;
    }

    /* If this is an INSERT or UPDATE, read the new.* record. */
    if( p->op!=SQLITE_DELETE ){
      p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew, pbEmpty);
      if( p->rc!=SQLITE_OK ) return p->rc;
    }

    if( (p->bPatchset || p->bInvert) && p->op==SQLITE_UPDATE ){
      /* If this is an UPDATE that is part of a patchset, then all PK and
      ** modified fields are present in the new.* record. The old.* record
      ** is currently completely empty. This block shifts the PK fields from
3113
3114
3115
3116
3117
3118
3119































3120
3121
3122
3123
3124
3125
3126
      if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE;
      else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT;
    }
  }

  return SQLITE_ROW;
}
































/*
** Advance an iterator created by sqlite3changeset_start() to the next
** change in the changeset. This function may return SQLITE_ROW, SQLITE_DONE
** or SQLITE_CORRUPT.
**
** This function may not be called on iterators passed to a conflict handler







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
      if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE;
      else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT;
    }
  }

  return SQLITE_ROW;
}

/*
** Advance the changeset iterator to the next change.
**
** If both paRec and pnRec are NULL, then this function works like the public
** API sqlite3changeset_next(). If SQLITE_ROW is returned, then the
** sqlite3changeset_new() and old() APIs may be used to query for values.
**
** Otherwise, if paRec and pnRec are not NULL, then a pointer to the change
** record is written to *paRec before returning and the number of bytes in
** the record to *pnRec.
**
** Either way, this function returns SQLITE_ROW if the iterator is 
** successfully advanced to the next change in the changeset, an SQLite 
** error code if an error occurs, or SQLITE_DONE if there are no further 
** changes in the changeset.
*/
static int sessionChangesetNext(
  sqlite3_changeset_iter *p,      /* Changeset iterator */
  u8 **paRec,                     /* If non-NULL, store record pointer here */
  int *pnRec,                     /* If non-NULL, store size of record here */
  int *pbNew                      /* If non-NULL, true if new table */
){
  int bEmpty;
  int rc;
  do {
    bEmpty = 0;
    rc = sessionChangesetNextOne(p, paRec, pnRec, pbNew, &bEmpty);
  }while( rc==SQLITE_ROW && p->bSkipEmpty && bEmpty);
  return rc;
}

/*
** Advance an iterator created by sqlite3changeset_start() to the next
** change in the changeset. This function may return SQLITE_ROW, SQLITE_DONE
** or SQLITE_CORRUPT.
**
** This function may not be called on iterators passed to a conflict handler
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402

        /* Write the header for the new UPDATE change. Same as the original. */
        sessionAppendByte(&sOut, eType, &rc);
        sessionAppendByte(&sOut, pInput->aData[pInput->iNext+1], &rc);

        /* Read the old.* and new.* records for the update change. */
        pInput->iNext += 2;
        rc = sessionReadRecord(pInput, nCol, 0, &apVal[0]);
        if( rc==SQLITE_OK ){
          rc = sessionReadRecord(pInput, nCol, 0, &apVal[nCol]);
        }

        /* Write the new old.* record. Consists of the PK columns from the
        ** original old.* record, and the other values from the original
        ** new.* record. */
        for(iCol=0; iCol<nCol; iCol++){
          sqlite3_value *pVal = apVal[iCol + (abPK[iCol] ? 0 : nCol)];







|

|







3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474

        /* Write the header for the new UPDATE change. Same as the original. */
        sessionAppendByte(&sOut, eType, &rc);
        sessionAppendByte(&sOut, pInput->aData[pInput->iNext+1], &rc);

        /* Read the old.* and new.* records for the update change. */
        pInput->iNext += 2;
        rc = sessionReadRecord(pInput, nCol, 0, &apVal[0], 0);
        if( rc==SQLITE_OK ){
          rc = sessionReadRecord(pInput, nCol, 0, &apVal[nCol], 0);
        }

        /* Write the new old.* record. Consists of the PK columns from the
        ** original old.* record, and the other values from the original
        ** new.* record. */
        for(iCol=0; iCol<nCol; iCol++){
          sqlite3_value *pVal = apVal[iCol + (abPK[iCol] ? 0 : nCol)];
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
  sInput.pIn = pIn;

  rc = sessionChangesetInvert(&sInput, xOutput, pOut, 0, 0);
  sqlite3_free(sInput.buf.aBuf);
  return rc;
}









typedef struct SessionApplyCtx SessionApplyCtx;
struct SessionApplyCtx {
  sqlite3 *db;
  sqlite3_stmt *pDelete;          /* DELETE statement */
  sqlite3_stmt *pUpdate;          /* UPDATE statement */
  sqlite3_stmt *pInsert;          /* INSERT statement */
  sqlite3_stmt *pSelect;          /* SELECT statement */
  int nCol;                       /* Size of azCol[] and abPK[] arrays */
  const char **azCol;             /* Array of column names */
  u8 *abPK;                       /* Boolean array - true if column is in PK */


  int bStat1;                     /* True if table is sqlite_stat1 */
  int bDeferConstraints;          /* True to defer constraints */
  int bInvertConstraints;         /* Invert when iterating constraints buffer */
  SessionBuffer constraints;      /* Deferred constraints are stored here */
  SessionBuffer rebase;           /* Rebase information (if any) here */
  u8 bRebaseStarted;              /* If table header is already in rebase */
  u8 bRebase;                     /* True to collect rebase information */
};


































































































































































/*
** Formulate a statement to DELETE a row from database db. Assuming a table
** structure like this:
**
**     CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
**







>
>
>
>
>
>
>
>




<





>
>








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
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
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
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
  sInput.pIn = pIn;

  rc = sessionChangesetInvert(&sInput, xOutput, pOut, 0, 0);
  sqlite3_free(sInput.buf.aBuf);
  return rc;
}


typedef struct SessionUpdate SessionUpdate;
struct SessionUpdate {
  sqlite3_stmt *pStmt;
  u32 *aMask;
  SessionUpdate *pNext;
};

typedef struct SessionApplyCtx SessionApplyCtx;
struct SessionApplyCtx {
  sqlite3 *db;
  sqlite3_stmt *pDelete;          /* DELETE statement */

  sqlite3_stmt *pInsert;          /* INSERT statement */
  sqlite3_stmt *pSelect;          /* SELECT statement */
  int nCol;                       /* Size of azCol[] and abPK[] arrays */
  const char **azCol;             /* Array of column names */
  u8 *abPK;                       /* Boolean array - true if column is in PK */
  u32 *aUpdateMask;               /* Used by sessionUpdateFind */
  SessionUpdate *pUp;
  int bStat1;                     /* True if table is sqlite_stat1 */
  int bDeferConstraints;          /* True to defer constraints */
  int bInvertConstraints;         /* Invert when iterating constraints buffer */
  SessionBuffer constraints;      /* Deferred constraints are stored here */
  SessionBuffer rebase;           /* Rebase information (if any) here */
  u8 bRebaseStarted;              /* If table header is already in rebase */
  u8 bRebase;                     /* True to collect rebase information */
};

/* Number of prepared UPDATE statements to cache. */
#define SESSION_UPDATE_CACHE_SZ 12

/*
** Find a prepared UPDATE statement suitable for the UPDATE step currently
** being visited by the iterator. The UPDATE is of the form:
**
**   UPDATE tbl SET col = ?, col2 = ? WHERE pk1 IS ? AND pk2 IS ?
*/
static int sessionUpdateFind(
  sqlite3_changeset_iter *pIter,
  SessionApplyCtx *p,
  int bPatchset,
  sqlite3_stmt **ppStmt
){
  int rc = SQLITE_OK;
  SessionUpdate *pUp = 0;
  int nCol = pIter->nCol;
  int nU32 = (pIter->nCol+33)/32;
  int ii;

  if( p->aUpdateMask==0 ){
    p->aUpdateMask = sqlite3_malloc(nU32*sizeof(u32));
    if( p->aUpdateMask==0 ){
      rc = SQLITE_NOMEM;
    }
  }

  if( rc==SQLITE_OK ){
    memset(p->aUpdateMask, 0, nU32*sizeof(u32));
    rc = SQLITE_CORRUPT;
    for(ii=0; ii<pIter->nCol; ii++){
      if( sessionChangesetNew(pIter, ii) ){
        p->aUpdateMask[ii/32] |= (1<<(ii%32));
        rc = SQLITE_OK;
      }
    }
  }

  if( rc==SQLITE_OK ){
    if( bPatchset ) p->aUpdateMask[nCol/32] |= (1<<(nCol%32));

    if( p->pUp ){
      int nUp = 0;
      SessionUpdate **pp = &p->pUp;
      while( 1 ){
        nUp++;
        if( 0==memcmp(p->aUpdateMask, (*pp)->aMask, nU32*sizeof(u32)) ){
          pUp = *pp;
          *pp = pUp->pNext;
          pUp->pNext = p->pUp;
          p->pUp = pUp;
          break;
        }

        if( (*pp)->pNext ){
          pp = &(*pp)->pNext;
        }else{
          if( nUp>=SESSION_UPDATE_CACHE_SZ ){
            sqlite3_finalize((*pp)->pStmt);
            sqlite3_free(*pp);
            *pp = 0;
          }
          break;
        }
      }
    }

    if( pUp==0 ){
      int nByte = sizeof(SessionUpdate) * nU32*sizeof(u32);
      int bStat1 = (sqlite3_stricmp(pIter->zTab, "sqlite_stat1")==0);
      pUp = (SessionUpdate*)sqlite3_malloc(nByte);
      if( pUp==0 ){
        rc = SQLITE_NOMEM;
      }else{
        const char *zSep = "";
        SessionBuffer buf;

        memset(&buf, 0, sizeof(buf));
        pUp->aMask = (u32*)&pUp[1];
        memcpy(pUp->aMask, p->aUpdateMask, nU32*sizeof(u32));

        sessionAppendStr(&buf, "UPDATE main.", &rc);
        sessionAppendIdent(&buf, pIter->zTab, &rc);
        sessionAppendStr(&buf, " SET ", &rc);

        /* Create the assignments part of the UPDATE */
        for(ii=0; ii<pIter->nCol; ii++){
          if( p->abPK[ii]==0 && sessionChangesetNew(pIter, ii) ){
            sessionAppendStr(&buf, zSep, &rc);
            sessionAppendIdent(&buf, p->azCol[ii], &rc);
            sessionAppendStr(&buf, " = ?", &rc);
            sessionAppendInteger(&buf, ii*2+1, &rc);
            zSep = ", ";
          }
        }

        /* Create the WHERE clause part of the UPDATE */
        zSep = "";
        sessionAppendStr(&buf, " WHERE ", &rc);
        for(ii=0; ii<pIter->nCol; ii++){
          if( p->abPK[ii] || (bPatchset==0 && sessionChangesetOld(pIter, ii)) ){
            sessionAppendStr(&buf, zSep, &rc);
            if( bStat1 && ii==1 ){
              assert( sqlite3_stricmp(p->azCol[ii], "idx")==0 );
              sessionAppendStr(&buf, 
                  "idx IS CASE "
                  "WHEN length(?4)=0 AND typeof(?4)='blob' THEN NULL "
                  "ELSE ?4 END ", &rc
              );
            }else{
              sessionAppendIdent(&buf, p->azCol[ii], &rc);
              sessionAppendStr(&buf, " IS ?", &rc);
              sessionAppendInteger(&buf, ii*2+2, &rc);
            }
            zSep = " AND ";
          }
        }

        if( rc==SQLITE_OK ){
          char *zSql = (char*)buf.aBuf;
          rc = sqlite3_prepare_v2(p->db, zSql, buf.nBuf, &pUp->pStmt, 0);
        }

        if( rc!=SQLITE_OK ){
          sqlite3_free(pUp);
          pUp = 0;
        }else{
          pUp->pNext = p->pUp;
          p->pUp = pUp;
        }
        sqlite3_free(buf.aBuf);
      }
    }
  }

  assert( (rc==SQLITE_OK)==(pUp!=0) );
  if( pUp ){
    *ppStmt = pUp->pStmt;
  }else{
    *ppStmt = 0;
  }
  return rc;
}

/*
** Free all cached UPDATE statements.
*/
static void sessionUpdateFree(SessionApplyCtx *p){
  SessionUpdate *pUp;
  SessionUpdate *pNext;
  for(pUp=p->pUp; pUp; pUp=pNext){
    pNext = pUp->pNext;
    sqlite3_finalize(pUp->pStmt);
    sqlite3_free(pUp);
  }
  p->pUp = 0;
  sqlite3_free(p->aUpdateMask);
  p->aUpdateMask = 0;
}

/*
** Formulate a statement to DELETE a row from database db. Assuming a table
** structure like this:
**
**     CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
**
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
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
  if( rc==SQLITE_OK ){
    rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pDelete, 0);
  }
  sqlite3_free(buf.aBuf);

  return rc;
}

/*
** Formulate and prepare a statement to UPDATE a row from database db. 
** Assuming a table structure like this:
**
**     CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
**
** The UPDATE statement looks like this:
**
**     UPDATE x SET
**     a = CASE WHEN ?2  THEN ?3  ELSE a END,
**     b = CASE WHEN ?5  THEN ?6  ELSE b END,
**     c = CASE WHEN ?8  THEN ?9  ELSE c END,
**     d = CASE WHEN ?11 THEN ?12 ELSE d END
**     WHERE a = ?1 AND c = ?7 AND (?13 OR 
**       (?5==0 OR b IS ?4) AND (?11==0 OR d IS ?10) AND
**     )
**
** For each column in the table, there are three variables to bind:
**
**     ?(i*3+1)    The old.* value of the column, if any.
**     ?(i*3+2)    A boolean flag indicating that the value is being modified.
**     ?(i*3+3)    The new.* value of the column, if any.
**
** Also, a boolean flag that, if set to true, causes the statement to update
** a row even if the non-PK values do not match. This is required if the
** conflict-handler is invoked with CHANGESET_DATA and returns
** CHANGESET_REPLACE. This is variable "?(nCol*3+1)".
**
** If successful, SQLITE_OK is returned and SessionApplyCtx.pUpdate is left
** pointing to the prepared version of the SQL statement.
*/
static int sessionUpdateRow(
  sqlite3 *db,                    /* Database handle */
  const char *zTab,               /* Table name */
  SessionApplyCtx *p              /* Session changeset-apply context */
){
  int rc = SQLITE_OK;
  int i;
  const char *zSep = "";
  SessionBuffer buf = {0, 0, 0};

  /* Append "UPDATE tbl SET " */
  sessionAppendStr(&buf, "UPDATE main.", &rc);
  sessionAppendIdent(&buf, zTab, &rc);
  sessionAppendStr(&buf, " SET ", &rc);

  /* Append the assignments */
  for(i=0; i<p->nCol; i++){
    sessionAppendStr(&buf, zSep, &rc);
    sessionAppendIdent(&buf, p->azCol[i], &rc);
    sessionAppendStr(&buf, " = CASE WHEN ?", &rc);
    sessionAppendInteger(&buf, i*3+2, &rc);
    sessionAppendStr(&buf, " THEN ?", &rc);
    sessionAppendInteger(&buf, i*3+3, &rc);
    sessionAppendStr(&buf, " ELSE ", &rc);
    sessionAppendIdent(&buf, p->azCol[i], &rc);
    sessionAppendStr(&buf, " END", &rc);
    zSep = ", ";
  }

  /* Append the PK part of the WHERE clause */
  sessionAppendStr(&buf, " WHERE ", &rc);
  for(i=0; i<p->nCol; i++){
    if( p->abPK[i] ){
      sessionAppendIdent(&buf, p->azCol[i], &rc);
      sessionAppendStr(&buf, " = ?", &rc);
      sessionAppendInteger(&buf, i*3+1, &rc);
      sessionAppendStr(&buf, " AND ", &rc);
    }
  }

  /* Append the non-PK part of the WHERE clause */
  sessionAppendStr(&buf, " (?", &rc);
  sessionAppendInteger(&buf, p->nCol*3+1, &rc);
  sessionAppendStr(&buf, " OR 1", &rc);
  for(i=0; i<p->nCol; i++){
    if( !p->abPK[i] ){
      sessionAppendStr(&buf, " AND (?", &rc);
      sessionAppendInteger(&buf, i*3+2, &rc);
      sessionAppendStr(&buf, "=0 OR ", &rc);
      sessionAppendIdent(&buf, p->azCol[i], &rc);
      sessionAppendStr(&buf, " IS ?", &rc);
      sessionAppendInteger(&buf, i*3+1, &rc);
      sessionAppendStr(&buf, ")", &rc);
    }
  }
  sessionAppendStr(&buf, ")", &rc);

  if( rc==SQLITE_OK ){
    rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pUpdate, 0);
  }
  sqlite3_free(buf.aBuf);

  return rc;
}


/*
** Formulate and prepare an SQL statement to query table zTab by primary
** key. Assuming the following table structure:
**
**     CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
**







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







3818
3819
3820
3821
3822
3823
3824

































































































3825
3826
3827
3828
3829
3830
3831
  if( rc==SQLITE_OK ){
    rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pDelete, 0);
  }
  sqlite3_free(buf.aBuf);

  return rc;
}


































































































/*
** Formulate and prepare an SQL statement to query table zTab by primary
** key. Assuming the following table structure:
**
**     CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
**
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
  if( rc==SQLITE_OK ){
    rc = sessionPrepare(db, &p->pInsert,
        "INSERT INTO main.sqlite_stat1 VALUES(?1, "
        "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END, "
        "?3)"
    );
  }
  if( rc==SQLITE_OK ){
    rc = sessionPrepare(db, &p->pUpdate,
        "UPDATE main.sqlite_stat1 SET "
        "tbl = CASE WHEN ?2 THEN ?3 ELSE tbl END, "
        "idx = CASE WHEN ?5 THEN ?6 ELSE idx END, "
        "stat = CASE WHEN ?8 THEN ?9 ELSE stat END  "
        "WHERE tbl=?1 AND idx IS "
        "CASE WHEN length(?4)=0 AND typeof(?4)='blob' THEN NULL ELSE ?4 END "
        "AND (?10 OR ?8=0 OR stat IS ?7)"
    );
  }
  if( rc==SQLITE_OK ){
    rc = sessionPrepare(db, &p->pDelete,
        "DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS "
        "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END "
        "AND (?4 OR stat IS ?3)"
    );
  }







<
<
<
<
<
<
<
<
<
<
<







3899
3900
3901
3902
3903
3904
3905











3906
3907
3908
3909
3910
3911
3912
  if( rc==SQLITE_OK ){
    rc = sessionPrepare(db, &p->pInsert,
        "INSERT INTO main.sqlite_stat1 VALUES(?1, "
        "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END, "
        "?3)"
    );
  }











  if( rc==SQLITE_OK ){
    rc = sessionPrepare(db, &p->pDelete,
        "DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS "
        "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END "
        "AND (?4 OR stat IS ?3)"
    );
  }
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
  int *pbRetry                    /* OUT: True to retry. */
){
  const char *zDummy;
  int op;
  int nCol;
  int rc = SQLITE_OK;

  assert( p->pDelete && p->pUpdate && p->pInsert && p->pSelect );
  assert( p->azCol && p->abPK );
  assert( !pbReplace || *pbReplace==0 );

  sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);

  if( op==SQLITE_DELETE ){








|







4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
  int *pbRetry                    /* OUT: True to retry. */
){
  const char *zDummy;
  int op;
  int nCol;
  int rc = SQLITE_OK;

  assert( p->pDelete && p->pInsert && p->pSelect );
  assert( p->azCol && p->abPK );
  assert( !pbReplace || *pbReplace==0 );

  sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);

  if( op==SQLITE_DELETE ){

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
      rc = sessionConflictHandler(
          SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0
      );
    }

  }else if( op==SQLITE_UPDATE ){
    int i;





    /* Bind values to the UPDATE statement. */
    for(i=0; rc==SQLITE_OK && i<nCol; i++){
      sqlite3_value *pOld = sessionChangesetOld(pIter, i);
      sqlite3_value *pNew = sessionChangesetNew(pIter, i);

      sqlite3_bind_int(p->pUpdate, i*3+2, !!pNew);
      if( pOld ){
        rc = sessionBindValue(p->pUpdate, i*3+1, pOld);
      }
      if( rc==SQLITE_OK && pNew ){
        rc = sessionBindValue(p->pUpdate, i*3+3, pNew);
      }
    }
    if( rc==SQLITE_OK ){
      sqlite3_bind_int(p->pUpdate, nCol*3+1, pbRetry==0 || pIter->bPatchset);
    }
    if( rc!=SQLITE_OK ) return rc;

    /* Attempt the UPDATE. In the case of a NOTFOUND or DATA conflict,
    ** the result will be SQLITE_OK with 0 rows modified. */
    sqlite3_step(p->pUpdate);
    rc = sqlite3_reset(p->pUpdate);

    if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){
      /* A NOTFOUND or DATA error. Search the table to see if it contains
      ** a row with a matching primary key. If so, this is a DATA conflict.
      ** Otherwise, if there is no primary key match, it is a NOTFOUND. */

      rc = sessionConflictHandler(







>
>
>
>





|
<
<
|


|


<
<
<




|
|







4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271


4272
4273
4274
4275
4276
4277



4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
      rc = sessionConflictHandler(
          SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0
      );
    }

  }else if( op==SQLITE_UPDATE ){
    int i;
    sqlite3_stmt *pUp = 0;
    int bPatchset = (pbRetry==0 || pIter->bPatchset);

    rc = sessionUpdateFind(pIter, p, bPatchset, &pUp);

    /* Bind values to the UPDATE statement. */
    for(i=0; rc==SQLITE_OK && i<nCol; i++){
      sqlite3_value *pOld = sessionChangesetOld(pIter, i);
      sqlite3_value *pNew = sessionChangesetNew(pIter, i);
      if( p->abPK[i] || (bPatchset==0 && pOld) ){


        rc = sessionBindValue(pUp, i*2+2, pOld);
      }
      if( rc==SQLITE_OK && pNew ){
        rc = sessionBindValue(pUp, i*2+1, pNew);
      }
    }



    if( rc!=SQLITE_OK ) return rc;

    /* Attempt the UPDATE. In the case of a NOTFOUND or DATA conflict,
    ** the result will be SQLITE_OK with 0 rows modified. */
    sqlite3_step(pUp);
    rc = sqlite3_reset(pUp);

    if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){
      /* A NOTFOUND or DATA error. Search the table to see if it contains
      ** a row with a matching primary key. If so, this is a DATA conflict.
      ** Otherwise, if there is no primary key match, it is a NOTFOUND. */

      rc = sessionConflictHandler(
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289

  while( pApply->constraints.nBuf ){
    sqlite3_changeset_iter *pIter2 = 0;
    SessionBuffer cons = pApply->constraints;
    memset(&pApply->constraints, 0, sizeof(SessionBuffer));

    rc = sessionChangesetStart(
        &pIter2, 0, 0, cons.nBuf, cons.aBuf, pApply->bInvertConstraints
    );
    if( rc==SQLITE_OK ){
      size_t nByte = 2*pApply->nCol*sizeof(sqlite3_value*);
      int rc2;
      pIter2->bPatchset = bPatchset;
      pIter2->zTab = (char*)zTab;
      pIter2->nCol = pApply->nCol;







|







4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422

  while( pApply->constraints.nBuf ){
    sqlite3_changeset_iter *pIter2 = 0;
    SessionBuffer cons = pApply->constraints;
    memset(&pApply->constraints, 0, sizeof(SessionBuffer));

    rc = sessionChangesetStart(
        &pIter2, 0, 0, cons.nBuf, cons.aBuf, pApply->bInvertConstraints, 1
    );
    if( rc==SQLITE_OK ){
      size_t nByte = 2*pApply->nCol*sizeof(sqlite3_value*);
      int rc2;
      pIter2->bPatchset = bPatchset;
      pIter2->zTab = (char*)zTab;
      pIter2->nCol = pApply->nCol;
4366
4367
4368
4369
4370
4371
4372

4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
      u8 *abPK;

      rc = sessionRetryConstraints(
          db, pIter->bPatchset, zTab, &sApply, xConflict, pCtx
      );
      if( rc!=SQLITE_OK ) break;


      sqlite3_free((char*)sApply.azCol);  /* cast works around VC++ bug */
      sqlite3_finalize(sApply.pDelete);
      sqlite3_finalize(sApply.pUpdate); 
      sqlite3_finalize(sApply.pInsert);
      sqlite3_finalize(sApply.pSelect);
      sApply.db = db;
      sApply.pDelete = 0;
      sApply.pUpdate = 0;
      sApply.pInsert = 0;
      sApply.pSelect = 0;
      sApply.nCol = 0;
      sApply.azCol = 0;
      sApply.abPK = 0;
      sApply.bStat1 = 0;
      sApply.bDeferConstraints = 1;







>


<




<







4499
4500
4501
4502
4503
4504
4505
4506
4507
4508

4509
4510
4511
4512

4513
4514
4515
4516
4517
4518
4519
      u8 *abPK;

      rc = sessionRetryConstraints(
          db, pIter->bPatchset, zTab, &sApply, xConflict, pCtx
      );
      if( rc!=SQLITE_OK ) break;

      sessionUpdateFree(&sApply);
      sqlite3_free((char*)sApply.azCol);  /* cast works around VC++ bug */
      sqlite3_finalize(sApply.pDelete);

      sqlite3_finalize(sApply.pInsert);
      sqlite3_finalize(sApply.pSelect);
      sApply.db = db;
      sApply.pDelete = 0;

      sApply.pInsert = 0;
      sApply.pSelect = 0;
      sApply.nCol = 0;
      sApply.azCol = 0;
      sApply.abPK = 0;
      sApply.bStat1 = 0;
      sApply.bDeferConstraints = 1;
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
        nTab = (int)strlen(zTab);
        sApply.azCol = (const char **)zTab;
      }else{
        int nMinCol = 0;
        int i;

        sqlite3changeset_pk(pIter, &abPK, 0);
        rc = sessionTableInfo(
            db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK
        );
        if( rc!=SQLITE_OK ) break;
        for(i=0; i<sApply.nCol; i++){
          if( sApply.abPK[i] ) nMinCol = i+1;
        }
  







|







4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
        nTab = (int)strlen(zTab);
        sApply.azCol = (const char **)zTab;
      }else{
        int nMinCol = 0;
        int i;

        sqlite3changeset_pk(pIter, &abPK, 0);
        rc = sessionTableInfo(0, 
            db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK
        );
        if( rc!=SQLITE_OK ) break;
        for(i=0; i<sApply.nCol; i++){
          if( sApply.abPK[i] ) nMinCol = i+1;
        }
  
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
          sApply.nCol = nCol;
          if( 0==sqlite3_stricmp(zTab, "sqlite_stat1") ){
            if( (rc = sessionStat1Sql(db, &sApply) ) ){
              break;
            }
            sApply.bStat1 = 1;
          }else{
            if((rc = sessionSelectRow(db, zTab, &sApply))
                || (rc = sessionUpdateRow(db, zTab, &sApply))
                || (rc = sessionDeleteRow(db, zTab, &sApply))
                || (rc = sessionInsertRow(db, zTab, &sApply))
              ){
              break;
            }
            sApply.bStat1 = 0;
          }
        }
        nTab = sqlite3Strlen30(zTab);
      }







|
<
|
|
|







4569
4570
4571
4572
4573
4574
4575
4576

4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
          sApply.nCol = nCol;
          if( 0==sqlite3_stricmp(zTab, "sqlite_stat1") ){
            if( (rc = sessionStat1Sql(db, &sApply) ) ){
              break;
            }
            sApply.bStat1 = 1;
          }else{
            if( (rc = sessionSelectRow(db, zTab, &sApply))

             || (rc = sessionDeleteRow(db, zTab, &sApply))
             || (rc = sessionInsertRow(db, zTab, &sApply))
            ){
              break;
            }
            sApply.bStat1 = 0;
          }
        }
        nTab = sqlite3Strlen30(zTab);
      }
4500
4501
4502
4503
4504
4505
4506

4507
4508
4509
4510
4511
4512
4513
4514
4515
4516

  assert( sApply.bRebase || sApply.rebase.nBuf==0 );
  if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){
    *ppRebase = (void*)sApply.rebase.aBuf;
    *pnRebase = sApply.rebase.nBuf;
    sApply.rebase.aBuf = 0;
  }

  sqlite3_finalize(sApply.pInsert);
  sqlite3_finalize(sApply.pDelete);
  sqlite3_finalize(sApply.pUpdate);
  sqlite3_finalize(sApply.pSelect);
  sqlite3_free((char*)sApply.azCol);  /* cast works around VC++ bug */
  sqlite3_free((char*)sApply.constraints.aBuf);
  sqlite3_free((char*)sApply.rebase.aBuf);
  sqlite3_mutex_leave(sqlite3_db_mutex(db));
  return rc;
}







>


<







4631
4632
4633
4634
4635
4636
4637
4638
4639
4640

4641
4642
4643
4644
4645
4646
4647

  assert( sApply.bRebase || sApply.rebase.nBuf==0 );
  if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){
    *ppRebase = (void*)sApply.rebase.aBuf;
    *pnRebase = sApply.rebase.nBuf;
    sApply.rebase.aBuf = 0;
  }
  sessionUpdateFree(&sApply);
  sqlite3_finalize(sApply.pInsert);
  sqlite3_finalize(sApply.pDelete);

  sqlite3_finalize(sApply.pSelect);
  sqlite3_free((char*)sApply.azCol);  /* cast works around VC++ bug */
  sqlite3_free((char*)sApply.constraints.aBuf);
  sqlite3_free((char*)sApply.rebase.aBuf);
  sqlite3_mutex_leave(sqlite3_db_mutex(db));
  return rc;
}
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
  ),
  void *pCtx,                     /* First argument passed to xConflict */
  void **ppRebase, int *pnRebase,
  int flags
){
  sqlite3_changeset_iter *pIter;  /* Iterator to skip through changeset */  
  int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
  int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset,bInverse);
  if( rc==SQLITE_OK ){
    rc = sessionChangesetApply(
        db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
    );
  }
  return rc;
}







|
|







4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
  ),
  void *pCtx,                     /* First argument passed to xConflict */
  void **ppRebase, int *pnRebase,
  int flags
){
  sqlite3_changeset_iter *pIter;  /* Iterator to skip through changeset */  
  int bInv = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
  int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset, bInv, 1);
  if( rc==SQLITE_OK ){
    rc = sessionChangesetApply(
        db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
    );
  }
  return rc;
}
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
  ),
  void *pCtx,                     /* First argument passed to xConflict */
  void **ppRebase, int *pnRebase,
  int flags
){
  sqlite3_changeset_iter *pIter;  /* Iterator to skip through changeset */  
  int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
  int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse);
  if( rc==SQLITE_OK ){
    rc = sessionChangesetApply(
        db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
    );
  }
  return rc;
}







|







4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
  ),
  void *pCtx,                     /* First argument passed to xConflict */
  void **ppRebase, int *pnRebase,
  int flags
){
  sqlite3_changeset_iter *pIter;  /* Iterator to skip through changeset */  
  int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
  int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse, 1);
  if( rc==SQLITE_OK ){
    rc = sessionChangesetApply(
        db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
    );
  }
  return rc;
}
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
        *ppTab = pTab;
      }else if( pTab->nCol!=nCol || memcmp(pTab->abPK, abPK, nCol) ){
        rc = SQLITE_SCHEMA;
        break;
      }
    }

    if( sessionGrowHash(pIter->bPatchset, pTab) ){
      rc = SQLITE_NOMEM;
      break;
    }
    iHash = sessionChangeHash(
        pTab, (pIter->bPatchset && op==SQLITE_DELETE), aRec, pTab->nChange
    );








|







5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
        *ppTab = pTab;
      }else if( pTab->nCol!=nCol || memcmp(pTab->abPK, abPK, nCol) ){
        rc = SQLITE_SCHEMA;
        break;
      }
    }

    if( sessionGrowHash(0, pIter->bPatchset, pTab) ){
      rc = SQLITE_NOMEM;
      break;
    }
    iHash = sessionChangeHash(
        pTab, (pIter->bPatchset && op==SQLITE_DELETE), aRec, pTab->nChange
    );

5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
}

/*
** Delete a changegroup object.
*/
void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){
  if( pGrp ){
    sessionDeleteTable(pGrp->pList);
    sqlite3_free(pGrp);
  }
}

/* 
** Combine two changesets together.
*/







|







5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
}

/*
** Delete a changegroup object.
*/
void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){
  if( pGrp ){
    sessionDeleteTable(0, pGrp->pList);
    sqlite3_free(pGrp);
  }
}

/* 
** Combine two changesets together.
*/
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227

    *pOut++ = SQLITE_UPDATE;
    *pOut++ = pIter->bIndirect;
    for(i=0; i<pIter->nCol; i++){
      int n1 = sessionSerialLen(a1);
      int n2 = sessionSerialLen(a2);
      if( pIter->abPK[i] || a2[0]==0 ){
        if( !pIter->abPK[i] ) bData = 1;
        memcpy(pOut, a1, n1);
        pOut += n1;
      }else if( a2[0]!=0xFF ){
        bData = 1;
        memcpy(pOut, a2, n2);
        pOut += n2;
      }else{







|







5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358

    *pOut++ = SQLITE_UPDATE;
    *pOut++ = pIter->bIndirect;
    for(i=0; i<pIter->nCol; i++){
      int n1 = sessionSerialLen(a1);
      int n2 = sessionSerialLen(a2);
      if( pIter->abPK[i] || a2[0]==0 ){
        if( !pIter->abPK[i] && a1[0] ) bData = 1;
        memcpy(pOut, a1, n1);
        pOut += n1;
      }else if( a2[0]!=0xFF ){
        bData = 1;
        memcpy(pOut, a2, n2);
        pOut += n2;
      }else{
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
}

/* 
** Destroy a rebaser object 
*/
void sqlite3rebaser_delete(sqlite3_rebaser *p){
  if( p ){
    sessionDeleteTable(p->grp.pList);
    sqlite3_free(p);
  }
}

/* 
** Global configuration
*/







|







5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
}

/* 
** Destroy a rebaser object 
*/
void sqlite3rebaser_delete(sqlite3_rebaser *p){
  if( p ){
    sessionDeleteTable(0, p->grp.pList);
    sqlite3_free(p);
  }
}

/* 
** Global configuration
*/
Changes to ext/session/sqlite3session.h.
449
450
451
452
453
454
455








456
457
458
459
460
461
462
** an attached table is modified and then later on the original values 
** are restored. However, if this function returns non-zero, then it is
** guaranteed that a call to sqlite3session_changeset() will return a 
** changeset containing zero changes.
*/
int sqlite3session_isempty(sqlite3_session *pSession);









/*
** CAPI3REF: Create An Iterator To Traverse A Changeset 
** CONSTRUCTOR: sqlite3_changeset_iter
**
** Create an iterator used to iterate through the contents of a changeset.
** If successful, *pp is set to point to the iterator handle and SQLITE_OK
** is returned. Otherwise, if an error occurs, *pp is set to zero and an







>
>
>
>
>
>
>
>







449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
** an attached table is modified and then later on the original values 
** are restored. However, if this function returns non-zero, then it is
** guaranteed that a call to sqlite3session_changeset() will return a 
** changeset containing zero changes.
*/
int sqlite3session_isempty(sqlite3_session *pSession);

/*
** CAPI3REF: Query for the amount of heap memory used by a session object.
**
** This API returns the total amount of heap memory in bytes currently 
** used by the session object passed as the only argument.
*/
sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession);

/*
** CAPI3REF: Create An Iterator To Traverse A Changeset 
** CONSTRUCTOR: sqlite3_changeset_iter
**
** Create an iterator used to iterate through the contents of a changeset.
** If successful, *pp is set to point to the iterator handle and SQLITE_OK
** is returned. Otherwise, if an error occurs, *pp is set to zero and an
Changes to ext/session/test_session.c.
142
143
144
145
146
147
148


149

150
151
152
153
154
155
156
**
** If the named variable cannot be found, or if it cannot be interpreted
** as a integer, return 0.
*/
static int test_tcl_integer(Tcl_Interp *interp, const char *zVar){
  Tcl_Obj *pObj;
  int iVal = 0;


  pObj = Tcl_ObjGetVar2(interp, Tcl_NewStringObj(zVar, -1), 0, TCL_GLOBAL_ONLY);

  if( pObj ) Tcl_GetIntFromObj(0, pObj, &iVal);
  return iVal;
}

static int test_session_error(Tcl_Interp *interp, int rc, char *zErr){
  extern const char *sqlite3ErrName(int);
  Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));







>
>
|
>







142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
**
** If the named variable cannot be found, or if it cannot be interpreted
** as a integer, return 0.
*/
static int test_tcl_integer(Tcl_Interp *interp, const char *zVar){
  Tcl_Obj *pObj;
  int iVal = 0;
  Tcl_Obj *pName = Tcl_NewStringObj(zVar, -1);
  Tcl_IncrRefCount(pName);
  pObj = Tcl_ObjGetVar2(interp, pName, 0, TCL_GLOBAL_ONLY);
  Tcl_DecrRefCount(pName);
  if( pObj ) Tcl_GetIntFromObj(0, pObj, &iVal);
  return iVal;
}

static int test_session_error(Tcl_Interp *interp, int rc, char *zErr){
  extern const char *sqlite3ErrName(int);
  Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
239
240
241
242
243
244
245

246
247
248
249
250
251
252
    { "enable",       1, "BOOL"        }, /* 3 */
    { "indirect",     1, "BOOL"        }, /* 4 */
    { "isempty",      0, ""            }, /* 5 */
    { "table_filter", 1, "SCRIPT"      }, /* 6 */
    { "patchset",     0, "",           }, /* 7 */
    { "diff",         2, "FROMDB TBL"  }, /* 8 */
    { "fullchangeset",0, ""            }, /* 9 */

    { 0 }
  };
  int iSub;
  int rc;

  if( objc<2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");







>







242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
    { "enable",       1, "BOOL"        }, /* 3 */
    { "indirect",     1, "BOOL"        }, /* 4 */
    { "isempty",      0, ""            }, /* 5 */
    { "table_filter", 1, "SCRIPT"      }, /* 6 */
    { "patchset",     0, "",           }, /* 7 */
    { "diff",         2, "FROMDB TBL"  }, /* 8 */
    { "fullchangeset",0, ""            }, /* 9 */
    { "memory_used",  0, "",           }, /* 10 */
    { 0 }
  };
  int iSub;
  int rc;

  if( objc<2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
348
349
350
351
352
353
354






355
356
357
358
359
360
361
      );
      assert( rc!=SQLITE_OK || zErr==0 );
      if( rc ){
        return test_session_error(interp, rc, zErr);
      }
      break;
    }






  }

  return TCL_OK;
}

static void SQLITE_TCLAPI test_session_del(void *clientData){
  TestSession *p = (TestSession*)clientData;







>
>
>
>
>
>







352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
      );
      assert( rc!=SQLITE_OK || zErr==0 );
      if( rc ){
        return test_session_error(interp, rc, zErr);
      }
      break;
    }

    case 10: {      /* memory_used */
      sqlite3_int64 nMalloc = sqlite3session_memory_used(pSession);
      Tcl_SetObjResult(interp, Tcl_NewWideIntObj(nMalloc));
      break;
    }
  }

  return TCL_OK;
}

static void SQLITE_TCLAPI test_session_del(void *clientData){
  TestSession *p = (TestSession*)clientData;
Changes to main.mk.
356
357
358
359
360
361
362

363
364
365
366
367
368
369
  $(TOP)/src/test_window.c \
  $(TOP)/src/test_wsd.c

# Extensions to be statically loaded.
#
TESTSRC += \
  $(TOP)/ext/misc/amatch.c \

  $(TOP)/ext/misc/carray.c \
  $(TOP)/ext/misc/cksumvfs.c \
  $(TOP)/ext/misc/closure.c \
  $(TOP)/ext/misc/csv.c \
  $(TOP)/ext/misc/decimal.c \
  $(TOP)/ext/misc/eval.c \
  $(TOP)/ext/misc/explain.c \







>







356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
  $(TOP)/src/test_window.c \
  $(TOP)/src/test_wsd.c

# Extensions to be statically loaded.
#
TESTSRC += \
  $(TOP)/ext/misc/amatch.c \
  $(TOP)/ext/misc/appendvfs.c \
  $(TOP)/ext/misc/carray.c \
  $(TOP)/ext/misc/cksumvfs.c \
  $(TOP)/ext/misc/closure.c \
  $(TOP)/ext/misc/csv.c \
  $(TOP)/ext/misc/decimal.c \
  $(TOP)/ext/misc/eval.c \
  $(TOP)/ext/misc/explain.c \
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
DBFUZZ_OPT =
KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
ST_OPT = -DSQLITE_THREADSAFE=0

# This is the default Makefile target.  The objects listed here
# are what get build when you type just "make" with no arguments.
#
all:	sqlite3.h libsqlite3.a sqlite3$(EXE)

libsqlite3.a:	$(LIBOBJ)
	$(AR) libsqlite3.a $(LIBOBJ)
	$(RANLIB) libsqlite3.a

sqlite3$(EXE):	shell.c libsqlite3.a sqlite3.h
	$(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) $(SHELL_OPT) \
		shell.c libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB)

sqldiff$(EXE):	$(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
	$(TCCX) -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \
		$(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) $(THREADLIB)








|

|



|







548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
DBFUZZ_OPT =
KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
ST_OPT = -DSQLITE_THREADSAFE=0

# This is the default Makefile target.  The objects listed here
# are what get build when you type just "make" with no arguments.
#
all:	sqlite3.h sqlite3ext.h libsqlite3.a sqlite3$(EXE)

libsqlite3.a: sqlite3.h	$(LIBOBJ)
	$(AR) libsqlite3.a $(LIBOBJ)
	$(RANLIB) libsqlite3.a

sqlite3$(EXE):	sqlite3.h libsqlite3.a shell.c
	$(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) $(SHELL_OPT) \
		shell.c libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB)

sqldiff$(EXE):	$(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
	$(TCCX) -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \
		$(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) $(THREADLIB)

821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841

fts3_unicode2.o:	$(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR)
	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode2.c

fts3_write.o:	$(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR)
	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c

fts5.o:	fts5.c
	$(TCCX) -DSQLITE_CORE -c fts5.c

json1.o:	$(TOP)/ext/misc/json1.c
	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/misc/json1.c

stmt.o:	$(TOP)/ext/misc/stmt.c
	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/misc/stmt.c

rtree.o:	$(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c










|


|


|







822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842

fts3_unicode2.o:	$(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR)
	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode2.c

fts3_write.o:	$(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR)
	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c

fts5.o:	fts5.c  sqlite3ext.h sqlite3.h
	$(TCCX) -DSQLITE_CORE -c fts5.c

json1.o:	$(TOP)/ext/misc/json1.c sqlite3ext.h sqlite3.h
	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/misc/json1.c

stmt.o:	$(TOP)/ext/misc/stmt.c sqlite3ext.h sqlite3.h
	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/misc/stmt.c

rtree.o:	$(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c



951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
	./testfixture$(EXE) $(TOP)/test/permutations.test queryplanner $(TESTOPTS)

fuzztest:	fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db
	./fuzzcheck$(EXE) $(FUZZDATA)
	./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db

valgrindfuzz:	fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db
	valgrind ./fuzzcheck$(EXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA)
	valgrind ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db

# The veryquick.test TCL tests.
#
tcltest:	./testfixture$(EXE)
	./testfixture$(EXE) $(TOP)/test/veryquick.test $(TESTOPTS)








|







952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
	./testfixture$(EXE) $(TOP)/test/permutations.test queryplanner $(TESTOPTS)

fuzztest:	fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db
	./fuzzcheck$(EXE) $(FUZZDATA)
	./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db

valgrindfuzz:	fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db
	valgrind ./fuzzcheck$(EXE) --cell-size-check --limit-mem 10M $(FUZZDATA)
	valgrind ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db

# The veryquick.test TCL tests.
#
tcltest:	./testfixture$(EXE)
	./testfixture$(EXE) $(TOP)/test/veryquick.test $(TESTOPTS)

Changes to src/alter.c.
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
/*
** Generate code to verify that the schemas of database zDb and, if
** bTemp is not true, database "temp", can still be parsed. This is
** called at the end of the generation of an ALTER TABLE ... RENAME ...
** statement to ensure that the operation has not rendered any schema
** objects unusable.
*/
static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){






  sqlite3NestedParse(pParse, 
      "SELECT 1 "
      "FROM \"%w\"." DFLT_SCHEMA_TABLE " "
      "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
      " AND sql NOT LIKE 'create virtual%%'"
      " AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ",
      zDb,
      zDb, bTemp
  );

  if( bTemp==0 ){
    sqlite3NestedParse(pParse, 
        "SELECT 1 "
        "FROM temp." DFLT_SCHEMA_TABLE " "
        "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
        " AND sql NOT LIKE 'create virtual%%'"
        " AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ",
        zDb 
    );
  }
}

/*
** Generate code to reload the schema for database iDb. And, if iDb!=1, for
** the temp database as well.
*/
static void renameReloadSchema(Parse *pParse, int iDb){
  Vdbe *v = pParse->pVdbe;
  if( v ){
    sqlite3ChangeCookie(pParse, iDb);
    sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0);
    if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0);
  }
}

/*
** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" 
** command. 
*/







|
>
>
>
>
>
>





|

|








|
|








|



|
|







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
/*
** Generate code to verify that the schemas of database zDb and, if
** bTemp is not true, database "temp", can still be parsed. This is
** called at the end of the generation of an ALTER TABLE ... RENAME ...
** statement to ensure that the operation has not rendered any schema
** objects unusable.
*/
static void renameTestSchema(
  Parse *pParse,                  /* Parse context */
  const char *zDb,                /* Name of db to verify schema of */
  int bTemp,                      /* True if this is the temp db */
  const char *zWhen               /* "when" part of error message */
){
  pParse->colNamesSet = 1;
  sqlite3NestedParse(pParse, 
      "SELECT 1 "
      "FROM \"%w\"." DFLT_SCHEMA_TABLE " "
      "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
      " AND sql NOT LIKE 'create virtual%%'"
      " AND sqlite_rename_test(%Q, sql, type, name, %d, %Q)=NULL ",
      zDb,
      zDb, bTemp, zWhen
  );

  if( bTemp==0 ){
    sqlite3NestedParse(pParse, 
        "SELECT 1 "
        "FROM temp." DFLT_SCHEMA_TABLE " "
        "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
        " AND sql NOT LIKE 'create virtual%%'"
        " AND sqlite_rename_test(%Q, sql, type, name, 1, %Q)=NULL ",
        zDb, zWhen
    );
  }
}

/*
** Generate code to reload the schema for database iDb. And, if iDb!=1, for
** the temp database as well.
*/
static void renameReloadSchema(Parse *pParse, int iDb, u16 p5){
  Vdbe *v = pParse->pVdbe;
  if( v ){
    sqlite3ChangeCookie(pParse, iDb);
    sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0, p5);
    if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0, p5);
  }
}

/*
** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" 
** command. 
*/
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
  ** as required.  */
  if( iDb!=1 ){
    sqlite3NestedParse(pParse, 
        "UPDATE sqlite_temp_schema SET "
            "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, 1), "
            "tbl_name = "
              "CASE WHEN tbl_name=%Q COLLATE nocase AND "
              "          sqlite_rename_test(%Q, sql, type, name, 1) "
              "THEN %Q ELSE tbl_name END "
            "WHERE type IN ('view', 'trigger')"
        , zDb, zTabName, zName, zTabName, zDb, zName);
  }

  /* 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( pVTab ){
    int i = ++pParse->nMem;
    sqlite3VdbeLoadString(v, i, zName);
    sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);
  }
#endif

  renameReloadSchema(pParse, iDb);
  renameTestSchema(pParse, zDb, iDb==1);

exit_rename_table:
  sqlite3SrcListDelete(db, pSrc);
  sqlite3DbFree(db, zName);
  db->mDbFlags = savedDbFlags;
}








|


















|
|







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
  ** as required.  */
  if( iDb!=1 ){
    sqlite3NestedParse(pParse, 
        "UPDATE sqlite_temp_schema SET "
            "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, 1), "
            "tbl_name = "
              "CASE WHEN tbl_name=%Q COLLATE nocase AND "
              "    sqlite_rename_test(%Q, sql, type, name, 1, 'after rename') "
              "THEN %Q ELSE tbl_name END "
            "WHERE type IN ('view', 'trigger')"
        , zDb, zTabName, zName, zTabName, zDb, zName);
  }

  /* 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( pVTab ){
    int i = ++pParse->nMem;
    sqlite3VdbeLoadString(v, i, zName);
    sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);
  }
#endif

  renameReloadSchema(pParse, iDb, INITFLAG_AlterRename);
  renameTestSchema(pParse, zDb, iDb==1, "after rename");

exit_rename_table:
  sqlite3SrcListDelete(db, pSrc);
  sqlite3DbFree(db, zName);
  db->mDbFlags = savedDbFlags;
}

377
378
379
380
381
382
383


384
385

386
387
388
389
390
391
392
393
394
395
  if( zCol ){
    char *zEnd = &zCol[pColDef->n-1];
    u32 savedDbFlags = db->mDbFlags;
    while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){
      *zEnd-- = '\0';
    }
    db->mDbFlags |= DBFLAG_PreferBuiltin;


    sqlite3NestedParse(pParse, 
        "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "

          "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) "
        "WHERE type = 'table' AND name = %Q", 
      zDb, pNew->addColOffset, zCol, pNew->addColOffset+1,
      zTab
    );
    sqlite3DbFree(db, zCol);
    db->mDbFlags = savedDbFlags;
  }

  /* Make sure the schema version is at least 3.  But do not upgrade







>
>


>
|

|







383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
  if( zCol ){
    char *zEnd = &zCol[pColDef->n-1];
    u32 savedDbFlags = db->mDbFlags;
    while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){
      *zEnd-- = '\0';
    }
    db->mDbFlags |= DBFLAG_PreferBuiltin;
    /* substr() operations on characters, but addColOffset is in bytes. So we
    ** have to use printf() to translate between these units: */
    sqlite3NestedParse(pParse, 
        "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
          "sql = printf('%%.%ds, ',sql) || %Q"
          " || substr(sql,1+length(printf('%%.%ds',sql))) "
        "WHERE type = 'table' AND name = %Q", 
      zDb, pNew->addColOffset, zCol, pNew->addColOffset,
      zTab
    );
    sqlite3DbFree(db, zCol);
    db->mDbFlags = savedDbFlags;
  }

  /* Make sure the schema version is at least 3.  But do not upgrade
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
    sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2);
    VdbeCoverage(v);
    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3);
    sqlite3ReleaseTempReg(pParse, r1);
  }

  /* Reload the table definition */
  renameReloadSchema(pParse, iDb);
}

/*
** This function is called by the parser after the table-name in
** an "ALTER TABLE <table-name> ADD" statement is parsed. Argument 
** pSrc is the full-name of the table being altered.
**







|







414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
    sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2);
    VdbeCoverage(v);
    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3);
    sqlite3ReleaseTempReg(pParse, r1);
  }

  /* Reload the table definition */
  renameReloadSchema(pParse, iDb, INITFLAG_AlterRename);
}

/*
** This function is called by the parser after the table-name in
** an "ALTER TABLE <table-name> ADD" statement is parsed. Argument 
** pSrc is the full-name of the table being altered.
**
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
** command. This function checks if the table is a view or virtual
** table (columns of views or virtual tables may not be renamed). If so,
** it loads an error message into pParse and returns non-zero.
**
** Or, if pTab is not a view or virtual table, zero is returned.
*/
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
static int isRealTable(Parse *pParse, Table *pTab){
  const char *zType = 0;
#ifndef SQLITE_OMIT_VIEW
  if( pTab->pSelect ){
    zType = "view";
  }
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( IsVirtual(pTab) ){
    zType = "virtual table";
  }
#endif
  if( zType ){
    sqlite3ErrorMsg(

        pParse, "cannot rename columns of %s \"%s\"", zType, pTab->zName
    );
    return 1;
  }
  return 0;
}
#else /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */
# define isRealTable(x,y) (0)
#endif

/*
** Handles the following parser reduction:
**
**  cmd ::= ALTER TABLE pSrc RENAME COLUMN pOld TO pNew
*/







|












|
>
|






|







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
** command. This function checks if the table is a view or virtual
** table (columns of views or virtual tables may not be renamed). If so,
** it loads an error message into pParse and returns non-zero.
**
** Or, if pTab is not a view or virtual table, zero is returned.
*/
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
static int isRealTable(Parse *pParse, Table *pTab, int bDrop){
  const char *zType = 0;
#ifndef SQLITE_OMIT_VIEW
  if( pTab->pSelect ){
    zType = "view";
  }
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( IsVirtual(pTab) ){
    zType = "virtual table";
  }
#endif
  if( zType ){
    sqlite3ErrorMsg(pParse, "cannot %s %s \"%s\"", 
        (bDrop ? "drop column from" : "rename columns of"),
        zType, pTab->zName
    );
    return 1;
  }
  return 0;
}
#else /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */
# define isRealTable(x,y,z) (0)
#endif

/*
** Handles the following parser reduction:
**
**  cmd ::= ALTER TABLE pSrc RENAME COLUMN pOld TO pNew
*/
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569

  /* Locate the table to be altered */
  pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
  if( !pTab ) goto exit_rename_column;

  /* Cannot alter a system table */
  if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_rename_column;
  if( SQLITE_OK!=isRealTable(pParse, pTab) ) goto exit_rename_column;

  /* Which schema holds the table to be altered */  
  iSchema = sqlite3SchemaToIndex(db, pTab->pSchema);
  assert( iSchema>=0 );
  zDb = db->aDb[iSchema].zDbSName;

#ifndef SQLITE_OMIT_AUTHORIZATION







|







565
566
567
568
569
570
571
572
573
574
575
576
577
578
579

  /* Locate the table to be altered */
  pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
  if( !pTab ) goto exit_rename_column;

  /* Cannot alter a system table */
  if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_rename_column;
  if( SQLITE_OK!=isRealTable(pParse, pTab, 0) ) goto exit_rename_column;

  /* Which schema holds the table to be altered */  
  iSchema = sqlite3SchemaToIndex(db, pTab->pSchema);
  assert( iSchema>=0 );
  zDb = db->aDb[iSchema].zDbSName;

#ifndef SQLITE_OMIT_AUTHORIZATION
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
      "UPDATE temp." DFLT_SCHEMA_TABLE " SET "
      "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) "
      "WHERE type IN ('trigger', 'view')",
      zDb, pTab->zName, iCol, zNew, bQuote
  );

  /* Drop and reload the database schema. */
  renameReloadSchema(pParse, iSchema);
  renameTestSchema(pParse, zDb, iSchema==1);

 exit_rename_column:
  sqlite3SrcListDelete(db, pSrc);
  sqlite3DbFree(db, zOld);
  sqlite3DbFree(db, zNew);
  return;
}







|
|







619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
      "UPDATE temp." DFLT_SCHEMA_TABLE " SET "
      "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) "
      "WHERE type IN ('trigger', 'view')",
      zDb, pTab->zName, iCol, zNew, bQuote
  );

  /* Drop and reload the database schema. */
  renameReloadSchema(pParse, iSchema, INITFLAG_AlterRename);
  renameTestSchema(pParse, zDb, iSchema==1, "after rename");

 exit_rename_column:
  sqlite3SrcListDelete(db, pSrc);
  sqlite3DbFree(db, zOld);
  sqlite3DbFree(db, zNew);
  return;
}
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
    pNext = p->pNext;
    sqlite3DbFree(db, p);
  }
}

/*
** Search the Parse object passed as the first argument for a RenameToken
** object associated with parse tree element pPtr. If found, remove it



** from the Parse object and add it to the list maintained by the
** RenameCtx object passed as the second argument.
*/


static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){


  RenameToken **pp;
  assert( pPtr!=0 );
  for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){
    if( (*pp)->p==pPtr ){
      RenameToken *pToken = *pp;

      *pp = pToken->pNext;
      pToken->pNext = pCtx->pList;
      pCtx->pList = pToken;
      pCtx->nList++;

      break;
    }
  }

}

/*
** This is a Walker select callback. It does nothing. It is only required
** because without a dummy callback, sqlite3WalkExpr() and similar do not
** descend into sub-select statements.
*/







|
>
>
>
|
|

>
>
|
>
>





>
|
|
|
|
>
|


>







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
    pNext = p->pNext;
    sqlite3DbFree(db, p);
  }
}

/*
** Search the Parse object passed as the first argument for a RenameToken
** object associated with parse tree element pPtr. If found, return a pointer
** to it. Otherwise, return NULL.
**
** If the second argument passed to this function is not NULL and a matching
** RenameToken object is found, remove it from the Parse object and add it to
** the list maintained by the RenameCtx object.
*/
static RenameToken *renameTokenFind(
  Parse *pParse, 
  struct RenameCtx *pCtx, 
  void *pPtr
){
  RenameToken **pp;
  assert( pPtr!=0 );
  for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){
    if( (*pp)->p==pPtr ){
      RenameToken *pToken = *pp;
      if( pCtx ){
        *pp = pToken->pNext;
        pToken->pNext = pCtx->pList;
        pCtx->pList = pToken;
        pCtx->nList++;
      }
      return pToken;
    }
  }
  return 0;
}

/*
** This is a Walker select callback. It does nothing. It is only required
** because without a dummy callback, sqlite3WalkExpr() and similar do not
** descend into sub-select statements.
*/
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
** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an
** ALTER TABLE RENAME COLUMN program. The error message emitted by the
** sub-routine is currently stored in pParse->zErrMsg. This function
** adds context to the error message and then stores it in pCtx.
*/
static void renameColumnParseError(
  sqlite3_context *pCtx, 
  int bPost,
  sqlite3_value *pType,
  sqlite3_value *pObject,
  Parse *pParse
){
  const char *zT = (const char*)sqlite3_value_text(pType);
  const char *zN = (const char*)sqlite3_value_text(pObject);
  char *zErr;

  zErr = sqlite3_mprintf("error in %s %s%s: %s", 
      zT, zN, (bPost ? " after rename" : ""),
      pParse->zErrMsg
  );
  sqlite3_result_error(pCtx, zErr, -1);
  sqlite3_free(zErr);
}

/*







|








|
|







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
** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an
** ALTER TABLE RENAME COLUMN program. The error message emitted by the
** sub-routine is currently stored in pParse->zErrMsg. This function
** adds context to the error message and then stores it in pCtx.
*/
static void renameColumnParseError(
  sqlite3_context *pCtx, 
  const char *zWhen,
  sqlite3_value *pType,
  sqlite3_value *pObject,
  Parse *pParse
){
  const char *zT = (const char*)sqlite3_value_text(pType);
  const char *zN = (const char*)sqlite3_value_text(pObject);
  char *zErr;

  zErr = sqlite3_mprintf("error in %s %s%s%s: %s", 
      zT, zN, (zWhen[0] ? " " : ""), zWhen,
      pParse->zErrMsg
  );
  sqlite3_result_error(pCtx, zErr, -1);
  sqlite3_free(zErr);
}

/*
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
  /* Parse the SQL statement passed as the first argument. If no error
  ** occurs and the parse does not result in a new table, index or
  ** trigger object, the database must be corrupt. */
  memset(p, 0, sizeof(Parse));
  p->eParseMode = PARSE_MODE_RENAME;
  p->db = db;
  p->nQueryLoop = 1;
  rc = sqlite3RunParser(p, zSql, &zErr);
  assert( p->zErrMsg==0 );
  assert( rc!=SQLITE_OK || zErr==0 );
  p->zErrMsg = zErr;
  if( db->mallocFailed ) rc = SQLITE_NOMEM;
  if( rc==SQLITE_OK 
   && p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0 
  ){







|







1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
  /* Parse the SQL statement passed as the first argument. If no error
  ** occurs and the parse does not result in a new table, index or
  ** trigger object, the database must be corrupt. */
  memset(p, 0, sizeof(Parse));
  p->eParseMode = PARSE_MODE_RENAME;
  p->db = db;
  p->nQueryLoop = 1;
  rc = zSql ? sqlite3RunParser(p, zSql, &zErr) : SQLITE_NOMEM;
  assert( p->zErrMsg==0 );
  assert( rc!=SQLITE_OK || zErr==0 );
  p->zErrMsg = zErr;
  if( db->mallocFailed ) rc = SQLITE_NOMEM;
  if( rc==SQLITE_OK 
   && p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0 
  ){
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
      if( pParse->nErr ) rc = pParse->rc;
    }
    if( rc==SQLITE_OK && pStep->zTarget ){
      SrcList *pSrc = sqlite3TriggerStepSrc(pParse, pStep);
      if( pSrc ){
        int i;
        for(i=0; i<pSrc->nSrc && rc==SQLITE_OK; i++){
          struct SrcList_item *p = &pSrc->a[i];
          p->iCursor = pParse->nTab++;
          if( p->pSelect ){
            sqlite3SelectPrep(pParse, p->pSelect, 0);
            sqlite3ExpandSubquery(pParse, p);
            assert( i>0 );
            assert( pStep->pFrom->a[i-1].pSelect );
            sqlite3SelectPrep(pParse, pStep->pFrom->a[i-1].pSelect, 0);







|







1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
      if( pParse->nErr ) rc = pParse->rc;
    }
    if( rc==SQLITE_OK && pStep->zTarget ){
      SrcList *pSrc = sqlite3TriggerStepSrc(pParse, pStep);
      if( pSrc ){
        int i;
        for(i=0; i<pSrc->nSrc && rc==SQLITE_OK; i++){
          SrcItem *p = &pSrc->a[i];
          p->iCursor = pParse->nTab++;
          if( p->pSelect ){
            sqlite3SelectPrep(pParse, p->pSelect, 0);
            sqlite3ExpandSubquery(pParse, p);
            assert( i>0 );
            assert( pStep->pFrom->a[i-1].pSelect );
            sqlite3SelectPrep(pParse, pStep->pFrom->a[i-1].pSelect, 0);
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
        if( rc==SQLITE_OK && pStep->pWhere ){
          rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
        }
        if( rc==SQLITE_OK ){
          rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList);
        }
        assert( !pStep->pUpsert || (!pStep->pWhere && !pStep->pExprList) );
        if( pStep->pUpsert ){
          Upsert *pUpsert = pStep->pUpsert;
          assert( rc==SQLITE_OK );
          pUpsert->pUpsertSrc = pSrc;
          sNC.uNC.pUpsert = pUpsert;
          sNC.ncFlags = NC_UUpsert;
          rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget);
          if( rc==SQLITE_OK ){
            ExprList *pUpsertSet = pUpsert->pUpsertSet;
            rc = sqlite3ResolveExprListNames(&sNC, pUpsertSet);







|

<







1237
1238
1239
1240
1241
1242
1243
1244
1245

1246
1247
1248
1249
1250
1251
1252
        if( rc==SQLITE_OK && pStep->pWhere ){
          rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
        }
        if( rc==SQLITE_OK ){
          rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList);
        }
        assert( !pStep->pUpsert || (!pStep->pWhere && !pStep->pExprList) );
        if( pStep->pUpsert && rc==SQLITE_OK ){
          Upsert *pUpsert = pStep->pUpsert;

          pUpsert->pUpsertSrc = pSrc;
          sNC.uNC.pUpsert = pUpsert;
          sNC.ncFlags = NC_UUpsert;
          rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget);
          if( rc==SQLITE_OK ){
            ExprList *pUpsertSet = pUpsert->pUpsertSet;
            rc = sqlite3ResolveExprListNames(&sNC, pUpsertSet);
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479

  assert( rc==SQLITE_OK );
  rc = renameEditSql(context, &sCtx, zSql, zNew, bQuote);

renameColumnFunc_done:
  if( rc!=SQLITE_OK ){
    if( sParse.zErrMsg ){
      renameColumnParseError(context, 0, argv[1], argv[2], &sParse);
    }else{
      sqlite3_result_error_code(context, rc);
    }
  }

  renameParseCleanup(&sParse);
  renameTokenFree(db, sCtx.pList);







|







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

  assert( rc==SQLITE_OK );
  rc = renameEditSql(context, &sCtx, zSql, zNew, bQuote);

renameColumnFunc_done:
  if( rc!=SQLITE_OK ){
    if( sParse.zErrMsg ){
      renameColumnParseError(context, "", argv[1], argv[2], &sParse);
    }else{
      sqlite3_result_error_code(context, rc);
    }
  }

  renameParseCleanup(&sParse);
  renameTokenFree(db, sCtx.pList);
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
  SrcList *pSrc = pSelect->pSrc;
  if( pSelect->selFlags & SF_View ) return WRC_Prune;
  if( pSrc==0 ){
    assert( pWalker->pParse->db->mallocFailed );
    return WRC_Abort;
  }
  for(i=0; i<pSrc->nSrc; i++){
    struct SrcList_item *pItem = &pSrc->a[i];
    if( pItem->pTab==p->pTab ){
      renameTokenFind(pWalker->pParse, p, pItem->zName);
    }
  }
  renameWalkWith(pWalker, pSelect);

  return WRC_Continue;







|







1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
  SrcList *pSrc = pSelect->pSrc;
  if( pSelect->selFlags & SF_View ) return WRC_Prune;
  if( pSrc==0 ){
    assert( pWalker->pParse->db->mallocFailed );
    return WRC_Abort;
  }
  for(i=0; i<pSrc->nSrc; i++){
    SrcItem *pItem = &pSrc->a[i];
    if( pItem->pTab==p->pTab ){
      renameTokenFind(pWalker->pParse, p, pItem->zName);
    }
  }
  renameWalkWith(pWalker, pSelect);

  return WRC_Continue;
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
    }

    if( rc==SQLITE_OK ){
      rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote);
    }
    if( rc!=SQLITE_OK ){
      if( sParse.zErrMsg ){
        renameColumnParseError(context, 0, argv[1], argv[2], &sParse);
      }else{
        sqlite3_result_error_code(context, rc);
      }
    }

    renameParseCleanup(&sParse);
    renameTokenFree(db, sCtx.pList);







|







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

    if( rc==SQLITE_OK ){
      rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote);
    }
    if( rc!=SQLITE_OK ){
      if( sParse.zErrMsg ){
        renameColumnParseError(context, "", argv[1], argv[2], &sParse);
      }else{
        sqlite3_result_error_code(context, rc);
      }
    }

    renameParseCleanup(&sParse);
    renameTokenFree(db, sCtx.pList);
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
** to ensure that it is still usable.
**
**   0: Database name ("main", "temp" etc.).
**   1: SQL statement.
**   2: Object type ("view", "table", "trigger" or "index").
**   3: Object name.
**   4: True if object is from temp schema.

**
** Unless it finds an error, this function normally returns NULL. However, it
** returns integer value 1 if:
**
**   * the SQL argument creates a trigger, and
**   * the table that the trigger is attached to is in database zDb.
*/
static void renameTableTest(
  sqlite3_context *context,
  int NotUsed,
  sqlite3_value **argv
){
  sqlite3 *db = sqlite3_context_db_handle(context);
  char const *zDb = (const char*)sqlite3_value_text(argv[0]);
  char const *zInput = (const char*)sqlite3_value_text(argv[1]);
  int bTemp = sqlite3_value_int(argv[4]);
  int isLegacy = (db->flags & SQLITE_LegacyAlter);


#ifndef SQLITE_OMIT_AUTHORIZATION
  sqlite3_xauth xAuth = db->xAuth;
  db->xAuth = 0;
#endif

  UNUSED_PARAMETER(NotUsed);







>

















>







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
** to ensure that it is still usable.
**
**   0: Database name ("main", "temp" etc.).
**   1: SQL statement.
**   2: Object type ("view", "table", "trigger" or "index").
**   3: Object name.
**   4: True if object is from temp schema.
**   5: "when" part of error message.
**
** Unless it finds an error, this function normally returns NULL. However, it
** returns integer value 1 if:
**
**   * the SQL argument creates a trigger, and
**   * the table that the trigger is attached to is in database zDb.
*/
static void renameTableTest(
  sqlite3_context *context,
  int NotUsed,
  sqlite3_value **argv
){
  sqlite3 *db = sqlite3_context_db_handle(context);
  char const *zDb = (const char*)sqlite3_value_text(argv[0]);
  char const *zInput = (const char*)sqlite3_value_text(argv[1]);
  int bTemp = sqlite3_value_int(argv[4]);
  int isLegacy = (db->flags & SQLITE_LegacyAlter);
  char const *zWhen = (const char*)sqlite3_value_text(argv[5]);

#ifndef SQLITE_OMIT_AUTHORIZATION
  sqlite3_xauth xAuth = db->xAuth;
  db->xAuth = 0;
#endif

  UNUSED_PARAMETER(NotUsed);
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
          int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema);
          int i2 = sqlite3FindDbName(db, zDb);
          if( i1==i2 ) sqlite3_result_int(context, 1);
        }
      }
    }

    if( rc!=SQLITE_OK ){
      renameColumnParseError(context, 1, argv[2], argv[3], &sParse);
    }
    renameParseCleanup(&sParse);
  }

#ifndef SQLITE_OMIT_AUTHORIZATION
  db->xAuth = xAuth;
#endif
}
































































































































































































/*
** Register built-in functions used to help implement ALTER TABLE
*/
void sqlite3AlterFunctions(void){
  static FuncDef aAlterTableFuncs[] = {
    INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc),
    INTERNAL_FUNCTION(sqlite_rename_table,  7, renameTableFunc),
    INTERNAL_FUNCTION(sqlite_rename_test,   5, renameTableTest),

  };
  sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
}
#endif  /* SQLITE_ALTER_TABLE */







|
|








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|
|
|
>




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
          int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema);
          int i2 = sqlite3FindDbName(db, zDb);
          if( i1==i2 ) sqlite3_result_int(context, 1);
        }
      }
    }

    if( rc!=SQLITE_OK && zWhen ){
      renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse);
    }
    renameParseCleanup(&sParse);
  }

#ifndef SQLITE_OMIT_AUTHORIZATION
  db->xAuth = xAuth;
#endif
}

/*
** The implementation of internal UDF sqlite_drop_column().
** 
** Arguments:
**
**  argv[0]: An integer - the index of the schema containing the table
**  argv[1]: CREATE TABLE statement to modify.
**  argv[2]: An integer - the index of the column to remove.
**
** The value returned is a string containing the CREATE TABLE statement
** with column argv[2] removed.
*/
static void dropColumnFunc(
  sqlite3_context *context,
  int NotUsed,
  sqlite3_value **argv
){
  sqlite3 *db = sqlite3_context_db_handle(context);
  int iSchema = sqlite3_value_int(argv[0]);
  const char *zSql = (const char*)sqlite3_value_text(argv[1]);
  int iCol = sqlite3_value_int(argv[2]);
  const char *zDb = db->aDb[iSchema].zDbSName;
  int rc;
  Parse sParse;
  RenameToken *pCol;
  Table *pTab;
  const char *zEnd;
  char *zNew = 0;

#ifndef SQLITE_OMIT_AUTHORIZATION
  sqlite3_xauth xAuth = db->xAuth;
  db->xAuth = 0;
#endif

  UNUSED_PARAMETER(NotUsed);
  rc = renameParseSql(&sParse, zDb, db, zSql, iSchema==1);
  if( rc!=SQLITE_OK ) goto drop_column_done;
  pTab = sParse.pNewTable;
  if( pTab==0 || pTab->nCol==1 || iCol>=pTab->nCol ){ 
    /* This can happen if the sqlite_schema table is corrupt */
    rc = SQLITE_CORRUPT_BKPT;
    goto drop_column_done;
  }

  pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zName);
  if( iCol<pTab->nCol-1 ){
    RenameToken *pEnd;
    pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zName);
    zEnd = (const char*)pEnd->t.z;
  }else{
    zEnd = (const char*)&zSql[pTab->addColOffset];
    while( ALWAYS(pCol->t.z[0]!=0) && pCol->t.z[0]!=',' ) pCol->t.z--;
  }

  zNew = sqlite3MPrintf(db, "%.*s%s", pCol->t.z-zSql, zSql, zEnd);
  sqlite3_result_text(context, zNew, -1, SQLITE_TRANSIENT);
  sqlite3_free(zNew);

drop_column_done:
  renameParseCleanup(&sParse);
#ifndef SQLITE_OMIT_AUTHORIZATION
  db->xAuth = xAuth;
#endif
  if( rc!=SQLITE_OK ){
    sqlite3_result_error_code(context, rc);
  }
}

/*
** This function is called by the parser upon parsing an 
**
**     ALTER TABLE pSrc DROP COLUMN pName
**
** statement. Argument pSrc contains the possibly qualified name of the
** table being edited, and token pName the name of the column to drop.
*/
void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){
  sqlite3 *db = pParse->db;       /* Database handle */
  Table *pTab;                    /* Table to modify */
  int iDb;                        /* Index of db containing pTab in aDb[] */
  const char *zDb;                /* Database containing pTab ("main" etc.) */
  char *zCol = 0;                 /* Name of column to drop */
  int iCol;                       /* Index of column zCol in pTab->aCol[] */

  /* Look up the table being altered. */
  assert( pParse->pNewTable==0 );
  assert( sqlite3BtreeHoldsAllMutexes(db) );
  if( NEVER(db->mallocFailed) ) goto exit_drop_column;
  pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
  if( !pTab ) goto exit_drop_column;

  /* Make sure this is not an attempt to ALTER a view, virtual table or 
  ** system table. */
  if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_drop_column;
  if( SQLITE_OK!=isRealTable(pParse, pTab, 1) ) goto exit_drop_column;

  /* Find the index of the column being dropped. */
  zCol = sqlite3NameFromToken(db, pName);
  if( zCol==0 ){
    assert( db->mallocFailed );
    goto exit_drop_column;
  }
  iCol = sqlite3ColumnIndex(pTab, zCol);
  if( iCol<0 ){
    sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zCol);
    goto exit_drop_column;
  }

  /* Do not allow the user to drop a PRIMARY KEY column or a column 
  ** constrained by a UNIQUE constraint.  */
  if( pTab->aCol[iCol].colFlags & (COLFLAG_PRIMKEY|COLFLAG_UNIQUE) ){
    sqlite3ErrorMsg(pParse, "cannot drop %s column: \"%s\"", 
        (pTab->aCol[iCol].colFlags&COLFLAG_PRIMKEY) ? "PRIMARY KEY" : "UNIQUE",
        zCol
    );
    goto exit_drop_column;
  }

  /* Do not allow the number of columns to go to zero */
  if( pTab->nCol<=1 ){
    sqlite3ErrorMsg(pParse, "cannot drop column \"%s\": no other columns exist",zCol);
    goto exit_drop_column;
  }

  /* Edit the sqlite_schema table */
  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  assert( iDb>=0 );
  zDb = db->aDb[iDb].zDbSName;
  renameTestSchema(pParse, zDb, iDb==1, "");
  sqlite3NestedParse(pParse, 
      "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
      "sql = sqlite_drop_column(%d, sql, %d) "
      "WHERE (type=='table' AND tbl_name=%Q COLLATE nocase)"
      , zDb, iDb, iCol, pTab->zName
  );

  /* Drop and reload the database schema. */
  renameReloadSchema(pParse, iDb, INITFLAG_AlterDrop);
  renameTestSchema(pParse, zDb, iDb==1, "after drop column");

  /* Edit rows of table on disk */
  if( pParse->nErr==0 && (pTab->aCol[iCol].colFlags & COLFLAG_VIRTUAL)==0 ){
    int i;
    int addr;
    int reg;
    int regRec;
    Index *pPk = 0;
    int nField = 0;               /* Number of non-virtual columns after drop */
    int iCur;
    Vdbe *v = sqlite3GetVdbe(pParse);
    iCur = pParse->nTab++;
    sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite);
    addr = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v);
    reg = ++pParse->nMem;
    pParse->nMem += pTab->nCol;
    if( HasRowid(pTab) ){
      sqlite3VdbeAddOp2(v, OP_Rowid, iCur, reg);
    }else{
      pPk = sqlite3PrimaryKeyIndex(pTab);
    }
    for(i=0; i<pTab->nCol; i++){
      if( i!=iCol && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){
        int regOut;
        if( pPk ){
          int iPos = sqlite3TableColumnToIndex(pPk, i);
          int iColPos = sqlite3TableColumnToIndex(pPk, iCol);
          regOut = reg+1+iPos-(iPos>iColPos);
        }else{
          regOut = reg+1+nField;
        }
        sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOut);
        nField++;
      }
    }
    regRec = reg + pTab->nCol;
    sqlite3VdbeAddOp3(v, OP_MakeRecord, reg+1, nField, regRec);
    if( pPk ){
      sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iCur, regRec, reg+1, pPk->nKeyCol);
    }else{
      sqlite3VdbeAddOp3(v, OP_Insert, iCur, regRec, reg);
    }

    sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+1); VdbeCoverage(v);
    sqlite3VdbeJumpHere(v, addr);
  }

exit_drop_column:
  sqlite3DbFree(db, zCol);
  sqlite3SrcListDelete(db, pSrc);
}

/*
** Register built-in functions used to help implement ALTER TABLE
*/
void sqlite3AlterFunctions(void){
  static FuncDef aAlterTableFuncs[] = {
    INTERNAL_FUNCTION(sqlite_rename_column,  9, renameColumnFunc),
    INTERNAL_FUNCTION(sqlite_rename_table,   7, renameTableFunc),
    INTERNAL_FUNCTION(sqlite_rename_test,    6, renameTableTest),
    INTERNAL_FUNCTION(sqlite_drop_column,    3, dropColumnFunc),
  };
  sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
}
#endif  /* SQLITE_ALTER_TABLE */
Changes to src/attach.c.
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
    0, 0,             /* xValue, xInverse */
    "sqlite_attach",  /* zName */
    {0}
  };
  codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey);
}
#endif /* SQLITE_OMIT_ATTACH */

























































/*
** Initialize a DbFixer structure.  This routine must be called prior
** to passing the structure to one of the sqliteFixAAAA() routines below.
*/
void sqlite3FixInit(
  DbFixer *pFix,      /* The fixer to be initialized */
  Parse *pParse,      /* Error messages will be written here */
  int iDb,            /* This is the database that must be used */
  const char *zType,  /* "view", "trigger", or "index" */
  const Token *pName  /* Name of the view, trigger, or index */
){
  sqlite3 *db;

  db = pParse->db;
  assert( db->nDb>iDb );
  pFix->pParse = pParse;
  pFix->zDb = db->aDb[iDb].zDbSName;
  pFix->pSchema = db->aDb[iDb].pSchema;
  pFix->zType = zType;
  pFix->pName = pName;
  pFix->bTemp = (iDb==1);







}

/*
** The following set of routines walk through the parse tree and assign
** a specific database to all table references where the database name
** was left unspecified in the original SQL statement.  The pFix structure
** must have been initialized by a prior call to sqlite3FixInit().
**
** These routines are used to make sure that an index, trigger, or
** view in one database does not refer to objects in a different database.
** (Exception: indices, triggers, and views in the TEMP database are
** allowed to refer to anything.)  If a reference is explicitly made
** to an object in a different database, an error message is added to
** pParse->zErrMsg and these routines return non-zero.  If everything
** checks out, these routines return 0.
*/
int sqlite3FixSrcList(
  DbFixer *pFix,       /* Context of the fixation */
  SrcList *pList       /* The Source list to check and modify */
){
  int i;
  struct SrcList_item *pItem;
  sqlite3 *db = pFix->pParse->db;
  int iDb = sqlite3FindDbName(db, pFix->zDb);

  if( NEVER(pList==0) ) return 0;

  for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
    if( pFix->bTemp==0 ){
      if( pItem->zDatabase && iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){
        sqlite3ErrorMsg(pFix->pParse,
            "%s %T cannot reference objects in database %s",
            pFix->zType, pFix->pName, pItem->zDatabase);
        return 1;
      }
      sqlite3DbFree(db, pItem->zDatabase);
      pItem->zDatabase = 0;
      pItem->pSchema = pFix->pSchema;
      pItem->fg.fromDDL = 1;
    }
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
    if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
    if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
#endif
    if( pItem->fg.isTabFunc && sqlite3FixExprList(pFix, pItem->u1.pFuncArg) ){
      return 1;
    }
  }
  return 0;
}
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
int sqlite3FixSelect(
  DbFixer *pFix,       /* Context of the fixation */
  Select *pSelect      /* The SELECT statement to be fixed to one database */
){
  while( pSelect ){
    if( sqlite3FixExprList(pFix, pSelect->pEList) ){
      return 1;
    }
    if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){
      return 1;
    }
    if( sqlite3FixExpr(pFix, pSelect->pWhere) ){
      return 1;
    }
    if( sqlite3FixExprList(pFix, pSelect->pGroupBy) ){
      return 1;
    }
    if( sqlite3FixExpr(pFix, pSelect->pHaving) ){
      return 1;
    }
    if( sqlite3FixExprList(pFix, pSelect->pOrderBy) ){
      return 1;
    }
    if( sqlite3FixExpr(pFix, pSelect->pLimit) ){
      return 1;
    }
    if( pSelect->pWith ){
      int i;
      for(i=0; i<pSelect->pWith->nCte; i++){
        if( sqlite3FixSelect(pFix, pSelect->pWith->a[i].pSelect) ){
          return 1;
        }
      }
    }
    pSelect = pSelect->pPrior;
  }
  return 0;
}
int sqlite3FixExpr(
  DbFixer *pFix,     /* Context of the fixation */
  Expr *pExpr        /* The expression to be fixed to one database */
){
  while( pExpr ){
    if( !pFix->bTemp ) ExprSetProperty(pExpr, EP_FromDDL);
    if( pExpr->op==TK_VARIABLE ){
      if( pFix->pParse->db->init.busy ){
        pExpr->op = TK_NULL;
      }else{
        sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType);
        return 1;
      }
    }
    if( ExprHasProperty(pExpr, EP_TokenOnly|EP_Leaf) ) break;
    if( ExprHasProperty(pExpr, EP_xIsSelect) ){
      if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1;
    }else{
      if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1;
    }
    if( sqlite3FixExpr(pFix, pExpr->pRight) ){
      return 1;
    }
    pExpr = pExpr->pLeft;
  }
  return 0;
}
int sqlite3FixExprList(
  DbFixer *pFix,     /* Context of the fixation */
  ExprList *pList    /* The expression to be fixed to one database */
){
  int i;
  struct ExprList_item *pItem;
  if( pList==0 ) return 0;
  for(i=0, pItem=pList->a; i<pList->nExpr; i++, pItem++){
    if( sqlite3FixExpr(pFix, pItem->pExpr) ){
      return 1;
    }
  }
  return 0;
}
#endif

#ifndef SQLITE_OMIT_TRIGGER
int sqlite3FixTriggerStep(
  DbFixer *pFix,     /* Context of the fixation */
  TriggerStep *pStep /* The trigger step be fixed to one database */
){
  while( pStep ){
    if( sqlite3FixSelect(pFix, pStep->pSelect) ){
      return 1;
    }
    if( sqlite3FixExpr(pFix, pStep->pWhere) ){
      return 1;
    }
    if( sqlite3FixExprList(pFix, pStep->pExprList) ){
      return 1;
    }
    if( pStep->pFrom && sqlite3FixSrcList(pFix, pStep->pFrom) ){

      return 1;
    }
#ifndef SQLITE_OMIT_UPSERT
    if( pStep->pUpsert ){
      Upsert *pUp = pStep->pUpsert;
      if( sqlite3FixExprList(pFix, pUp->pUpsertTarget)
       || sqlite3FixExpr(pFix, pUp->pUpsertTargetWhere)
       || sqlite3FixExprList(pFix, pUp->pUpsertSet)
       || sqlite3FixExpr(pFix, pUp->pUpsertWhere)
      ){
        return 1;
      }
    }
#endif
    pStep = pStep->pNext;
  }

  return 0;
}
#endif







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>












|
<
<







>
>
>
>
>
>
>




















|
|
<
<
|
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
|
<
|






<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









|
<
<
|
<
<
|
<
<
|
>





|
|
|
|







>



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
    0, 0,             /* xValue, xInverse */
    "sqlite_attach",  /* zName */
    {0}
  };
  codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey);
}
#endif /* SQLITE_OMIT_ATTACH */

/*
** Expression callback used by sqlite3FixAAAA() routines.
*/
static int fixExprCb(Walker *p, Expr *pExpr){
  DbFixer *pFix = p->u.pFix;
  if( !pFix->bTemp ) ExprSetProperty(pExpr, EP_FromDDL);
  if( pExpr->op==TK_VARIABLE ){
    if( pFix->pParse->db->init.busy ){
      pExpr->op = TK_NULL;
    }else{
      sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType);
      return WRC_Abort;
    }
  }
  return WRC_Continue;
}

/*
** Select callback used by sqlite3FixAAAA() routines.
*/
static int fixSelectCb(Walker *p, Select *pSelect){
  DbFixer *pFix = p->u.pFix;
  int i;
  SrcItem *pItem;
  sqlite3 *db = pFix->pParse->db;
  int iDb = sqlite3FindDbName(db, pFix->zDb);
  SrcList *pList = pSelect->pSrc;

  if( NEVER(pList==0) ) return WRC_Continue;
  for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
    if( pFix->bTemp==0 ){
      if( pItem->zDatabase && iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){
        sqlite3ErrorMsg(pFix->pParse,
            "%s %T cannot reference objects in database %s",
            pFix->zType, pFix->pName, pItem->zDatabase);
        return WRC_Abort;
      }
      sqlite3DbFree(db, pItem->zDatabase);
      pItem->zDatabase = 0;
      pItem->pSchema = pFix->pSchema;
      pItem->fg.fromDDL = 1;
    }
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
    if( sqlite3WalkExpr(&pFix->w, pList->a[i].pOn) ) return WRC_Abort;
#endif
  }
  if( pSelect->pWith ){
    for(i=0; i<pSelect->pWith->nCte; i++){
      if( sqlite3WalkSelect(p, pSelect->pWith->a[i].pSelect) ){
        return WRC_Abort;
      }
    }
  }
  return WRC_Continue;
}

/*
** Initialize a DbFixer structure.  This routine must be called prior
** to passing the structure to one of the sqliteFixAAAA() routines below.
*/
void sqlite3FixInit(
  DbFixer *pFix,      /* The fixer to be initialized */
  Parse *pParse,      /* Error messages will be written here */
  int iDb,            /* This is the database that must be used */
  const char *zType,  /* "view", "trigger", or "index" */
  const Token *pName  /* Name of the view, trigger, or index */
){
  sqlite3 *db = pParse->db;


  assert( db->nDb>iDb );
  pFix->pParse = pParse;
  pFix->zDb = db->aDb[iDb].zDbSName;
  pFix->pSchema = db->aDb[iDb].pSchema;
  pFix->zType = zType;
  pFix->pName = pName;
  pFix->bTemp = (iDb==1);
  pFix->w.pParse = pParse;
  pFix->w.xExprCallback = fixExprCb;
  pFix->w.xSelectCallback = fixSelectCb;
  pFix->w.xSelectCallback2 = 0;
  pFix->w.walkerDepth = 0;
  pFix->w.eCode = 0;
  pFix->w.u.pFix = pFix;
}

/*
** The following set of routines walk through the parse tree and assign
** a specific database to all table references where the database name
** was left unspecified in the original SQL statement.  The pFix structure
** must have been initialized by a prior call to sqlite3FixInit().
**
** These routines are used to make sure that an index, trigger, or
** view in one database does not refer to objects in a different database.
** (Exception: indices, triggers, and views in the TEMP database are
** allowed to refer to anything.)  If a reference is explicitly made
** to an object in a different database, an error message is added to
** pParse->zErrMsg and these routines return non-zero.  If everything
** checks out, these routines return 0.
*/
int sqlite3FixSrcList(
  DbFixer *pFix,       /* Context of the fixation */
  SrcList *pList       /* The Source list to check and modify */
){
  int res = 0;
  if( pList ){


    Select s; 

    memset(&s, 0, sizeof(s));










    s.pSrc = pList;




    res = sqlite3WalkSelect(&pFix->w, &s);



  }

  return res;
}
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
int sqlite3FixSelect(
  DbFixer *pFix,       /* Context of the fixation */
  Select *pSelect      /* The SELECT statement to be fixed to one database */
){


  return sqlite3WalkSelect(&pFix->w, pSelect);






























}
int sqlite3FixExpr(
  DbFixer *pFix,     /* Context of the fixation */
  Expr *pExpr        /* The expression to be fixed to one database */
){







  return sqlite3WalkExpr(&pFix->w, pExpr);




























}
#endif

#ifndef SQLITE_OMIT_TRIGGER
int sqlite3FixTriggerStep(
  DbFixer *pFix,     /* Context of the fixation */
  TriggerStep *pStep /* The trigger step be fixed to one database */
){
  while( pStep ){
    if( sqlite3WalkSelect(&pFix->w, pStep->pSelect)


     || sqlite3WalkExpr(&pFix->w, pStep->pWhere) 


     || sqlite3WalkExprList(&pFix->w, pStep->pExprList)


     || sqlite3FixSrcList(pFix, pStep->pFrom)
    ){
      return 1;
    }
#ifndef SQLITE_OMIT_UPSERT
    if( pStep->pUpsert ){
      Upsert *pUp = pStep->pUpsert;
      if( sqlite3WalkExprList(&pFix->w, pUp->pUpsertTarget)
       || sqlite3WalkExpr(&pFix->w, pUp->pUpsertTargetWhere)
       || sqlite3WalkExprList(&pFix->w, pUp->pUpsertSet)
       || sqlite3WalkExpr(&pFix->w, pUp->pUpsertWhere)
      ){
        return 1;
      }
    }
#endif
    pStep = pStep->pNext;
  }

  return 0;
}
#endif
Changes to src/auth.c.
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
*/
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;
  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 */
  int iDb;              /* The index of the database the expression refers to */
  int iCol;             /* Index of column in table */

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

  if( pExpr->op==TK_TRIGGER ){
    pTab = pParse->pTriggerTab;
  }else{
    assert( pTabList );
    for(iSrc=0; ALWAYS(iSrc<pTabList->nSrc); iSrc++){
      if( pExpr->iTable==pTabList->a[iSrc].iCursor ){
        pTab = pTabList->a[iSrc].pTab;
        break;
      }
    }
  }
  iCol = pExpr->iColumn;
  if( NEVER(pTab==0) ) return;

  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 );
  if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){
    pExpr->op = TK_NULL;
  }
}

/*
** Do an authorization check using the code and arguments given.  Return







<







|
|











|







|










|







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
*/
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 */
){

  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 */
  int iDb;              /* The index of the database the expression refers to */
  int iCol;             /* Index of column in table */

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

  if( pExpr->op==TK_TRIGGER ){
    pTab = pParse->pTriggerTab;
  }else{
    assert( pTabList );
    for(iSrc=0; iSrc<pTabList->nSrc; iSrc++){
      if( pExpr->iTable==pTabList->a[iSrc].iCursor ){
        pTab = pTabList->a[iSrc].pTab;
        break;
      }
    }
  }
  iCol = pExpr->iColumn;
  if( pTab==0 ) return;

  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<pParse->db->nDb );
  if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){
    pExpr->op = TK_NULL;
  }
}

/*
** Do an authorization check using the code and arguments given.  Return
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
  sqlite3 *db = pParse->db;
  int rc;

  /* Don't do any authorization checks if the database is initialising
  ** or if the parser is being invoked from within sqlite3_declare_vtab.
  */
  assert( !IN_RENAME_OBJECT || db->xAuth==0 );
  if( db->init.busy || IN_SPECIAL_PARSE ){
    return SQLITE_OK;
  }

  if( db->xAuth==0 ){
    return SQLITE_OK;
  }

  /* EVIDENCE-OF: R-43249-19882 The third through sixth parameters to the
  ** callback are either NULL pointers or zero-terminated strings that
  ** contain additional details about the action to be authorized.
  **







<
<
<
<
|







204
205
206
207
208
209
210




211
212
213
214
215
216
217
218
  sqlite3 *db = pParse->db;
  int rc;

  /* Don't do any authorization checks if the database is initialising
  ** or if the parser is being invoked from within sqlite3_declare_vtab.
  */
  assert( !IN_RENAME_OBJECT || db->xAuth==0 );




  if( db->xAuth==0 || db->init.busy || IN_SPECIAL_PARSE ){
    return SQLITE_OK;
  }

  /* EVIDENCE-OF: R-43249-19882 The third through sixth parameters to the
  ** callback are either NULL pointers or zero-terminated strings that
  ** contain additional details about the action to be authorized.
  **
Changes to src/btree.c.
1378
1379
1380
1381
1382
1383
1384


















1385
1386
1387
1388
1389
1390
1391
  if( surplus <= maxLocal ){
    pInfo->nLocal = (u16)surplus;
  }else{
    pInfo->nLocal = (u16)minLocal;
  }
  pInfo->nSize = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell) + 4;
}



















/*
** The following routines are implementations of the MemPage.xParseCell()
** method.
**
** Parse a cell content block and fill in the CellInfo structure.
**







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
  if( surplus <= maxLocal ){
    pInfo->nLocal = (u16)surplus;
  }else{
    pInfo->nLocal = (u16)minLocal;
  }
  pInfo->nSize = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell) + 4;
}

/*
** Given a record with nPayload bytes of payload stored within btree
** page pPage, return the number of bytes of payload stored locally.
*/
static int btreePayloadToLocal(MemPage *pPage, i64 nPayload){
  int maxLocal;  /* Maximum amount of payload held locally */
  maxLocal = pPage->maxLocal;
  if( nPayload<=maxLocal ){
    return nPayload;
  }else{
    int minLocal;  /* Minimum amount of payload held locally */
    int surplus;   /* Overflow payload available for local storage */
    minLocal = pPage->minLocal;
    surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize-4);
    return ( surplus <= maxLocal ) ? surplus : minLocal;
  }
}

/*
** The following routines are implementations of the MemPage.xParseCell()
** method.
**
** Parse a cell content block and fill in the CellInfo structure.
**
3130
3131
3132
3133
3134
3135
3136

3137
3138
3139
3140
3141
3142
3143
    return SQLITE_READONLY;
  }
  assert( nReserve>=0 && nReserve<=255 );
  if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
        ((pageSize-1)&pageSize)==0 ){
    assert( (pageSize & 7)==0 );
    assert( !pBt->pCursor );

    pBt->pageSize = (u32)pageSize;
    freeTempSpace(pBt);
  }
  rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve);
  pBt->usableSize = pBt->pageSize - (u16)nReserve;
  if( iFix ) pBt->btsFlags |= BTS_PAGESIZE_FIXED;
  sqlite3BtreeLeave(p);







>







3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
    return SQLITE_READONLY;
  }
  assert( nReserve>=0 && nReserve<=255 );
  if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
        ((pageSize-1)&pageSize)==0 ){
    assert( (pageSize & 7)==0 );
    assert( !pBt->pCursor );
    if( nReserve>32 && pageSize==512 ) pageSize = 1024;
    pBt->pageSize = (u32)pageSize;
    freeTempSpace(pBt);
  }
  rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve);
  pBt->usableSize = pBt->pageSize - (u16)nReserve;
  if( iFix ) pBt->btsFlags |= BTS_PAGESIZE_FIXED;
  sqlite3BtreeLeave(p);
8624
8625
8626
8627
8628
8629
8630

8631

8632
8633
8634
8635
8636
8637
8638
  if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){
    pRight = &pParent->aData[pParent->hdrOffset+8];
  }else{
    pRight = findCell(pParent, i+nxDiv-pParent->nOverflow);
  }
  pgno = get4byte(pRight);
  while( 1 ){

    rc = getAndInitPage(pBt, pgno, &apOld[i], 0, 0);

    if( rc ){
      memset(apOld, 0, (i+1)*sizeof(MemPage*));
      goto balance_cleanup;
    }
    setMempageRoot(apOld[i], pgnoRoot);
    if( apOld[i]->nFree<0 ){
      rc = btreeComputeFreeSpace(apOld[i]);







>
|
>







8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658
8659
  if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){
    pRight = &pParent->aData[pParent->hdrOffset+8];
  }else{
    pRight = findCell(pParent, i+nxDiv-pParent->nOverflow);
  }
  pgno = get4byte(pRight);
  while( 1 ){
    if( rc==SQLITE_OK ){
      rc = getAndInitPage(pBt, pgno, &apOld[i], 0, 0);
    }
    if( rc ){
      memset(apOld, 0, (i+1)*sizeof(MemPage*));
      goto balance_cleanup;
    }
    setMempageRoot(apOld[i], pgnoRoot);
    if( apOld[i]->nFree<0 ){
      rc = btreeComputeFreeSpace(apOld[i]);
8664
8665
8666
8667
8668
8669
8670


8671
8672
8673
8674
8675
8676
8677
8678
8679
8680
8681
8682
8683
      ** the dropCell() routine will overwrite the entire cell with zeroes.
      ** 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.  */
      if( pBt->btsFlags & BTS_FAST_SECURE ){
        int iOff;



        iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData);
        if( (iOff+szNew[i])>(int)pBt->usableSize ){
          rc = SQLITE_CORRUPT_BKPT;
          memset(apOld, 0, (i+1)*sizeof(MemPage*));
          goto balance_cleanup;
        }else{
          memcpy(&aOvflSpace[iOff], apDiv[i], szNew[i]);
          apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData];
        }
      }
      dropCell(pParent, i+nxDiv-pParent->nOverflow, szNew[i], &rc);
    }
  }







>
>

|
<
<
<
<







8685
8686
8687
8688
8689
8690
8691
8692
8693
8694
8695




8696
8697
8698
8699
8700
8701
8702
      ** the dropCell() routine will overwrite the entire cell with zeroes.
      ** 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.  */
      if( pBt->btsFlags & BTS_FAST_SECURE ){
        int iOff;

        /* If the following if() condition is not true, the db is corrupted.
        ** The call to dropCell() below will detect this.  */
        iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData);
        if( (iOff+szNew[i])<=(int)pBt->usableSize ){




          memcpy(&aOvflSpace[iOff], apDiv[i], szNew[i]);
          apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData];
        }
      }
      dropCell(pParent, i+nxDiv-pParent->nOverflow, szNew[i], &rc);
    }
  }
8963
8964
8965
8966
8967
8968
8969



8970
8971
8972
8973
8974
8975
8976
  for(i=0; i<k; i++){
    MemPage *pNew;
    if( i<nOld ){
      pNew = apNew[i] = apOld[i];
      apOld[i] = 0;
      rc = sqlite3PagerWrite(pNew->pDbPage);
      nNew++;



      if( rc ) goto balance_cleanup;
    }else{
      assert( i>0 );
      rc = allocateBtreePage(pBt, &pNew, &pgno, (bBulk ? 1 : pgno), 0);
      if( rc ) goto balance_cleanup;
      zeroPage(pNew, pageFlags);
      apNew[i] = pNew;







>
>
>







8982
8983
8984
8985
8986
8987
8988
8989
8990
8991
8992
8993
8994
8995
8996
8997
8998
  for(i=0; i<k; i++){
    MemPage *pNew;
    if( i<nOld ){
      pNew = apNew[i] = apOld[i];
      apOld[i] = 0;
      rc = sqlite3PagerWrite(pNew->pDbPage);
      nNew++;
      if( sqlite3PagerPageRefcount(pNew->pDbPage)!=1+(i==(iParentIdx-nxDiv)) ){
        rc = SQLITE_CORRUPT_BKPT;
      }
      if( rc ) goto balance_cleanup;
    }else{
      assert( i>0 );
      rc = allocateBtreePage(pBt, &pNew, &pgno, (bBulk ? 1 : pgno), 0);
      if( rc ) goto balance_cleanup;
      zeroPage(pNew, pageFlags);
      apNew[i] = pNew;
8999
9000
9001
9002
9003
9004
9005
9006
9007
9008
9009
9010
9011
9012
9013
  ** When NB==3, this one optimization makes the database about 25% faster 
  ** for large insertions and deletions.
  */
  for(i=0; i<nNew; i++){
    aPgOrder[i] = aPgno[i] = apNew[i]->pgno;
    aPgFlags[i] = apNew[i]->pDbPage->flags;
    for(j=0; j<i; j++){
      if( aPgno[j]==aPgno[i] ){
        /* This branch is taken if the set of sibling pages somehow contains
        ** duplicate entries. This can happen if the database is corrupt. 
        ** It would be simpler to detect this as part of the loop below, but
        ** we do the detection here in order to avoid populating the pager
        ** cache with two separate objects associated with the same
        ** page number.  */
        assert( CORRUPT_DB );







|







9021
9022
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
9035
  ** When NB==3, this one optimization makes the database about 25% faster 
  ** for large insertions and deletions.
  */
  for(i=0; i<nNew; i++){
    aPgOrder[i] = aPgno[i] = apNew[i]->pgno;
    aPgFlags[i] = apNew[i]->pDbPage->flags;
    for(j=0; j<i; j++){
      if( NEVER(aPgno[j]==aPgno[i]) ){
        /* This branch is taken if the set of sibling pages somehow contains
        ** duplicate entries. This can happen if the database is corrupt. 
        ** It would be simpler to detect this as part of the loop below, but
        ** we do the detection here in order to avoid populating the pager
        ** cache with two separate objects associated with the same
        ** page number.  */
        assert( CORRUPT_DB );
9667
9668
9669
9670
9671
9672
9673
9674

9675
9676
9677
9678
9679
9680
9681
9682
9683
9684
9685
9686
9687
9688
9689
9690
9691
9692
9693
9694
9695
9696
9697
9698
9699
  int idx;
  MemPage *pPage;
  Btree *p = pCur->pBtree;
  BtShared *pBt = p->pBt;
  unsigned char *oldCell;
  unsigned char *newCell = 0;

  assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND))==flags );


  if( pCur->eState==CURSOR_FAULT ){
    assert( pCur->skipNext!=SQLITE_OK );
    return pCur->skipNext;
  }

  assert( cursorOwnsBtShared(pCur) );
  assert( (pCur->curFlags & BTCF_WriteFlag)!=0
              && pBt->inTransaction==TRANS_WRITE
              && (pBt->btsFlags & BTS_READ_ONLY)==0 );
  assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );

  /* 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( (pX->pKey==0)==(pCur->pKeyInfo==0) );

  /* Save the positions of any other cursors open on this table.
  **
  ** 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 







|
>

















|







9689
9690
9691
9692
9693
9694
9695
9696
9697
9698
9699
9700
9701
9702
9703
9704
9705
9706
9707
9708
9709
9710
9711
9712
9713
9714
9715
9716
9717
9718
9719
9720
9721
9722
  int idx;
  MemPage *pPage;
  Btree *p = pCur->pBtree;
  BtShared *pBt = p->pBt;
  unsigned char *oldCell;
  unsigned char *newCell = 0;

  assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags );
  assert( (flags & BTREE_PREFORMAT)==0 || seekResult || pCur->pKeyInfo==0 );

  if( pCur->eState==CURSOR_FAULT ){
    assert( pCur->skipNext!=SQLITE_OK );
    return pCur->skipNext;
  }

  assert( cursorOwnsBtShared(pCur) );
  assert( (pCur->curFlags & BTCF_WriteFlag)!=0
              && pBt->inTransaction==TRANS_WRITE
              && (pBt->btsFlags & BTS_READ_ONLY)==0 );
  assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );

  /* 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( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) );

  /* Save the positions of any other cursors open on this table.
  **
  ** 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 
9795
9796
9797
9798
9799
9800
9801
9802
9803
9804
9805
9806
9807
9808
9809
9810
9811
9812
9813
9814
9815
9816
9817
9818













9819

9820
9821
9822
9823
9824
9825
9826

  }
  assert( pCur->eState==CURSOR_VALID 
       || (pCur->eState==CURSOR_INVALID && loc)
       || CORRUPT_DB );

  pPage = pCur->pPage;
  assert( pPage->intKey || pX->nKey>=0 );
  assert( pPage->leaf || !pPage->intKey );
  if( pPage->nFree<0 ){
    if( pCur->eState>CURSOR_INVALID ){
      rc = SQLITE_CORRUPT_BKPT;
    }else{
      rc = btreeComputeFreeSpace(pPage);
    }
    if( rc ) return rc;
  }

  TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
          pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno,
          loc==0 ? "overwrite" : "new entry"));
  assert( pPage->isInit );
  newCell = pBt->pTmpSpace;
  assert( newCell!=0 );













  rc = fillInCell(pPage, newCell, pX, &szNew);

  if( rc ) goto end_insert;
  assert( szNew==pPage->xCellSize(pPage, newCell) );
  assert( szNew <= MX_CELL_SIZE(pBt) );
  idx = pCur->ix;
  if( loc==0 ){
    CellInfo info;
    assert( idx<pPage->nCell );







|
















>
>
>
>
>
>
>
>
>
>
>
>
>
|
>







9818
9819
9820
9821
9822
9823
9824
9825
9826
9827
9828
9829
9830
9831
9832
9833
9834
9835
9836
9837
9838
9839
9840
9841
9842
9843
9844
9845
9846
9847
9848
9849
9850
9851
9852
9853
9854
9855
9856
9857
9858
9859
9860
9861
9862
9863

  }
  assert( pCur->eState==CURSOR_VALID 
       || (pCur->eState==CURSOR_INVALID && loc)
       || CORRUPT_DB );

  pPage = pCur->pPage;
  assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) );
  assert( pPage->leaf || !pPage->intKey );
  if( pPage->nFree<0 ){
    if( pCur->eState>CURSOR_INVALID ){
      rc = SQLITE_CORRUPT_BKPT;
    }else{
      rc = btreeComputeFreeSpace(pPage);
    }
    if( rc ) return rc;
  }

  TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
          pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno,
          loc==0 ? "overwrite" : "new entry"));
  assert( pPage->isInit );
  newCell = pBt->pTmpSpace;
  assert( newCell!=0 );
  if( flags & BTREE_PREFORMAT ){
    rc = SQLITE_OK;
    szNew = pBt->nPreformatSize;
    if( szNew<4 ) szNew = 4;
    if( ISAUTOVACUUM && szNew>pPage->maxLocal ){
      CellInfo info;
      pPage->xParseCell(pPage, newCell, &info);
      if( info.nPayload!=info.nLocal ){
        Pgno ovfl = get4byte(&newCell[szNew-4]);
        ptrmapPut(pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, &rc);
      }
    }
  }else{
    rc = fillInCell(pPage, newCell, pX, &szNew);
  }
  if( rc ) goto end_insert;
  assert( szNew==pPage->xCellSize(pPage, newCell) );
  assert( szNew <= MX_CELL_SIZE(pBt) );
  idx = pCur->ix;
  if( loc==0 ){
    CellInfo info;
    assert( idx<pPage->nCell );
9916
9917
9918
9919
9920
9921
9922












































































































9923
9924
9925
9926
9927
9928
9929
      pCur->eState = CURSOR_REQUIRESEEK;
      pCur->nKey = pX->nKey;
    }
  }
  assert( pCur->iPage<0 || pCur->pPage->nOverflow==0 );

end_insert:












































































































  return rc;
}

/*
** Delete the entry that the cursor is pointing to. 
**
** If the BTREE_SAVEPOSITION bit of the flags parameter is zero, then







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







9953
9954
9955
9956
9957
9958
9959
9960
9961
9962
9963
9964
9965
9966
9967
9968
9969
9970
9971
9972
9973
9974
9975
9976
9977
9978
9979
9980
9981
9982
9983
9984
9985
9986
9987
9988
9989
9990
9991
9992
9993
9994
9995
9996
9997
9998
9999
10000
10001
10002
10003
10004
10005
10006
10007
10008
10009
10010
10011
10012
10013
10014
10015
10016
10017
10018
10019
10020
10021
10022
10023
10024
10025
10026
10027
10028
10029
10030
10031
10032
10033
10034
10035
10036
10037
10038
10039
10040
10041
10042
10043
10044
10045
10046
10047
10048
10049
10050
10051
10052
10053
10054
10055
10056
10057
10058
10059
10060
10061
10062
10063
10064
10065
10066
10067
10068
10069
10070
10071
10072
10073
10074
      pCur->eState = CURSOR_REQUIRESEEK;
      pCur->nKey = pX->nKey;
    }
  }
  assert( pCur->iPage<0 || pCur->pPage->nOverflow==0 );

end_insert:
  return rc;
}

/*
** This function is used as part of copying the current row from cursor
** pSrc into cursor pDest. If the cursors are open on intkey tables, then
** parameter iKey is used as the rowid value when the record is copied
** into pDest. Otherwise, the record is copied verbatim.
**
** This function does not actually write the new value to cursor pDest.
** Instead, it creates and populates any required overflow pages and
** writes the data for the new cell into the BtShared.pTmpSpace buffer
** for the destination database. The size of the cell, in bytes, is left
** in BtShared.nPreformatSize. The caller completes the insertion by
** calling sqlite3BtreeInsert() with the BTREE_PREFORMAT flag specified.
**
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
*/
int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){
  int rc = SQLITE_OK;
  BtShared *pBt = pDest->pBt;
  u8 *aOut = pBt->pTmpSpace;    /* Pointer to next output buffer */
  const u8 *aIn;                /* Pointer to next input buffer */
  u32 nIn;                      /* Size of input buffer aIn[] */
  u32 nRem;                     /* Bytes of data still to copy */

  getCellInfo(pSrc);
  aOut += putVarint32(aOut, pSrc->info.nPayload);
  if( pDest->pKeyInfo==0 ) aOut += putVarint(aOut, iKey);
  nIn = pSrc->info.nLocal;
  aIn = pSrc->info.pPayload;
  if( aIn+nIn>pSrc->pPage->aDataEnd ){
    return SQLITE_CORRUPT_BKPT;
  }
  nRem = pSrc->info.nPayload;
  if( nIn==nRem && nIn<pDest->pPage->maxLocal ){
    memcpy(aOut, aIn, nIn);
    pBt->nPreformatSize = nIn + (aOut - pBt->pTmpSpace);
  }else{
    Pager *pSrcPager = pSrc->pBt->pPager;
    u8 *pPgnoOut = 0;
    Pgno ovflIn = 0;
    DbPage *pPageIn = 0;
    MemPage *pPageOut = 0;
    u32 nOut;                     /* Size of output buffer aOut[] */

    nOut = btreePayloadToLocal(pDest->pPage, pSrc->info.nPayload);
    pBt->nPreformatSize = nOut + (aOut - pBt->pTmpSpace);
    if( nOut<pSrc->info.nPayload ){
      pPgnoOut = &aOut[nOut];
      pBt->nPreformatSize += 4;
    }
  
    if( nRem>nIn ){
      if( aIn+nIn+4>pSrc->pPage->aDataEnd ){
        return SQLITE_CORRUPT_BKPT;
      }
      ovflIn = get4byte(&pSrc->info.pPayload[nIn]);
    }
  
    do {
      nRem -= nOut;
      do{
        assert( nOut>0 );
        if( nIn>0 ){
          int nCopy = MIN(nOut, nIn);
          memcpy(aOut, aIn, nCopy);
          nOut -= nCopy;
          nIn -= nCopy;
          aOut += nCopy;
          aIn += nCopy;
        }
        if( nOut>0 ){
          sqlite3PagerUnref(pPageIn);
          pPageIn = 0;
          rc = sqlite3PagerGet(pSrcPager, ovflIn, &pPageIn, PAGER_GET_READONLY);
          if( rc==SQLITE_OK ){
            aIn = (const u8*)sqlite3PagerGetData(pPageIn);
            ovflIn = get4byte(aIn);
            aIn += 4;
            nIn = pSrc->pBt->usableSize - 4;
          }
        }
      }while( rc==SQLITE_OK && nOut>0 );
  
      if( rc==SQLITE_OK && nRem>0 ){
        Pgno pgnoNew;
        MemPage *pNew = 0;
        rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
        put4byte(pPgnoOut, pgnoNew);
        if( ISAUTOVACUUM && pPageOut ){
          ptrmapPut(pBt, pgnoNew, PTRMAP_OVERFLOW2, pPageOut->pgno, &rc);
        }
        releasePage(pPageOut);
        pPageOut = pNew;
        if( pPageOut ){
          pPgnoOut = pPageOut->aData;
          put4byte(pPgnoOut, 0);
          aOut = &pPgnoOut[4];
          nOut = MIN(pBt->usableSize - 4, nRem);
        }
      }
    }while( nRem>0 && rc==SQLITE_OK );
  
    releasePage(pPageOut);
    sqlite3PagerUnref(pPageIn);
  }

  return rc;
}

/*
** Delete the entry that the cursor is pointing to. 
**
** If the BTREE_SAVEPOSITION bit of the flags parameter is zero, then
Changes to src/btree.h.
258
259
260
261
262
263
264

265
266
267
268
269
270
271
int sqlite3BtreeCursorRestore(BtCursor*, int*);
int sqlite3BtreeDelete(BtCursor*, u8 flags);

/* Allowed flags for sqlite3BtreeDelete() and sqlite3BtreeInsert() */
#define BTREE_SAVEPOSITION 0x02  /* Leave cursor pointing at NEXT or PREV */
#define BTREE_AUXDELETE    0x04  /* not the primary delete operation */
#define BTREE_APPEND       0x08  /* Insert is likely an append */


/* An instance of the BtreePayload object describes the content of a single
** entry in either an index or table btree.
**
** Index btrees (used for indexes and also WITHOUT ROWID tables) contain
** an arbitrary key and no data.  These btrees have pKey,nKey set to the
** key and the pData,nData,nZero fields are uninitialized.  The aMem,nMem







>







258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
int sqlite3BtreeCursorRestore(BtCursor*, int*);
int sqlite3BtreeDelete(BtCursor*, u8 flags);

/* Allowed flags for sqlite3BtreeDelete() and sqlite3BtreeInsert() */
#define BTREE_SAVEPOSITION 0x02  /* Leave cursor pointing at NEXT or PREV */
#define BTREE_AUXDELETE    0x04  /* not the primary delete operation */
#define BTREE_APPEND       0x08  /* Insert is likely an append */
#define BTREE_PREFORMAT    0x80  /* Inserted data is a preformated cell */

/* An instance of the BtreePayload object describes the content of a single
** entry in either an index or table btree.
**
** Index btrees (used for indexes and also WITHOUT ROWID tables) contain
** an arbitrary key and no data.  These btrees have pKey,nKey set to the
** key and the pData,nData,nZero fields are uninitialized.  The aMem,nMem
358
359
360
361
362
363
364


365
366
367
368
369
370
371
int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
void sqlite3BtreeCursorList(Btree*);
#endif

#ifndef SQLITE_OMIT_WAL
  int sqlite3BtreeCheckpoint(Btree*, int, int *, int *);
#endif



/*
** If we are not using shared cache, then there is no need to
** use mutexes to access the BtShared structures.  So make the
** Enter and Leave procedures no-ops.
*/
#ifndef SQLITE_OMIT_SHARED_CACHE







>
>







359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
void sqlite3BtreeCursorList(Btree*);
#endif

#ifndef SQLITE_OMIT_WAL
  int sqlite3BtreeCheckpoint(Btree*, int, int *, int *);
#endif

int sqlite3BtreeTransferRow(BtCursor*, BtCursor*, i64);

/*
** If we are not using shared cache, then there is no need to
** use mutexes to access the BtShared structures.  So make the
** Enter and Leave procedures no-ops.
*/
#ifndef SQLITE_OMIT_SHARED_CACHE
Changes to src/btreeInt.h.
458
459
460
461
462
463
464

465
466
467
468
469
470
471
  BtLock *pLock;        /* List of locks held on this shared-btree struct */
  Btree *pWriter;       /* Btree with currently open write transaction */
#endif
  u8 *pTmpSpace;        /* Temp space sufficient to hold a single cell */
#ifndef SQLITE_OMIT_CONCURRENT
  BtreePtrmap *pMap;
#endif

};

/*
** Allowed values for BtShared.btsFlags
*/
#define BTS_READ_ONLY        0x0001   /* Underlying file is readonly */
#define BTS_PAGESIZE_FIXED   0x0002   /* Page size can no longer be changed */







>







458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
  BtLock *pLock;        /* List of locks held on this shared-btree struct */
  Btree *pWriter;       /* Btree with currently open write transaction */
#endif
  u8 *pTmpSpace;        /* Temp space sufficient to hold a single cell */
#ifndef SQLITE_OMIT_CONCURRENT
  BtreePtrmap *pMap;
#endif
  int nPreformatSize;   /* Size of last cell written by TransferRow() */
};

/*
** Allowed values for BtShared.btsFlags
*/
#define BTS_READ_ONLY        0x0001   /* Underlying file is readonly */
#define BTS_PAGESIZE_FIXED   0x0002   /* Page size can no longer be changed */
Changes to src/build.c.
141
142
143
144
145
146
147






148


149
150
151


















152
153
154
155
156
157
158
    if( pParse->rc==SQLITE_OK ) pParse->rc = SQLITE_ERROR;
    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);

#if SQLITE_USER_AUTHENTICATION
    if( pParse->nTableLock>0 && db->init.busy==0 ){
      sqlite3UserAuthInit(db);
      if( db->auth.authLevel<UAUTH_User ){
        sqlite3ErrorMsg(pParse, "user not authenticated");







>
>
>
>
>
>
|
>
>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    if( pParse->rc==SQLITE_OK ) pParse->rc = SQLITE_ERROR;
    return;
  }

  /* Begin by generating some termination code at the end of the
  ** vdbe program
  */
  v = pParse->pVdbe;
  if( v==0 ){
    if( db->init.busy ){
      pParse->rc = SQLITE_DONE;
      return;
    }
    v = sqlite3GetVdbe(pParse);
    if( v==0 ) pParse->rc = SQLITE_ERROR;
  }
  assert( !pParse->isMultiWrite 
       || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
  if( v ){
    if( pParse->bReturning ){
      Returning *pReturning = pParse->u1.pReturning;
      int addrRewind;
      int i;
      int reg;

      addrRewind =
         sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur);
      VdbeCoverage(v);
      reg = pReturning->iRetReg;
      for(i=0; i<pReturning->nRetCol; i++){
        sqlite3VdbeAddOp3(v, OP_Column, pReturning->iRetCur, i, reg+i);
      }
      sqlite3VdbeAddOp2(v, OP_ResultRow, reg, i);
      sqlite3VdbeAddOp2(v, OP_Next, pReturning->iRetCur, addrRewind+1);
      VdbeCoverage(v);
      sqlite3VdbeJumpHere(v, addrRewind);
    }
    sqlite3VdbeAddOp0(v, OP_Halt);

#if SQLITE_USER_AUTHENTICATION
    if( pParse->nTableLock>0 && db->init.busy==0 ){
      sqlite3UserAuthInit(db);
      if( db->auth.authLevel<UAUTH_User ){
        sqlite3ErrorMsg(pParse, "user not authenticated");
221
222
223
224
225
226
227





228
229
230
231
232
233
234
235
236
237
238
239
240
        for(i=0; i<pEL->nExpr; i++){
          int iReg = pEL->a[i].u.iConstExprReg;
          if( iReg>0 ){
            sqlite3ExprCode(pParse, pEL->a[i].pExpr, iReg);
          }
        }
      }






      /* Finally, jump back to the beginning of the executable code. */
      sqlite3VdbeGoto(v, 1);
    }
  }


  /* Get the VDBE program ready for execution
  */
  if( v && pParse->nErr==0 && !db->mallocFailed ){
    /* A minimum of one cursor is required if autoincrement is used
    *  See ticket [a696379c1f08866] */
    assert( pParse->pAinc==0 || pParse->nTab>0 );







>
>
>
>
>





<







247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
        for(i=0; i<pEL->nExpr; i++){
          int iReg = pEL->a[i].u.iConstExprReg;
          if( iReg>0 ){
            sqlite3ExprCode(pParse, pEL->a[i].pExpr, iReg);
          }
        }
      }

      if( pParse->bReturning ){
        Returning *pRet = pParse->u1.pReturning;
        sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol);
      }

      /* Finally, jump back to the beginning of the executable code. */
      sqlite3VdbeGoto(v, 1);
    }
  }


  /* Get the VDBE program ready for execution
  */
  if( v && pParse->nErr==0 && !db->mallocFailed ){
    /* A minimum of one cursor is required if autoincrement is used
    *  See ticket [a696379c1f08866] */
    assert( pParse->pAinc==0 || pParse->nTab>0 );
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
** the search to schema (p->pSchema) if it is not NULL. p->pSchema may be
** non-NULL if it is part of a view or trigger program definition. See
** sqlite3FixSrcList() for details.
*/
Table *sqlite3LocateTableItem(
  Parse *pParse, 
  u32 flags,
  struct SrcList_item *p
){
  const char *zDb;
  assert( p->pSchema==0 || p->zDatabase==0 );
  if( p->pSchema ){
    int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
    zDb = pParse->db->aDb[iDb].zDbSName;
  }else{







|







476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
** the search to schema (p->pSchema) if it is not NULL. p->pSchema may be
** non-NULL if it is part of a view or trigger program definition. See
** sqlite3FixSrcList() for details.
*/
Table *sqlite3LocateTableItem(
  Parse *pParse, 
  u32 flags,
  SrcItem *p
){
  const char *zDb;
  assert( p->pSchema==0 || p->zDatabase==0 );
  if( p->pSchema ){
    int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
    zDb = pParse->db->aDb[iDb].zDbSName;
  }else{
1204
1205
1206
1207
1208
1209
1210

1211
1212
1213
1214
1215
1216
1217
1218
    */
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
    if( isView || isVirtual ){
      sqlite3VdbeAddOp2(v, OP_Integer, 0, reg2);
    }else
#endif
    {

      pParse->addrCrTab =
         sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY);
    }
    sqlite3OpenSchemaTable(pParse, iDb);
    sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
    sqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC);
    sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
    sqlite3VdbeChangeP5(v, OPFLAG_APPEND);







>
|







1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
    */
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
    if( isView || isVirtual ){
      sqlite3VdbeAddOp2(v, OP_Integer, 0, reg2);
    }else
#endif
    {
      assert( !pParse->bReturning );
      pParse->u1.addrCrTab =
         sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY);
    }
    sqlite3OpenSchemaTable(pParse, iDb);
    sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
    sqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC);
    sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
    sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
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
/* Set properties of a table column based on the (magical)
** name of the column.
*/
#if SQLITE_ENABLE_HIDDEN_COLUMNS
void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){
  if( sqlite3_strnicmp(pCol->zName, "__hidden__", 10)==0 ){
    pCol->colFlags |= COLFLAG_HIDDEN;

  }else if( pTab && pCol!=pTab->aCol && (pCol[-1].colFlags & COLFLAG_HIDDEN) ){
    pTab->tabFlags |= TF_OOOHidden;
  }
}
#endif










































































/*
** Add a new column to the table currently being constructed.
**
** The parser calls this routine once for each column declaration
** in a CREATE TABLE statement.  sqlite3StartTable() gets called
** first to get things going.  Then this routine is called for each
** column.
*/
void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
  Table *p;
  int i;
  char *z;
  char *zType;
  Column *pCol;
  sqlite3 *db = pParse->db;


  if( (p = pParse->pNewTable)==0 ) return;
  if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){
    sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName);
    return;
  }
  z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2);
  if( z==0 ) return;
  if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, pName);
  memcpy(z, pName->z, pName->n);
  z[pName->n] = 0;
  sqlite3Dequote(z);

  for(i=0; i<p->nCol; i++){
    if( sqlite3_stricmp(z, p->aCol[i].zName)==0 ){
      sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);
      sqlite3DbFree(db, z);
      return;
    }
  }
  if( (p->nCol & 0x7)==0 ){
    Column *aNew;
    aNew = sqlite3DbRealloc(db,p->aCol,(p->nCol+8)*sizeof(p->aCol[0]));
    if( aNew==0 ){
      sqlite3DbFree(db, z);
      return;
    }
    p->aCol = aNew;
  }
  pCol = &p->aCol[p->nCol];
  memset(pCol, 0, sizeof(p->aCol[0]));
  pCol->zName = z;
  pCol->hName = sqlite3StrIHash(z);
  sqlite3ColumnPropertiesFromName(p, pCol);
 
  if( pType->n==0 ){
    /* If there is no type specified, columns have the default affinity
    ** 'BLOB' with a default size of 4 bytes. */
    pCol->affinity = SQLITE_AFF_BLOB;
    pCol->szEst = 1;







>






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
















>
>











>

|

















|







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
/* Set properties of a table column based on the (magical)
** name of the column.
*/
#if SQLITE_ENABLE_HIDDEN_COLUMNS
void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){
  if( sqlite3_strnicmp(pCol->zName, "__hidden__", 10)==0 ){
    pCol->colFlags |= COLFLAG_HIDDEN;
    if( pTab ) pTab->tabFlags |= TF_HasHidden;
  }else if( pTab && pCol!=pTab->aCol && (pCol[-1].colFlags & COLFLAG_HIDDEN) ){
    pTab->tabFlags |= TF_OOOHidden;
  }
}
#endif

/*
** Name of the special TEMP trigger used to implement RETURNING.  The
** name begins with "sqlite_" so that it is guaranteed not to collide
** with any application-generated triggers.
*/
#define RETURNING_TRIGGER_NAME  "sqlite_returning"

/*
** Clean up the data structures associated with the RETURNING clause.
*/
static void sqlite3DeleteReturning(sqlite3 *db, Returning *pRet){
  Hash *pHash;
  pHash = &(db->aDb[1].pSchema->trigHash);
  sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, 0);
  sqlite3ExprListDelete(db, pRet->pReturnEL);
  sqlite3DbFree(db, pRet);
}

/*
** Add the RETURNING clause to the parse currently underway.
**
** This routine creates a special TEMP trigger that will fire for each row
** of the DML statement.  That TEMP trigger contains a single SELECT
** statement with a result set that is the argument of the RETURNING clause.
** The trigger has the Trigger.bReturning flag and an opcode of
** TK_RETURNING instead of TK_SELECT, so that the trigger code generator
** knows to handle it specially.  The TEMP trigger is automatically
** removed at the end of the parse.
**
** When this routine is called, we do not yet know if the RETURNING clause
** is attached to a DELETE, INSERT, or UPDATE, so construct it as a
** RETURNING trigger instead.  It will then be converted into the appropriate
** type on the first call to sqlite3TriggersExist().
*/
void sqlite3AddReturning(Parse *pParse, ExprList *pList){
  Returning *pRet;
  Hash *pHash;
  sqlite3 *db = pParse->db;
  if( pParse->pNewTrigger ){
    sqlite3ErrorMsg(pParse, "cannot use RETURNING in a trigger");
  }else{
    assert( pParse->bReturning==0 );
  }
  pParse->bReturning = 1;
  pRet = sqlite3DbMallocZero(db, sizeof(*pRet));
  if( pRet==0 ){
    sqlite3ExprListDelete(db, pList);
    return;
  }
  pParse->u1.pReturning = pRet;
  pRet->pParse = pParse;
  pRet->pReturnEL = pList;
  sqlite3ParserAddCleanup(pParse,
     (void(*)(sqlite3*,void*))sqlite3DeleteReturning, pRet);
  testcase( pParse->earlyCleanup );
  if( db->mallocFailed ) return;
  pRet->retTrig.zName = RETURNING_TRIGGER_NAME;
  pRet->retTrig.op = TK_RETURNING;
  pRet->retTrig.tr_tm = TRIGGER_AFTER;
  pRet->retTrig.bReturning = 1;
  pRet->retTrig.pSchema = db->aDb[1].pSchema;
  pRet->retTrig.step_list = &pRet->retTStep;
  pRet->retTStep.op = TK_RETURNING;
  pRet->retTStep.pTrig = &pRet->retTrig;
  pRet->retTStep.pExprList = pList;
  pHash = &(db->aDb[1].pSchema->trigHash);
  assert( sqlite3HashFind(pHash, RETURNING_TRIGGER_NAME)==0 || pParse->nErr );
  if( sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, &pRet->retTrig)
          ==&pRet->retTrig ){
    sqlite3OomFault(db);
  }
}

/*
** Add a new column to the table currently being constructed.
**
** The parser calls this routine once for each column declaration
** in a CREATE TABLE statement.  sqlite3StartTable() gets called
** first to get things going.  Then this routine is called for each
** column.
*/
void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
  Table *p;
  int i;
  char *z;
  char *zType;
  Column *pCol;
  sqlite3 *db = pParse->db;
  u8 hName;

  if( (p = pParse->pNewTable)==0 ) return;
  if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){
    sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName);
    return;
  }
  z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2);
  if( z==0 ) return;
  if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, pName);
  memcpy(z, pName->z, pName->n);
  z[pName->n] = 0;
  sqlite3Dequote(z);
  hName = sqlite3StrIHash(z);
  for(i=0; i<p->nCol; i++){
    if( p->aCol[i].hName==hName && sqlite3StrICmp(z, p->aCol[i].zName)==0 ){
      sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);
      sqlite3DbFree(db, z);
      return;
    }
  }
  if( (p->nCol & 0x7)==0 ){
    Column *aNew;
    aNew = sqlite3DbRealloc(db,p->aCol,(p->nCol+8)*sizeof(p->aCol[0]));
    if( aNew==0 ){
      sqlite3DbFree(db, z);
      return;
    }
    p->aCol = aNew;
  }
  pCol = &p->aCol[p->nCol];
  memset(pCol, 0, sizeof(p->aCol[0]));
  pCol->zName = z;
  pCol->hName = hName;
  sqlite3ColumnPropertiesFromName(p, pCol);
 
  if( pType->n==0 ){
    /* If there is no type specified, columns have the default affinity
    ** 'BLOB' with a default size of 4 bytes. */
    pCol->affinity = SQLITE_AFF_BLOB;
    pCol->szEst = 1;
2066
2067
2068
2069
2070
2071
2072

2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
    }
    pTab->tabFlags |= TF_HasNotNull;
  }

  /* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY
  ** into BTREE_BLOBKEY.
  */

  if( pParse->addrCrTab ){
    assert( v );
    sqlite3VdbeChangeP3(v, pParse->addrCrTab, BTREE_BLOBKEY);
  }

  /* Locate the PRIMARY KEY index.  Or, if this table was originally
  ** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index. 
  */
  if( pTab->iPKey>=0 ){
    ExprList *pList;







>
|

|







2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
    }
    pTab->tabFlags |= TF_HasNotNull;
  }

  /* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY
  ** into BTREE_BLOBKEY.
  */
  assert( !pParse->bReturning );
  if( pParse->u1.addrCrTab ){
    assert( v );
    sqlite3VdbeChangeP3(v, pParse->u1.addrCrTab, BTREE_BLOBKEY);
  }

  /* Locate the PRIMARY KEY index.  Or, if this table was originally
  ** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index. 
  */
  if( pTab->iPKey>=0 ){
    ExprList *pList;
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
        );
      }
    }
#endif

    /* Reparse everything to update our internal data structures */
    sqlite3VdbeAddParseSchemaOp(v, iDb,
           sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName));
  }

  /* Add the table to the in-memory representation of the database.
  */
  if( db->init.busy ){
    Table *pOld;
    Schema *pSchema = p->pSchema;
    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
    pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p);
    if( pOld ){
      assert( p==pOld );  /* Malloc must have failed inside HashInsert() */
      sqlite3OomFault(db);
      return;
    }
    pParse->pNewTable = 0;
    db->mDbFlags |= DBFLAG_SchemaChange;


#ifndef SQLITE_OMIT_ALTERTABLE
    if( !p->pSelect ){
      const char *zName = (const char *)pParse->sNameToken.z;
      int nName;
      assert( !pSelect && pCons && pEnd );
      if( pCons->z==0 ){
        pCons = pEnd;
      }
      nName = (int)((const char *)pCons->z - zName);
      p->addColOffset = 13 + sqlite3Utf8CharLen(zName, nName);
    }
#endif
  }
}

#ifndef SQLITE_OMIT_VIEW
/*
** The parser calls this routine in order to create a new VIEW
*/
void sqlite3CreateView(







|
















|
>

|
<
<
|
|
|
|
<
|
|

<







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
        );
      }
    }
#endif

    /* Reparse everything to update our internal data structures */
    sqlite3VdbeAddParseSchemaOp(v, iDb,
           sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName),0);
  }

  /* Add the table to the in-memory representation of the database.
  */
  if( db->init.busy ){
    Table *pOld;
    Schema *pSchema = p->pSchema;
    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
    pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p);
    if( pOld ){
      assert( p==pOld );  /* Malloc must have failed inside HashInsert() */
      sqlite3OomFault(db);
      return;
    }
    pParse->pNewTable = 0;
    db->mDbFlags |= DBFLAG_SchemaChange;
  }

#ifndef SQLITE_OMIT_ALTERTABLE
  if( !pSelect && !p->pSelect ){


    assert( pCons && pEnd );
    if( pCons->z==0 ){
      pCons = pEnd;
    }

    p->addColOffset = 13 + (int)(pCons->z - pParse->sNameToken.z);
  }
#endif

}

#ifndef SQLITE_OMIT_VIEW
/*
** The parser calls this routine in order to create a new VIEW
*/
void sqlite3CreateView(
2753
2754
2755
2756
2757
2758
2759

2760
2761
2762
2763
2764
2765
2766
    }else{
      /* CREATE VIEW name AS...  without an argument list.  Construct
      ** the column names from the SELECT statement that defines the view.
      */
      assert( pTable->aCol==0 );
      pTable->nCol = pSelTab->nCol;
      pTable->aCol = pSelTab->aCol;

      pSelTab->nCol = 0;
      pSelTab->aCol = 0;
      assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) );
    }
    pTable->nNVCol = pTable->nCol;
    sqlite3DeleteTable(db, pSelTab);
    sqlite3SelectDelete(db, pSel);







>







2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
    }else{
      /* CREATE VIEW name AS...  without an argument list.  Construct
      ** the column names from the SELECT statement that defines the view.
      */
      assert( pTable->aCol==0 );
      pTable->nCol = pSelTab->nCol;
      pTable->aCol = pSelTab->aCol;
      pTable->tabFlags |= (pSelTab->tabFlags & COLFLAG_NOINSERT);
      pSelTab->nCol = 0;
      pSelTab->aCol = 0;
      assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) );
    }
    pTable->nNVCol = pTable->nCol;
    sqlite3DeleteTable(db, pSelTab);
    sqlite3SelectDelete(db, pSel);
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
      /* Fill the index with data and reparse the schema. Code an OP_Expire
      ** to invalidate all pre-compiled statements.
      */
      if( pTblName ){
        sqlite3RefillIndex(pParse, pIndex, iMem);
        sqlite3ChangeCookie(pParse, iDb);
        sqlite3VdbeAddParseSchemaOp(v, iDb,
            sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
        sqlite3VdbeAddOp2(v, OP_Expire, 0, 1);
      }

      sqlite3VdbeJumpHere(v, (int)pIndex->tnum);
    }
  }
  if( db->init.busy || pTblName==0 ){







|







4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
      /* Fill the index with data and reparse the schema. Code an OP_Expire
      ** to invalidate all pre-compiled statements.
      */
      if( pTblName ){
        sqlite3RefillIndex(pParse, pIndex, iMem);
        sqlite3ChangeCookie(pParse, iDb);
        sqlite3VdbeAddParseSchemaOp(v, iDb,
            sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName), 0);
        sqlite3VdbeAddOp2(v, OP_Expire, 0, 1);
      }

      sqlite3VdbeJumpHere(v, (int)pIndex->tnum);
    }
  }
  if( db->init.busy || pTblName==0 ){
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
*/
SrcList *sqlite3SrcListAppend(
  Parse *pParse,      /* Parsing context, in which errors are reported */
  SrcList *pList,     /* Append to this SrcList. NULL creates a new SrcList */
  Token *pTable,      /* Table to append */
  Token *pDatabase    /* Database of the table */
){
  struct SrcList_item *pItem;
  sqlite3 *db;
  assert( pDatabase==0 || pTable!=0 );  /* Cannot have C without B */
  assert( pParse!=0 );
  assert( pParse->db!=0 );
  db = pParse->db;
  if( pList==0 ){
    pList = sqlite3DbMallocRawNN(pParse->db, sizeof(SrcList) );







|







4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
*/
SrcList *sqlite3SrcListAppend(
  Parse *pParse,      /* Parsing context, in which errors are reported */
  SrcList *pList,     /* Append to this SrcList. NULL creates a new SrcList */
  Token *pTable,      /* Table to append */
  Token *pDatabase    /* Database of the table */
){
  SrcItem *pItem;
  sqlite3 *db;
  assert( pDatabase==0 || pTable!=0 );  /* Cannot have C without B */
  assert( pParse!=0 );
  assert( pParse->db!=0 );
  db = pParse->db;
  if( pList==0 ){
    pList = sqlite3DbMallocRawNN(pParse->db, sizeof(SrcList) );
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
}

/*
** Assign VdbeCursor index numbers to all tables in a SrcList
*/
void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
  int i;
  struct SrcList_item *pItem;
  assert(pList || pParse->db->mallocFailed );
  if( pList ){
    for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
      if( pItem->iCursor>=0 ) continue;
      pItem->iCursor = pParse->nTab++;
      if( pItem->pSelect ){
        sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc);
      }
    }
  }
}

/*
** Delete an entire SrcList including all its substructure.
*/
void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
  int i;
  struct SrcList_item *pItem;
  if( pList==0 ) return;
  for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){
    if( pItem->zDatabase ) sqlite3DbFreeNN(db, pItem->zDatabase);
    sqlite3DbFree(db, pItem->zName);
    if( pItem->zAlias ) sqlite3DbFreeNN(db, pItem->zAlias);
    if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy);
    if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg);







|

















|







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
4589
4590
4591
4592
}

/*
** Assign VdbeCursor index numbers to all tables in a SrcList
*/
void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
  int i;
  SrcItem *pItem;
  assert(pList || pParse->db->mallocFailed );
  if( pList ){
    for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
      if( pItem->iCursor>=0 ) continue;
      pItem->iCursor = pParse->nTab++;
      if( pItem->pSelect ){
        sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc);
      }
    }
  }
}

/*
** Delete an entire SrcList including all its substructure.
*/
void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
  int i;
  SrcItem *pItem;
  if( pList==0 ) return;
  for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){
    if( pItem->zDatabase ) sqlite3DbFreeNN(db, pItem->zDatabase);
    sqlite3DbFree(db, pItem->zName);
    if( pItem->zAlias ) sqlite3DbFreeNN(db, pItem->zAlias);
    if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy);
    if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg);
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
  Token *pTable,          /* Name of the table to add to the FROM clause */
  Token *pDatabase,       /* Name of the database containing pTable */
  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;
  }







|







4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
  Token *pTable,          /* Name of the table to add to the FROM clause */
  Token *pDatabase,       /* Name of the database containing pTable */
  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 */
){
  SrcItem *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;
  }
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
/*
** 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){
  assert( pIndexedBy!=0 );
  if( p && pIndexedBy->n>0 ){
    struct SrcList_item *pItem;
    assert( p->nSrc>0 );
    pItem = &p->a[p->nSrc-1];
    assert( pItem->fg.notIndexed==0 );
    assert( pItem->fg.isIndexedBy==0 );
    assert( pItem->fg.isTabFunc==0 );
    if( pIndexedBy->n==1 && !pIndexedBy->z ){
      /* A "NOT INDEXED" clause was supplied. See parse.y 







|







4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
/*
** 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){
  assert( pIndexedBy!=0 );
  if( p && pIndexedBy->n>0 ){
    SrcItem *pItem;
    assert( p->nSrc>0 );
    pItem = &p->a[p->nSrc-1];
    assert( pItem->fg.notIndexed==0 );
    assert( pItem->fg.isIndexedBy==0 );
    assert( pItem->fg.isTabFunc==0 );
    if( pIndexedBy->n==1 && !pIndexedBy->z ){
      /* A "NOT INDEXED" clause was supplied. See parse.y 
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
  assert( p1 && p1->nSrc==1 );
  if( p2 ){
    SrcList *pNew = sqlite3SrcListEnlarge(pParse, p1, p2->nSrc, 1);
    if( pNew==0 ){
      sqlite3SrcListDelete(pParse->db, p2);
    }else{
      p1 = pNew;
      memcpy(&p1->a[1], p2->a, p2->nSrc*sizeof(struct SrcList_item));
      sqlite3DbFree(pParse->db, p2);
    }
  }
  return p1;
}

/*
** Add the list of function arguments to the SrcList entry for a
** table-valued-function.
*/
void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){
  if( p ){
    struct SrcList_item *pItem = &p->a[p->nSrc-1];
    assert( pItem->fg.notIndexed==0 );
    assert( pItem->fg.isIndexedBy==0 );
    assert( pItem->fg.isTabFunc==0 );
    pItem->u1.pFuncArg = pList;
    pItem->fg.isTabFunc = 1;
  }else{
    sqlite3ExprListDelete(pParse->db, pList);







|












|







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
  assert( p1 && p1->nSrc==1 );
  if( p2 ){
    SrcList *pNew = sqlite3SrcListEnlarge(pParse, p1, p2->nSrc, 1);
    if( pNew==0 ){
      sqlite3SrcListDelete(pParse->db, p2);
    }else{
      p1 = pNew;
      memcpy(&p1->a[1], p2->a, p2->nSrc*sizeof(SrcItem));
      sqlite3DbFree(pParse->db, p2);
    }
  }
  return p1;
}

/*
** Add the list of function arguments to the SrcList entry for a
** table-valued-function.
*/
void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){
  if( p ){
    SrcItem *pItem = &p->a[p->nSrc-1];
    assert( pItem->fg.notIndexed==0 );
    assert( pItem->fg.isIndexedBy==0 );
    assert( pItem->fg.isTabFunc==0 );
    pItem->u1.pFuncArg = pList;
    pItem->fg.isTabFunc = 1;
  }else{
    sqlite3ExprListDelete(pParse->db, pList);
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
** for database iDb.  The code to actually verify the schema cookie
** will occur at the end of the top-level VDBE and will be generated
** later, by sqlite3FinishCoding().
*/
static void sqlite3CodeVerifySchemaAtToplevel(Parse *pToplevel, int iDb){
  assert( iDb>=0 && iDb<pToplevel->db->nDb );
  assert( pToplevel->db->aDb[iDb].pBt!=0 || iDb==1 );
  assert( iDb<SQLITE_MAX_ATTACHED+2 );
  assert( sqlite3SchemaMutexHeld(pToplevel->db, iDb, 0) );
  if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){
    DbMaskSet(pToplevel->cookieMask, iDb);
    if( !OMIT_TEMPDB && iDb==1 ){
      sqlite3OpenTempDatabase(pToplevel);
    }
  }







|







4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
** for database iDb.  The code to actually verify the schema cookie
** will occur at the end of the top-level VDBE and will be generated
** later, by sqlite3FinishCoding().
*/
static void sqlite3CodeVerifySchemaAtToplevel(Parse *pToplevel, int iDb){
  assert( iDb>=0 && iDb<pToplevel->db->nDb );
  assert( pToplevel->db->aDb[iDb].pBt!=0 || iDb==1 );
  assert( iDb<SQLITE_MAX_DB );
  assert( sqlite3SchemaMutexHeld(pToplevel->db, iDb, 0) );
  if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){
    DbMaskSet(pToplevel->cookieMask, iDb);
    if( !OMIT_TEMPDB && iDb==1 ){
      sqlite3OpenTempDatabase(pToplevel);
    }
  }
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
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
      pKey = 0;
    }
  }
  return pKey;
}

#ifndef SQLITE_OMIT_CTE
/* 
















































** This routine is invoked once per CTE by the parser while parsing a 
** WITH clause. 


*/
With *sqlite3WithAdd(
  Parse *pParse,          /* Parsing context */
  With *pWith,            /* Existing WITH clause, or NULL */
  Token *pName,           /* Name of the common-table */
  ExprList *pArglist,     /* Optional column name list for the table */
  Select *pQuery          /* Query used to initialize the table */
){
  sqlite3 *db = pParse->db;
  With *pNew;
  char *zName;





  /* Check that the CTE name is unique within this WITH clause. If
  ** not, store an error in the Parse structure. */
  zName = sqlite3NameFromToken(pParse->db, pName);
  if( zName && pWith ){
    int i;
    for(i=0; i<pWith->nCte; i++){
      if( sqlite3StrICmp(zName, pWith->a[i].zName)==0 ){
        sqlite3ErrorMsg(pParse, "duplicate WITH table name: %s", zName);
      }
    }
  }

  if( pWith ){
    sqlite3_int64 nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte);
    pNew = sqlite3DbRealloc(db, pWith, nByte);
  }else{
    pNew = sqlite3DbMallocZero(db, sizeof(*pWith));
  }
  assert( (pNew!=0 && zName!=0) || db->mallocFailed );

  if( db->mallocFailed ){
    sqlite3ExprListDelete(db, pArglist);
    sqlite3SelectDelete(db, pQuery);
    sqlite3DbFree(db, zName);
    pNew = pWith;
  }else{
    pNew->a[pNew->nCte].pSelect = pQuery;
    pNew->a[pNew->nCte].pCols = pArglist;
    pNew->a[pNew->nCte].zName = zName;
    pNew->a[pNew->nCte].zCteErr = 0;
    pNew->nCte++;
  }

  return pNew;
}

/*
** Free the contents of the With object passed as the second argument.
*/
void sqlite3WithDelete(sqlite3 *db, With *pWith){
  if( pWith ){
    int i;
    for(i=0; i<pWith->nCte; i++){
      struct Cte *pCte = &pWith->a[i];
      sqlite3ExprListDelete(db, pCte->pCols);
      sqlite3SelectDelete(db, pCte->pSelect);
      sqlite3DbFree(db, pCte->zName);
    }
    sqlite3DbFree(db, pWith);
  }
}
#endif /* !defined(SQLITE_OMIT_CTE) */







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
>
>




|
<
<




>
>
>
>



|


















<
|
<


<
<
<
|
|












|
<
<
<





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
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
      pKey = 0;
    }
  }
  return pKey;
}

#ifndef SQLITE_OMIT_CTE
/*
** Create a new CTE object
*/
Cte *sqlite3CteNew(
  Parse *pParse,          /* Parsing context */
  Token *pName,           /* Name of the common-table */
  ExprList *pArglist,     /* Optional column name list for the table */
  Select *pQuery,         /* Query used to initialize the table */
  u8 eM10d                /* The MATERIALIZED flag */
){
  Cte *pNew;
  sqlite3 *db = pParse->db;

  pNew = sqlite3DbMallocZero(db, sizeof(*pNew));
  assert( pNew!=0 || db->mallocFailed );

  if( db->mallocFailed ){
    sqlite3ExprListDelete(db, pArglist);
    sqlite3SelectDelete(db, pQuery);
  }else{
    pNew->pSelect = pQuery;
    pNew->pCols = pArglist;
    pNew->zName = sqlite3NameFromToken(pParse->db, pName);
    pNew->eM10d = eM10d;
  }
  return pNew;
}

/*
** Clear information from a Cte object, but do not deallocate storage
** for the object itself.
*/
static void cteClear(sqlite3 *db, Cte *pCte){
  assert( pCte!=0 );
  sqlite3ExprListDelete(db, pCte->pCols);
  sqlite3SelectDelete(db, pCte->pSelect);
  sqlite3DbFree(db, pCte->zName);
}

/*
** Free the contents of the CTE object passed as the second argument.
*/
void sqlite3CteDelete(sqlite3 *db, Cte *pCte){
  assert( pCte!=0 );
  cteClear(db, pCte);
  sqlite3DbFree(db, pCte);
}

/* 
** This routine is invoked once per CTE by the parser while parsing a 
** WITH clause.  The CTE described by teh third argument is added to
** the WITH clause of the second argument.  If the second argument is
** NULL, then a new WITH argument is created.
*/
With *sqlite3WithAdd(
  Parse *pParse,          /* Parsing context */
  With *pWith,            /* Existing WITH clause, or NULL */
  Cte *pCte               /* CTE to add to the WITH clause */


){
  sqlite3 *db = pParse->db;
  With *pNew;
  char *zName;

  if( pCte==0 ){
    return pWith;
  }

  /* Check that the CTE name is unique within this WITH clause. If
  ** not, store an error in the Parse structure. */
  zName = pCte->zName;
  if( zName && pWith ){
    int i;
    for(i=0; i<pWith->nCte; i++){
      if( sqlite3StrICmp(zName, pWith->a[i].zName)==0 ){
        sqlite3ErrorMsg(pParse, "duplicate WITH table name: %s", zName);
      }
    }
  }

  if( pWith ){
    sqlite3_int64 nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte);
    pNew = sqlite3DbRealloc(db, pWith, nByte);
  }else{
    pNew = sqlite3DbMallocZero(db, sizeof(*pWith));
  }
  assert( (pNew!=0 && zName!=0) || db->mallocFailed );

  if( db->mallocFailed ){

    sqlite3CteDelete(db, pCte);

    pNew = pWith;
  }else{



    pNew->a[pNew->nCte++] = *pCte;
    sqlite3DbFree(db, pCte);
  }

  return pNew;
}

/*
** Free the contents of the With object passed as the second argument.
*/
void sqlite3WithDelete(sqlite3 *db, With *pWith){
  if( pWith ){
    int i;
    for(i=0; i<pWith->nCte; i++){
      cteClear(db, &pWith->a[i]);



    }
    sqlite3DbFree(db, pWith);
  }
}
#endif /* !defined(SQLITE_OMIT_CTE) */
Changes to src/ctime.c.
254
255
256
257
258
259
260



261
262
263
264
265
266
267
  "ENABLE_JSON1",
#endif
#if SQLITE_ENABLE_LOAD_EXTENSION
  "ENABLE_LOAD_EXTENSION",
#endif
#ifdef SQLITE_ENABLE_LOCKING_STYLE
  "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE),



#endif
#if SQLITE_ENABLE_MEMORY_MANAGEMENT
  "ENABLE_MEMORY_MANAGEMENT",
#endif
#if SQLITE_ENABLE_MEMSYS3
  "ENABLE_MEMSYS3",
#endif







>
>
>







254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
  "ENABLE_JSON1",
#endif
#if SQLITE_ENABLE_LOAD_EXTENSION
  "ENABLE_LOAD_EXTENSION",
#endif
#ifdef SQLITE_ENABLE_LOCKING_STYLE
  "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE),
#endif
#if SQLITE_ENABLE_MATH_FUNCTIONS
  "ENABLE_MATH_FUNCTIONS",
#endif
#if SQLITE_ENABLE_MEMORY_MANAGEMENT
  "ENABLE_MEMORY_MANAGEMENT",
#endif
#if SQLITE_ENABLE_MEMSYS3
  "ENABLE_MEMSYS3",
#endif
Changes to src/delete.c.
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
** The following fields are initialized appropriate in pSrc:
**
**    pSrc->a[0].pTab       Pointer to the Table object
**    pSrc->a[0].pIndex     Pointer to the INDEXED BY index, if there is one
**
*/
Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
  struct SrcList_item *pItem = pSrc->a;
  Table *pTab;
  assert( pItem && pSrc->nSrc>=1 );
  pTab = sqlite3LocateTableItem(pParse, 0, pItem);
  sqlite3DeleteTable(pParse->db, pItem->pTab);
  pItem->pTab = pTab;
  if( pTab ){
    pTab->nTabRef++;
  }
  if( sqlite3IndexedByLookup(pParse, pItem) ){
    pTab = 0;

  }
  return pTab;
}

/* Return true if table pTab is read-only.
**
** A table is read-only if any of the following are true:







|







<
|
|
>







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
** The following fields are initialized appropriate in pSrc:
**
**    pSrc->a[0].pTab       Pointer to the Table object
**    pSrc->a[0].pIndex     Pointer to the INDEXED BY index, if there is one
**
*/
Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
  SrcItem *pItem = pSrc->a;
  Table *pTab;
  assert( pItem && pSrc->nSrc>=1 );
  pTab = sqlite3LocateTableItem(pParse, 0, pItem);
  sqlite3DeleteTable(pParse->db, pItem->pTab);
  pItem->pTab = pTab;
  if( pTab ){
    pTab->nTabRef++;

    if( pItem->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pItem) ){
      pTab = 0;
    }
  }
  return pTab;
}

/* Return true if table pTab is read-only.
**
** A table is read-only if any of the following are true:
203
204
205
206
207
208
209
210
211

212





213
214
215
216
217
218
219
      }
    }
  }

  /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
  ** and the SELECT subtree. */
  pSrc->a[0].pTab = 0;
  pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0);
  pSrc->a[0].pTab = pTab;

  pSrc->a[0].pIBIndex = 0;






  /* generate the SELECT expression tree. */
  pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0, 
      pOrderBy,0,pLimit
  );

  /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */







|

>
|
>
>
>
>
>







203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
      }
    }
  }

  /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
  ** and the SELECT subtree. */
  pSrc->a[0].pTab = 0;
  pSelectSrc = sqlite3SrcListDup(db, pSrc, 0);
  pSrc->a[0].pTab = pTab;
  if( pSrc->a[0].fg.isIndexedBy ){
    pSrc->a[0].u2.pIBIndex = 0;
    pSrc->a[0].fg.isIndexedBy = 0;
    sqlite3DbFree(db, pSrc->a[0].u1.zIndexedBy);
  }else if( pSrc->a[0].fg.isCte ){
    pSrc->a[0].u2.pCteUse->nUse++;
  }

  /* generate the SELECT expression tree. */
  pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0, 
      pOrderBy,0,pLimit
  );

  /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
383
384
385
386
387
388
389

390
391
392
393
394
395
396

  /* Initialize the counter of the number of rows deleted, if
  ** we are counting rows.
  */
  if( (db->flags & SQLITE_CountRows)!=0
   && !pParse->nested
   && !pParse->pTriggerTab

  ){
    memCnt = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt);
  }

#ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
  /* Special case: A DELETE without a WHERE clause deletes everything.







>







389
390
391
392
393
394
395
396
397
398
399
400
401
402
403

  /* Initialize the counter of the number of rows deleted, if
  ** we are counting rows.
  */
  if( (db->flags & SQLITE_CountRows)!=0
   && !pParse->nested
   && !pParse->pTriggerTab
   && !pParse->bReturning
  ){
    memCnt = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt);
  }

#ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
  /* Special case: A DELETE without a WHERE clause deletes everything.
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
  }

  /* 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( memCnt ){
    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);







|







611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
  }

  /* 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( memCnt ){
    sqlite3VdbeAddOp2(v, OP_ChngCntRow, memCnt, 1);
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC);
  }

delete_from_cleanup:
  sqlite3AuthContextPop(&sContext);
  sqlite3SrcListDelete(db, pTabList);
Changes to src/expr.c.
91
92
93
94
95
96
97











98
99
100
101
102
103
104
105
*/
Expr *sqlite3ExprAddCollateToken(
  Parse *pParse,           /* Parsing context */
  Expr *pExpr,             /* Add the "COLLATE" clause to this expression */
  const Token *pCollName,  /* Name of collating sequence */
  int dequote              /* True to dequote pCollName */
){











  if( pCollName->n>0 ){
    Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote);
    if( pNew ){
      pNew->pLeft = pExpr;
      pNew->flags |= EP_Collate|EP_Skip;
      pExpr = pNew;
    }
  }







>
>
>
>
>
>
>
>
>
>
>
|







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
*/
Expr *sqlite3ExprAddCollateToken(
  Parse *pParse,           /* Parsing context */
  Expr *pExpr,             /* Add the "COLLATE" clause to this expression */
  const Token *pCollName,  /* Name of collating sequence */
  int dequote              /* True to dequote pCollName */
){
  assert( pExpr!=0 || pParse->db->mallocFailed );
  if( pExpr==0 ) return 0;
  if( pExpr->op==TK_VECTOR ){
    ExprList *pList = pExpr->x.pList;
    if( ALWAYS(pList!=0) ){
      int i;
      for(i=0; i<pList->nExpr; i++){
        pList->a[i].pExpr = sqlite3ExprAddCollateToken(pParse,pList->a[i].pExpr,
                                                       pCollName, dequote);
      }
    }
  }else if( pCollName->n>0 ){
    Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote);
    if( pNew ){
      pNew->pLeft = pExpr;
      pNew->flags |= EP_Collate|EP_Skip;
      pExpr = pNew;
    }
  }
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
  assert( db!=0 );
  if( p==0 ) return 0;
  nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0);
  pNew = sqlite3DbMallocRawNN(db, nByte );
  if( pNew==0 ) return 0;
  pNew->nSrc = pNew->nAlloc = p->nSrc;
  for(i=0; i<p->nSrc; i++){
    struct SrcList_item *pNewItem = &pNew->a[i];
    struct SrcList_item *pOldItem = &p->a[i];
    Table *pTab;
    pNewItem->pSchema = pOldItem->pSchema;
    pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
    pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
    pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
    pNewItem->fg = pOldItem->fg;
    pNewItem->iCursor = pOldItem->iCursor;
    pNewItem->addrFillSub = pOldItem->addrFillSub;
    pNewItem->regReturn = pOldItem->regReturn;
    if( pNewItem->fg.isIndexedBy ){
      pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy);
    }
    pNewItem->pIBIndex = pOldItem->pIBIndex;



    if( pNewItem->fg.isTabFunc ){
      pNewItem->u1.pFuncArg = 
          sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags);
    }
    pTab = pNewItem->pTab = pOldItem->pTab;
    if( pTab ){
      pTab->nTabRef++;







|
|












|
>
>
>







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
  assert( db!=0 );
  if( p==0 ) return 0;
  nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0);
  pNew = sqlite3DbMallocRawNN(db, nByte );
  if( pNew==0 ) return 0;
  pNew->nSrc = pNew->nAlloc = p->nSrc;
  for(i=0; i<p->nSrc; i++){
    SrcItem *pNewItem = &pNew->a[i];
    SrcItem *pOldItem = &p->a[i];
    Table *pTab;
    pNewItem->pSchema = pOldItem->pSchema;
    pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
    pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
    pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
    pNewItem->fg = pOldItem->fg;
    pNewItem->iCursor = pOldItem->iCursor;
    pNewItem->addrFillSub = pOldItem->addrFillSub;
    pNewItem->regReturn = pOldItem->regReturn;
    if( pNewItem->fg.isIndexedBy ){
      pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy);
    }
    pNewItem->u2 = pOldItem->u2;
    if( pNewItem->fg.isCte ){
      pNewItem->u2.pCteUse->nUse++;
    }
    if( pNewItem->fg.isTabFunc ){
      pNewItem->u1.pFuncArg = 
          sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags);
    }
    pTab = pNewItem->pTab = pOldItem->pTab;
    if( pTab ){
      pTab->nTabRef++;
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
    assert( p->pEList!=0 );             /* Because of isCandidateForInOpt(p) */
    assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
    assert( p->pSrc!=0 );               /* Because of isCandidateForInOpt(p) */
    pTab = p->pSrc->a[0].pTab;

    /* Code an OP_Transaction and OP_TableLock for <table>. */
    iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
    assert( iDb>=0 && iDb<SQLITE_MAX_ATTACHED );
    sqlite3CodeVerifySchema(pParse, iDb);
    sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);

    assert(v);  /* sqlite3GetVdbe() has always been previously called */
    if( nExpr==1 && pEList->a[0].pExpr->iColumn<0 ){
      /* The "x IN (SELECT rowid FROM table)" case */
      int iAddr = sqlite3VdbeAddOp0(v, OP_Once);







|







2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
    assert( p->pEList!=0 );             /* Because of isCandidateForInOpt(p) */
    assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
    assert( p->pSrc!=0 );               /* Because of isCandidateForInOpt(p) */
    pTab = p->pSrc->a[0].pTab;

    /* Code an OP_Transaction and OP_TableLock for <table>. */
    iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
    assert( iDb>=0 && iDb<SQLITE_MAX_DB );
    sqlite3CodeVerifySchema(pParse, iDb);
    sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);

    assert(v);  /* sqlite3GetVdbe() has always been previously called */
    if( nExpr==1 && pEList->a[0].pExpr->iColumn<0 ){
      /* The "x IN (SELECT rowid FROM table)" case */
      int iAddr = sqlite3VdbeAddOp0(v, OP_Once);
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
    case TK_AGG_COLUMN:
    case TK_COLUMN: {
      testcase( pExpr->op==TK_AGG_COLUMN );
      testcase( pExpr->op==TK_COLUMN );
      /* Check to see if the column is in one of the tables in the FROM
      ** clause of the aggregate query */
      if( ALWAYS(pSrcList!=0) ){
        struct SrcList_item *pItem = pSrcList->a;
        for(i=0; i<pSrcList->nSrc; i++, pItem++){
          struct AggInfo_col *pCol;
          assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
          if( pExpr->iTable==pItem->iCursor ){
            /* If we reach this point, it means that pExpr refers to a table
            ** that is in the FROM clause of the aggregate query.  
            **







|







5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
    case TK_AGG_COLUMN:
    case TK_COLUMN: {
      testcase( pExpr->op==TK_AGG_COLUMN );
      testcase( pExpr->op==TK_COLUMN );
      /* Check to see if the column is in one of the tables in the FROM
      ** clause of the aggregate query */
      if( ALWAYS(pSrcList!=0) ){
        SrcItem *pItem = pSrcList->a;
        for(i=0; i<pSrcList->nSrc; i++, pItem++){
          struct AggInfo_col *pCol;
          assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
          if( pExpr->iTable==pItem->iCursor ){
            /* If we reach this point, it means that pExpr refers to a table
            ** that is in the FROM clause of the aggregate query.  
            **
Changes to src/fkey.c.
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
    }
    assert( aiCol || pFKey->nCol==1 );

    /* Create a SrcList structure containing the child table.  We need the
    ** child table as a SrcList for sqlite3WhereBegin() */
    pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
    if( pSrc ){
      struct SrcList_item *pItem = pSrc->a;
      pItem->pTab = pFKey->pFrom;
      pItem->zName = pFKey->pFrom->zName;
      pItem->pTab->nTabRef++;
      pItem->iCursor = pParse->nTab++;
  
      if( regNew!=0 ){
        fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1);







|







1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
    }
    assert( aiCol || pFKey->nCol==1 );

    /* Create a SrcList structure containing the child table.  We need the
    ** child table as a SrcList for sqlite3WhereBegin() */
    pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
    if( pSrc ){
      SrcItem *pItem = pSrc->a;
      pItem->pTab = pFKey->pFrom;
      pItem->zName = pFKey->pFrom->zName;
      pItem->pTab->nTabRef++;
      pItem->iCursor = pParse->nTab++;
  
      if( regNew!=0 ){
        fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1);
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
**
** If any foreign key processing will be required, this function returns
** non-zero. If there is no foreign key related processing, this function 
** returns zero.
**
** For an UPDATE, this function returns 2 if:
**
**   * There are any FKs for which pTab is the child and the parent table, or


**   * the UPDATE modifies one or more parent keys for which the action is
**     not "NO ACTION" (i.e. is CASCADE, SET DEFAULT or SET NULL).
**
** Or, assuming some other foreign key processing is required, 1.
*/
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 */
){
  int eRet = 0;

  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.  */
      eRet = (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. */
      FKey *p;

      /* Check if any child key columns are being modified. */
      for(p=pTab->pFKey; p; p=p->pNextFrom){
        if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) return 2;
        if( fkChildIsModified(pTab, p, aChange, chngRowid) ){

          eRet = 1;
        }
      }

      /* Check if any parent key columns are being modified. */
      for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
        if( fkParentIsModified(pTab, p, aChange, chngRowid) ){
          if( p->aAction[1]!=OE_None ) return 2;
          eRet = 1;
        }
      }
    }
  }
  return eRet;
}

/*
** 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







|
>
>











|
>





|







<

>
|







|




|







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
**
** If any foreign key processing will be required, this function returns
** non-zero. If there is no foreign key related processing, this function 
** returns zero.
**
** For an UPDATE, this function returns 2 if:
**
**   * There are any FKs for which pTab is the child and the parent table
**     and any FK processing at all is required (even of a different FK), or
**
**   * the UPDATE modifies one or more parent keys for which the action is
**     not "NO ACTION" (i.e. is CASCADE, SET DEFAULT or SET NULL).
**
** Or, assuming some other foreign key processing is required, 1.
*/
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 */
){
  int eRet = 1;                   /* Value to return if bHaveFK is true */
  int bHaveFK = 0;                /* If FK processing is required */
  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.  */
      bHaveFK = (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. */
      FKey *p;

      /* Check if any child key columns are being modified. */
      for(p=pTab->pFKey; p; p=p->pNextFrom){

        if( fkChildIsModified(pTab, p, aChange, chngRowid) ){
          if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) eRet = 2;
          bHaveFK = 1;
        }
      }

      /* Check if any parent key columns are being modified. */
      for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
        if( fkParentIsModified(pTab, p, aChange, chngRowid) ){
          if( p->aAction[1]!=OE_None ) return 2;
          bHaveFK = 1;
        }
      }
    }
  }
  return bHaveFK ? eRet : 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
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
      return 0;
    }
    assert( pStep!=0 );
    assert( pTrigger!=0 );

    switch( action ){
      case OE_Restrict:
        pStep->op = TK_SELECT; 
        break;
      case OE_Cascade: 
        if( !pChanges ){ 
          pStep->op = TK_DELETE; 
          break; 
        }
        /* no break */ deliberate_fall_through







|







1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
      return 0;
    }
    assert( pStep!=0 );
    assert( pTrigger!=0 );

    switch( action ){
      case OE_Restrict:
        pStep->op = TK_SELECT;
        break;
      case OE_Cascade: 
        if( !pChanges ){ 
          pStep->op = TK_DELETE; 
          break; 
        }
        /* no break */ deliberate_fall_through
Changes to src/func.c.
692
693
694
695
696
697
698
699

700
701
702
703
704
705
706
  const u8 *zEscaped = 0;          /* One past the last escaped input char */
  
  while( (c = Utf8Read(zPattern))!=0 ){
    if( c==matchAll ){  /* Match "*" */
      /* Skip over multiple "*" characters in the pattern.  If there
      ** are also "?" characters, skip those as well, but consume a
      ** single character of the input string for each "?" skipped */
      while( (c=Utf8Read(zPattern)) == matchAll || c == matchOne ){

        if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
          return SQLITE_NOWILDCARDMATCH;
        }
      }
      if( c==0 ){
        return SQLITE_MATCH;   /* "*" at the end of the pattern matches */
      }else if( c==matchOther ){







|
>







692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
  const u8 *zEscaped = 0;          /* One past the last escaped input char */
  
  while( (c = Utf8Read(zPattern))!=0 ){
    if( c==matchAll ){  /* Match "*" */
      /* Skip over multiple "*" characters in the pattern.  If there
      ** are also "?" characters, skip those as well, but consume a
      ** single character of the input string for each "?" skipped */
      while( (c=Utf8Read(zPattern)) == matchAll 
             || (c == matchOne && matchOne!=0) ){
        if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
          return SQLITE_NOWILDCARDMATCH;
        }
      }
      if( c==0 ){
        return SQLITE_MATCH;   /* "*" at the end of the pattern matches */
      }else if( c==matchOther ){
1863
1864
1865
1866
1867
1868
1869


1870
1871
1872
1873
1874
1875
1876
1877
** the function (default for LIKE).  If the function makes the distinction
** between uppercase and lowercase (as does GLOB) then *pIsNocase is set to
** false.
*/
int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
  FuncDef *pDef;
  int nExpr;


  if( pExpr->op!=TK_FUNCTION || !pExpr->x.pList ){
    return 0;
  }
  assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
  nExpr = pExpr->x.pList->nExpr;
  pDef = sqlite3FindFunction(db, pExpr->u.zToken, nExpr, SQLITE_UTF8, 0);
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
  if( pDef==0 ) return 0;







>
>
|







1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
** the function (default for LIKE).  If the function makes the distinction
** between uppercase and lowercase (as does GLOB) then *pIsNocase is set to
** false.
*/
int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
  FuncDef *pDef;
  int nExpr;
  assert( pExpr!=0 );
  assert( pExpr->op==TK_FUNCTION );
  if( !pExpr->x.pList ){
    return 0;
  }
  assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
  nExpr = pExpr->x.pList->nExpr;
  pDef = sqlite3FindFunction(db, pExpr->u.zToken, nExpr, SQLITE_UTF8, 0);
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
  if( pDef==0 ) return 0;
1901
1902
1903
1904
1905
1906
1907





































































































































































































1908
1909
1910
1911
1912
1913
1914
    if( zEscape[0]==aWc[1] ) return 0;
    aWc[3] = zEscape[0];
  }

  *pIsNocase = (pDef->funcFlags & SQLITE_FUNC_CASE)==0;
  return 1;
}






































































































































































































/*
** All of the FuncDef structures in the aBuiltinFunc[] array above
** to the global function hash table.  This occurs at start-time (as
** a consequence of calling sqlite3_initialize()).
**
** After this routine runs







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    if( zEscape[0]==aWc[1] ) return 0;
    aWc[3] = zEscape[0];
  }

  *pIsNocase = (pDef->funcFlags & SQLITE_FUNC_CASE)==0;
  return 1;
}

/* Mathematical Constants */
#ifndef M_PI
# define M_PI   3.141592653589793238462643383279502884
#endif
#ifndef M_LN10
# define M_LN10 2.302585092994045684017991454684364208
#endif
#ifndef M_LN2
# define M_LN2  0.693147180559945309417232121458176568
#endif


/* Extra math functions that require linking with -lm
*/
#ifdef SQLITE_ENABLE_MATH_FUNCTIONS
/*
** Implementation SQL functions:
**
**   ceil(X)
**   ceiling(X)
**   floor(X)
**
** The sqlite3_user_data() pointer is a pointer to the libm implementation
** of the underlying C function.
*/
static void ceilingFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  assert( argc==1 );
  switch( sqlite3_value_numeric_type(argv[0]) ){
    case SQLITE_INTEGER: {
       sqlite3_result_int64(context, sqlite3_value_int64(argv[0]));
       break;
    }
    case SQLITE_FLOAT: {
       double (*x)(double) = (double(*)(double))sqlite3_user_data(context);
       sqlite3_result_double(context, x(sqlite3_value_double(argv[0])));
       break;
    }
    default: {
       break;
    }
  }
}

/*
** On some systems, ceil() and floor() are intrinsic function.  You are
** unable to take a pointer to these functions.  Hence, we here wrap them
** in our own actual functions.
*/
static double xCeil(double x){ return ceil(x); }
static double xFloor(double x){ return floor(x); }

/*
** Implementation of SQL functions:
**
**   ln(X)       - natural logarithm
**   log(X)      - log X base 10
**   log10(X)    - log X base 10
**   log(B,X)    - log X base B
*/
static void logFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  double x, b, ans;
  assert( argc==1 || argc==2 );
  switch( sqlite3_value_numeric_type(argv[0]) ){
    case SQLITE_INTEGER:
    case SQLITE_FLOAT:
      x = sqlite3_value_double(argv[0]);
      if( x<=0.0 ) return;
      break;
    default:
      return;
  }
  if( argc==2 ){
    switch( sqlite3_value_numeric_type(argv[0]) ){
      case SQLITE_INTEGER:
      case SQLITE_FLOAT:
        b = log(x);
        if( b<=0.0 ) return;
        x = sqlite3_value_double(argv[1]);
        if( x<=0.0 ) return;
        break;
     default:
        return;
    }
    ans = log(x)/b;
  }else{
    ans = log(x);
    switch( SQLITE_PTR_TO_INT(sqlite3_user_data(context)) ){
      case 1:
        /* Convert from natural logarithm to log base 10 */
        ans *= 1.0/M_LN10;
        break;
      case 2:
        /* Convert from natural logarithm to log base 2 */
        ans *= 1.0/M_LN2;
        break;
      default:
        break;
    }
  }
  sqlite3_result_double(context, ans);
}

/*
** Functions to converts degrees to radians and radians to degrees.
*/
static double degToRad(double x){ return x*(M_PI/180.0); }
static double radToDeg(double x){ return x*(180.0/M_PI); }

/*
** Implementation of 1-argument SQL math functions:
**
**   exp(X)  - Compute e to the X-th power
*/
static void math1Func(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int type0;
  double v0, ans;
  double (*x)(double);
  assert( argc==1 );
  type0 = sqlite3_value_numeric_type(argv[0]);
  if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return;
  v0 = sqlite3_value_double(argv[0]);
  x = (double(*)(double))sqlite3_user_data(context);
  ans = x(v0);
  sqlite3_result_double(context, ans);
}

/*
** Implementation of 2-argument SQL math functions:
**
**   power(X,Y)  - Compute X to the Y-th power
*/
static void math2Func(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int type0, type1;
  double v0, v1, ans;
  double (*x)(double,double);
  assert( argc==2 );
  type0 = sqlite3_value_numeric_type(argv[0]);
  if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return;
  type1 = sqlite3_value_numeric_type(argv[1]);
  if( type1!=SQLITE_INTEGER && type1!=SQLITE_FLOAT ) return;
  v0 = sqlite3_value_double(argv[0]);
  v1 = sqlite3_value_double(argv[1]);
  x = (double(*)(double,double))sqlite3_user_data(context);
  ans = x(v0, v1);
  sqlite3_result_double(context, ans);
}

/*
** Implementation of 2-argument SQL math functions:
**
**   power(X,Y)  - Compute X to the Y-th power
*/
static void piFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  assert( argc==0 );
  sqlite3_result_double(context, M_PI);
}

#endif /* SQLITE_ENABLE_MATH_FUNCTIONS */

/*
** Implementation of sign(X) function.
*/
static void signFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int type0;
  double x;
  UNUSED_PARAMETER(argc);
  assert( argc==1 );
  type0 = sqlite3_value_numeric_type(argv[0]);
  if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return;
  x = sqlite3_value_double(argv[0]);
  sqlite3_result_int(context, x<0.0 ? -1 : x>0.0 ? +1 : 0);
}

/*
** All of the FuncDef structures in the aBuiltinFunc[] array above
** to the global function hash table.  This occurs at start-time (as
** a consequence of calling sqlite3_initialize()).
**
** After this routine runs
2020
2021
2022
2023
2024
2025
2026





































2027
2028
2029
2030
2031
2032
2033
    LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
#endif
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
    FUNCTION(unknown,           -1, 0, 0, unknownFunc      ),
#endif
    FUNCTION(coalesce,           1, 0, 0, 0                ),
    FUNCTION(coalesce,           0, 0, 0, 0                ),





































    INLINE_FUNC(coalesce,       -1, INLINEFUNC_coalesce, 0 ),
    INLINE_FUNC(iif,             3, INLINEFUNC_iif,      0 ),
  };
#ifndef SQLITE_OMIT_ALTERTABLE
  sqlite3AlterFunctions();
#endif
  sqlite3WindowFunctions();







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
#endif
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
    FUNCTION(unknown,           -1, 0, 0, unknownFunc      ),
#endif
    FUNCTION(coalesce,           1, 0, 0, 0                ),
    FUNCTION(coalesce,           0, 0, 0, 0                ),
#ifdef SQLITE_ENABLE_MATH_FUNCTIONS
    MFUNCTION(ceil,              1, xCeil,     ceilingFunc ),
    MFUNCTION(ceiling,           1, xCeil,     ceilingFunc ),
    MFUNCTION(floor,             1, xFloor,    ceilingFunc ),
#if SQLITE_HAVE_C99_MATH_FUNCS
    MFUNCTION(trunc,             1, trunc,     ceilingFunc ),
#endif
    FUNCTION(ln,                 1, 0, 0,      logFunc     ),
    FUNCTION(log,                1, 1, 0,      logFunc     ),
    FUNCTION(log10,              1, 1, 0,      logFunc     ),
    FUNCTION(log2,               1, 2, 0,      logFunc     ),
    FUNCTION(log,                2, 0, 0,      logFunc     ),
    MFUNCTION(exp,               1, exp,       math1Func   ),
    MFUNCTION(pow,               2, pow,       math2Func   ),
    MFUNCTION(power,             2, pow,       math2Func   ),
    MFUNCTION(mod,               2, fmod,      math2Func   ),
    MFUNCTION(acos,              1, acos,      math1Func   ),
    MFUNCTION(asin,              1, asin,      math1Func   ),
    MFUNCTION(atan,              1, atan,      math1Func   ),
    MFUNCTION(atan2,             2, atan2,     math2Func   ),
    MFUNCTION(cos,               1, cos,       math1Func   ),
    MFUNCTION(sin,               1, sin,       math1Func   ),
    MFUNCTION(tan,               1, tan,       math1Func   ),
    MFUNCTION(cosh,              1, cosh,      math1Func   ),
    MFUNCTION(sinh,              1, sinh,      math1Func   ),
    MFUNCTION(tanh,              1, tanh,      math1Func   ),
#if SQLITE_HAVE_C99_MATH_FUNCS
    MFUNCTION(acosh,             1, acosh,     math1Func   ),
    MFUNCTION(asinh,             1, asinh,     math1Func   ),
    MFUNCTION(atanh,             1, atanh,     math1Func   ),
#endif
    MFUNCTION(sqrt,              1, sqrt,      math1Func   ),
    MFUNCTION(radians,           1, degToRad,  math1Func   ),
    MFUNCTION(degrees,           1, radToDeg,  math1Func   ),
    FUNCTION(pi,                 0, 0, 0,      piFunc      ),
#endif /* SQLITE_ENABLE_MATH_FUNCTIONS */
    FUNCTION(sign,               1, 0, 0,      signFunc    ),
    INLINE_FUNC(coalesce,       -1, INLINEFUNC_coalesce, 0 ),
    INLINE_FUNC(iif,             3, INLINEFUNC_iif,      0 ),
  };
#ifndef SQLITE_OMIT_ALTERTABLE
  sqlite3AlterFunctions();
#endif
  sqlite3WindowFunctions();
Changes to src/global.c.
297
298
299
300
301
302
303
304
305
306

307
308
309
310
311
312
313
** and incorrect behavior.
*/
#ifndef SQLITE_OMIT_WSD
int sqlite3PendingByte = 0x40000000;
#endif

/*
** Flags for select tracing and the ".selecttrace" macro of the CLI
*/
u32 sqlite3_unsupported_selecttrace = 0;


#include "opcodes.h"
/*
** Properties of opcodes.  The OPFLG_INITIALIZER macro is
** created by mkopcodeh.awk during compilation.  Data is obtained
** from the comments following the "case OP_xxxx:" statements in
** the vdbe.c file.  







|

|
>







297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
** and incorrect behavior.
*/
#ifndef SQLITE_OMIT_WSD
int sqlite3PendingByte = 0x40000000;
#endif

/*
** Tracing flags set by SQLITE_TESTCTRL_TRACEFLAGS.
*/
u32 sqlite3SelectTrace = 0;
u32 sqlite3WhereTrace = 0;

#include "opcodes.h"
/*
** Properties of opcodes.  The OPFLG_INITIALIZER macro is
** created by mkopcodeh.awk during compilation.  Data is obtained
** from the comments following the "case OP_xxxx:" statements in
** the vdbe.c file.  
Changes to src/insert.c.
366
367
368
369
370
371
372


373
374
375
376
377
378
379
380
      return 0;
    }

    pInfo = pToplevel->pAinc;
    while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; }
    if( pInfo==0 ){
      pInfo = sqlite3DbMallocRawNN(pParse->db, sizeof(*pInfo));


      if( pInfo==0 ) return 0;
      pInfo->pNext = pToplevel->pAinc;
      pToplevel->pAinc = pInfo;
      pInfo->pTab = pTab;
      pInfo->iDb = iDb;
      pToplevel->nMem++;                  /* Register to hold name of table */
      pInfo->regCtr = ++pToplevel->nMem;  /* Max rowid register */
      pToplevel->nMem +=2;       /* Rowid in sqlite_sequence + orig max val */







>
>
|







366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
      return 0;
    }

    pInfo = pToplevel->pAinc;
    while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; }
    if( pInfo==0 ){
      pInfo = sqlite3DbMallocRawNN(pParse->db, sizeof(*pInfo));
      sqlite3ParserAddCleanup(pToplevel, sqlite3DbFree, pInfo);
      testcase( pParse->earlyCleanup );
      if( pParse->db->mallocFailed ) return 0;
      pInfo->pNext = pToplevel->pAinc;
      pToplevel->pAinc = pInfo;
      pInfo->pTab = pTab;
      pInfo->iDb = iDb;
      pToplevel->nMem++;                  /* Register to hold name of table */
      pInfo->regCtr = ++pToplevel->nMem;  /* Max rowid register */
      pToplevel->nMem +=2;       /* Rowid in sqlite_sequence + orig max val */
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
          testcase( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL );
          testcase( pTab->aCol[i].colFlags & COLFLAG_STORED );
          ipkColumn--;
        }
      }
    }
#endif
  }

  /* Make sure the number of columns in the source data matches the number
  ** of columns to be inserted into the table.
  */




  for(i=0; i<pTab->nCol; i++){
    if( pTab->aCol[i].colFlags & COLFLAG_NOINSERT ) nHidden++;
  }

  if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){
    sqlite3ErrorMsg(pParse, 
       "table %S has %d columns but %d values were supplied",
       pTabList, 0, pTab->nCol-nHidden, nColumn);
    goto insert_cleanup;

  }
  if( pColumn!=0 && nColumn!=pColumn->nId ){
    sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId);
    goto insert_cleanup;
  }
    
  /* Initialize the count of rows to be inserted
  */
  if( (db->flags & SQLITE_CountRows)!=0
   && !pParse->nested
   && !pParse->pTriggerTab

  ){
    regRowCount = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
  }

  /* If this is not a view, open the table and and all indices */
  if( !isView ){







|
<
|
|
|
>
>
>
>
|
|
|
>
|
|
|
|
|
>











>







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
          testcase( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL );
          testcase( pTab->aCol[i].colFlags & COLFLAG_STORED );
          ipkColumn--;
        }
      }
    }
#endif


    /* Make sure the number of columns in the source data matches the number
    ** of columns to be inserted into the table.
    */
    assert( TF_HasHidden==COLFLAG_HIDDEN );
    assert( TF_HasGenerated==COLFLAG_GENERATED );
    assert( COLFLAG_NOINSERT==(COLFLAG_GENERATED|COLFLAG_HIDDEN) );
    if( (pTab->tabFlags & (TF_HasGenerated|TF_HasHidden))!=0 ){
      for(i=0; i<pTab->nCol; i++){
        if( pTab->aCol[i].colFlags & COLFLAG_NOINSERT ) nHidden++;
      }
    }
    if( nColumn!=(pTab->nCol-nHidden) ){
      sqlite3ErrorMsg(pParse, 
         "table %S has %d columns but %d values were supplied",
         pTabList, 0, pTab->nCol-nHidden, nColumn);
     goto insert_cleanup;
    }
  }
  if( pColumn!=0 && nColumn!=pColumn->nId ){
    sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId);
    goto insert_cleanup;
  }
    
  /* Initialize the count of rows to be inserted
  */
  if( (db->flags & SQLITE_CountRows)!=0
   && !pParse->nested
   && !pParse->pTriggerTab
   && !pParse->bReturning
  ){
    regRowCount = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
  }

  /* If this is not a view, open the table and and all indices */
  if( !isView ){
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
      aRegIdx[i] = ++pParse->nMem;
      pParse->nMem += pIdx->nColumn;
    }
    aRegIdx[i] = ++pParse->nMem;  /* Register to store the table record */
  }
#ifndef SQLITE_OMIT_UPSERT
  if( pUpsert ){

    if( IsVirtual(pTab) ){
      sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"",
              pTab->zName);
      goto insert_cleanup;
    }
    if( pTab->pSelect ){
      sqlite3ErrorMsg(pParse, "cannot UPSERT a view");
      goto insert_cleanup;
    }
    if( sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget) ){
      goto insert_cleanup;
    }
    pTabList->a[0].iCursor = iDataCur;


    pUpsert->pUpsertSrc = pTabList;
    pUpsert->regData = regData;
    pUpsert->iDataCur = iDataCur;
    pUpsert->iIdxCur = iIdxCur;
    if( pUpsert->pUpsertTarget ){
      sqlite3UpsertAnalyzeTarget(pParse, pTabList, pUpsert);
    }


  }
#endif


  /* This is the top of the main insertion loop */
  if( useTempTable ){
    /* This block codes the top of loop only.  The complete loop is the







>













>
>
|
|
|
|
|
|
|
>
>







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
      aRegIdx[i] = ++pParse->nMem;
      pParse->nMem += pIdx->nColumn;
    }
    aRegIdx[i] = ++pParse->nMem;  /* Register to store the table record */
  }
#ifndef SQLITE_OMIT_UPSERT
  if( pUpsert ){
    Upsert *pNx;
    if( IsVirtual(pTab) ){
      sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"",
              pTab->zName);
      goto insert_cleanup;
    }
    if( pTab->pSelect ){
      sqlite3ErrorMsg(pParse, "cannot UPSERT a view");
      goto insert_cleanup;
    }
    if( sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget) ){
      goto insert_cleanup;
    }
    pTabList->a[0].iCursor = iDataCur;
    pNx = pUpsert;
    do{
      pNx->pUpsertSrc = pTabList;
      pNx->regData = regData;
      pNx->iDataCur = iDataCur;
      pNx->iIdxCur = iIdxCur;
      if( pNx->pUpsertTarget ){
        sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx);
      }
      pNx = pNx->pNextUpsert;
    }while( pNx!=0 );
  }
#endif


  /* This is the top of the main insertion loop */
  if( useTempTable ){
    /* This block codes the top of loop only.  The complete loop is the
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
      }
      addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v);
      sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
      sqlite3VdbeJumpHere(v, addr1);
      sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v);
    }

    /* Cannot have triggers on a virtual table. If it were possible,
    ** this block would have to account for hidden column.
    */
    assert( !IsVirtual(pTab) );

    /* Copy the new data already generated. */
    assert( pTab->nNVCol>0 );
    sqlite3VdbeAddOp3(v, OP_Copy, regRowid+1, regCols+1, pTab->nNVCol-1);

#ifndef SQLITE_OMIT_GENERATED_COLUMNS
    /* Compute the new value for generated columns after all other
    ** columns have already been computed.  This must be done after







<
<
<
<
<







1144
1145
1146
1147
1148
1149
1150





1151
1152
1153
1154
1155
1156
1157
      }
      addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v);
      sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
      sqlite3VdbeJumpHere(v, addr1);
      sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v);
    }






    /* Copy the new data already generated. */
    assert( pTab->nNVCol>0 );
    sqlite3VdbeAddOp3(v, OP_Copy, regRowid+1, regCols+1, pTab->nNVCol-1);

#ifndef SQLITE_OMIT_GENERATED_COLUMNS
    /* Compute the new value for generated columns after all other
    ** columns have already been computed.  This must be done after
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
      assert( sqlite3VdbeGetOp(v, addrCont)->opcode==OP_Yield );
      sqlite3VdbeChangeP5(v, 1);
    }
#endif
    sqlite3VdbeJumpHere(v, addrInsTop);
  }


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->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( regRowCount ){
    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);







>

>














|







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
      assert( sqlite3VdbeGetOp(v, addrCont)->opcode==OP_Yield );
      sqlite3VdbeChangeP5(v, 1);
    }
#endif
    sqlite3VdbeJumpHere(v, addrInsTop);
  }

#ifndef SQLITE_OMIT_XFER_OPT
insert_end:
#endif /* SQLITE_OMIT_XFER_OPT */
  /* 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->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( regRowCount ){
    sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1);
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC);
  }

insert_cleanup:
  sqlite3SrcListDelete(db, pTabList);
  sqlite3ExprListDelete(db, pList);
1395
1396
1397
1398
1399
1400
1401
































































1402
1403
1404
1405
1406
1407
1408
  testcase( w.eCode==0 );
  testcase( w.eCode==CKCNSTRNT_COLUMN );
  testcase( w.eCode==CKCNSTRNT_ROWID );
  testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) );
  return w.eCode!=0;
}

































































/*
** Generate code to do constraint checks prior to an INSERT or an UPDATE
** on table pTab.
**
** The regNewData parameter is the first register in a range that contains
** the data to be inserted or the data after the update.  There will be
** pTab->nCol+1 registers in this range.  The first register (the one







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
  testcase( w.eCode==0 );
  testcase( w.eCode==CKCNSTRNT_COLUMN );
  testcase( w.eCode==CKCNSTRNT_ROWID );
  testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) );
  return w.eCode!=0;
}

/*
** The sqlite3GenerateConstraintChecks() routine usually wants to visit
** the indexes of a table in the order provided in the Table->pIndex list.
** However, sometimes (rarely - when there is an upsert) it wants to visit
** the indexes in a different order.  The following data structures accomplish
** this.
**
** The IndexIterator object is used to walk through all of the indexes
** of a table in either Index.pNext order, or in some other order established
** by an array of IndexListTerm objects.
*/
typedef struct IndexListTerm IndexListTerm;
typedef struct IndexIterator IndexIterator;
struct IndexIterator {
  int eType;    /* 0 for Index.pNext list.  1 for an array of IndexListTerm */
  int i;        /* Index of the current item from the list */
  union {
    struct {    /* Use this object for eType==0: A Index.pNext list */
      Index *pIdx;   /* The current Index */
    } lx;      
    struct {    /* Use this object for eType==1; Array of IndexListTerm */
      int nIdx;               /* Size of the array */
      IndexListTerm *aIdx;    /* Array of IndexListTerms */
    } ax;
  } u;
};

/* When IndexIterator.eType==1, then each index is an array of instances
** of the following object
*/
struct IndexListTerm {
  Index *p;  /* The index */
  int ix;    /* Which entry in the original Table.pIndex list is this index*/
};

/* Return the first index on the list */
static Index *indexIteratorFirst(IndexIterator *pIter, int *pIx){
  assert( pIter->i==0 );
  if( pIter->eType ){
    *pIx = pIter->u.ax.aIdx[0].ix;
    return pIter->u.ax.aIdx[0].p;
  }else{
    *pIx = 0;
    return pIter->u.lx.pIdx;
  }
}

/* Return the next index from the list.  Return NULL when out of indexes */
static Index *indexIteratorNext(IndexIterator *pIter, int *pIx){
  if( pIter->eType ){
    int i = ++pIter->i;
    if( i>=pIter->u.ax.nIdx ){
      *pIx = i;
      return 0;
    }
    *pIx = pIter->u.ax.aIdx[i].ix;
    return pIter->u.ax.aIdx[i].p;
  }else{
    ++(*pIx);
    pIter->u.lx.pIdx = pIter->u.lx.pIdx->pNext;
    return pIter->u.lx.pIdx;
  }
}
  
/*
** Generate code to do constraint checks prior to an INSERT or an UPDATE
** on table pTab.
**
** The regNewData parameter is the first register in a range that contains
** the data to be inserted or the data after the update.  There will be
** pTab->nCol+1 registers in this range.  The first register (the one
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
  int ignoreDest,      /* Jump to this label on an OE_Ignore resolution */
  int *pbMayReplace,   /* OUT: Set to true if constraint may cause a replace */
  int *aiChng,         /* column i is unchanged if aiChng[i]<0 */
  Upsert *pUpsert      /* ON CONFLICT clauses, if any.  NULL otherwise */
){
  Vdbe *v;             /* VDBE under constrution */
  Index *pIdx;         /* Pointer to one of the indices */
  Index *pPk = 0;      /* The PRIMARY KEY index */
  sqlite3 *db;         /* Database connection */
  int i;               /* loop counter */
  int ix;              /* Index loop counter */
  int nCol;            /* Number of columns */
  int onError;         /* Conflict resolution strategy */
  int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
  int nPkField;        /* Number of fields in PRIMARY KEY. 1 for ROWID tables */
  Index *pUpIdx = 0;   /* Index to which to apply the upsert */
  u8 isUpdate;         /* True if this is an UPDATE operation */
  u8 bAffinityDone = 0;  /* True if the OP_Affinity operation has been run */
  int upsertBypass = 0;  /* Address of Goto to bypass upsert subroutine */
  int upsertJump = 0;    /* Address of Goto that jumps into upsert subroutine */
  int ipkTop = 0;        /* Top of the IPK uniqueness check */
  int ipkBottom = 0;     /* OP_Goto at the end of the IPK uniqueness check */
  /* Variables associated with retesting uniqueness constraints after
  ** replace triggers fire have run */
  int regTrigCnt;       /* Register used to count replace trigger invocations */
  int addrRecheck = 0;  /* Jump here to recheck all uniqueness constraints */
  int lblRecheckOk = 0; /* Each recheck jumps to this label if it passes */
  Trigger *pTrigger;    /* List of DELETE triggers on the table pTab */
  int nReplaceTrig = 0; /* Number of replace triggers coded */


  isUpdate = regOldData!=0;
  db = pParse->db;
  v = pParse->pVdbe;
  assert( v!=0 );
  assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  nCol = pTab->nCol;







|







|
|

|
|









>







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
  int ignoreDest,      /* Jump to this label on an OE_Ignore resolution */
  int *pbMayReplace,   /* OUT: Set to true if constraint may cause a replace */
  int *aiChng,         /* column i is unchanged if aiChng[i]<0 */
  Upsert *pUpsert      /* ON CONFLICT clauses, if any.  NULL otherwise */
){
  Vdbe *v;             /* VDBE under constrution */
  Index *pIdx;         /* Pointer to one of the indices */
  Index *pPk = 0;      /* The PRIMARY KEY index for WITHOUT ROWID tables */
  sqlite3 *db;         /* Database connection */
  int i;               /* loop counter */
  int ix;              /* Index loop counter */
  int nCol;            /* Number of columns */
  int onError;         /* Conflict resolution strategy */
  int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
  int nPkField;        /* Number of fields in PRIMARY KEY. 1 for ROWID tables */
  Upsert *pUpsertClause = 0;  /* The specific ON CONFLICT clause for pIdx */
  u8 isUpdate;           /* True if this is an UPDATE operation */
  u8 bAffinityDone = 0;  /* True if the OP_Affinity operation has been run */
  int upsertIpkReturn = 0; /* Address of Goto at end of IPK uniqueness check */
  int upsertIpkDelay = 0;  /* Address of Goto to bypass initial IPK check */
  int ipkTop = 0;        /* Top of the IPK uniqueness check */
  int ipkBottom = 0;     /* OP_Goto at the end of the IPK uniqueness check */
  /* Variables associated with retesting uniqueness constraints after
  ** replace triggers fire have run */
  int regTrigCnt;       /* Register used to count replace trigger invocations */
  int addrRecheck = 0;  /* Jump here to recheck all uniqueness constraints */
  int lblRecheckOk = 0; /* Each recheck jumps to this label if it passes */
  Trigger *pTrigger;    /* List of DELETE triggers on the table pTab */
  int nReplaceTrig = 0; /* Number of replace triggers coded */
  IndexIterator sIdxIter;  /* Index iterator */

  isUpdate = regOldData!=0;
  db = pParse->db;
  v = pParse->pVdbe;
  assert( v!=0 );
  assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  nCol = pTab->nCol;
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
  **        default conflict resolution strategy
  **   (C)  Unique index that do use OE_Replace by default.
  **
  ** The ordering of (2) and (3) is accomplished by making sure the linked
  ** list of indexes attached to a table puts all OE_Replace indexes last
  ** in the list.  See sqlite3CreateIndex() for where that happens.
  */




  if( pUpsert ){
    if( pUpsert->pUpsertTarget==0 ){



      /* An ON CONFLICT DO NOTHING clause, without a constraint-target.
      ** Make all unique constraint resolution be OE_Ignore */
      assert( pUpsert->pUpsertSet==0 );
      overrideError = OE_Ignore;
      pUpsert = 0;




    }else if( (pUpIdx = pUpsert->pUpsertIdx)!=0 ){

      /* If the constraint-target uniqueness check must be run first.
      ** Jump to that uniqueness check now */










      upsertJump = sqlite3VdbeAddOp0(v, OP_Goto);
      VdbeComment((v, "UPSERT constraint goes first"));

























    }
  }

  /* Determine if it is possible that triggers (either explicitly coded
  ** triggers or FK resolution actions) might run as a result of deletes
  ** that happen when OE_Replace conflict resolution occurs. (Call these
  ** "replace triggers".)  If any replace triggers run, we will need to







|
>
>
>


>
>
>
|
|
<
|
|
>
>
>
>
|
>
|
|
>
>
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
  **        default conflict resolution strategy
  **   (C)  Unique index that do use OE_Replace by default.
  **
  ** The ordering of (2) and (3) is accomplished by making sure the linked
  ** list of indexes attached to a table puts all OE_Replace indexes last
  ** in the list.  See sqlite3CreateIndex() for where that happens.
  */
  sIdxIter.eType = 0;
  sIdxIter.i = 0;
  sIdxIter.u.ax.aIdx = 0;  /* Silence harmless compiler warning */
  sIdxIter.u.lx.pIdx = pTab->pIndex;
  if( pUpsert ){
    if( pUpsert->pUpsertTarget==0 ){
      /* There is just on ON CONFLICT clause and it has no constraint-target */
      assert( pUpsert->pNextUpsert==0 );
      if( pUpsert->isDoUpdate==0 ){
        /* A single ON CONFLICT DO NOTHING clause, without a constraint-target.
        ** Make all unique constraint resolution be OE_Ignore */

        overrideError = OE_Ignore;
        pUpsert = 0;
      }else{
        /* A single ON CONFLICT DO UPDATE.  Make all resolutions OE_Update */
        overrideError = OE_Update;
      }
    }else if( pTab->pIndex!=0 ){
      /* Otherwise, we'll need to run the IndexListTerm array version of the
      ** iterator to ensure that all of the ON CONFLICT conditions are
      ** checked first and in order. */
      int nIdx, jj;
      u64 nByte;
      Upsert *pTerm;
      u8 *bUsed;
      for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){
         assert( aRegIdx[nIdx]>0 );
      }
      sIdxIter.eType = 1;
      sIdxIter.u.ax.nIdx = nIdx;
      nByte = (sizeof(IndexListTerm)+1)*nIdx + nIdx;
      sIdxIter.u.ax.aIdx = sqlite3DbMallocZero(db, nByte);

      if( sIdxIter.u.ax.aIdx==0 ) return; /* OOM */
      bUsed = (u8*)&sIdxIter.u.ax.aIdx[nIdx];
      pUpsert->pToFree = sIdxIter.u.ax.aIdx;
      for(i=0, pTerm=pUpsert; pTerm; pTerm=pTerm->pNextUpsert){
        if( pTerm->pUpsertTarget==0 ) break;
        if( pTerm->pUpsertIdx==0 ) continue;  /* Skip ON CONFLICT for the IPK */
        jj = 0;
        pIdx = pTab->pIndex;
        while( ALWAYS(pIdx!=0) && pIdx!=pTerm->pUpsertIdx ){
           pIdx = pIdx->pNext;
           jj++;
        }
        if( bUsed[jj] ) continue; /* Duplicate ON CONFLICT clause ignored */
        bUsed[jj] = 1;
        sIdxIter.u.ax.aIdx[i].p = pIdx;
        sIdxIter.u.ax.aIdx[i].ix = jj;
        i++;
      }
      for(jj=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, jj++){
        if( bUsed[jj] ) continue;
        sIdxIter.u.ax.aIdx[i].p = pIdx;
        sIdxIter.u.ax.aIdx[i].ix = jj;
        i++;
      }
      assert( i==nIdx );
    }
  }

  /* Determine if it is possible that triggers (either explicitly coded
  ** triggers or FK resolution actions) might run as a result of deletes
  ** that happen when OE_Replace conflict resolution occurs. (Call these
  ** "replace triggers".)  If any replace triggers run, we will need to
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
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }

    /* figure out whether or not upsert applies in this case */
    if( pUpsert && pUpsert->pUpsertIdx==0 ){

      if( pUpsert->pUpsertSet==0 ){

        onError = OE_Ignore;  /* DO NOTHING is the same as INSERT OR IGNORE */
      }else{
        onError = OE_Update;  /* DO UPDATE */







      }
    }

    /* If the response to a rowid conflict is REPLACE but the response
    ** to some other UNIQUE constraint is FAIL or IGNORE, then we need
    ** to defer the running of the rowid conflict checking until after
    ** the UNIQUE constraints have run.
    */
    if( onError==OE_Replace      /* IPK rule is REPLACE */
     && onError!=overrideError   /* Rules for other contraints are different */
     && pTab->pIndex             /* There exist other constraints */
    ){
      ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1;
      VdbeComment((v, "defer IPK REPLACE until last"));
    }

    if( isUpdate ){







|
>
|
>
|
|
|
>
>
>
>
>
>
>









|







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
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }

    /* figure out whether or not upsert applies in this case */
    if( pUpsert ){
      pUpsertClause = sqlite3UpsertOfIndex(pUpsert,0);
      if( pUpsertClause!=0 ){
        if( pUpsertClause->isDoUpdate==0 ){
          onError = OE_Ignore;  /* DO NOTHING is the same as INSERT OR IGNORE */
        }else{
          onError = OE_Update;  /* DO UPDATE */
        }
      }
      if( pUpsertClause!=pUpsert ){
        /* The first ON CONFLICT clause has a conflict target other than
        ** the IPK.  We have to jump ahead to that first ON CONFLICT clause
        ** and then come back here and deal with the IPK afterwards */
        upsertIpkDelay = sqlite3VdbeAddOp0(v, OP_Goto);
      }
    }

    /* If the response to a rowid conflict is REPLACE but the response
    ** to some other UNIQUE constraint is FAIL or IGNORE, then we need
    ** to defer the running of the rowid conflict checking until after
    ** the UNIQUE constraints have run.
    */
    if( onError==OE_Replace      /* IPK rule is REPLACE */
     && onError!=overrideError   /* Rules for other constraints are different */
     && pTab->pIndex             /* There exist other constraints */
    ){
      ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1;
      VdbeComment((v, "defer IPK REPLACE until last"));
    }

    if( isUpdate ){
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
      case OE_Ignore: {
        testcase( onError==OE_Ignore );
        sqlite3VdbeGoto(v, ignoreDest);
        break;
      }
    }
    sqlite3VdbeResolveLabel(v, addrRowidOk);


    if( ipkTop ){
      ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto);
      sqlite3VdbeJumpHere(v, ipkTop-1);
    }
  }

  /* Test all UNIQUE constraints by creating entries for each UNIQUE
  ** index and making sure that duplicate entries do not already exist.
  ** Compute the revised record entries for indices as we go.
  **
  ** This loop also handles the case of the PRIMARY KEY index for a
  ** WITHOUT ROWID table.
  */

  for(ix=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, ix++){


    int regIdx;          /* Range of registers hold conent for pIdx */
    int regR;            /* Range of registers holding conflicting PK */
    int iThisCur;        /* Cursor for this UNIQUE index */
    int addrUniqueOk;    /* Jump here if the UNIQUE constraint is satisfied */
    int addrConflictCk;  /* First opcode in the conflict check logic */

    if( aRegIdx[ix]==0 ) continue;  /* Skip indices that do not change */
    if( pUpIdx==pIdx ){
      addrUniqueOk = upsertJump+1;
      upsertBypass = sqlite3VdbeGoto(v, 0);
      VdbeComment((v, "Skip upsert subroutine"));
      sqlite3VdbeJumpHere(v, upsertJump);
    }else{
      addrUniqueOk = sqlite3VdbeMakeLabel(pParse);
    }


    if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){
      sqlite3TableAffinity(v, pTab, regNewData+1);
      bAffinityDone = 1;
    }
    VdbeNoopComment((v, "prep index %s", pIdx->zName));
    iThisCur = iIdxCur+ix;









>
>
|












>
|
>
>







|
<
|
|
|
<
<
|
>
>
|







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
      case OE_Ignore: {
        testcase( onError==OE_Ignore );
        sqlite3VdbeGoto(v, ignoreDest);
        break;
      }
    }
    sqlite3VdbeResolveLabel(v, addrRowidOk);
    if( pUpsert && pUpsertClause!=pUpsert ){
      upsertIpkReturn = sqlite3VdbeAddOp0(v, OP_Goto);
    }else if( ipkTop ){
      ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto);
      sqlite3VdbeJumpHere(v, ipkTop-1);
    }
  }

  /* Test all UNIQUE constraints by creating entries for each UNIQUE
  ** index and making sure that duplicate entries do not already exist.
  ** Compute the revised record entries for indices as we go.
  **
  ** This loop also handles the case of the PRIMARY KEY index for a
  ** WITHOUT ROWID table.
  */
  for(pIdx = indexIteratorFirst(&sIdxIter, &ix);
      pIdx;
      pIdx = indexIteratorNext(&sIdxIter, &ix)
  ){
    int regIdx;          /* Range of registers hold conent for pIdx */
    int regR;            /* Range of registers holding conflicting PK */
    int iThisCur;        /* Cursor for this UNIQUE index */
    int addrUniqueOk;    /* Jump here if the UNIQUE constraint is satisfied */
    int addrConflictCk;  /* First opcode in the conflict check logic */

    if( aRegIdx[ix]==0 ) continue;  /* Skip indices that do not change */
    if( pUpsert ){

      pUpsertClause = sqlite3UpsertOfIndex(pUpsert, pIdx);
      if( upsertIpkDelay && pUpsertClause==pUpsert ){
        sqlite3VdbeJumpHere(v, upsertIpkDelay);


      }
    }
    addrUniqueOk = sqlite3VdbeMakeLabel(pParse);
    if( bAffinityDone==0 ){
      sqlite3TableAffinity(v, pTab, regNewData+1);
      bAffinityDone = 1;
    }
    VdbeNoopComment((v, "prep index %s", pIdx->zName));
    iThisCur = iIdxCur+ix;


2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }

    /* Figure out if the upsert clause applies to this index */
    if( pUpIdx==pIdx ){
      if( pUpsert->pUpsertSet==0 ){
        onError = OE_Ignore;  /* DO NOTHING is the same as INSERT OR IGNORE */
      }else{
        onError = OE_Update;  /* DO UPDATE */
      }
    }

    /* Collision detection may be omitted if all of the following are true:







|
|







2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }

    /* Figure out if the upsert clause applies to this index */
    if( pUpsertClause ){
      if( pUpsertClause->isDoUpdate==0 ){
        onError = OE_Ignore;  /* DO NOTHING is the same as INSERT OR IGNORE */
      }else{
        onError = OE_Update;  /* DO UPDATE */
      }
    }

    /* Collision detection may be omitted if all of the following are true:
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
    /* Check to see if the new index entry will be unique */
    sqlite3VdbeVerifyAbortable(v, onError);
    addrConflictCk = 
      sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
                           regIdx, pIdx->nKeyCol); VdbeCoverage(v);

    /* Generate code to handle collisions */
    regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField);
    if( isUpdate || onError==OE_Replace ){
      if( HasRowid(pTab) ){
        sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR);
        /* Conflict only if the rowid of the existing index entry
        ** is different from old-rowid */
        if( isUpdate ){
          sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData);







|







2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
    /* Check to see if the new index entry will be unique */
    sqlite3VdbeVerifyAbortable(v, onError);
    addrConflictCk = 
      sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
                           regIdx, pIdx->nKeyCol); VdbeCoverage(v);

    /* Generate code to handle collisions */
    regR = pIdx==pPk ? regIdx : sqlite3GetTempRange(pParse, nPkField);
    if( isUpdate || onError==OE_Replace ){
      if( HasRowid(pTab) ){
        sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR);
        /* Conflict only if the rowid of the existing index entry
        ** is different from old-rowid */
        if( isUpdate ){
          sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData);
2199
2200
2201
2202
2203
2204
2205


2206



2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219

          sqlite3VdbeJumpHere(v, addrBypass); /* Terminate the recheck bypass */
        }
        seenReplace = 1;
        break;
      }
    }


    if( pUpIdx==pIdx ){



      sqlite3VdbeGoto(v, upsertJump+1);
      sqlite3VdbeJumpHere(v, upsertBypass);
    }else{
      sqlite3VdbeResolveLabel(v, addrUniqueOk);
    }
    if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField);
  }

  /* If the IPK constraint is a REPLACE, run it last */
  if( ipkTop ){
    sqlite3VdbeGoto(v, ipkTop);
    VdbeComment((v, "Do IPK REPLACE"));
    sqlite3VdbeJumpHere(v, ipkBottom);







>
>
|
>
>
>
|
|
|
<

<







2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346

2347

2348
2349
2350
2351
2352
2353
2354

          sqlite3VdbeJumpHere(v, addrBypass); /* Terminate the recheck bypass */
        }
        seenReplace = 1;
        break;
      }
    }
    sqlite3VdbeResolveLabel(v, addrUniqueOk);
    if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField);
    if( pUpsertClause 
     && upsertIpkReturn
     && sqlite3UpsertNextIsIPK(pUpsertClause)
    ){
      sqlite3VdbeGoto(v, upsertIpkDelay+1);
      sqlite3VdbeJumpHere(v, upsertIpkReturn);
      upsertIpkReturn = 0;

    }

  }

  /* If the IPK constraint is a REPLACE, run it last */
  if( ipkTop ){
    sqlite3VdbeGoto(v, ipkTop);
    VdbeComment((v, "Do IPK REPLACE"));
    sqlite3VdbeJumpHere(v, ipkBottom);
2271
2272
2273
2274
2275
2276
2277



























2278
2279
2280
2281
2282
2283
2284
    if( pTab->aCol[i].pDflt!=0 ) break;
    if( pTab->aCol[i].colFlags & COLFLAG_PRIMKEY ) break;
  }
  sqlite3VdbeChangeP5(v, i+1);
}
#endif




























/*
** This routine generates code to finish the INSERT or UPDATE operation
** that was started by a prior call to sqlite3GenerateConstraintChecks.
** A consecutive range of registers starting at regNewData contains the
** rowid and the content to be inserted.
**
** The arguments to this routine should be the same as the first six







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    if( pTab->aCol[i].pDflt!=0 ) break;
    if( pTab->aCol[i].colFlags & COLFLAG_PRIMKEY ) break;
  }
  sqlite3VdbeChangeP5(v, i+1);
}
#endif

/*
** Table pTab is a WITHOUT ROWID table that is being written to. The cursor
** number is iCur, and register regData contains the new record for the
** PK index. This function adds code to invoke the pre-update hook,
** if one is registered.
*/
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
static void codeWithoutRowidPreupdate(
  Parse *pParse,                  /* Parse context */
  Table *pTab,                    /* Table being updated */
  int iCur,                       /* Cursor number for table */
  int regData,                    /* Data containing new record */
  u16 flags
){
  Vdbe *v = pParse->pVdbe;
  int r = sqlite3GetTempReg(pParse);
  assert( !HasRowid(pTab) );
  assert( 0==(pParse->db->mDbFlags & DBFLAG_Vacuum) );
  sqlite3VdbeAddOp2(v, OP_Integer, 0, r);
  sqlite3VdbeAddOp4(v, OP_Insert, iCur, regData, r, (char*)pTab, P4_TABLE);
  sqlite3VdbeChangeP5(v, flags);
  sqlite3ReleaseTempReg(pParse, r);
}
#else
# define codeWithoutRowidPreupdate(a,b,c,d)
#endif

/*
** This routine generates code to finish the INSERT or UPDATE operation
** that was started by a prior call to sqlite3GenerateConstraintChecks.
** A consecutive range of registers starting at regNewData contains the
** rowid and the content to be inserted.
**
** The arguments to this routine should be the same as the first six
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
      VdbeCoverage(v);
    }
    pik_flags = (useSeekResult ? OPFLAG_USESEEKRESULT : 0);
    if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){
      assert( pParse->nested==0 );
      pik_flags |= OPFLAG_NCHANGE;
      pik_flags |= (update_flags & OPFLAG_SAVEPOSITION);
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
      if( 1 || update_flags==0 ){
        int r = sqlite3GetTempReg(pParse);
        sqlite3VdbeAddOp2(v, OP_Integer, 0, r);
        sqlite3VdbeAddOp4(v, OP_Insert,
            iIdxCur+i, aRegIdx[i], r, (char*)pTab, P4_TABLE

        );
        sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP|(update_flags&OPFLAG_ISUPDATE));
        sqlite3ReleaseTempReg(pParse, r);
      }
#endif
    }
    sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i],
                         aRegIdx[i]+1,
                         pIdx->uniqNotNull ? pIdx->nKeyCol: pIdx->nColumn);
    sqlite3VdbeChangeP5(v, pik_flags);
  }
  if( !HasRowid(pTab) ) return;







<

<
<
<
|
>

<
<

<







2481
2482
2483
2484
2485
2486
2487

2488



2489
2490
2491


2492

2493
2494
2495
2496
2497
2498
2499
      VdbeCoverage(v);
    }
    pik_flags = (useSeekResult ? OPFLAG_USESEEKRESULT : 0);
    if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){
      assert( pParse->nested==0 );
      pik_flags |= OPFLAG_NCHANGE;
      pik_flags |= (update_flags & OPFLAG_SAVEPOSITION);

      if( 1 || update_flags==0 ){



        codeWithoutRowidPreupdate(pParse, pTab, iIdxCur+i, aRegIdx[i],
            OPFLAG_ISNOOP|(update_flags & OPFLAG_ISUPDATE)
        );


      }

    }
    sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i],
                         aRegIdx[i]+1,
                         pIdx->uniqNotNull ? pIdx->nKeyCol: pIdx->nColumn);
    sqlite3VdbeChangeP5(v, pik_flags);
  }
  if( !HasRowid(pTab) ) return;
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
  int onError,          /* How to handle constraint errors */
  int iDbDest           /* The database of pDest */
){
  sqlite3 *db = pParse->db;
  ExprList *pEList;                /* The result set of the SELECT */
  Table *pSrc;                     /* The table in the FROM clause of SELECT */
  Index *pSrcIdx, *pDestIdx;       /* Source and destination indices */
  struct SrcList_item *pItem;      /* An element of pSelect->pSrc */
  int i;                           /* Loop counter */
  int iDbSrc;                      /* The database of pSrc */
  int iSrc, iDest;                 /* Cursors from source and destination */
  int addr1, addr2;                /* Loop addresses */
  int emptyDestTest = 0;           /* Address of test for empty pDest */
  int emptySrcTest = 0;            /* Address of test for empty pSrc */
  Vdbe *v;                         /* The VDBE we are building */







|







2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
  int onError,          /* How to handle constraint errors */
  int iDbDest           /* The database of pDest */
){
  sqlite3 *db = pParse->db;
  ExprList *pEList;                /* The result set of the SELECT */
  Table *pSrc;                     /* The table in the FROM clause of SELECT */
  Index *pSrcIdx, *pDestIdx;       /* Source and destination indices */
  SrcItem *pItem;                  /* An element of pSelect->pSrc */
  int i;                           /* Loop counter */
  int iDbSrc;                      /* The database of pSrc */
  int iSrc, iDest;                 /* Cursors from source and destination */
  int addr1, addr2;                /* Loop addresses */
  int emptyDestTest = 0;           /* Address of test for empty pDest */
  int emptySrcTest = 0;            /* Address of test for empty pSrc */
  Vdbe *v;                         /* The VDBE we are building */
2744
2745
2746
2747
2748
2749
2750

2751
2752
2753
2754
2755
2756
2757
  iDbSrc = sqlite3SchemaToIndex(db, pSrc->pSchema);
  v = sqlite3GetVdbe(pParse);
  sqlite3CodeVerifySchema(pParse, iDbSrc);
  iSrc = pParse->nTab++;
  iDest = pParse->nTab++;
  regAutoinc = autoIncBegin(pParse, iDbDest, pDest);
  regData = sqlite3GetTempReg(pParse);

  regRowid = sqlite3GetTempReg(pParse);
  sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
  assert( HasRowid(pDest) || destHasUniqueIdx );
  if( (db->mDbFlags & DBFLAG_Vacuum)==0 && (
      (pDest->iPKey<0 && pDest->pIndex!=0)          /* (1) */
   || destHasUniqueIdx                              /* (2) */
   || (onError!=OE_Abort && onError!=OE_Rollback)   /* (3) */







>







2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
  iDbSrc = sqlite3SchemaToIndex(db, pSrc->pSchema);
  v = sqlite3GetVdbe(pParse);
  sqlite3CodeVerifySchema(pParse, iDbSrc);
  iSrc = pParse->nTab++;
  iDest = pParse->nTab++;
  regAutoinc = autoIncBegin(pParse, iDbDest, pDest);
  regData = sqlite3GetTempReg(pParse);
  sqlite3VdbeAddOp2(v, OP_Null, 0, regData);
  regRowid = sqlite3GetTempReg(pParse);
  sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
  assert( HasRowid(pDest) || destHasUniqueIdx );
  if( (db->mDbFlags & DBFLAG_Vacuum)==0 && (
      (pDest->iPKey<0 && pDest->pIndex!=0)          /* (1) */
   || destHasUniqueIdx                              /* (2) */
   || (onError!=OE_Abort && onError!=OE_Rollback)   /* (3) */
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
  }
  if( HasRowid(pSrc) ){
    u8 insFlags;
    sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
    emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
    if( pDest->iPKey>=0 ){
      addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);

      sqlite3VdbeVerifyAbortable(v, onError);
      addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
      VdbeCoverage(v);
      sqlite3RowidConstraint(pParse, onError, pDest);
      sqlite3VdbeJumpHere(v, addr2);

      autoIncStep(pParse, regAutoinc, regRowid);
    }else if( pDest->pIndex==0 && !(db->mDbFlags & DBFLAG_VacuumInto) ){
      addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
    }else{
      addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
      assert( (pDest->tabFlags & TF_Autoincrement)==0 );
    }

    if( db->mDbFlags & DBFLAG_Vacuum ){
      sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest);
      insFlags = OPFLAG_APPEND|OPFLAG_USESEEKRESULT;
    }else{
      insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND;
    }


    sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);






    sqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid,

                      (char*)pDest, P4_TABLE);

    sqlite3VdbeChangeP5(v, insFlags);

    sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v);
    sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
    sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
  }else{
    sqlite3TableLock(pParse, iDbDest, pDest->tnum, 1, pDest->zName);
    sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName);
  }







>
|
|
|
|
|
>







>


|

|

>
>
|
>
>
>
>
>
>
|
>
|
>

>







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
  }
  if( HasRowid(pSrc) ){
    u8 insFlags;
    sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
    emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
    if( pDest->iPKey>=0 ){
      addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
      if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){
        sqlite3VdbeVerifyAbortable(v, onError);
        addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
        VdbeCoverage(v);
        sqlite3RowidConstraint(pParse, onError, pDest);
        sqlite3VdbeJumpHere(v, addr2);
      }
      autoIncStep(pParse, regAutoinc, regRowid);
    }else if( pDest->pIndex==0 && !(db->mDbFlags & DBFLAG_VacuumInto) ){
      addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
    }else{
      addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
      assert( (pDest->tabFlags & TF_Autoincrement)==0 );
    }

    if( db->mDbFlags & DBFLAG_Vacuum ){
      sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest);
      insFlags = OPFLAG_APPEND|OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT;
    }else{
      insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND|OPFLAG_PREFORMAT;
    }
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
    if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){
      sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
      insFlags &= ~OPFLAG_PREFORMAT;
    }else
#endif
    {
      sqlite3VdbeAddOp3(v, OP_RowCell, iDest, iSrc, regRowid);
    }
    sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid);
    if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){
      sqlite3VdbeChangeP4(v, -1, (char*)pDest, P4_TABLE);
    }
    sqlite3VdbeChangeP5(v, insFlags);

    sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v);
    sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
    sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
  }else{
    sqlite3TableLock(pParse, iDbDest, pDest->tnum, 1, pDest->zName);
    sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName);
  }
2842
2843
2844
2845
2846
2847
2848
2849
2850

2851
2852
2853
2854

2855







2856
2857
2858
2859
2860
2861
2862
      ** a VACUUM command. In that case keys may not be written in strictly
      ** sorted order.  */
      for(i=0; i<pSrcIdx->nColumn; i++){
        const char *zColl = pSrcIdx->azColl[i];
        if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break;
      }
      if( i==pSrcIdx->nColumn ){
        idxInsFlags = OPFLAG_USESEEKRESULT;
        sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest);

      }
    }else if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){
      idxInsFlags |= OPFLAG_NCHANGE;
    }

    sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);







    sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData);
    sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND);
    sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
    sqlite3VdbeJumpHere(v, addr1);
    sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
    sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
  }







|

>




>
|
>
>
>
>
>
>
>







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
      ** a VACUUM command. In that case keys may not be written in strictly
      ** sorted order.  */
      for(i=0; i<pSrcIdx->nColumn; i++){
        const char *zColl = pSrcIdx->azColl[i];
        if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break;
      }
      if( i==pSrcIdx->nColumn ){
        idxInsFlags = OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT;
        sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest);
        sqlite3VdbeAddOp2(v, OP_RowCell, iDest, iSrc);
      }
    }else if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){
      idxInsFlags |= OPFLAG_NCHANGE;
    }
    if( idxInsFlags!=(OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT) ){
      sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
      if( (db->mDbFlags & DBFLAG_Vacuum)==0 
       && !HasRowid(pDest) 
       && IsPrimaryKeyIndex(pDestIdx) 
      ){
        codeWithoutRowidPreupdate(pParse, pDest, iDest, regData, OPFLAG_ISNOOP);
      }
    }
    sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData);
    sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND);
    sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
    sqlite3VdbeJumpHere(v, addr1);
    sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
    sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
  }
Changes to src/main.c.
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
  int *pnLog,                     /* OUT: Size of WAL log in frames */
  int *pnCkpt                     /* OUT: Total number of frames checkpointed */
){
#ifdef SQLITE_OMIT_WAL
  return SQLITE_OK;
#else
  int rc;                         /* Return code */
  int iDb = SQLITE_MAX_ATTACHED;  /* sqlite3.aDb[] index of db to checkpoint */

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif

  /* Initialize the output variables to -1 in case an error occurs. */
  if( pnLog ) *pnLog = -1;







|







2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
  int *pnLog,                     /* OUT: Size of WAL log in frames */
  int *pnCkpt                     /* OUT: Total number of frames checkpointed */
){
#ifdef SQLITE_OMIT_WAL
  return SQLITE_OK;
#else
  int rc;                         /* Return code */
  int iDb;                        /* Schema to checkpoint */

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif

  /* Initialize the output variables to -1 in case an error occurs. */
  if( pnLog ) *pnLog = -1;
2397
2398
2399
2400
2401
2402
2403


2404
2405
2406
2407
2408
2409
2410
    ** mode: */
    return SQLITE_MISUSE;
  }

  sqlite3_mutex_enter(db->mutex);
  if( zDb && zDb[0] ){
    iDb = sqlite3FindDbName(db, zDb);


  }
  if( iDb<0 ){
    rc = SQLITE_ERROR;
    sqlite3ErrorWithMsg(db, SQLITE_ERROR, "unknown database: %s", zDb);
  }else{
    db->busyHandler.nBusy = 0;
    rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt);







>
>







2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
    ** mode: */
    return SQLITE_MISUSE;
  }

  sqlite3_mutex_enter(db->mutex);
  if( zDb && zDb[0] ){
    iDb = sqlite3FindDbName(db, zDb);
  }else{
    iDb = SQLITE_MAX_DB;   /* This means process all schemas */
  }
  if( iDb<0 ){
    rc = SQLITE_ERROR;
    sqlite3ErrorWithMsg(db, SQLITE_ERROR, "unknown database: %s", zDb);
  }else{
    db->busyHandler.nBusy = 0;
    rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt);
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
** an error occurs while running the checkpoint, an SQLite error code is 
** returned (i.e. SQLITE_IOERR). Otherwise, SQLITE_OK.
**
** The mutex on database handle db should be held by the caller. The mutex
** associated with the specific b-tree being checkpointed is taken by
** this function while the checkpoint is running.
**
** If iDb is passed SQLITE_MAX_ATTACHED, then all attached databases are
** checkpointed. If an error is encountered it is returned immediately -
** no attempt is made to checkpoint any remaining databases.
**
** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL, RESTART
** or TRUNCATE.
*/
int sqlite3Checkpoint(sqlite3 *db, int iDb, int eMode, int *pnLog, int *pnCkpt){
  int rc = SQLITE_OK;             /* Return code */
  int i;                          /* Used to iterate through attached dbs */
  int bBusy = 0;                  /* True if SQLITE_BUSY has been encountered */

  assert( sqlite3_mutex_held(db->mutex) );
  assert( !pnLog || *pnLog==-1 );
  assert( !pnCkpt || *pnCkpt==-1 );



  for(i=0; i<db->nDb && rc==SQLITE_OK; i++){
    if( i==iDb || iDb==SQLITE_MAX_ATTACHED ){
      rc = sqlite3BtreeCheckpoint(db->aDb[i].pBt, eMode, pnLog, pnCkpt);
      pnLog = 0;
      pnCkpt = 0;
      if( rc==SQLITE_BUSY ){
        bBusy = 1;
        rc = SQLITE_OK;
      }







|














>
>


|







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
** an error occurs while running the checkpoint, an SQLite error code is 
** returned (i.e. SQLITE_IOERR). Otherwise, SQLITE_OK.
**
** The mutex on database handle db should be held by the caller. The mutex
** associated with the specific b-tree being checkpointed is taken by
** this function while the checkpoint is running.
**
** If iDb is passed SQLITE_MAX_DB then all attached databases are
** checkpointed. If an error is encountered it is returned immediately -
** no attempt is made to checkpoint any remaining databases.
**
** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL, RESTART
** or TRUNCATE.
*/
int sqlite3Checkpoint(sqlite3 *db, int iDb, int eMode, int *pnLog, int *pnCkpt){
  int rc = SQLITE_OK;             /* Return code */
  int i;                          /* Used to iterate through attached dbs */
  int bBusy = 0;                  /* True if SQLITE_BUSY has been encountered */

  assert( sqlite3_mutex_held(db->mutex) );
  assert( !pnLog || *pnLog==-1 );
  assert( !pnCkpt || *pnCkpt==-1 );
  testcase( iDb==SQLITE_MAX_ATTACHED ); /* See forum post a006d86f72 */
  testcase( iDb==SQLITE_MAX_DB );

  for(i=0; i<db->nDb && rc==SQLITE_OK; i++){
    if( i==iDb || iDb==SQLITE_MAX_DB ){
      rc = sqlite3BtreeCheckpoint(db->aDb[i].pBt, eMode, pnLog, pnCkpt);
      pnLog = 0;
      pnCkpt = 0;
      if( rc==SQLITE_BUSY ){
        bBusy = 1;
        rc = SQLITE_OK;
      }
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
    ** operation N should be 0.  The idea is that a test program (like the
    ** SQL Logic Test or SLT test module) can run the same SQL multiple times
    ** with various optimizations disabled to verify that the same answer
    ** is obtained in every case.
    */
    case SQLITE_TESTCTRL_OPTIMIZATIONS: {
      sqlite3 *db = va_arg(ap, sqlite3*);
      db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff);
      break;
    }

    /*   sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
    **
    ** If parameter onoff is non-zero, subsequent calls to localtime()
    ** and its variants fail. If onoff is zero, undo this setting.







|







4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
    ** operation N should be 0.  The idea is that a test program (like the
    ** SQL Logic Test or SLT test module) can run the same SQL multiple times
    ** with various optimizations disabled to verify that the same answer
    ** is obtained in every case.
    */
    case SQLITE_TESTCTRL_OPTIMIZATIONS: {
      sqlite3 *db = va_arg(ap, sqlite3*);
      db->dbOptFlags = va_arg(ap, u32);
      break;
    }

    /*   sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
    **
    ** If parameter onoff is non-zero, subsequent calls to localtime()
    ** and its variants fail. If onoff is zero, undo this setting.
4255
4256
4257
4258
4259
4260
4261

















4262


4263
4264
4265
4266
4267
4268
4269
      sqlite3 *db = va_arg(ap, sqlite3*);
      u64 *pn = va_arg(ap, sqlite3_uint64*);
      *pn = sqlite3BtreeSeekCount(db->aDb->pBt);
      (void)db;  /* Silence harmless unused variable warning */
      break;
    }





















  }
  va_end(ap);
#endif /* SQLITE_UNTESTABLE */
  return rc;
}

/*







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>







4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
      sqlite3 *db = va_arg(ap, sqlite3*);
      u64 *pn = va_arg(ap, sqlite3_uint64*);
      *pn = sqlite3BtreeSeekCount(db->aDb->pBt);
      (void)db;  /* Silence harmless unused variable warning */
      break;
    }

    /*  sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, op, ptr)
    **
    **  "ptr" is a pointer to a u32.  
    **
    **   op==0       Store the current sqlite3SelectTrace in *ptr
    **   op==1       Set sqlite3SelectTrace to the value *ptr
    **   op==3       Store the current sqlite3WhereTrace in *ptr
    **   op==3       Set sqlite3WhereTrace to the value *ptr
    */
    case SQLITE_TESTCTRL_TRACEFLAGS: {
       int opTrace = va_arg(ap, int);
       u32 *ptr = va_arg(ap, u32*);
       switch( opTrace ){
         case 0:   *ptr = sqlite3SelectTrace;      break;
         case 1:   sqlite3SelectTrace = *ptr;      break;
         case 2:   *ptr = sqlite3WhereTrace;       break;
         case 3:   sqlite3WhereTrace = *ptr;       break;
       }
       break;
    }
  }
  va_end(ap);
#endif /* SQLITE_UNTESTABLE */
  return rc;
}

/*
Changes to src/memjournal.c.
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
** is an instance of this class.
*/
struct MemJournal {
  const sqlite3_io_methods *pMethod; /* Parent class. MUST BE FIRST */
  int nChunkSize;                 /* In-memory chunk-size */

  int nSpill;                     /* Bytes of data before flushing */
  int nSize;                      /* Bytes of data currently in memory */
  FileChunk *pFirst;              /* Head of in-memory chunk-list */
  FilePoint endpoint;             /* Pointer to the end of the file */
  FilePoint readpoint;            /* Pointer to the end of the last xRead() */

  int flags;                      /* xOpen flags */
  sqlite3_vfs *pVfs;              /* The "real" underlying VFS */
  const char *zJournal;           /* Name of the journal file */







<







66
67
68
69
70
71
72

73
74
75
76
77
78
79
** is an instance of this class.
*/
struct MemJournal {
  const sqlite3_io_methods *pMethod; /* Parent class. MUST BE FIRST */
  int nChunkSize;                 /* In-memory chunk-size */

  int nSpill;                     /* Bytes of data before flushing */

  FileChunk *pFirst;              /* Head of in-memory chunk-list */
  FilePoint endpoint;             /* Pointer to the end of the file */
  FilePoint readpoint;            /* Pointer to the end of the last xRead() */

  int flags;                      /* xOpen flags */
  sqlite3_vfs *pVfs;              /* The "real" underlying VFS */
  const char *zJournal;           /* Name of the journal file */
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

  return SQLITE_OK;
}

/*
** Free the list of FileChunk structures headed at MemJournal.pFirst.
*/
static void memjrnlFreeChunks(MemJournal *p){
  FileChunk *pIter;
  FileChunk *pNext;
  for(pIter=p->pFirst; pIter; pIter=pNext){
    pNext = pIter->pNext;
    sqlite3_free(pIter);
  } 
  p->pFirst = 0;
}

/*
** Flush the contents of memory to a real file on disk.
*/
static int memjrnlCreateFile(MemJournal *p){
  int rc;







|


|



<







126
127
128
129
130
131
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146

  return SQLITE_OK;
}

/*
** Free the list of FileChunk structures headed at MemJournal.pFirst.
*/
static void memjrnlFreeChunks(FileChunk *pFirst){
  FileChunk *pIter;
  FileChunk *pNext;
  for(pIter=pFirst; pIter; pIter=pNext){
    pNext = pIter->pNext;
    sqlite3_free(pIter);
  } 

}

/*
** Flush the contents of memory to a real file on disk.
*/
static int memjrnlCreateFile(MemJournal *p){
  int rc;
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
      }
      rc = sqlite3OsWrite(pReal, (u8*)pIter->zChunk, nChunk, iOff);
      if( rc ) break;
      iOff += nChunk;
    }
    if( rc==SQLITE_OK ){
      /* No error has occurred. Free the in-memory buffers. */
      memjrnlFreeChunks(&copy);
    }
  }
  if( rc!=SQLITE_OK ){
    /* If an error occurred while creating or writing to the file, restore
    ** the original before returning. This way, SQLite uses the in-memory
    ** journal data to roll back changes made to the internal page-cache
    ** before this function was called.  */







|







159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
      }
      rc = sqlite3OsWrite(pReal, (u8*)pIter->zChunk, nChunk, iOff);
      if( rc ) break;
      iOff += nChunk;
    }
    if( rc==SQLITE_OK ){
      /* No error has occurred. Free the in-memory buffers. */
      memjrnlFreeChunks(copy.pFirst);
    }
  }
  if( rc!=SQLITE_OK ){
    /* If an error occurred while creating or writing to the file, restore
    ** the original before returning. This way, SQLite uses the in-memory
    ** journal data to roll back changes made to the internal page-cache
    ** before this function was called.  */
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
        }

        memcpy((u8*)p->endpoint.pChunk->zChunk + iChunkOffset, zWrite, iSpace);
        zWrite += iSpace;
        nWrite -= iSpace;
        p->endpoint.iOffset += iSpace;
      }
      p->nSize = iAmt + iOfst;
    }
  }

  return SQLITE_OK;
}

/*
** Truncate the file.
**
** If the journal file is already on disk, truncate it there. Or, if it
** is still in main memory but is being truncated to zero bytes in size,
** ignore 
*/
static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
  MemJournal *p = (MemJournal *)pJfd;










  if( ALWAYS(size==0) ){
    memjrnlFreeChunks(p);
    p->nSize = 0;



    p->endpoint.pChunk = 0;
    p->endpoint.iOffset = 0;
    p->readpoint.pChunk = 0;
    p->readpoint.iOffset = 0;
  }
  return SQLITE_OK;
}

/*
** Close the file.
*/
static int memjrnlClose(sqlite3_file *pJfd){
  MemJournal *p = (MemJournal *)pJfd;
  memjrnlFreeChunks(p);
  return SQLITE_OK;
}

/*
** Sync the file.
**
** If the real file has been created, call its xSync method. Otherwise, 







<







|
<
<
<
<



>
>
>
>
>
>
>
>
>
>
|
|
|
>
>
>
|
|
|
|
<








|







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
        }

        memcpy((u8*)p->endpoint.pChunk->zChunk + iChunkOffset, zWrite, iSpace);
        zWrite += iSpace;
        nWrite -= iSpace;
        p->endpoint.iOffset += iSpace;
      }

    }
  }

  return SQLITE_OK;
}

/*
** Truncate the in-memory file.




*/
static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
  MemJournal *p = (MemJournal *)pJfd;
  FileChunk *pIter = 0;

  if( size==0 ){
    memjrnlFreeChunks(p->pFirst);
    p->pFirst = 0;
  }else{
    i64 iOff = p->nChunkSize;
    for(pIter=p->pFirst; ALWAYS(pIter) && iOff<=size; pIter=pIter->pNext){
      iOff += p->nChunkSize;
    }
    if( ALWAYS(pIter) ){
      memjrnlFreeChunks(pIter->pNext);
      pIter->pNext = 0;
    }
  }

  p->endpoint.pChunk = pIter;
  p->endpoint.iOffset = size;
  p->readpoint.pChunk = 0;
  p->readpoint.iOffset = 0;

  return SQLITE_OK;
}

/*
** Close the file.
*/
static int memjrnlClose(sqlite3_file *pJfd){
  MemJournal *p = (MemJournal *)pJfd;
  memjrnlFreeChunks(p->pFirst);
  return SQLITE_OK;
}

/*
** Sync the file.
**
** If the real file has been created, call its xSync method. Otherwise, 
Changes to src/os.c.
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
** routine has no return value since the return value would be meaningless.
*/
int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
  if( id->pMethods==0 ) return SQLITE_NOTFOUND;
#ifdef SQLITE_TEST
  if( op!=SQLITE_FCNTL_COMMIT_PHASETWO
   && op!=SQLITE_FCNTL_LOCK_TIMEOUT


  ){
    /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite
    ** is using a regular VFS, it is called after the corresponding
    ** transaction has been committed. Injecting a fault at this point
    ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM
    ** but the transaction is committed anyway.
    **
    ** The core must call OsFileControl() though, not OsFileControlHint(),
    ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably
    ** means the commit really has failed and an error should be returned
    ** to the user.  */





    DO_OS_MALLOC_TEST(id);
  }
#endif
  return id->pMethods->xFileControl(id, op, pArg);
}
void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){
  if( id->pMethods ) (void)id->pMethods->xFileControl(id, op, pArg);







>
>










|
>
>
>
>
>







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
** routine has no return value since the return value would be meaningless.
*/
int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
  if( id->pMethods==0 ) return SQLITE_NOTFOUND;
#ifdef SQLITE_TEST
  if( op!=SQLITE_FCNTL_COMMIT_PHASETWO
   && op!=SQLITE_FCNTL_LOCK_TIMEOUT
   && op!=SQLITE_FCNTL_CKPT_DONE
   && op!=SQLITE_FCNTL_CKPT_START
  ){
    /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite
    ** is using a regular VFS, it is called after the corresponding
    ** transaction has been committed. Injecting a fault at this point
    ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM
    ** but the transaction is committed anyway.
    **
    ** The core must call OsFileControl() though, not OsFileControlHint(),
    ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably
    ** means the commit really has failed and an error should be returned
    ** to the user.
    **
    ** The CKPT_DONE and CKPT_START file-controls are write-only signals
    ** to the cksumvfs.  Their return code is meaningless and is ignored
    ** by the SQLite core, so there is no point in simulating OOMs for them.
    */
    DO_OS_MALLOC_TEST(id);
  }
#endif
  return id->pMethods->xFileControl(id, op, pArg);
}
void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){
  if( id->pMethods ) (void)id->pMethods->xFileControl(id, op, pArg);
Changes to src/pager.c.
431
432
433
434
435
436
437

438
439
440
441
442
443
444
typedef struct PagerSavepoint PagerSavepoint;
struct PagerSavepoint {
  i64 iOffset;                 /* Starting offset in main journal */
  i64 iHdrOffset;              /* See above */
  Bitvec *pInSavepoint;        /* Set of pages in this savepoint */
  Pgno nOrig;                  /* Original number of pages in file */
  Pgno iSubRec;                /* Index of first record in sub-journal */

#ifndef SQLITE_OMIT_WAL
  u32 aWalData[WAL_SAVEPOINT_NDATA];        /* WAL savepoint context */
#endif
};

/*
** Bits of the Pager.doNotSpill flag.  See further description below.







>







431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
typedef struct PagerSavepoint PagerSavepoint;
struct PagerSavepoint {
  i64 iOffset;                 /* Starting offset in main journal */
  i64 iHdrOffset;              /* See above */
  Bitvec *pInSavepoint;        /* Set of pages in this savepoint */
  Pgno nOrig;                  /* Original number of pages in file */
  Pgno iSubRec;                /* Index of first record in sub-journal */
  int bTruncateOnRelease;      /* If stmt journal may be truncated on RELEASE */
#ifndef SQLITE_OMIT_WAL
  u32 aWalData[WAL_SAVEPOINT_NDATA];        /* WAL savepoint context */
#endif
};

/*
** Bits of the Pager.doNotSpill flag.  See further description below.
1071
1072
1073
1074
1075
1076
1077



1078
1079
1080
1081
1082
1083
1084
  Pager *pPager = pPg->pPager;
  PagerSavepoint *p;
  Pgno pgno = pPg->pgno;
  int i;
  for(i=0; i<pPager->nSavepoint; i++){
    p = &pPager->aSavepoint[i];
    if( p->nOrig>=pgno && 0==sqlite3BitvecTestNotNull(p->pInSavepoint, pgno) ){



      return 1;
    }
  }
  return 0;
}

#ifdef SQLITE_DEBUG







>
>
>







1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
  Pager *pPager = pPg->pPager;
  PagerSavepoint *p;
  Pgno pgno = pPg->pgno;
  int i;
  for(i=0; i<pPager->nSavepoint; i++){
    p = &pPager->aSavepoint[i];
    if( p->nOrig>=pgno && 0==sqlite3BitvecTestNotNull(p->pInSavepoint, pgno) ){
      for(i=i+1; i<pPager->nSavepoint; i++){
        pPager->aSavepoint[i].bTruncateOnRelease = 0;
      }
      return 1;
    }
  }
  return 0;
}

#ifdef SQLITE_DEBUG
7013
7014
7015
7016
7017
7018
7019

7020
7021
7022
7023
7024
7025
7026
    if( isOpen(pPager->jfd) && 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_BKPT;
    }
    if( pagerUseWal(pPager) ){
      sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData);
    }
    pPager->nSavepoint = ii+1;







>







7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
    if( isOpen(pPager->jfd) && 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);
    aNew[ii].bTruncateOnRelease = 1;
    if( !aNew[ii].pInSavepoint ){
      return SQLITE_NOMEM_BKPT;
    }
    if( pagerUseWal(pPager) ){
      sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData);
    }
    pPager->nSavepoint = ii+1;
7094
7095
7096
7097
7098
7099
7100

7101
7102
7103

7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
      sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
    }
    pPager->nSavepoint = nNew;

    /* If this is a release of the outermost savepoint, truncate 
    ** the sub-journal to zero bytes in size. */
    if( op==SAVEPOINT_RELEASE ){

      if( nNew==0 && isOpen(pPager->sjfd) ){
        /* Only truncate if it is an in-memory sub-journal. */
        if( sqlite3JournalIsInMemory(pPager->sjfd) ){

          rc = sqlite3OsTruncate(pPager->sjfd, 0);
          assert( rc==SQLITE_OK );
        }
        pPager->nSubRec = 0;
      }
    }
    /* Else this is a rollback operation, playback the specified savepoint.
    ** If this is a temp-file, it is possible that the journal file has
    ** not yet been opened. In this case there have been no changes to
    ** the database file, so the playback operation can be skipped.
    */







>
|


>
|


|







7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
      sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
    }
    pPager->nSavepoint = nNew;

    /* If this is a release of the outermost savepoint, truncate 
    ** the sub-journal to zero bytes in size. */
    if( op==SAVEPOINT_RELEASE ){
      PagerSavepoint *pRel = &pPager->aSavepoint[nNew];
      if( pRel->bTruncateOnRelease && isOpen(pPager->sjfd) ){
        /* Only truncate if it is an in-memory sub-journal. */
        if( sqlite3JournalIsInMemory(pPager->sjfd) ){
          i64 sz = (pPager->pageSize+4)*pRel->iSubRec;
          rc = sqlite3OsTruncate(pPager->sjfd, sz);
          assert( rc==SQLITE_OK );
        }
        pPager->nSubRec = pRel->iSubRec;
      }
    }
    /* Else this is a rollback operation, playback the specified savepoint.
    ** If this is a temp-file, it is possible that the journal file has
    ** not yet been opened. In this case there have been no changes to
    ** the database file, so the playback operation can be skipped.
    */
Changes to src/parse.y.
262
263
264
265
266
267
268

269
270
271
272
273
274
275
%ifndef SQLITE_OMIT_WINDOWFUNC
  CURRENT FOLLOWING PARTITION PRECEDING RANGE UNBOUNDED
  EXCLUDE GROUPS OTHERS TIES
%endif SQLITE_OMIT_WINDOWFUNC
%ifndef SQLITE_OMIT_GENERATED_COLUMNS
  GENERATED ALWAYS
%endif

  REINDEX RENAME CTIME_KW IF
  .
%wildcard ANY.

// Define operator precedence early so that this is the first occurrence
// of the operator tokens in the grammer.  Keeping the operators together
// causes them to be assigned integer values that are close together,







>







262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
%ifndef SQLITE_OMIT_WINDOWFUNC
  CURRENT FOLLOWING PARTITION PRECEDING RANGE UNBOUNDED
  EXCLUDE GROUPS OTHERS TIES
%endif SQLITE_OMIT_WINDOWFUNC
%ifndef SQLITE_OMIT_GENERATED_COLUMNS
  GENERATED ALWAYS
%endif
  MATERIALIZED
  REINDEX RENAME CTIME_KW IF
  .
%wildcard ANY.

// Define operator precedence early so that this is the first occurrence
// of the operator tokens in the grammer.  Keeping the operators together
// causes them to be assigned integer values that are close together,
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
  ** For a compound SELECT statement, make sure p->pPrior->pNext==p for
  ** all elements in the list.  And make sure list length does not exceed
  ** SQLITE_LIMIT_COMPOUND_SELECT.
  */
  static void parserDoubleLinkSelect(Parse *pParse, Select *p){
    assert( p!=0 );
    if( p->pPrior ){
      Select *pNext = 0, *pLoop;
      int mxSelect, cnt = 0;
      for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){
        pLoop->pNext = pNext;
        pLoop->selFlags |= SF_Compound;










      }
      if( (p->selFlags & SF_MultiValue)==0 && 
        (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 &&
        cnt>mxSelect
      ){
        sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
      }
    }
  }
}

%ifndef SQLITE_OMIT_CTE
select(A) ::= WITH wqlist(W) selectnowith(X). {

  Select *p = X;
  if( p ){
    p->pWith = W;
    parserDoubleLinkSelect(pParse, p);
  }else{
    sqlite3WithDelete(pParse->db, W);
  }
  A = p;
}
select(A) ::= WITH RECURSIVE wqlist(W) selectnowith(X). {
  Select *p = X;
  if( p ){
    p->pWith = W;
    parserDoubleLinkSelect(pParse, p);
  }else{
    sqlite3WithDelete(pParse->db, W);
  }
  A = p;
}




%endif /* SQLITE_OMIT_CTE */
select(A) ::= selectnowith(X). {
  Select *p = X;
  if( p ){
    parserDoubleLinkSelect(pParse, p);
  }
  A = p; /*A-overwrites-X*/







|
|
|


>
>
>
>
>
>
>
>
>
>









|
|
|
<
>
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
|
<
|
>
>
>
>







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
  ** For a compound SELECT statement, make sure p->pPrior->pNext==p for
  ** all elements in the list.  And make sure list length does not exceed
  ** SQLITE_LIMIT_COMPOUND_SELECT.
  */
  static void parserDoubleLinkSelect(Parse *pParse, Select *p){
    assert( p!=0 );
    if( p->pPrior ){
      Select *pNext = 0, *pLoop = p;
      int mxSelect, cnt = 1;
      while(1){
        pLoop->pNext = pNext;
        pLoop->selFlags |= SF_Compound;
        pNext = pLoop;
        pLoop = pLoop->pPrior;
        if( pLoop==0 ) break;
        cnt++;        
        if( pLoop->pOrderBy || pLoop->pLimit ){
          sqlite3ErrorMsg(pParse,"%s clause should come after %s not before",
             pLoop->pOrderBy!=0 ? "ORDER BY" : "LIMIT",
             sqlite3SelectOpName(pNext->op));
          break;
        }
      }
      if( (p->selFlags & SF_MultiValue)==0 && 
        (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 &&
        cnt>mxSelect
      ){
        sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
      }
    }
  }

  /* Attach a With object describing the WITH clause to a Select
  ** object describing the query for which the WITH clause is a prefix.

  */
  static Select *attachWithToSelect(Parse *pParse, Select *pSelect, With *pWith){
    if( pSelect ){
      pSelect->pWith = pWith;
      parserDoubleLinkSelect(pParse, pSelect);
    }else{
      sqlite3WithDelete(pParse->db, pWith);
    }
    return pSelect;
  }







}


%ifndef SQLITE_OMIT_CTE
select(A) ::= WITH wqlist(W) selectnowith(X). {A = attachWithToSelect(pParse,X,W);}
select(A) ::= WITH RECURSIVE wqlist(W) selectnowith(X).
                                              {A = attachWithToSelect(pParse,X,W);}
%endif /* SQLITE_OMIT_CTE */
select(A) ::= selectnowith(X). {
  Select *p = X;
  if( p ){
    parserDoubleLinkSelect(pParse, p);
  }
  A = p; /*A-overwrites-X*/
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
  seltablist(A) ::= stl_prefix(A) LP seltablist(F) RP
                    as(Z) on_opt(N) using_opt(U). {
    if( A==0 && Z.n==0 && N==0 && U==0 ){
      A = F;
    }else if( F->nSrc==1 ){
      A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,0,N,U);
      if( A ){
        struct SrcList_item *pNew = &A->a[A->nSrc-1];
        struct SrcList_item *pOld = F->a;
        pNew->zName = pOld->zName;
        pNew->zDatabase = pOld->zDatabase;
        pNew->pSelect = pOld->pSelect;
        if( pOld->fg.isTabFunc ){
          pNew->u1.pFuncArg = pOld->u1.pFuncArg;
          pOld->u1.pFuncArg = 0;
          pOld->fg.isTabFunc = 0;







|
|







717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
  seltablist(A) ::= stl_prefix(A) LP seltablist(F) RP
                    as(Z) on_opt(N) using_opt(U). {
    if( A==0 && Z.n==0 && N==0 && U==0 ){
      A = F;
    }else if( F->nSrc==1 ){
      A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,0,N,U);
      if( A ){
        SrcItem *pNew = &A->a[A->nSrc-1];
        SrcItem *pOld = F->a;
        pNew->zName = pOld->zName;
        pNew->zDatabase = pOld->zDatabase;
        pNew->pSelect = pOld->pSelect;
        if( pOld->fg.isTabFunc ){
          pNew->u1.pFuncArg = pOld->u1.pFuncArg;
          pOld->u1.pFuncArg = 0;
          pOld->fg.isTabFunc = 0;
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
                         {A = sqlite3PExpr(pParse,TK_LIMIT,X,Y);}
limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y). 
                         {A = sqlite3PExpr(pParse,TK_LIMIT,Y,X);}

/////////////////////////// The DELETE statement /////////////////////////////
//
%if SQLITE_ENABLE_UPDATE_DELETE_LIMIT || SQLITE_UDL_CAPABLE_PARSER
cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt(W) 
        orderby_opt(O) limit_opt(L). {
  sqlite3SrcListIndexedBy(pParse, X, &I);
#ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
  if( O || L ){
    updateDeleteLimitError(pParse,O,L);
    O = 0;
    L = 0;
  }
#endif
  sqlite3DeleteFrom(pParse,X,W,O,L);
}
%else
cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt(W). {
  sqlite3SrcListIndexedBy(pParse, X, &I);
  sqlite3DeleteFrom(pParse,X,W,0,0);
}
%endif

%type where_opt {Expr*}
%destructor where_opt {sqlite3ExprDelete(pParse->db, $$);}



where_opt(A) ::= .                    {A = 0;}
where_opt(A) ::= WHERE expr(X).       {A = X;}







////////////////////////// The UPDATE command ////////////////////////////////
//
%if SQLITE_ENABLE_UPDATE_DELETE_LIMIT || SQLITE_UDL_CAPABLE_PARSER
cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F)
        where_opt(W) orderby_opt(O) limit_opt(L).  {
  sqlite3SrcListIndexedBy(pParse, X, &I);
  X = sqlite3SrcListAppendList(pParse, X, F);
  sqlite3ExprListCheckLength(pParse,Y,"set list"); 
#ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
  if( O || L ){
    updateDeleteLimitError(pParse,O,L);
    O = 0;
    L = 0;
  }
#endif
  sqlite3Update(pParse,X,Y,W,R,O,L,0);
}
%else
cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F)
        where_opt(W). {
  sqlite3SrcListIndexedBy(pParse, X, &I);
  sqlite3ExprListCheckLength(pParse,Y,"set list"); 
  X = sqlite3SrcListAppendList(pParse, X, F);
  sqlite3Update(pParse,X,Y,W,R,0,0,0);
}
%endif








|












|







>
>



>
>
>
>
>
>





|














|







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
                         {A = sqlite3PExpr(pParse,TK_LIMIT,X,Y);}
limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y). 
                         {A = sqlite3PExpr(pParse,TK_LIMIT,Y,X);}

/////////////////////////// The DELETE statement /////////////////////////////
//
%if SQLITE_ENABLE_UPDATE_DELETE_LIMIT || SQLITE_UDL_CAPABLE_PARSER
cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt_ret(W)
        orderby_opt(O) limit_opt(L). {
  sqlite3SrcListIndexedBy(pParse, X, &I);
#ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
  if( O || L ){
    updateDeleteLimitError(pParse,O,L);
    O = 0;
    L = 0;
  }
#endif
  sqlite3DeleteFrom(pParse,X,W,O,L);
}
%else
cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt_ret(W). {
  sqlite3SrcListIndexedBy(pParse, X, &I);
  sqlite3DeleteFrom(pParse,X,W,0,0);
}
%endif

%type where_opt {Expr*}
%destructor where_opt {sqlite3ExprDelete(pParse->db, $$);}
%type where_opt_ret {Expr*}
%destructor where_opt_ret {sqlite3ExprDelete(pParse->db, $$);}

where_opt(A) ::= .                    {A = 0;}
where_opt(A) ::= WHERE expr(X).       {A = X;}
where_opt_ret(A) ::= .                                      {A = 0;}
where_opt_ret(A) ::= WHERE expr(X).                         {A = X;}
where_opt_ret(A) ::= RETURNING selcollist(X).               
       {sqlite3AddReturning(pParse,X); A = 0;}
where_opt_ret(A) ::= WHERE expr(X) RETURNING selcollist(Y).
       {sqlite3AddReturning(pParse,Y); A = X;}

////////////////////////// The UPDATE command ////////////////////////////////
//
%if SQLITE_ENABLE_UPDATE_DELETE_LIMIT || SQLITE_UDL_CAPABLE_PARSER
cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F)
        where_opt_ret(W) orderby_opt(O) limit_opt(L).  {
  sqlite3SrcListIndexedBy(pParse, X, &I);
  X = sqlite3SrcListAppendList(pParse, X, F);
  sqlite3ExprListCheckLength(pParse,Y,"set list"); 
#ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
  if( O || L ){
    updateDeleteLimitError(pParse,O,L);
    O = 0;
    L = 0;
  }
#endif
  sqlite3Update(pParse,X,Y,W,R,O,L,0);
}
%else
cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F)
        where_opt_ret(W). {
  sqlite3SrcListIndexedBy(pParse, X, &I);
  sqlite3ExprListCheckLength(pParse,Y,"set list"); 
  X = sqlite3SrcListAppendList(pParse, X, F);
  sqlite3Update(pParse,X,Y,W,R,0,0,0);
}
%endif

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

////////////////////////// The INSERT command /////////////////////////////////
//
cmd ::= with insert_cmd(R) INTO xfullname(X) idlist_opt(F) select(S)
        upsert(U). {
  sqlite3Insert(pParse, X, S, F, R, U);
}
cmd ::= with insert_cmd(R) INTO xfullname(X) idlist_opt(F) DEFAULT VALUES.
{
  sqlite3Insert(pParse, X, 0, F, R, 0);
}

%type upsert {Upsert*}

// Because upsert only occurs at the tip end of the INSERT rule for cmd,
// there is never a case where the value of the upsert pointer will not
// be destroyed by the cmd action.  So comment-out the destructor to
// avoid unreachable code.
//%destructor upsert {sqlite3UpsertDelete(pParse->db,$$);}
upsert(A) ::= . { A = 0; }

upsert(A) ::= ON CONFLICT LP sortlist(T) RP where_opt(TW)
              DO UPDATE SET setlist(Z) where_opt(W).
              { A = sqlite3UpsertNew(pParse->db,T,TW,Z,W);}
upsert(A) ::= ON CONFLICT LP sortlist(T) RP where_opt(TW) DO NOTHING.
              { A = sqlite3UpsertNew(pParse->db,T,TW,0,0); }
upsert(A) ::= ON CONFLICT DO NOTHING.
              { A = sqlite3UpsertNew(pParse->db,0,0,0,0); }






%type insert_cmd {int}
insert_cmd(A) ::= INSERT orconf(R).   {A = R;}
insert_cmd(A) ::= REPLACE.            {A = OE_Replace;}

%type idlist_opt {IdList*}
%destructor idlist_opt {sqlite3IdListDelete(pParse->db, $$);}







|












>

|
|
|
|
|
|
>
>
>
>
>







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

////////////////////////// The INSERT command /////////////////////////////////
//
cmd ::= with insert_cmd(R) INTO xfullname(X) idlist_opt(F) select(S)
        upsert(U). {
  sqlite3Insert(pParse, X, S, F, R, U);
}
cmd ::= with insert_cmd(R) INTO xfullname(X) idlist_opt(F) DEFAULT VALUES returning.
{
  sqlite3Insert(pParse, X, 0, F, R, 0);
}

%type upsert {Upsert*}

// Because upsert only occurs at the tip end of the INSERT rule for cmd,
// there is never a case where the value of the upsert pointer will not
// be destroyed by the cmd action.  So comment-out the destructor to
// avoid unreachable code.
//%destructor upsert {sqlite3UpsertDelete(pParse->db,$$);}
upsert(A) ::= . { A = 0; }
upsert(A) ::= RETURNING selcollist(X).  { A = 0; sqlite3AddReturning(pParse,X); }
upsert(A) ::= ON CONFLICT LP sortlist(T) RP where_opt(TW)
              DO UPDATE SET setlist(Z) where_opt(W) upsert(N).
              { A = sqlite3UpsertNew(pParse->db,T,TW,Z,W,N);}
upsert(A) ::= ON CONFLICT LP sortlist(T) RP where_opt(TW) DO NOTHING upsert(N).
              { A = sqlite3UpsertNew(pParse->db,T,TW,0,0,N); }
upsert(A) ::= ON CONFLICT DO NOTHING returning.
              { A = sqlite3UpsertNew(pParse->db,0,0,0,0,0); }
upsert(A) ::= ON CONFLICT DO UPDATE SET setlist(Z) where_opt(W) returning.
              { A = sqlite3UpsertNew(pParse->db,0,0,Z,W,0);}

returning ::= RETURNING selcollist(X).  {sqlite3AddReturning(pParse,X);}
returning ::= .

%type insert_cmd {int}
insert_cmd(A) ::= INSERT orconf(R).   {A = R;}
insert_cmd(A) ::= REPLACE.            {A = OE_Replace;}

%type idlist_opt {IdList*}
%destructor idlist_opt {sqlite3IdListDelete(pParse->db, $$);}
1618
1619
1620
1621
1622
1623
1624




1625
1626
1627
1628
1629
1630
1631
  sqlite3AlterRenameTable(pParse,X,&Z);
}
cmd ::= ALTER TABLE add_column_fullname
        ADD kwcolumn_opt columnname(Y) carglist. {
  Y.n = (int)(pParse->sLastToken.z-Y.z) + pParse->sLastToken.n;
  sqlite3AlterFinishAddColumn(pParse, &Y);
}




add_column_fullname ::= fullname(X). {
  disableLookaside(pParse);
  sqlite3AlterBeginAddColumn(pParse, X);
}
cmd ::= ALTER TABLE fullname(X) RENAME kwcolumn_opt nm(Y) TO nm(Z). {
  sqlite3AlterRenameColumn(pParse, X, &Y, &Z);
}







>
>
>
>







1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
  sqlite3AlterRenameTable(pParse,X,&Z);
}
cmd ::= ALTER TABLE add_column_fullname
        ADD kwcolumn_opt columnname(Y) carglist. {
  Y.n = (int)(pParse->sLastToken.z-Y.z) + pParse->sLastToken.n;
  sqlite3AlterFinishAddColumn(pParse, &Y);
}
cmd ::= ALTER TABLE fullname(X) DROP kwcolumn_opt nm(Y). {
  sqlite3AlterDropColumn(pParse, X, &Y);
}

add_column_fullname ::= fullname(X). {
  disableLookaside(pParse);
  sqlite3AlterBeginAddColumn(pParse, X);
}
cmd ::= ALTER TABLE fullname(X) RENAME kwcolumn_opt nm(Y) TO nm(Z). {
  sqlite3AlterRenameColumn(pParse, X, &Y, &Z);
}
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
anylist ::= anylist ANY.
%endif  SQLITE_OMIT_VIRTUALTABLE


//////////////////////// COMMON TABLE EXPRESSIONS ////////////////////////////
%type wqlist {With*}
%destructor wqlist {sqlite3WithDelete(pParse->db, $$);}



with ::= .
%ifndef SQLITE_OMIT_CTE
with ::= WITH wqlist(W).              { sqlite3WithPush(pParse, W, 1); }
with ::= WITH RECURSIVE wqlist(W).    { sqlite3WithPush(pParse, W, 1); }








wqlist(A) ::= nm(X) eidlist_opt(Y) AS LP select(Z) RP. {
  A = sqlite3WithAdd(pParse, 0, &X, Y, Z); /*A-overwrites-X*/
}
wqlist(A) ::= wqlist(A) COMMA nm(X) eidlist_opt(Y) AS LP select(Z) RP. {
  A = sqlite3WithAdd(pParse, A, &X, Y, Z);
}
%endif  SQLITE_OMIT_CTE

//////////////////////// WINDOW FUNCTION EXPRESSIONS /////////////////////////
// These must be at the end of this file. Specifically, the rules that
// introduce tokens WINDOW, OVER and FILTER must appear last. This causes 
// the integer values assigned to these tokens to be larger than all other 







>
>






>
>
>
>
>
>
>
|
|

|
|







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
anylist ::= anylist ANY.
%endif  SQLITE_OMIT_VIRTUALTABLE


//////////////////////// COMMON TABLE EXPRESSIONS ////////////////////////////
%type wqlist {With*}
%destructor wqlist {sqlite3WithDelete(pParse->db, $$);}
%type wqitem {Cte*}
// %destructor wqitem {sqlite3CteDelete(pParse->db, $$);} // not reachable

with ::= .
%ifndef SQLITE_OMIT_CTE
with ::= WITH wqlist(W).              { sqlite3WithPush(pParse, W, 1); }
with ::= WITH RECURSIVE wqlist(W).    { sqlite3WithPush(pParse, W, 1); }

%type wqas {u8}
wqas(A)   ::= AS.                  {A = M10d_Any;}
wqas(A)   ::= AS MATERIALIZED.     {A = M10d_Yes;}
wqas(A)   ::= AS NOT MATERIALIZED. {A = M10d_No;}
wqitem(A) ::= nm(X) eidlist_opt(Y) wqas(M) LP select(Z) RP. {
  A = sqlite3CteNew(pParse, &X, Y, Z, M); /*A-overwrites-X*/
}
wqlist(A) ::= wqitem(X). {
  A = sqlite3WithAdd(pParse, 0, X); /*A-overwrites-X*/
}
wqlist(A) ::= wqlist(A) COMMA wqitem(X). {
  A = sqlite3WithAdd(pParse, A, X);
}
%endif  SQLITE_OMIT_CTE

//////////////////////// WINDOW FUNCTION EXPRESSIONS /////////////////////////
// These must be at the end of this file. Specifically, the rules that
// introduce tokens WINDOW, OVER and FILTER must appear last. This causes 
// the integer values assigned to these tokens to be larger than all other 
Changes to src/pcache1.c.
457
458
459
460
461
462
463

464
465
466
467
468
469
470
#ifndef SQLITE_PCACHE_SEPARATE_HEADER
    p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
#endif
    p->page.pBuf = pPg;
    p->page.pExtra = &p[1];
    p->isBulkLocal = 0;
    p->isAnchor = 0;

  }
  (*pCache->pnPurgeable)++;
  return p;
}

/*
** Free a page object allocated by pcache1AllocPage().







>







457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
#ifndef SQLITE_PCACHE_SEPARATE_HEADER
    p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
#endif
    p->page.pBuf = pPg;
    p->page.pExtra = &p[1];
    p->isBulkLocal = 0;
    p->isAnchor = 0;
    p->pLruPrev = 0;           /* Initializing this saves a valgrind error */
  }
  (*pCache->pnPurgeable)++;
  return p;
}

/*
** Free a page object allocated by pcache1AllocPage().
Changes to src/pragma.c.
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
#ifndef SQLITE_OMIT_WAL
  /*
  **   PRAGMA [schema.]wal_checkpoint = passive|full|restart|truncate
  **
  ** Checkpoint the database.
  */
  case PragTyp_WAL_CHECKPOINT: {
    int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED);
    int eMode = SQLITE_CHECKPOINT_PASSIVE;
    if( zRight ){
      if( sqlite3StrICmp(zRight, "full")==0 ){
        eMode = SQLITE_CHECKPOINT_FULL;
      }else if( sqlite3StrICmp(zRight, "restart")==0 ){
        eMode = SQLITE_CHECKPOINT_RESTART;
      }else if( sqlite3StrICmp(zRight, "truncate")==0 ){







|







1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
#ifndef SQLITE_OMIT_WAL
  /*
  **   PRAGMA [schema.]wal_checkpoint = passive|full|restart|truncate
  **
  ** Checkpoint the database.
  */
  case PragTyp_WAL_CHECKPOINT: {
    int iBt = (pId2->z?iDb:SQLITE_MAX_DB);
    int eMode = SQLITE_CHECKPOINT_PASSIVE;
    if( zRight ){
      if( sqlite3StrICmp(zRight, "full")==0 ){
        eMode = SQLITE_CHECKPOINT_FULL;
      }else if( sqlite3StrICmp(zRight, "restart")==0 ){
        eMode = SQLITE_CHECKPOINT_RESTART;
      }else if( sqlite3StrICmp(zRight, "truncate")==0 ){
Changes to src/prepare.c.
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

/*
** 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 ){
    pData->rc = SQLITE_NOMEM_BKPT;
  }else if( pData->pzErrMsg[0]!=0 ){
    /* A error message has already been generated.  Do not overwrite it */
  }else if( pData->mInitFlags & INITFLAG_AlterTable ){
    *pData->pzErrMsg = sqlite3DbStrDup(db, zExtra);




    pData->rc = SQLITE_ERROR;
  }else if( db->flags & SQLITE_WriteSchema ){
    pData->rc = SQLITE_CORRUPT_BKPT;
  }else{
    char *z;
    if( zObj==0 ) zObj = "?";
    z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj);
    if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra);
    *pData->pzErrMsg = z;
    pData->rc = SQLITE_CORRUPT_BKPT;
  }
}








|







|
|
>
>
>
>





|







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

/*
** Fill the InitData structure with an error message that indicates
** that the database is corrupt.
*/
static void corruptSchema(
  InitData *pData,     /* Initialization context */
  char **azObj,        /* Type and name of object being parsed */
  const char *zExtra   /* Error information */
){
  sqlite3 *db = pData->db;
  if( db->mallocFailed ){
    pData->rc = SQLITE_NOMEM_BKPT;
  }else if( pData->pzErrMsg[0]!=0 ){
    /* A error message has already been generated.  Do not overwrite it */
  }else if( pData->mInitFlags & (INITFLAG_AlterRename|INITFLAG_AlterDrop) ){
    *pData->pzErrMsg = sqlite3MPrintf(db, 
        "error in %s %s after %s: %s", azObj[0], azObj[1], 
        (pData->mInitFlags & INITFLAG_AlterRename) ? "rename" : "drop column",
        zExtra
    );
    pData->rc = SQLITE_ERROR;
  }else if( db->flags & SQLITE_WriteSchema ){
    pData->rc = SQLITE_CORRUPT_BKPT;
  }else{
    char *z;
    const char *zObj = azObj[1] ? azObj[1] : "?";
    z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj);
    if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra);
    *pData->pzErrMsg = z;
    pData->rc = SQLITE_CORRUPT_BKPT;
  }
}

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

  assert( argc==5 );
  UNUSED_PARAMETER2(NotUsed, argc);
  assert( sqlite3_mutex_held(db->mutex) );
  db->mDbFlags |= DBFLAG_EncodingFixed;
  pData->nInitRow++;
  if( db->mallocFailed ){
    corruptSchema(pData, argv[1], 0);
    return 1;
  }

  assert( iDb>=0 && iDb<db->nDb );
  if( argv==0 ) return 0;   /* Might happen if EMPTY_RESULT_CALLBACKS are on */
  if( argv[3]==0 ){
    corruptSchema(pData, argv[1], 0);
  }else if( sqlite3_strnicmp(argv[4],"create ",7)==0 ){


    /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
    ** But because db->init.busy is set to 1, no VDBE code is generated
    ** or executed.  All the parser does is build the internal data
    ** structures that describe the table, index, or view.





    */
    int rc;
    u8 saved_iDb = db->init.iDb;
    sqlite3_stmt *pStmt;
    TESTONLY(int rcp);            /* Return code from sqlite3_prepare() */

    assert( db->init.busy );
    db->init.iDb = iDb;
    if( sqlite3GetUInt32(argv[3], &db->init.newTnum)==0
     || (db->init.newTnum>pData->mxPage && pData->mxPage>0)
    ){
      if( sqlite3Config.bExtraSchemaChecks ){
        corruptSchema(pData, argv[1], "invalid rootpage");
      }
    }
    db->init.orphanTrigger = 0;
    db->init.azInit = argv;
    pStmt = 0;
    TESTONLY(rcp = ) sqlite3Prepare(db, argv[4], -1, 0, 0, &pStmt, 0);
    rc = db->errCode;
    assert( (rc&0xFF)==(rcp&0xFF) );
    db->init.iDb = saved_iDb;
    /* assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 ); */
    if( SQLITE_OK!=rc ){
      if( db->init.orphanTrigger ){
        assert( iDb==1 );
      }else{
        if( rc > pData->rc ) pData->rc = rc;
        if( rc==SQLITE_NOMEM ){
          sqlite3OomFault(db);
        }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){
          corruptSchema(pData, argv[1], sqlite3_errmsg(db));
        }
      }
    }
    sqlite3_finalize(pStmt);
  }else if( argv[1]==0 || (argv[4]!=0 && argv[4][0]!=0) ){
    corruptSchema(pData, argv[1], 0);
  }else{
    /* If the SQL column is blank it means this is an index that
    ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
    ** constraint for a CREATE TABLE.  The index should have already
    ** been created when we processed the CREATE TABLE.  All we have
    ** to do here is record the root page number for that index.
    */
    Index *pIndex;
    pIndex = sqlite3FindIndex(db, argv[1], db->aDb[iDb].zDbSName);
    if( pIndex==0 ){
      corruptSchema(pData, argv[1], "orphan index");
    }else
    if( sqlite3GetUInt32(argv[3],&pIndex->tnum)==0
     || pIndex->tnum<2
     || pIndex->tnum>pData->mxPage
     || sqlite3IndexHasDuplicateRootPage(pIndex)
    ){
      if( sqlite3Config.bExtraSchemaChecks ){
        corruptSchema(pData, argv[1], "invalid rootpage");
      }
    }
  }
  return 0;
}

/*







|






|
|
>
>




>
>
>
>
>












|


















|





|










|







|







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

  assert( argc==5 );
  UNUSED_PARAMETER2(NotUsed, argc);
  assert( sqlite3_mutex_held(db->mutex) );
  db->mDbFlags |= DBFLAG_EncodingFixed;
  pData->nInitRow++;
  if( db->mallocFailed ){
    corruptSchema(pData, argv, 0);
    return 1;
  }

  assert( iDb>=0 && iDb<db->nDb );
  if( argv==0 ) return 0;   /* Might happen if EMPTY_RESULT_CALLBACKS are on */
  if( argv[3]==0 ){
    corruptSchema(pData, argv, 0);
  }else if( argv[4]
         && 'c'==sqlite3UpperToLower[(unsigned char)argv[4][0]]
         && 'r'==sqlite3UpperToLower[(unsigned char)argv[4][1]] ){
    /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
    ** But because db->init.busy is set to 1, no VDBE code is generated
    ** or executed.  All the parser does is build the internal data
    ** structures that describe the table, index, or view.
    **
    ** No other valid SQL statement, other than the variable CREATE statements,
    ** can begin with the letters "C" and "R".  Thus, it is not possible run
    ** any other kind of statement while parsing the schema, even a corrupt
    ** schema.
    */
    int rc;
    u8 saved_iDb = db->init.iDb;
    sqlite3_stmt *pStmt;
    TESTONLY(int rcp);            /* Return code from sqlite3_prepare() */

    assert( db->init.busy );
    db->init.iDb = iDb;
    if( sqlite3GetUInt32(argv[3], &db->init.newTnum)==0
     || (db->init.newTnum>pData->mxPage && pData->mxPage>0)
    ){
      if( sqlite3Config.bExtraSchemaChecks ){
        corruptSchema(pData, argv, "invalid rootpage");
      }
    }
    db->init.orphanTrigger = 0;
    db->init.azInit = argv;
    pStmt = 0;
    TESTONLY(rcp = ) sqlite3Prepare(db, argv[4], -1, 0, 0, &pStmt, 0);
    rc = db->errCode;
    assert( (rc&0xFF)==(rcp&0xFF) );
    db->init.iDb = saved_iDb;
    /* assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 ); */
    if( SQLITE_OK!=rc ){
      if( db->init.orphanTrigger ){
        assert( iDb==1 );
      }else{
        if( rc > pData->rc ) pData->rc = rc;
        if( rc==SQLITE_NOMEM ){
          sqlite3OomFault(db);
        }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){
          corruptSchema(pData, argv, sqlite3_errmsg(db));
        }
      }
    }
    sqlite3_finalize(pStmt);
  }else if( argv[1]==0 || (argv[4]!=0 && argv[4][0]!=0) ){
    corruptSchema(pData, argv, 0);
  }else{
    /* If the SQL column is blank it means this is an index that
    ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
    ** constraint for a CREATE TABLE.  The index should have already
    ** been created when we processed the CREATE TABLE.  All we have
    ** to do here is record the root page number for that index.
    */
    Index *pIndex;
    pIndex = sqlite3FindIndex(db, argv[1], db->aDb[iDb].zDbSName);
    if( pIndex==0 ){
      corruptSchema(pData, argv, "orphan index");
    }else
    if( sqlite3GetUInt32(argv[3],&pIndex->tnum)==0
     || pIndex->tnum<2
     || pIndex->tnum>pData->mxPage
     || sqlite3IndexHasDuplicateRootPage(pIndex)
    ){
      if( sqlite3Config.bExtraSchemaChecks ){
        corruptSchema(pData, argv, "invalid rootpage");
      }
    }
  }
  return 0;
}

/*
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
      }
    }
    assert( i>=0 && i<db->nDb );
  }
  return i;
}

/*
** Deallocate a single AggInfo object
*/
static void agginfoFree(sqlite3 *db, AggInfo *p){
  sqlite3DbFree(db, p->aCol);
  sqlite3DbFree(db, p->aFunc);
  sqlite3DbFree(db, p);
}

/*
** Free all memory allocations in the pParse object
*/
void sqlite3ParserReset(Parse *pParse){
  sqlite3 *db = pParse->db;
  AggInfo *pThis = pParse->pAggList;
  while( pThis ){

    AggInfo *pNext = pThis->pNext;
    agginfoFree(db, pThis);
    pThis = pNext;
  }
  sqlite3DbFree(db, pParse->aLabel);

  sqlite3ExprListDelete(db, pParse->pConstExpr);

  if( db ){
    assert( db->lookaside.bDisable >= pParse->disableLookaside );
    db->lookaside.bDisable -= pParse->disableLookaside;
    db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue;
  }
  pParse->disableLookaside = 0;
}


















































/*
** 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. */







<
<
<
<
<
<
<
<
<





<
|
>
|
|
|


>
|
>







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
      }
    }
    assert( i>=0 && i<db->nDb );
  }
  return i;
}










/*
** Free all memory allocations in the pParse object
*/
void sqlite3ParserReset(Parse *pParse){
  sqlite3 *db = pParse->db;

  while( pParse->pCleanup ){
    ParseCleanup *pCleanup = pParse->pCleanup;
    pParse->pCleanup = pCleanup->pNext;
    pCleanup->xCleanup(db, pCleanup->pPtr);
    sqlite3DbFreeNN(db, pCleanup);
  }
  sqlite3DbFree(db, pParse->aLabel);
  if( pParse->pConstExpr ){
    sqlite3ExprListDelete(db, pParse->pConstExpr);
  }
  if( db ){
    assert( db->lookaside.bDisable >= pParse->disableLookaside );
    db->lookaside.bDisable -= pParse->disableLookaside;
    db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue;
  }
  pParse->disableLookaside = 0;
}

/*
** Add a new cleanup operation to a Parser.  The cleanup should happen when
** the parser object is destroyed.  But, beware: the cleanup might happen
** immediately.
**
** Use this mechanism for uncommon cleanups.  There is a higher setup
** cost for this mechansim (an extra malloc), so it should not be used
** for common cleanups that happen on most calls.  But for less
** common cleanups, we save a single NULL-pointer comparison in
** sqlite3ParserReset(), which reduces the total CPU cycle count.
**
** If a memory allocation error occurs, then the cleanup happens immediately.
** When either SQLITE_DEBUG or SQLITE_COVERAGE_TEST are defined, the
** pParse->earlyCleanup flag is set in that case.  Calling code show verify
** that test cases exist for which this happens, to guard against possible
** use-after-free errors following an OOM.  The preferred way to do this is
** to immediately follow the call to this routine with:
**
**       testcase( pParse->earlyCleanup );
**
** This routine returns a copy of its pPtr input (the third parameter)
** except if an early cleanup occurs, in which case it returns NULL.  So
** another way to check for early cleanup is to check the return value.
** Or, stop using the pPtr parameter with this call and use only its
** return value thereafter.  Something like this:
**
**       pObj = sqlite3ParserAddCleanup(pParse, destructor, pObj);
*/
void *sqlite3ParserAddCleanup(
  Parse *pParse,                      /* Destroy when this Parser finishes */
  void (*xCleanup)(sqlite3*,void*),   /* The cleanup routine */
  void *pPtr                          /* Pointer to object to be cleaned up */
){
  ParseCleanup *pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup));
  if( pCleanup ){
    pCleanup->pNext = pParse->pCleanup;
    pParse->pCleanup = pCleanup;
    pCleanup->pPtr = pPtr;
    pCleanup->xCleanup = xCleanup;
  }else{
    xCleanup(pParse->db, pPtr);
    pPtr = 0;
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
    pParse->earlyCleanup = 1;
#endif
  }
  return pPtr;
}

/*
** 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. */
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
      sParse.zTail = &zSql[nBytes];
    }
  }else{
    sqlite3RunParser(&sParse, zSql, &zErrMsg);
  }
  assert( 0==sParse.nQueryLoop );

  if( sParse.rc==SQLITE_DONE ){
    sParse.rc = SQLITE_OK;
  }
  if( sParse.checkSchema ){
    schemaIsValid(&sParse);
  }
  if( pzTail ){
    *pzTail = sParse.zTail;
  }

  if( db->init.busy==0 ){
    sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail-zSql), prepFlags);
  }
  if( db->mallocFailed ){
    sParse.rc = SQLITE_NOMEM_BKPT;
  }
  rc = sParse.rc;
  if( rc!=SQLITE_OK ){


    if( sParse.pVdbe ) sqlite3VdbeFinalize(sParse.pVdbe);
    assert(!(*ppStmt));
  }else{
    *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
  }


  if( zErrMsg ){
    sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg);
    sqlite3DbFree(db, zErrMsg);
  }else{
    sqlite3Error(db, rc);
  }








  /* Delete any TriggerPrg structures allocated while parsing this statement. */
  while( sParse.pTriggerPrg ){
    TriggerPrg *pT = sParse.pTriggerPrg;
    sParse.pTriggerPrg = pT->pNext;
    sqlite3DbFree(db, pT);
  }







<
<
<
<
<
<










|
|
>
>
|
<
<
|
|
|
>
|
|
|
|
|
|
>
>
>
>
>
>
>







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
      sParse.zTail = &zSql[nBytes];
    }
  }else{
    sqlite3RunParser(&sParse, zSql, &zErrMsg);
  }
  assert( 0==sParse.nQueryLoop );







  if( pzTail ){
    *pzTail = sParse.zTail;
  }

  if( db->init.busy==0 ){
    sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail-zSql), prepFlags);
  }
  if( db->mallocFailed ){
    sParse.rc = SQLITE_NOMEM_BKPT;
  }
  if( sParse.rc!=SQLITE_OK && sParse.rc!=SQLITE_DONE ){
    if( sParse.checkSchema ){
      schemaIsValid(&sParse);
    }
    if( sParse.pVdbe ){


      sqlite3VdbeFinalize(sParse.pVdbe);
    }
    assert( 0==(*ppStmt) );
    rc = sParse.rc;
    if( zErrMsg ){
      sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg);
      sqlite3DbFree(db, zErrMsg);
    }else{
      sqlite3Error(db, rc);
    }
  }else{
    assert( zErrMsg==0 );
    *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
    rc = SQLITE_OK;
    sqlite3ErrorClear(db);
  }


  /* Delete any TriggerPrg structures allocated while parsing this statement. */
  while( sParse.pTriggerPrg ){
    TriggerPrg *pT = sParse.pTriggerPrg;
    sParse.pTriggerPrg = pT->pNext;
    sqlite3DbFree(db, pT);
  }
Changes to src/printf.c.
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
        }
        length = width = 0;
        break;
      }
      case etSRCLIST: {
        SrcList *pSrc;
        int k;
        struct SrcList_item *pItem;
        if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
        pSrc = va_arg(ap, SrcList*);
        k = va_arg(ap, int);
        pItem = &pSrc->a[k];
        assert( bArgList==0 );
        assert( k>=0 && k<pSrc->nSrc );
        if( pItem->zDatabase ){







|







852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
        }
        length = width = 0;
        break;
      }
      case etSRCLIST: {
        SrcList *pSrc;
        int k;
        SrcItem *pItem;
        if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
        pSrc = va_arg(ap, SrcList*);
        k = va_arg(ap, int);
        pItem = &pSrc->a[k];
        assert( bArgList==0 );
        assert( k>=0 && k<pSrc->nSrc );
        if( pItem->zDatabase ){
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
  }
  if( p->mxAlloc==0 ){
    setStrAccumError(p, SQLITE_TOOBIG);
    return p->nAlloc - p->nChar - 1;
  }else{
    char *zOld = isMalloced(p) ? p->zText : 0;
    i64 szNew = p->nChar;
    szNew += N + 1;
    if( szNew+p->nChar<=p->mxAlloc ){
      /* Force exponential buffer size growth as long as it does not overflow,
      ** to avoid having to call this routine too often */
      szNew += p->nChar;
    }
    if( szNew > p->mxAlloc ){
      sqlite3_str_reset(p);







|







917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
  }
  if( p->mxAlloc==0 ){
    setStrAccumError(p, SQLITE_TOOBIG);
    return p->nAlloc - p->nChar - 1;
  }else{
    char *zOld = isMalloced(p) ? p->zText : 0;
    i64 szNew = p->nChar;
    szNew += (sqlite3_int64)N + 1;
    if( szNew+p->nChar<=p->mxAlloc ){
      /* Force exponential buffer size growth as long as it does not overflow,
      ** to avoid having to call this routine too often */
      szNew += p->nChar;
    }
    if( szNew > p->mxAlloc ){
      sqlite3_str_reset(p);
Changes to src/resolve.c.
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
** structures must be increased by the nSubquery amount.
*/
static void resolveAlias(
  Parse *pParse,         /* Parsing context */
  ExprList *pEList,      /* A result set */
  int iCol,              /* A column in the result set.  0..pEList->nExpr-1 */
  Expr *pExpr,           /* Transform this into an alias to the result set */
  const char *zType,     /* "GROUP" or "ORDER" or "" */
  int nSubquery          /* Number of subqueries that the label is moving */
){
  Expr *pOrig;           /* The iCol-th column of the result set */
  Expr *pDup;            /* Copy of pOrig */
  sqlite3 *db;           /* The database connection */

  assert( iCol>=0 && iCol<pEList->nExpr );
  pOrig = pEList->a[iCol].pExpr;
  assert( pOrig!=0 );
  db = pParse->db;
  pDup = sqlite3ExprDup(db, pOrig, 0);
  if( pDup!=0 ){
    if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery);
    if( pExpr->op==TK_COLLATE ){
      pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
    }

    /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This 
    ** prevents ExprDelete() from deleting the Expr structure itself,
    ** allowing it to be repopulated by the memcpy() on the following line.







<












|







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
** structures must be increased by the nSubquery amount.
*/
static void resolveAlias(
  Parse *pParse,         /* Parsing context */
  ExprList *pEList,      /* A result set */
  int iCol,              /* A column in the result set.  0..pEList->nExpr-1 */
  Expr *pExpr,           /* Transform this into an alias to the result set */

  int nSubquery          /* Number of subqueries that the label is moving */
){
  Expr *pOrig;           /* The iCol-th column of the result set */
  Expr *pDup;            /* Copy of pOrig */
  sqlite3 *db;           /* The database connection */

  assert( iCol>=0 && iCol<pEList->nExpr );
  pOrig = pEList->a[iCol].pExpr;
  assert( pOrig!=0 );
  db = pParse->db;
  pDup = sqlite3ExprDup(db, pOrig, 0);
  if( pDup!=0 ){
    incrAggFunctionDepth(pDup, nSubquery);
    if( pExpr->op==TK_COLLATE ){
      pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
    }

    /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This 
    ** prevents ExprDelete() from deleting the Expr structure itself,
    ** allowing it to be repopulated by the memcpy() on the following line.
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
        pExpr->y.pWin->pOwner = pExpr;
      }else{
        assert( db->mallocFailed );
      }
    }
    sqlite3DbFree(db, pDup);
  }
  ExprSetProperty(pExpr, EP_Alias);
}


/*
** Return TRUE if the name zCol occurs anywhere in the USING clause.
**
** Return FALSE if the USING clause is NULL or if it does not contain







<







107
108
109
110
111
112
113

114
115
116
117
118
119
120
        pExpr->y.pWin->pOwner = pExpr;
      }else{
        assert( db->mallocFailed );
      }
    }
    sqlite3DbFree(db, pDup);
  }

}


/*
** Return TRUE if the name zCol occurs anywhere in the USING clause.
**
** Return FALSE if the USING clause is NULL or if it does not contain
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
  Expr *pExpr          /* Make this EXPR node point to the selected column */
){
  int i, j;                         /* Loop counters */
  int cnt = 0;                      /* Number of matching column names */
  int cntTab = 0;                   /* Number of matching table names */
  int nSubquery = 0;                /* How many levels of subquery */
  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 eNewExprOp = TK_COLUMN;       /* New value for pExpr->op on success */
  Table *pTab = 0;                  /* Table hold the row */
  Column *pCol;                     /* A column of pTab */

  assert( pNC );     /* the name context cannot be NULL. */







|
|







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
  Expr *pExpr          /* Make this EXPR node point to the selected column */
){
  int i, j;                         /* Loop counters */
  int cnt = 0;                      /* Number of matching column names */
  int cntTab = 0;                   /* Number of matching table names */
  int nSubquery = 0;                /* How many levels of subquery */
  sqlite3 *db = pParse->db;         /* The database connection */
  SrcItem *pItem;                   /* Use for looping over pSrcList items */
  SrcItem *pMatch = 0;              /* The matching pSrcList item */
  NameContext *pTopNC = pNC;        /* First namecontext in the list */
  Schema *pSchema = 0;              /* Schema of the expression */
  int eNewExprOp = TK_COLUMN;       /* New value for pExpr->op on success */
  Table *pTab = 0;                  /* Table hold the row */
  Column *pCol;                     /* A column of pTab */

  assert( pNC );     /* the name context cannot be NULL. */
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
        pSchema = pExpr->y.pTab->pSchema;
      }
    } /* if( pSrcList ) */

#if !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT)
    /* If we have not already resolved the name, then maybe 
    ** it is a new.* or old.* trigger argument reference.  Or
    ** maybe it is an excluded.* from an upsert.

    */
    if( zDb==0 && zTab!=0 && cntTab==0 ){
      pTab = 0;
#ifndef SQLITE_OMIT_TRIGGER
      if( pParse->pTriggerTab!=0 ){
        int op = pParse->eTriggerOp;
        assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT );
        if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){
          pExpr->iTable = 1;
          pTab = pParse->pTriggerTab;
        }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){
          pExpr->iTable = 0;



          pTab = pParse->pTriggerTab;
        }
      }
#endif /* SQLITE_OMIT_TRIGGER */
#ifndef SQLITE_OMIT_UPSERT
      if( (pNC->ncFlags & NC_UUpsert)!=0 ){
        Upsert *pUpsert = pNC->uNC.pUpsert;
        if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){
          pTab = pUpsert->pUpsertSrc->a[0].pTab;
          pExpr->iTable = EXCLUDED_TABLE_NUMBER;
        }
      }
#endif /* SQLITE_OMIT_UPSERT */







|
>

|





|


|

>
>
>





|







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
        pSchema = pExpr->y.pTab->pSchema;
      }
    } /* if( pSrcList ) */

#if !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT)
    /* If we have not already resolved the name, then maybe 
    ** it is a new.* or old.* trigger argument reference.  Or
    ** maybe it is an excluded.* from an upsert.  Or maybe it is
    ** a reference in the RETURNING clause to a table being modified.
    */
    if( cnt==0 && zDb==0 ){
      pTab = 0;
#ifndef SQLITE_OMIT_TRIGGER
      if( pParse->pTriggerTab!=0 ){
        int op = pParse->eTriggerOp;
        assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT );
        if( op!=TK_DELETE && zTab && sqlite3StrICmp("new",zTab) == 0 ){
          pExpr->iTable = 1;
          pTab = pParse->pTriggerTab;
        }else if( op!=TK_INSERT && zTab && sqlite3StrICmp("old",zTab)==0 ){
          pExpr->iTable = 0;
          pTab = pParse->pTriggerTab;
        }else if( pParse->bReturning && (pNC->ncFlags & NC_UBaseReg)!=0 ){
          pExpr->iTable = op!=TK_DELETE;
          pTab = pParse->pTriggerTab;
        }
      }
#endif /* SQLITE_OMIT_TRIGGER */
#ifndef SQLITE_OMIT_UPSERT
      if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab!=0 ){
        Upsert *pUpsert = pNC->uNC.pUpsert;
        if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){
          pTab = pUpsert->pUpsertSrc->a[0].pTab;
          pExpr->iTable = EXCLUDED_TABLE_NUMBER;
        }
      }
#endif /* SQLITE_OMIT_UPSERT */
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
        }
        if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){
          /* IMP: R-51414-32910 */
          iCol = -1;
        }
        if( iCol<pTab->nCol ){
          cnt++;

#ifndef SQLITE_OMIT_UPSERT
          if( pExpr->iTable==EXCLUDED_TABLE_NUMBER ){
            testcase( iCol==(-1) );
            if( IN_RENAME_OBJECT ){
              pExpr->iColumn = iCol;
              pExpr->y.pTab = pTab;
              eNewExprOp = TK_COLUMN;
            }else{
              pExpr->iTable = pNC->uNC.pUpsert->regData +
                 sqlite3TableColumnToStorage(pTab, iCol);
              eNewExprOp = TK_REGISTER;
              ExprSetProperty(pExpr, EP_Alias);
            }
          }else
#endif /* SQLITE_OMIT_UPSERT */
          {








#ifndef SQLITE_OMIT_TRIGGER
            if( iCol<0 ){
              pExpr->affExpr = SQLITE_AFF_INTEGER;
            }else if( pExpr->iTable==0 ){
              testcase( iCol==31 );
              testcase( iCol==32 );
              pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
            }else{
              testcase( iCol==31 );
              testcase( iCol==32 );
              pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
            }
            pExpr->y.pTab = pTab;
            pExpr->iColumn = (i16)iCol;
            eNewExprOp = TK_TRIGGER;
#endif /* SQLITE_OMIT_TRIGGER */

          }
        }
      }
    }
#endif /* !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT) */

    /*







>











<




>
>
>
>
>
>
>
>

|
|
|
|
|
|
|
|
|
|
|
<
<
<

>







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
        }
        if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){
          /* IMP: R-51414-32910 */
          iCol = -1;
        }
        if( iCol<pTab->nCol ){
          cnt++;
          pMatch = 0;
#ifndef SQLITE_OMIT_UPSERT
          if( pExpr->iTable==EXCLUDED_TABLE_NUMBER ){
            testcase( iCol==(-1) );
            if( IN_RENAME_OBJECT ){
              pExpr->iColumn = iCol;
              pExpr->y.pTab = pTab;
              eNewExprOp = TK_COLUMN;
            }else{
              pExpr->iTable = pNC->uNC.pUpsert->regData +
                 sqlite3TableColumnToStorage(pTab, iCol);
              eNewExprOp = TK_REGISTER;

            }
          }else
#endif /* SQLITE_OMIT_UPSERT */
          {
            pExpr->y.pTab = pTab;
            if( pParse->bReturning ){
              eNewExprOp = TK_REGISTER;
              pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable +
                 sqlite3TableColumnToStorage(pTab, iCol) + 1;
            }else{
              pExpr->iColumn = (i16)iCol;
              eNewExprOp = TK_TRIGGER;
#ifndef SQLITE_OMIT_TRIGGER
              if( iCol<0 ){
                pExpr->affExpr = SQLITE_AFF_INTEGER;
              }else if( pExpr->iTable==0 ){
                testcase( iCol==31 );
                testcase( iCol==32 );
                pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
              }else{
                testcase( iCol==31 );
                testcase( iCol==32 );
                pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
              }



#endif /* SQLITE_OMIT_TRIGGER */
            }
          }
        }
      }
    }
#endif /* !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT) */

    /*
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
            sqlite3ErrorMsg(pParse, "misuse of aliased window function %s",zAs);
            return WRC_Abort;
          }
          if( sqlite3ExprVectorSize(pOrig)!=1 ){
            sqlite3ErrorMsg(pParse, "row value misused");
            return WRC_Abort;
          }
          resolveAlias(pParse, pEList, j, pExpr, "", nSubquery);
          cnt = 1;
          pMatch = 0;
          assert( zTab==0 && zDb==0 );
          if( IN_RENAME_OBJECT ){
            sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr);
          }
          goto lookupname_end;







|







520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
            sqlite3ErrorMsg(pParse, "misuse of aliased window function %s",zAs);
            return WRC_Abort;
          }
          if( sqlite3ExprVectorSize(pOrig)!=1 ){
            sqlite3ErrorMsg(pParse, "row value misused");
            return WRC_Abort;
          }
          resolveAlias(pParse, pEList, j, pExpr, nSubquery);
          cnt = 1;
          pMatch = 0;
          assert( zTab==0 && zDb==0 );
          if( IN_RENAME_OBJECT ){
            sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr);
          }
          goto lookupname_end;
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
  */
  if( pExpr->iColumn>=0 && pMatch!=0 ){
    pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
  }

  /* Clean up and return
  */

  sqlite3ExprDelete(db, pExpr->pLeft);
  pExpr->pLeft = 0;
  sqlite3ExprDelete(db, pExpr->pRight);
  pExpr->pRight = 0;

  pExpr->op = eNewExprOp;
  ExprSetProperty(pExpr, EP_Leaf);
lookupname_end:
  if( cnt==1 ){
    assert( pNC!=0 );

    if( !ExprHasProperty(pExpr, EP_Alias) ){


      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;







>
|
|
|
|
>





>
|
>
>


>







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
  */
  if( pExpr->iColumn>=0 && pMatch!=0 ){
    pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
  }

  /* Clean up and return
  */
  if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
    sqlite3ExprDelete(db, pExpr->pLeft);
    pExpr->pLeft = 0;
    sqlite3ExprDelete(db, pExpr->pRight);
    pExpr->pRight = 0;
  }
  pExpr->op = eNewExprOp;
  ExprSetProperty(pExpr, EP_Leaf);
lookupname_end:
  if( cnt==1 ){
    assert( pNC!=0 );
#ifndef SQLITE_OMIT_AUTHORIZATION
    if( pParse->db->xAuth
     && (pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER)
    ){
      sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
    }
#endif
    /* 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;
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
/*
** Allocate and return a pointer to an expression to load the column iCol
** from datasource iSrc 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];
    Table *pTab = p->y.pTab = pItem->pTab;
    p->iTable = pItem->iCursor;
    if( p->y.pTab->iPKey==iCol ){
      p->iColumn = -1;
    }else{
      p->iColumn = (ynVar)iCol;
      if( (pTab->tabFlags & TF_HasGenerated)!=0







|







661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
/*
** Allocate and return a pointer to an expression to load the column iCol
** from datasource iSrc in SrcList pSrc.
*/
Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){
  Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
  if( p ){
    SrcItem *pItem = &pSrc->a[iSrc];
    Table *pTab = p->y.pTab = pItem->pTab;
    p->iTable = pItem->iCursor;
    if( p->y.pTab->iPKey==iCol ){
      p->iColumn = -1;
    }else{
      p->iColumn = (ynVar)iCol;
      if( (pTab->tabFlags & TF_HasGenerated)!=0
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775









































776
777
778
779
780
781
782
    /* The special operator TK_ROW means use the rowid for the first
    ** column in the FROM clause.  This is used by the LIMIT and ORDER BY
    ** clause processing on UPDATE and DELETE statements, and by 
    ** UPDATE ... FROM statement processing.
    */
    case TK_ROW: {
      SrcList *pSrcList = pNC->pSrcList;
      struct SrcList_item *pItem;
      assert( pSrcList && pSrcList->nSrc>=1 );
      pItem = pSrcList->a;
      pExpr->op = TK_COLUMN;
      pExpr->y.pTab = pItem->pTab;
      pExpr->iTable = pItem->iCursor;
      pExpr->iColumn--;
      pExpr->affExpr = SQLITE_AFF_INTEGER;
      break;
    }










































    /* A column name:                    ID
    ** Or table name and column name:    ID.ID
    ** Or a database, table and column:  ID.ID.ID
    **
    ** The TK_ID and TK_OUT cases are combined so that there will only
    ** be one call to lookupName().  Then the compiler will in-line 







|









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    /* The special operator TK_ROW means use the rowid for the first
    ** column in the FROM clause.  This is used by the LIMIT and ORDER BY
    ** clause processing on UPDATE and DELETE statements, and by 
    ** UPDATE ... FROM statement processing.
    */
    case TK_ROW: {
      SrcList *pSrcList = pNC->pSrcList;
      SrcItem *pItem;
      assert( pSrcList && pSrcList->nSrc>=1 );
      pItem = pSrcList->a;
      pExpr->op = TK_COLUMN;
      pExpr->y.pTab = pItem->pTab;
      pExpr->iTable = pItem->iCursor;
      pExpr->iColumn--;
      pExpr->affExpr = SQLITE_AFF_INTEGER;
      break;
    }

    /* An optimization:  Attempt to convert
    **
    **      "expr IS NOT NULL"  -->  "TRUE"
    **      "expr IS NULL"      -->  "FALSE"
    **
    ** if we can prove that "expr" is never NULL.  Call this the
    ** "NOT NULL strength reduction optimization".
    **
    ** If this optimization occurs, also restore the NameContext ref-counts
    ** to the state they where in before the "column" LHS expression was
    ** resolved.  This prevents "column" from being counted as having been
    ** referenced, which might prevent a SELECT from being erroneously
    ** marked as correlated.
    */
    case TK_NOTNULL:
    case TK_ISNULL: {
      int anRef[8];
      NameContext *p;
      int i;
      for(i=0, p=pNC; p && i<ArraySize(anRef); p=p->pNext, i++){ 
        anRef[i] = p->nRef;
      }
      sqlite3WalkExpr(pWalker, pExpr->pLeft);
      if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){
        if( pExpr->op==TK_NOTNULL ){
          pExpr->u.zToken = "true";
          ExprSetProperty(pExpr, EP_IsTrue);
        }else{
          pExpr->u.zToken = "false";
          ExprSetProperty(pExpr, EP_IsFalse);
        }
        pExpr->op = TK_TRUEFALSE;
        for(i=0, p=pNC; p && i<ArraySize(anRef); p=p->pNext, i++){
          p->nRef = anRef[i];
        }
        sqlite3ExprDelete(pParse->db, pExpr->pLeft);
        pExpr->pLeft = 0;
      }
      return WRC_Prune;
    }

    /* A column name:                    ID
    ** Or table name and column name:    ID.ID
    ** Or a database, table and column:  ID.ID.ID
    **
    ** The TK_ID and TK_OUT cases are combined so that there will only
    ** be one call to lookupName().  Then the compiler will in-line 
997
998
999
1000
1001
1002
1003

1004
1005
1006
1007
1008
1009
1010
      if( is_agg ){
#ifndef SQLITE_OMIT_WINDOWFUNC
        if( pWin ){
          Select *pSel = pNC->pWinSelect;
          assert( pWin==pExpr->y.pWin );
          if( IN_RENAME_OBJECT==0 ){
            sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef);

          }
          sqlite3WalkExprList(pWalker, pWin->pPartition);
          sqlite3WalkExprList(pWalker, pWin->pOrderBy);
          sqlite3WalkExpr(pWalker, pWin->pFilter);
          sqlite3WindowLink(pSel, pWin);
          pNC->ncFlags |= NC_HasWin;
        }else







>







1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
      if( is_agg ){
#ifndef SQLITE_OMIT_WINDOWFUNC
        if( pWin ){
          Select *pSel = pNC->pWinSelect;
          assert( pWin==pExpr->y.pWin );
          if( IN_RENAME_OBJECT==0 ){
            sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef);
            if( pParse->db->mallocFailed ) break;
          }
          sqlite3WalkExprList(pWalker, pWin->pPartition);
          sqlite3WalkExprList(pWalker, pWin->pOrderBy);
          sqlite3WalkExpr(pWalker, pWin->pFilter);
          sqlite3WindowLink(pSel, pWin);
          pNC->ncFlags |= NC_HasWin;
        }else
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
    }
    case TK_IS:
    case TK_ISNOT: {
      Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight);
      assert( !ExprHasProperty(pExpr, EP_Reduced) );
      /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE",
      ** and "x IS NOT FALSE". */
      if( pRight && (pRight->op==TK_ID || pRight->op==TK_TRUEFALSE) ){
        int rc = resolveExprStep(pWalker, pRight);
        if( rc==WRC_Abort ) return WRC_Abort;
        if( pRight->op==TK_TRUEFALSE ){
          pExpr->op2 = pExpr->op;
          pExpr->op = TK_TRUTH;
          return WRC_Continue;
        }







|







1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
    }
    case TK_IS:
    case TK_ISNOT: {
      Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight);
      assert( !ExprHasProperty(pExpr, EP_Reduced) );
      /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE",
      ** and "x IS NOT FALSE". */
      if( ALWAYS(pRight) && (pRight->op==TK_ID || pRight->op==TK_TRUEFALSE) ){
        int rc = resolveExprStep(pWalker, pRight);
        if( rc==WRC_Abort ) return WRC_Abort;
        if( pRight->op==TK_TRUEFALSE ){
          pExpr->op2 = pExpr->op;
          pExpr->op = TK_TRUTH;
          return WRC_Continue;
        }
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
  assert( pEList!=0 );  /* sqlite3SelectNew() guarantees this */
  for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
    if( pItem->u.x.iOrderByCol ){
      if( pItem->u.x.iOrderByCol>pEList->nExpr ){
        resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
        return 1;
      }
      resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,
                   zType,0);
    }
  }
  return 0;
}

#ifndef SQLITE_OMIT_WINDOWFUNC
/*







|
<







1443
1444
1445
1446
1447
1448
1449
1450

1451
1452
1453
1454
1455
1456
1457
  assert( pEList!=0 );  /* sqlite3SelectNew() guarantees this */
  for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
    if( pItem->u.x.iOrderByCol ){
      if( pItem->u.x.iOrderByCol>pEList->nExpr ){
        resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
        return 1;
      }
      resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,0);

    }
  }
  return 0;
}

#ifndef SQLITE_OMIT_WINDOWFUNC
/*
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
      pSub->pOrderBy = p->pOrderBy;
      p->pOrderBy = 0;
    }
  
    /* Recursively resolve names in all subqueries
    */
    for(i=0; i<p->pSrc->nSrc; i++){
      struct SrcList_item *pItem = &p->pSrc->a[i];
      if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
        NameContext *pNC;         /* Used to iterate name contexts */
        int nRef = 0;             /* Refcount for pOuterNC and outer contexts */
        const char *zSavedContext = pParse->zAuthContext;

        /* Count the total number of references to pOuterNC and all of its
        ** parent contexts. After resolving references to expressions in
        ** pItem->pSelect, check if this value has changed. If so, then
        ** SELECT statement pItem->pSelect must be correlated. Set the
        ** pItem->fg.isCorrelated flag if this is the case. */
        for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef += pNC->nRef;

        if( pItem->zName ) pParse->zAuthContext = pItem->zName;
        sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC);
        pParse->zAuthContext = zSavedContext;
        if( pParse->nErr || db->mallocFailed ) return WRC_Abort;







        for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef;
        assert( pItem->fg.isCorrelated==0 && nRef<=0 );
        pItem->fg.isCorrelated = (nRef!=0);

      }
    }
  
    /* Set up the local name-context to pass to sqlite3ResolveExprNames() to
    ** resolve the result-set expression list.
    */
    sNC.ncFlags = NC_AllowAgg|NC_AllowWin;







|

<
|


<
<
<
<
<
<
<





>
>
>
>
>
>
|
|
|
>







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
      pSub->pOrderBy = p->pOrderBy;
      p->pOrderBy = 0;
    }
  
    /* Recursively resolve names in all subqueries
    */
    for(i=0; i<p->pSrc->nSrc; i++){
      SrcItem *pItem = &p->pSrc->a[i];
      if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){

        int nRef = pOuterNC ? pOuterNC->nRef : 0;
        const char *zSavedContext = pParse->zAuthContext;








        if( pItem->zName ) pParse->zAuthContext = pItem->zName;
        sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC);
        pParse->zAuthContext = zSavedContext;
        if( pParse->nErr || db->mallocFailed ) return WRC_Abort;

        /* If the number of references to the outer context changed when
        ** expressions in the sub-select were resolved, the sub-select
        ** is correlated. It is not required to check the refcount on any
        ** but the innermost outer context object, as lookupName() increments
        ** the refcount on all contexts between the current one and the
        ** context containing the column when it resolves a name. */
        if( pOuterNC ){
          assert( pItem->fg.isCorrelated==0 && pOuterNC->nRef>=nRef );
          pItem->fg.isCorrelated = (pOuterNC->nRef>nRef);
        }
      }
    }
  
    /* Set up the local name-context to pass to sqlite3ResolveExprNames() to
    ** resolve the result-set expression list.
    */
    sNC.ncFlags = NC_AllowAgg|NC_AllowWin;
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
    ** other expressions in the SELECT statement. This is so that
    ** expressions in the WHERE clause (etc.) can refer to expressions by
    ** aliases in the result set.
    **
    ** Minor point: If this is the case, then the expression will be
    ** re-evaluated for each reference to it.
    */
    assert( (sNC.ncFlags & (NC_UAggInfo|NC_UUpsert))==0 );
    sNC.uNC.pEList = p->pEList;
    sNC.ncFlags |= NC_UEList;
    if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
    if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;

    /* Resolve names in table-valued-function arguments */
    for(i=0; i<p->pSrc->nSrc; i++){
      struct SrcList_item *pItem = &p->pSrc->a[i];
      if( pItem->fg.isTabFunc
       && sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg) 
      ){
        return WRC_Abort;
      }
    }








|







|







1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
    ** other expressions in the SELECT statement. This is so that
    ** expressions in the WHERE clause (etc.) can refer to expressions by
    ** aliases in the result set.
    **
    ** Minor point: If this is the case, then the expression will be
    ** re-evaluated for each reference to it.
    */
    assert( (sNC.ncFlags & (NC_UAggInfo|NC_UUpsert|NC_UBaseReg))==0 );
    sNC.uNC.pEList = p->pEList;
    sNC.ncFlags |= NC_UEList;
    if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
    if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;

    /* Resolve names in table-valued-function arguments */
    for(i=0; i<p->pSrc->nSrc; i++){
      SrcItem *pItem = &p->pSrc->a[i];
      if( pItem->fg.isTabFunc
       && sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg) 
      ){
        return WRC_Abort;
      }
    }

Changes to src/select.c.
81
82
83
84
85
86
87

88
89
90
91




92
93
94
95
96
97
98
99
100
    sqlite3ExprListDelete(db, p->pEList);
    sqlite3SrcListDelete(db, p->pSrc);
    sqlite3ExprDelete(db, p->pWhere);
    sqlite3ExprListDelete(db, p->pGroupBy);
    sqlite3ExprDelete(db, p->pHaving);
    sqlite3ExprListDelete(db, p->pOrderBy);
    sqlite3ExprDelete(db, p->pLimit);

#ifndef SQLITE_OMIT_WINDOWFUNC
    if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){
      sqlite3WindowListDelete(db, p->pWinDefn);
    }




#endif
    if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith);
    if( bFree ) sqlite3DbFreeNN(db, p);
    p = pPrior;
    bFree = 1;
  }
}

/*







>




>
>
>
>

<







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
    sqlite3ExprListDelete(db, p->pEList);
    sqlite3SrcListDelete(db, p->pSrc);
    sqlite3ExprDelete(db, p->pWhere);
    sqlite3ExprListDelete(db, p->pGroupBy);
    sqlite3ExprDelete(db, p->pHaving);
    sqlite3ExprListDelete(db, p->pOrderBy);
    sqlite3ExprDelete(db, p->pLimit);
    if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith);
#ifndef SQLITE_OMIT_WINDOWFUNC
    if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){
      sqlite3WindowListDelete(db, p->pWinDefn);
    }
    while( p->pWin ){
      assert( p->pWin->ppThis==&p->pWin );
      sqlite3WindowUnlinkFromSelect(p->pWin);
    }
#endif

    if( bFree ) sqlite3DbFreeNN(db, p);
    p = pPrior;
    bFree = 1;
  }
}

/*
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
  return jointype;
}

/*
** Return the index of a column in a table.  Return -1 if the column
** is not contained in the table.
*/
static int columnIndex(Table *pTab, const char *zCol){
  int i;
  u8 h = sqlite3StrIHash(zCol);
  Column *pCol;
  for(pCol=pTab->aCol, i=0; i<pTab->nCol; pCol++, i++){
    if( pCol->hName==h && sqlite3StrICmp(pCol->zName, zCol)==0 ) return i;
  }
  return -1;







|







262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
  return jointype;
}

/*
** Return the index of a column in a table.  Return -1 if the column
** is not contained in the table.
*/
int sqlite3ColumnIndex(Table *pTab, const char *zCol){
  int i;
  u8 h = sqlite3StrIHash(zCol);
  Column *pCol;
  for(pCol=pTab->aCol, i=0; i<pTab->nCol; pCol++, i++){
    if( pCol->hName==h && sqlite3StrICmp(pCol->zName, zCol)==0 ) return i;
  }
  return -1;
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
  int bIgnoreHidden    /* True to ignore hidden columns */
){
  int i;               /* For looping over tables in pSrc */
  int iCol;            /* Index of column matching zCol */

  assert( (piTab==0)==(piCol==0) );  /* Both or neither are NULL */
  for(i=0; i<N; i++){
    iCol = columnIndex(pSrc->a[i].pTab, zCol);
    if( iCol>=0 
     && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0)
    ){
      if( piTab ){
        *piTab = i;
        *piCol = iCol;
      }







|







294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
  int bIgnoreHidden    /* True to ignore hidden columns */
){
  int i;               /* For looping over tables in pSrc */
  int iCol;            /* Index of column matching zCol */

  assert( (piTab==0)==(piCol==0) );  /* Both or neither are NULL */
  for(i=0; i<N; i++){
    iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol);
    if( iCol>=0 
     && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0)
    ){
      if( piTab ){
        *piTab = i;
        *piCol = iCol;
      }
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
  pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight);

  pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2);
  if( pEq && isOuterJoin ){
    ExprSetProperty(pEq, EP_FromJoin);
    assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
    ExprSetVVAProperty(pEq, EP_NoReduce);
    pEq->iRightJoinTable = (i16)pE2->iTable;
  }
  *ppWhere = sqlite3ExprAnd(pParse, *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







|







347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
  pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight);

  pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2);
  if( pEq && isOuterJoin ){
    ExprSetProperty(pEq, EP_FromJoin);
    assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
    ExprSetVVAProperty(pEq, EP_NoReduce);
    pEq->iRightJoinTable = pE2->iTable;
  }
  *ppWhere = sqlite3ExprAnd(pParse, *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
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
** the output, which is incorrect.
*/
void sqlite3SetJoinExpr(Expr *p, int iTable){
  while( p ){
    ExprSetProperty(p, EP_FromJoin);
    assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
    ExprSetVVAProperty(p, EP_NoReduce);
    p->iRightJoinTable = (i16)iTable;
    if( p->op==TK_FUNCTION && p->x.pList ){
      int i;
      for(i=0; i<p->x.pList->nExpr; i++){
        sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable);
      }
    }
    sqlite3SetJoinExpr(p->pLeft, iTable);







|







383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
** the output, which is incorrect.
*/
void sqlite3SetJoinExpr(Expr *p, int iTable){
  while( p ){
    ExprSetProperty(p, EP_FromJoin);
    assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
    ExprSetVVAProperty(p, EP_NoReduce);
    p->iRightJoinTable = iTable;
    if( p->op==TK_FUNCTION && p->x.pList ){
      int i;
      for(i=0; i<p->x.pList->nExpr; i++){
        sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable);
      }
    }
    sqlite3SetJoinExpr(p->pLeft, iTable);
402
403
404
405
406
407
408



409
410
411
412
413
414
415
** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
*/
static void unsetJoinExpr(Expr *p, int iTable){
  while( p ){
    if( ExprHasProperty(p, EP_FromJoin)
     && (iTable<0 || p->iRightJoinTable==iTable) ){
      ExprClearProperty(p, EP_FromJoin);



    }
    if( p->op==TK_FUNCTION && p->x.pList ){
      int i;
      for(i=0; i<p->x.pList->nExpr; i++){
        unsetJoinExpr(p->x.pList->a[i].pExpr, iTable);
      }
    }







>
>
>







406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
*/
static void unsetJoinExpr(Expr *p, int iTable){
  while( p ){
    if( ExprHasProperty(p, EP_FromJoin)
     && (iTable<0 || p->iRightJoinTable==iTable) ){
      ExprClearProperty(p, EP_FromJoin);
    }
    if( p->op==TK_COLUMN && p->iTable==iTable ){
      ExprClearProperty(p, EP_CanBeNull);
    }
    if( p->op==TK_FUNCTION && p->x.pList ){
      int i;
      for(i=0; i<p->x.pList->nExpr; i++){
        unsetJoinExpr(p->x.pList->a[i].pExpr, iTable);
      }
    }
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
** also attached to the left entry.
**
** This routine returns the number of errors encountered.
*/
static int sqliteProcessJoin(Parse *pParse, Select *p){
  SrcList *pSrc;                  /* All tables in the FROM clause */
  int i, j;                       /* Loop counters */
  struct SrcList_item *pLeft;     /* Left table being joined */
  struct SrcList_item *pRight;    /* Right table being joined */

  pSrc = p->pSrc;
  pLeft = &pSrc->a[0];
  pRight = &pLeft[1];
  for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
    Table *pRightTab = pRight->pTab;
    int isOuter;







|
|







438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
** also attached to the left entry.
**
** This routine returns the number of errors encountered.
*/
static int sqliteProcessJoin(Parse *pParse, Select *p){
  SrcList *pSrc;                  /* All tables in the FROM clause */
  int i, j;                       /* Loop counters */
  SrcItem *pLeft;                 /* Left table being joined */
  SrcItem *pRight;                /* Right table being joined */

  pSrc = p->pSrc;
  pLeft = &pSrc->a[0];
  pRight = &pLeft[1];
  for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
    Table *pRightTab = pRight->pTab;
    int isOuter;
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
      for(j=0; j<pList->nId; j++){
        char *zName;     /* Name of the term in the USING clause */
        int iLeft;       /* Table on the left with matching column name */
        int iLeftCol;    /* Column number of matching column on the left */
        int iRightCol;   /* Column number of matching column on the right */

        zName = pList->a[j].zName;
        iRightCol = columnIndex(pRightTab, zName);
        if( iRightCol<0
         || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 0)
        ){
          sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
            "not present in both tables", zName);
          return 1;
        }







|







507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
      for(j=0; j<pList->nId; j++){
        char *zName;     /* Name of the term in the USING clause */
        int iLeft;       /* Table on the left with matching column name */
        int iLeftCol;    /* Column number of matching column on the left */
        int iRightCol;   /* Column number of matching column on the right */

        zName = pList->a[j].zName;
        iRightCol = sqlite3ColumnIndex(pRightTab, zName);
        if( iRightCol<0
         || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 0)
        ){
          sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
            "not present in both tables", zName);
          return 1;
        }
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
  }
  return pInfo;
}

/*
** Name of the connection operator, used for error messages.
*/
static const char *selectOpName(int id){
  char *z;
  switch( id ){
    case TK_ALL:       z = "UNION ALL";   break;
    case TK_INTERSECT: z = "INTERSECT";   break;
    case TK_EXCEPT:    z = "EXCEPT";      break;
    default:           z = "UNION";       break;
  }







|







1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
  }
  return pInfo;
}

/*
** Name of the connection operator, used for error messages.
*/
const char *sqlite3SelectOpName(int id){
  char *z;
  switch( id ){
    case TK_ALL:       z = "UNION ALL";   break;
    case TK_INTERSECT: z = "INTERSECT";   break;
    case TK_EXCEPT:    z = "EXCEPT";      break;
    default:           z = "UNION";       break;
  }
2082
2083
2084
2085
2086
2087
2088

2089
2090
2091
2092
2093
2094
2095
  if( db->mallocFailed ) return;
  memset(&sNC, 0, sizeof(sNC));
  sNC.pSrcList = pSelect->pSrc;
  a = pSelect->pEList->a;
  for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
    const char *zType;
    int n, m;

    p = a[i].pExpr;
    zType = columnType(&sNC, p, 0, 0, 0);
    /* pCol->szEst = ... // Column size est for SELECT tables never used */
    pCol->affinity = sqlite3ExprAffinity(p);
    if( zType ){
      m = sqlite3Strlen30(zType);
      n = sqlite3Strlen30(pCol->zName);







>







2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
  if( db->mallocFailed ) return;
  memset(&sNC, 0, sizeof(sNC));
  sNC.pSrcList = pSelect->pSrc;
  a = pSelect->pEList->a;
  for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
    const char *zType;
    int n, m;
    pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT);
    p = a[i].pExpr;
    zType = columnType(&sNC, p, 0, 0, 0);
    /* pCol->szEst = ... // Column size est for SELECT tables never used */
    pCol->affinity = sqlite3ExprAffinity(p);
    if( zType ){
      m = sqlite3Strlen30(zType);
      n = sqlite3Strlen30(pCol->zName);
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
  */
  assert( p && p->pPrior );  /* Calling function guarantees this much */
  assert( (p->selFlags & SF_Recursive)==0 || p->op==TK_ALL || p->op==TK_UNION );
  assert( p->selFlags & SF_Compound );
  db = pParse->db;
  pPrior = p->pPrior;
  dest = *pDest;
  if( pPrior->pOrderBy || pPrior->pLimit ){
    sqlite3ErrorMsg(pParse,"%s clause should come after %s not before",
      pPrior->pOrderBy!=0 ? "ORDER BY" : "LIMIT", selectOpName(p->op));
    rc = 1;
    goto multi_select_end;
  }

  v = sqlite3GetVdbe(pParse);
  assert( v!=0 );  /* The VDBE already created by calling function */

  /* Create the destination temporary table if necessary
  */
  if( dest.eDest==SRT_EphemTab ){







|
<
|
<
<
<







2605
2606
2607
2608
2609
2610
2611
2612

2613



2614
2615
2616
2617
2618
2619
2620
  */
  assert( p && p->pPrior );  /* Calling function guarantees this much */
  assert( (p->selFlags & SF_Recursive)==0 || p->op==TK_ALL || p->op==TK_UNION );
  assert( p->selFlags & SF_Compound );
  db = pParse->db;
  pPrior = p->pPrior;
  dest = *pDest;
  assert( pPrior->pOrderBy==0 );

  assert( pPrior->pLimit==0 );




  v = sqlite3GetVdbe(pParse);
  assert( v!=0 );  /* The VDBE already created by calling function */

  /* Create the destination temporary table if necessary
  */
  if( dest.eDest==SRT_EphemTab ){
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
        int addr = 0;
        int nLimit;
        assert( !pPrior->pLimit );
        pPrior->iLimit = p->iLimit;
        pPrior->iOffset = p->iOffset;
        pPrior->pLimit = p->pLimit;
        rc = sqlite3Select(pParse, pPrior, &dest);
        p->pLimit = 0;
        if( rc ){
          goto multi_select_end;
        }
        p->pPrior = 0;
        p->iLimit = pPrior->iLimit;
        p->iOffset = pPrior->iOffset;
        if( p->iLimit ){
          addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
          VdbeComment((v, "Jump ahead if LIMIT reached"));
          if( p->iOffset ){
            sqlite3VdbeAddOp3(v, OP_OffsetLimit,
                              p->iLimit, p->iOffset+1, p->iOffset);
          }
        }
        ExplainQueryPlan((pParse, 1, "UNION ALL"));
        rc = sqlite3Select(pParse, p, &dest);
        testcase( rc!=SQLITE_OK );
        pDelete = p->pPrior;
        p->pPrior = pPrior;
        p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
        if( pPrior->pLimit
         && sqlite3ExprIsInteger(pPrior->pLimit->pLeft, &nLimit)
         && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) 
        ){
          p->nSelectRow = sqlite3LogEst((u64)nLimit);
        }
        if( addr ){
          sqlite3VdbeJumpHere(v, addr);
        }







|




















|
|







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
        int addr = 0;
        int nLimit;
        assert( !pPrior->pLimit );
        pPrior->iLimit = p->iLimit;
        pPrior->iOffset = p->iOffset;
        pPrior->pLimit = p->pLimit;
        rc = sqlite3Select(pParse, pPrior, &dest);
        pPrior->pLimit = 0;
        if( rc ){
          goto multi_select_end;
        }
        p->pPrior = 0;
        p->iLimit = pPrior->iLimit;
        p->iOffset = pPrior->iOffset;
        if( p->iLimit ){
          addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
          VdbeComment((v, "Jump ahead if LIMIT reached"));
          if( p->iOffset ){
            sqlite3VdbeAddOp3(v, OP_OffsetLimit,
                              p->iLimit, p->iOffset+1, p->iOffset);
          }
        }
        ExplainQueryPlan((pParse, 1, "UNION ALL"));
        rc = sqlite3Select(pParse, p, &dest);
        testcase( rc!=SQLITE_OK );
        pDelete = p->pPrior;
        p->pPrior = pPrior;
        p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
        if( p->pLimit
         && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit)
         && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) 
        ){
          p->nSelectRow = sqlite3LogEst((u64)nLimit);
        }
        if( addr ){
          sqlite3VdbeJumpHere(v, addr);
        }
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
          op = SRT_Union;
        }
        p->pPrior = 0;
        pLimit = p->pLimit;
        p->pLimit = 0;
        uniondest.eDest = op;
        ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
                          selectOpName(p->op)));
        rc = sqlite3Select(pParse, p, &uniondest);
        testcase( rc!=SQLITE_OK );
        assert( p->pOrderBy==0 );
        pDelete = p->pPrior;
        p->pPrior = pPrior;
        p->pOrderBy = 0;
        if( p->op==TK_UNION ){







|







2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
          op = SRT_Union;
        }
        p->pPrior = 0;
        pLimit = p->pLimit;
        p->pLimit = 0;
        uniondest.eDest = op;
        ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
                          sqlite3SelectOpName(p->op)));
        rc = sqlite3Select(pParse, p, &uniondest);
        testcase( rc!=SQLITE_OK );
        assert( p->pOrderBy==0 );
        pDelete = p->pPrior;
        p->pPrior = pPrior;
        p->pOrderBy = 0;
        if( p->op==TK_UNION ){
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
        assert( p->addrOpenEphm[1] == -1 );
        p->addrOpenEphm[1] = addr;
        p->pPrior = 0;
        pLimit = p->pLimit;
        p->pLimit = 0;
        intersectdest.iSDParm = tab2;
        ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
                          selectOpName(p->op)));
        rc = sqlite3Select(pParse, p, &intersectdest);
        testcase( rc!=SQLITE_OK );
        pDelete = p->pPrior;
        p->pPrior = pPrior;
        if( p->nSelectRow>pPrior->nSelectRow ){
          p->nSelectRow = pPrior->nSelectRow;
        }







|







2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
        assert( p->addrOpenEphm[1] == -1 );
        p->addrOpenEphm[1] = addr;
        p->pPrior = 0;
        pLimit = p->pLimit;
        p->pLimit = 0;
        intersectdest.iSDParm = tab2;
        ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
                          sqlite3SelectOpName(p->op)));
        rc = sqlite3Select(pParse, p, &intersectdest);
        testcase( rc!=SQLITE_OK );
        pDelete = p->pPrior;
        p->pPrior = pPrior;
        if( p->nSelectRow>pPrior->nSelectRow ){
          p->nSelectRow = pPrior->nSelectRow;
        }
2930
2931
2932
2933
2934
2935
2936
2937

2938
2939
2940
2941
2942
2943
2944
** size result sets.
*/
void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){
  if( p->selFlags & SF_Values ){
    sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms");
  }else{
    sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
      " do not have the same number of result columns", selectOpName(p->op));

  }
}

/*
** Code an output subroutine for a coroutine implementation of a
** SELECT statment.
**







|
>







2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
** size result sets.
*/
void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){
  if( p->selFlags & SF_Values ){
    sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms");
  }else{
    sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
      " do not have the same number of result columns",
      sqlite3SelectOpName(p->op));
  }
}

/*
** Code an output subroutine for a coroutine implementation of a
** SELECT statment.
**
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044

    /* If this is a scalar select that is part of an expression, then
    ** store the results in the appropriate memory cell and break out
    ** of the scan loop.  Note that the select might return multiple columns
    ** if it is the RHS of a row-value IN operator.
    */
    case SRT_Mem: {
      if( pParse->nErr==0 ){
        testcase( pIn->nSdst>1 );
        sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, pIn->nSdst);
      }
      /* The LIMIT clause will jump out of the loop for us */
      break;
    }
#endif /* #ifndef SQLITE_OMIT_SUBQUERY */

    /* The results are stored in a sequence of registers
    ** starting at pDest->iSdst.  Then the co-routine yields.







<
|
|
<







3032
3033
3034
3035
3036
3037
3038

3039
3040

3041
3042
3043
3044
3045
3046
3047

    /* If this is a scalar select that is part of an expression, then
    ** store the results in the appropriate memory cell and break out
    ** of the scan loop.  Note that the select might return multiple columns
    ** if it is the RHS of a row-value IN operator.
    */
    case SRT_Mem: {

      testcase( pIn->nSdst>1 );
      sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, pIn->nSdst);

      /* The LIMIT clause will jump out of the loop for us */
      break;
    }
#endif /* #ifndef SQLITE_OMIT_SUBQUERY */

    /* The results are stored in a sequence of registers
    ** starting at pDest->iSdst.  Then the co-routine yields.
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
  regAddrA = ++pParse->nMem;
  regAddrB = ++pParse->nMem;
  regOutA = ++pParse->nMem;
  regOutB = ++pParse->nMem;
  sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA);
  sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB);

  ExplainQueryPlan((pParse, 1, "MERGE (%s)", selectOpName(p->op)));

  /* Generate a coroutine to evaluate the SELECT statement to the
  ** left of the compound operator - the "A" select.
  */
  addrSelectA = sqlite3VdbeCurrentAddr(v) + 1;
  addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
  VdbeComment((v, "left SELECT"));







|







3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
  regAddrA = ++pParse->nMem;
  regAddrB = ++pParse->nMem;
  regOutA = ++pParse->nMem;
  regOutB = ++pParse->nMem;
  sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA);
  sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB);

  ExplainQueryPlan((pParse, 1, "MERGE (%s)", sqlite3SelectOpName(p->op)));

  /* Generate a coroutine to evaluate the SELECT statement to the
  ** left of the compound operator - the "A" select.
  */
  addrSelectA = sqlite3VdbeCurrentAddr(v) + 1;
  addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
  VdbeComment((v, "left SELECT"));
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
}
static void substSelect(
  SubstContext *pSubst, /* Description of the substitution */
  Select *p,            /* SELECT statement in which to make substitutions */
  int doPrior           /* Do substitutes on p->pPrior too */
){
  SrcList *pSrc;
  struct SrcList_item *pItem;
  int i;
  if( !p ) return;
  do{
    substExprList(pSubst, p->pEList);
    substExprList(pSubst, p->pGroupBy);
    substExprList(pSubst, p->pOrderBy);
    p->pHaving = substExpr(pSubst, p->pHaving);







|







3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
}
static void substSelect(
  SubstContext *pSubst, /* Description of the substitution */
  Select *p,            /* SELECT statement in which to make substitutions */
  int doPrior           /* Do substitutes on p->pPrior too */
){
  SrcList *pSrc;
  SrcItem *pItem;
  int i;
  if( !p ) return;
  do{
    substExprList(pSubst, p->pEList);
    substExprList(pSubst, p->pGroupBy);
    substExprList(pSubst, p->pOrderBy);
    p->pHaving = substExpr(pSubst, p->pHaving);
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
** pSelect is a SELECT statement and pSrcItem is one item in the FROM
** clause of that SELECT.
**
** This routine scans the entire SELECT statement and recomputes the
** pSrcItem->colUsed mask.
*/
static int recomputeColumnsUsedExpr(Walker *pWalker, Expr *pExpr){
  struct SrcList_item *pItem;
  if( pExpr->op!=TK_COLUMN ) return WRC_Continue;
  pItem = pWalker->u.pSrcItem;
  if( pItem->iCursor!=pExpr->iTable ) return WRC_Continue;
  if( pExpr->iColumn<0 ) return WRC_Continue;
  pItem->colUsed |= sqlite3ExprColUsed(pExpr);
  return WRC_Continue;
}
static void recomputeColumnsUsed(
  Select *pSelect,                 /* The complete SELECT statement */
  struct SrcList_item *pSrcItem    /* Which FROM clause item to recompute */
){
  Walker w;
  if( NEVER(pSrcItem->pTab==0) ) return;
  memset(&w, 0, sizeof(w));
  w.xExprCallback = recomputeColumnsUsedExpr;
  w.xSelectCallback = sqlite3SelectWalkNoop;
  w.u.pSrcItem = pSrcItem;
  pSrcItem->colUsed = 0;
  sqlite3WalkSelect(&w, pSelect);



















































































}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */

#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/*
** This routine attempts to flatten subqueries as a performance optimization.
** This routine returns 1 if it makes changes and 0 if no flattening occurs.







|









|









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
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
** pSelect is a SELECT statement and pSrcItem is one item in the FROM
** clause of that SELECT.
**
** This routine scans the entire SELECT statement and recomputes the
** pSrcItem->colUsed mask.
*/
static int recomputeColumnsUsedExpr(Walker *pWalker, Expr *pExpr){
  SrcItem *pItem;
  if( pExpr->op!=TK_COLUMN ) return WRC_Continue;
  pItem = pWalker->u.pSrcItem;
  if( pItem->iCursor!=pExpr->iTable ) return WRC_Continue;
  if( pExpr->iColumn<0 ) return WRC_Continue;
  pItem->colUsed |= sqlite3ExprColUsed(pExpr);
  return WRC_Continue;
}
static void recomputeColumnsUsed(
  Select *pSelect,                 /* The complete SELECT statement */
  SrcItem *pSrcItem                /* Which FROM clause item to recompute */
){
  Walker w;
  if( NEVER(pSrcItem->pTab==0) ) return;
  memset(&w, 0, sizeof(w));
  w.xExprCallback = recomputeColumnsUsedExpr;
  w.xSelectCallback = sqlite3SelectWalkNoop;
  w.u.pSrcItem = pSrcItem;
  pSrcItem->colUsed = 0;
  sqlite3WalkSelect(&w, pSelect);
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */

#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/*
** Assign new cursor numbers to each of the items in pSrc. For each
** new cursor number assigned, set an entry in the aCsrMap[] array 
** to map the old cursor number to the new:
**
**     aCsrMap[iOld] = iNew;
**
** The array is guaranteed by the caller to be large enough for all
** existing cursor numbers in pSrc.
**
** If pSrc contains any sub-selects, call this routine recursively
** on the FROM clause of each such sub-select, with iExcept set to -1.
*/
static void srclistRenumberCursors(
  Parse *pParse,                  /* Parse context */
  int *aCsrMap,                   /* Array to store cursor mappings in */
  SrcList *pSrc,                  /* FROM clause to renumber */
  int iExcept                     /* FROM clause item to skip */
){
  int i;
  SrcItem *pItem;
  for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){
    if( i!=iExcept ){
      Select *p;
      pItem->iCursor = aCsrMap[pItem->iCursor] = pParse->nTab++;
      for(p=pItem->pSelect; p; p=p->pPrior){
        srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1);
      }
    }
  }
}

/*
** Expression walker callback used by renumberCursors() to update
** Expr objects to match newly assigned cursor numbers.
*/
static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){
  int *aCsrMap = pWalker->u.aiCol;
  int op = pExpr->op;
  if( (op==TK_COLUMN || op==TK_IF_NULL_ROW) && aCsrMap[pExpr->iTable] ){
    pExpr->iTable = aCsrMap[pExpr->iTable];
  }
  if( ExprHasProperty(pExpr, EP_FromJoin) && aCsrMap[pExpr->iRightJoinTable] ){
    pExpr->iRightJoinTable = aCsrMap[pExpr->iRightJoinTable];
  }
  return WRC_Continue;
}

/*
** Assign a new cursor number to each cursor in the FROM clause (Select.pSrc)
** of the SELECT statement passed as the second argument, and to each 
** cursor in the FROM clause of any FROM clause sub-selects, recursively.
** Except, do not assign a new cursor number to the iExcept'th element in
** the FROM clause of (*p). Update all expressions and other references 
** to refer to the new cursor numbers.
**
** Argument aCsrMap is an array that may be used for temporary working
** space. Two guarantees are made by the caller:
**
**   * the array is larger than the largest cursor number used within the
**     select statement passed as an argument, and
**
**   * the array entries for all cursor numbers that do *not* appear in 
**     FROM clauses of the select statement as described above are 
**     initialized to zero.
*/
static void renumberCursors(
  Parse *pParse,                  /* Parse context */
  Select *p,                      /* Select to renumber cursors within */
  int iExcept,                    /* FROM clause item to skip */
  int *aCsrMap                    /* Working space */
){
  Walker w;
  srclistRenumberCursors(pParse, aCsrMap, p->pSrc, iExcept);
  memset(&w, 0, sizeof(w));
  w.u.aiCol = aCsrMap;
  w.xExprCallback = renumberCursorsCb;
  w.xSelectCallback = sqlite3SelectWalkNoop;
  sqlite3WalkSelect(&w, p);
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */

#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/*
** This routine attempts to flatten subqueries as a performance optimization.
** This routine returns 1 if it makes changes and 0 if no flattening occurs.
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
**  (17)  If the subquery is a compound select, then
**        (17a) all compound operators must be a UNION ALL, and
**        (17b) no terms within the subquery compound may be aggregate
**              or DISTINCT, and
**        (17c) every term within the subquery compound must have a FROM clause
**        (17d) the outer query may not be
**              (17d1) aggregate, or
**              (17d2) DISTINCT, or
**              (17d3) a join.
**        (17e) the subquery may not contain window functions

**
**        The parent and sub-query may contain WHERE clauses. Subject to
**        rules (11), (13) and (14), they may also contain ORDER BY,
**        LIMIT and OFFSET clauses.  The subquery cannot use any compound
**        operator other than UNION ALL because all the other compound
**        operators have an implied DISTINCT which is disallowed by
**        restriction (4).
**
**        Also, each component of the sub-query must return the same number
**        of result columns. This is actually a requirement for any compound
**        SELECT statement, but all the code here does is make sure that no
**        such (illegal) sub-query is flattened. The caller will detect the
**        syntax error and return a detailed message.
**
**  (18)  If the sub-query is a compound select, then all terms of the
**        ORDER BY clause of the parent must be simple references to 
**        columns of the sub-query.
**
**  (19)  If the subquery uses LIMIT then the outer query may not
**        have a WHERE clause.
**
**  (20)  If the sub-query is a compound select, then it must not use
**        an ORDER BY clause.  Ticket #3773.  We could relax this constraint
**        somewhat by saying that the terms of the ORDER BY clause must
**        appear as unmodified result columns in the outer query.  But we
**        have other optimizations in mind to deal with that case.
**
**  (21)  If the subquery uses LIMIT then the outer query may not be
**        DISTINCT.  (See ticket [752e1646fc]).
**
**  (22)  The subquery may not be a recursive CTE.
**
**  (**)  Subsumed into restriction (17d3).  Was: If the outer query is
**        a recursive CTE, then the sub-query may not be a compound query.
**        This restriction is because transforming the
**        parent to a compound query confuses the code that handles
**        recursive queries in multiSelect().
**
**  (**)  We no longer attempt to flatten aggregate subqueries.  Was:
**        The subquery may not be an aggregate that uses the built-in min() or 
**        or max() functions.  (Without this restriction, a query like:
**        "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily







|
<
|
>















|
|















<
|
|







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
3874
3875
**  (17)  If the subquery is a compound select, then
**        (17a) all compound operators must be a UNION ALL, and
**        (17b) no terms within the subquery compound may be aggregate
**              or DISTINCT, and
**        (17c) every term within the subquery compound must have a FROM clause
**        (17d) the outer query may not be
**              (17d1) aggregate, or
**              (17d2) DISTINCT

**        (17e) the subquery may not contain window functions, and
**        (17f) the subquery must not be the RHS of a LEFT JOIN.
**
**        The parent and sub-query may contain WHERE clauses. Subject to
**        rules (11), (13) and (14), they may also contain ORDER BY,
**        LIMIT and OFFSET clauses.  The subquery cannot use any compound
**        operator other than UNION ALL because all the other compound
**        operators have an implied DISTINCT which is disallowed by
**        restriction (4).
**
**        Also, each component of the sub-query must return the same number
**        of result columns. This is actually a requirement for any compound
**        SELECT statement, but all the code here does is make sure that no
**        such (illegal) sub-query is flattened. The caller will detect the
**        syntax error and return a detailed message.
**
**  (18)  If the sub-query is a compound select, then all terms of the
**        ORDER BY clause of the parent must be copies of a term returned
**        by the parent query.
**
**  (19)  If the subquery uses LIMIT then the outer query may not
**        have a WHERE clause.
**
**  (20)  If the sub-query is a compound select, then it must not use
**        an ORDER BY clause.  Ticket #3773.  We could relax this constraint
**        somewhat by saying that the terms of the ORDER BY clause must
**        appear as unmodified result columns in the outer query.  But we
**        have other optimizations in mind to deal with that case.
**
**  (21)  If the subquery uses LIMIT then the outer query may not be
**        DISTINCT.  (See ticket [752e1646fc]).
**
**  (22)  The subquery may not be a recursive CTE.
**

**  (23)  If the outer query is a recursive CTE, then the sub-query may not be
**        a compound query.  This restriction is because transforming the
**        parent to a compound query confuses the code that handles
**        recursive queries in multiSelect().
**
**  (**)  We no longer attempt to flatten aggregate subqueries.  Was:
**        The subquery may not be an aggregate that uses the built-in min() or 
**        or max() functions.  (Without this restriction, a query like:
**        "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827

3828
3829
3830
3831
3832
3833
3834
  SrcList *pSrc;      /* The FROM clause of the outer query */
  SrcList *pSubSrc;   /* The FROM clause of the subquery */
  int iParent;        /* VDBE cursor number of the pSub result set temp table */
  int iNewParent = -1;/* Replacement table for iParent */
  int isLeftJoin = 0; /* True if pSub is the right side of a LEFT JOIN */    
  int i;              /* Loop counter */
  Expr *pWhere;                    /* The WHERE clause */
  struct SrcList_item *pSubitem;   /* The subquery */
  sqlite3 *db = pParse->db;
  Walker w;                        /* Walker to persist agginfo data */


  /* Check to see if flattening is permitted.  Return 0 if not.
  */
  assert( p!=0 );
  assert( p->pPrior==0 );
  if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0;
  pSrc = p->pSrc;







|


>







3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
  SrcList *pSrc;      /* The FROM clause of the outer query */
  SrcList *pSubSrc;   /* The FROM clause of the subquery */
  int iParent;        /* VDBE cursor number of the pSub result set temp table */
  int iNewParent = -1;/* Replacement table for iParent */
  int isLeftJoin = 0; /* True if pSub is the right side of a LEFT JOIN */    
  int i;              /* Loop counter */
  Expr *pWhere;                    /* The WHERE clause */
  SrcItem *pSubitem;               /* The subquery */
  sqlite3 *db = pParse->db;
  Walker w;                        /* Walker to persist agginfo data */
  int *aCsrMap = 0;

  /* Check to see if flattening is permitted.  Return 0 if not.
  */
  assert( p!=0 );
  assert( p->pPrior==0 );
  if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0;
  pSrc = p->pSrc;
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
  ** that make up the compound SELECT are allowed to be aggregate or distinct
  ** queries.
  */
  if( pSub->pPrior ){
    if( pSub->pOrderBy ){
      return 0;  /* Restriction (20) */
    }
    if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){
      return 0; /* (17d1), (17d2), or (17d3) */
    }
    for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){
      testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
      testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
      assert( pSub->pSrc!=0 );

      assert( pSub->pEList->nExpr==pSub1->pEList->nExpr );
      if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0    /* (17b) */
       || (pSub1->pPrior && pSub1->op!=TK_ALL)                 /* (17a) */
       || pSub1->pSrc->nSrc<1                                  /* (17c) */
#ifndef SQLITE_OMIT_WINDOWFUNC
       || pSub1->pWin                                          /* (17e) */
#endif
      ){
        return 0;
      }
      testcase( pSub1->pSrc->nSrc>1 );
    }

    /* Restriction (18). */
    if( p->pOrderBy ){
      int ii;
      for(ii=0; ii<p->pOrderBy->nExpr; ii++){
        if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0;
      }
    }
  }

  /* Ex-restriction (23):
  ** The only way that the recursive part of a CTE can contain a compound
  ** subquery is for the subquery to be one term of a join.  But if the
  ** subquery is a join, then the flattening has already been stopped by
  ** restriction (17d3)
  */
  assert( (p->selFlags & SF_Recursive)==0 || pSub->pPrior==0 );






  /***** If we reach this point, flattening is permitted. *****/
  SELECTTRACE(1,pParse,p,("flatten %u.%p from term %d\n",
                   pSub->selId, pSub, iFrom));

  /* Authorize the subquery */
  pParse->zAuthContext = pSubitem->zName;
  TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0);
  testcase( i==SQLITE_DENY );
  pParse->zAuthContext = zSavedAuthContext;












  /* If the sub-query is a compound SELECT statement, then (by restrictions
  ** 17 and 18 above) it must be a UNION ALL and the parent query must 
  ** be of the form:
  **
  **     SELECT <expr-list> FROM (<sub-query>) <where-clause> 
  **







|
|





>




















|
<
|
<
<
<
<
<
|
>
>
>
>
>










>
>
>
>
>
>
>
>
>
>
>







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
  ** that make up the compound SELECT are allowed to be aggregate or distinct
  ** queries.
  */
  if( pSub->pPrior ){
    if( pSub->pOrderBy ){
      return 0;  /* Restriction (20) */
    }
    if( isAgg || (p->selFlags & SF_Distinct)!=0 || isLeftJoin>0 ){
      return 0; /* (17d1), (17d2), or (17f) */
    }
    for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){
      testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
      testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
      assert( pSub->pSrc!=0 );
      assert( (pSub->selFlags & SF_Recursive)==0 );
      assert( pSub->pEList->nExpr==pSub1->pEList->nExpr );
      if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0    /* (17b) */
       || (pSub1->pPrior && pSub1->op!=TK_ALL)                 /* (17a) */
       || pSub1->pSrc->nSrc<1                                  /* (17c) */
#ifndef SQLITE_OMIT_WINDOWFUNC
       || pSub1->pWin                                          /* (17e) */
#endif
      ){
        return 0;
      }
      testcase( pSub1->pSrc->nSrc>1 );
    }

    /* Restriction (18). */
    if( p->pOrderBy ){
      int ii;
      for(ii=0; ii<p->pOrderBy->nExpr; ii++){
        if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0;
      }
    }


    /* Restriction (23) */





    if( (p->selFlags & SF_Recursive) ) return 0;

    if( pSrc->nSrc>1 ){
      aCsrMap = sqlite3DbMallocZero(db, pParse->nTab*sizeof(int));
    }
  }

  /***** If we reach this point, flattening is permitted. *****/
  SELECTTRACE(1,pParse,p,("flatten %u.%p from term %d\n",
                   pSub->selId, pSub, iFrom));

  /* Authorize the subquery */
  pParse->zAuthContext = pSubitem->zName;
  TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0);
  testcase( i==SQLITE_DENY );
  pParse->zAuthContext = zSavedAuthContext;

  /* Delete the transient structures associated with thesubquery */
  pSub1 = pSubitem->pSelect;
  sqlite3DbFree(db, pSubitem->zDatabase);
  sqlite3DbFree(db, pSubitem->zName);
  sqlite3DbFree(db, pSubitem->zAlias);
  pSubitem->zDatabase = 0;
  pSubitem->zName = 0;
  pSubitem->zAlias = 0;
  pSubitem->pSelect = 0;
  assert( pSubitem->pOn==0 );

  /* If the sub-query is a compound SELECT statement, then (by restrictions
  ** 17 and 18 above) it must be a UNION ALL and the parent query must 
  ** be of the form:
  **
  **     SELECT <expr-list> FROM (<sub-query>) <where-clause> 
  **
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
4098
4099
4100
4101
4102
  ** We call this the "compound-subquery flattening".
  */
  for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){
    Select *pNew;
    ExprList *pOrderBy = p->pOrderBy;
    Expr *pLimit = p->pLimit;
    Select *pPrior = p->pPrior;


    p->pOrderBy = 0;
    p->pSrc = 0;
    p->pPrior = 0;
    p->pLimit = 0;
    pNew = sqlite3SelectDup(db, p, 0);
    p->pLimit = pLimit;
    p->pOrderBy = pOrderBy;
    p->pSrc = pSrc;
    p->op = TK_ALL;

    if( pNew==0 ){
      p->pPrior = pPrior;
    }else{



      pNew->pPrior = pPrior;
      if( pPrior ) pPrior->pNext = pNew;
      pNew->pNext = p;
      p->pPrior = pNew;
      SELECTTRACE(2,pParse,p,("compound-subquery flattener"
                              " creates %u as peer\n",pNew->selId));
    }
    if( db->mallocFailed ) return 1;
  }

  /* Begin flattening the iFrom-th entry of the FROM clause 
  ** in the outer query.
  */
  pSub = pSub1 = pSubitem->pSelect;

  /* Delete the transient table structure associated with the
  ** subquery
  */
  sqlite3DbFree(db, pSubitem->zDatabase);
  sqlite3DbFree(db, pSubitem->zName);
  sqlite3DbFree(db, pSubitem->zAlias);
  pSubitem->zDatabase = 0;
  pSubitem->zName = 0;
  pSubitem->zAlias = 0;
  pSubitem->pSelect = 0;



  /* Defer deleting the Table object associated with the
  ** subquery until code generation is
  ** complete, since there may still exist Expr.pTab entries that
  ** 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->nTabRef==1 ){
      Parse *pToplevel = sqlite3ParseToplevel(pParse);


      pTabToDel->pNextZombie = pToplevel->pZombieTab;
      pToplevel->pZombieTab = pTabToDel;
    }else{
      pTabToDel->nTabRef--;
    }
    pSubitem->pTab = 0;
  }

  /* The following loop runs once for each term in a compound-subquery
  ** flattening (as described above).  If we are doing a different kind
  ** of flattening - a flattening other than a compound-subquery flattening -
  ** then this loop only runs once.
  **
  ** This loop moves all of the FROM elements of the subquery into the
  ** the FROM clause of the outer query.  Before doing this, remember
  ** the cursor number for the original outer query FROM element in
  ** iParent.  The iParent cursor will never be used.  Subsequent code
  ** will scan expressions looking for iParent references and replace
  ** those references with expressions that resolve to the subquery FROM
  ** elements we are now copying in.
  */

  for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){
    int nSubSrc;
    u8 jointype = 0;
    assert( pSub!=0 );
    pSubSrc = pSub->pSrc;     /* FROM clause of subquery */
    nSubSrc = pSubSrc->nSrc;  /* Number of terms in subquery FROM clause */
    pSrc = pParent->pSrc;     /* FROM clause of the outer query */

    if( pSrc ){
      assert( pParent==p );  /* First time through the loop */
      jointype = pSubitem->fg.jointype;
    }else{
      assert( pParent!=p );  /* 2nd and subsequent times through the loop */
      pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
      if( pSrc==0 ) break;
      pParent->pSrc = pSrc;
    }

    /* The subquery uses a single slot of the FROM clause of the outer
    ** query.  If the subquery has more than one element in its FROM clause,
    ** then expand the outer query to make space for it to hold all elements
    ** of the subquery.
    **
    ** Example:
    **







>
>

<





<

>



>
>
>







<
<
<
<
<
<
|
|
<
<
<
<
|
<
<
|
<
|
>
>












>
>
|
|



















>








<
|
|
<
<
<
<
<

|







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
4183
4184
4185
4186
4187
4188
4189
  ** We call this the "compound-subquery flattening".
  */
  for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){
    Select *pNew;
    ExprList *pOrderBy = p->pOrderBy;
    Expr *pLimit = p->pLimit;
    Select *pPrior = p->pPrior;
    Table *pItemTab = pSubitem->pTab;
    pSubitem->pTab = 0;
    p->pOrderBy = 0;

    p->pPrior = 0;
    p->pLimit = 0;
    pNew = sqlite3SelectDup(db, p, 0);
    p->pLimit = pLimit;
    p->pOrderBy = pOrderBy;

    p->op = TK_ALL;
    pSubitem->pTab = pItemTab;
    if( pNew==0 ){
      p->pPrior = pPrior;
    }else{
      if( aCsrMap && db->mallocFailed==0 ){
        renumberCursors(pParse, pNew, iFrom, aCsrMap);
      }
      pNew->pPrior = pPrior;
      if( pPrior ) pPrior->pNext = pNew;
      pNew->pNext = p;
      p->pPrior = pNew;
      SELECTTRACE(2,pParse,p,("compound-subquery flattener"
                              " creates %u as peer\n",pNew->selId));
    }






    assert( pSubitem->pSelect==0 );
  }




  sqlite3DbFree(db, aCsrMap);


  if( db->mallocFailed ){

    pSubitem->pSelect = pSub1;
    return 1;
  }

  /* Defer deleting the Table object associated with the
  ** subquery until code generation is
  ** complete, since there may still exist Expr.pTab entries that
  ** 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->nTabRef==1 ){
      Parse *pToplevel = sqlite3ParseToplevel(pParse);
      sqlite3ParserAddCleanup(pToplevel, 
         (void(*)(sqlite3*,void*))sqlite3DeleteTable,
         pTabToDel);
      testcase( pToplevel->earlyCleanup );
    }else{
      pTabToDel->nTabRef--;
    }
    pSubitem->pTab = 0;
  }

  /* The following loop runs once for each term in a compound-subquery
  ** flattening (as described above).  If we are doing a different kind
  ** of flattening - a flattening other than a compound-subquery flattening -
  ** then this loop only runs once.
  **
  ** This loop moves all of the FROM elements of the subquery into the
  ** the FROM clause of the outer query.  Before doing this, remember
  ** the cursor number for the original outer query FROM element in
  ** iParent.  The iParent cursor will never be used.  Subsequent code
  ** will scan expressions looking for iParent references and replace
  ** those references with expressions that resolve to the subquery FROM
  ** elements we are now copying in.
  */
  pSub = pSub1;
  for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){
    int nSubSrc;
    u8 jointype = 0;
    assert( pSub!=0 );
    pSubSrc = pSub->pSrc;     /* FROM clause of subquery */
    nSubSrc = pSubSrc->nSrc;  /* Number of terms in subquery FROM clause */
    pSrc = pParent->pSrc;     /* FROM clause of the outer query */


    if( pParent==p ){
      jointype = pSubitem->fg.jointype;     /* First time through the loop */





    }
    
    /* The subquery uses a single slot of the FROM clause of the outer
    ** query.  If the subquery has more than one element in its FROM clause,
    ** then expand the outer query to make space for it to hold all elements
    ** of the subquery.
    **
    ** Example:
    **
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
  ** success.
  */
  sqlite3AggInfoPersistWalkerInit(&w, pParse);
  sqlite3WalkSelect(&w,pSub1);
  sqlite3SelectDelete(db, pSub1);

#if SELECTTRACE_ENABLED
  if( sqlite3_unsupported_selecttrace & 0x100 ){
    SELECTTRACE(0x100,pParse,p,("After flattening:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif

  return 1;
}







|







4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
  ** success.
  */
  sqlite3AggInfoPersistWalkerInit(&w, pParse);
  sqlite3WalkSelect(&w,pSub1);
  sqlite3SelectDelete(db, pSub1);

#if SELECTTRACE_ENABLED
  if( sqlite3SelectTrace & 0x100 ){
    SELECTTRACE(0x100,pParse,p,("After flattening:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif

  return 1;
}
4400
4401
4402
4403
4404
4405
4406





























4407
4408
4409
4410
4411
4412
4413
      sqlite3DbFree(x.pParse->db, x.apExpr);
      nChng += x.nChng;
    }
  }while( x.nChng );  
  return nChng;
}






























#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/*
** Make copies of relevant WHERE clause terms of the outer query into
** the WHERE clause of subquery.  Example:
**
**    SELECT * FROM (SELECT a AS x, c-d AS y FROM t1) WHERE x=5 AND y=10;
**







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
      sqlite3DbFree(x.pParse->db, x.apExpr);
      nChng += x.nChng;
    }
  }while( x.nChng );  
  return nChng;
}

#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
# if !defined(SQLITE_OMIT_WINDOWFUNC)
/*
** This function is called to determine whether or not it is safe to
** push WHERE clause expression pExpr down to FROM clause sub-query
** pSubq, which contains at least one window function. Return 1
** if it is safe and the expression should be pushed down, or 0 
** otherwise.
**
** It is only safe to push the expression down if it consists only 
** of constants and copies of expressions that appear in the PARTITION
** BY clause of all window function used by the sub-query. It is safe
** to filter out entire partitions, but not rows within partitions, as
** this may change the results of the window functions.
**
** At the time this function is called it is guaranteed that 
**
**   * the sub-query uses only one distinct window frame, and 
**   * that the window frame has a PARTITION BY clase.
*/
static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){
  assert( pSubq->pWin->pPartition );
  assert( (pSubq->selFlags & SF_MultiPart)==0 );
  assert( pSubq->pPrior==0 );
  return sqlite3ExprIsConstantOrGroupBy(pParse, pExpr, pSubq->pWin->pPartition);
}
# endif /* SQLITE_OMIT_WINDOWFUNC */
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */

#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/*
** Make copies of relevant WHERE clause terms of the outer query into
** the WHERE clause of subquery.  Example:
**
**    SELECT * FROM (SELECT a AS x, c-d AS y FROM t1) WHERE x=5 AND y=10;
**
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
**           JOIN (SELECT 1 AS b2 UNION ALL SELECT 2) AS bb ON (a1=b2)
**           LEFT JOIN (SELECT 8 AS c3 UNION ALL SELECT 9) AS cc ON (b2=2);
**
**       The correct answer is three rows:  (1,1,NULL),(2,2,8),(2,2,9).
**       But if the (b2=2) term were to be pushed down into the bb subquery,
**       then the (1,1,NULL) row would be suppressed.
**
**   (6) The inner query features one or more window-functions (since 
**       changes to the WHERE clause of the inner query could change the 

**       window over which window functions are calculated).














**
** Return 0 if no changes are made and non-zero if one or more WHERE clause
** terms are duplicated into the subquery.
*/
static int pushDownWhereTerms(
  Parse *pParse,        /* Parse context (for malloc() and error reporting) */
  Select *pSubq,        /* The subquery whose WHERE clause is to be augmented */
  Expr *pWhere,         /* The WHERE clause of the outer query */
  int iCursor,          /* Cursor number of the subquery */
  int isLeftJoin        /* True if pSubq is the right term of a LEFT JOIN */
){
  Expr *pNew;
  int nChng = 0;
  Select *pSel;
  if( pWhere==0 ) return 0;
  if( pSubq->selFlags & SF_Recursive ) return 0;  /* restriction (2) */

#ifndef SQLITE_OMIT_WINDOWFUNC


  for(pSel=pSubq; pSel; pSel=pSel->pPrior){
    if( pSel->pWin ) return 0;    /* restriction (6) */



  }
#endif

#ifdef SQLITE_DEBUG
  /* Only the first term of a compound can have a WITH clause.  But make
  ** sure no other terms are marked SF_Recursive in case something changes
  ** in the future.







|
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>













<

|


>
>
|
|
>
>
>







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
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600

4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
**           JOIN (SELECT 1 AS b2 UNION ALL SELECT 2) AS bb ON (a1=b2)
**           LEFT JOIN (SELECT 8 AS c3 UNION ALL SELECT 9) AS cc ON (b2=2);
**
**       The correct answer is three rows:  (1,1,NULL),(2,2,8),(2,2,9).
**       But if the (b2=2) term were to be pushed down into the bb subquery,
**       then the (1,1,NULL) row would be suppressed.
**
**   (6) Window functions make things tricky as changes to the WHERE clause 
**       of the inner query could change the window over which window 
**       functions are calculated. Therefore, do not attempt the optimization
**       if:
**
**     (6a) The inner query uses multiple incompatible window partitions.
**
**     (6b) The inner query is a compound and uses window-functions. 
**
**     (6c) The WHERE clause does not consist entirely of constants and
**          copies of expressions found in the PARTITION BY clause of
**          all window-functions used by the sub-query. It is safe to
**          filter out entire partitions, as this does not change the 
**          window over which any window-function is calculated.
**
**   (7) The inner query is a Common Table Expression (CTE) that should
**       be materialized.  (This restriction is implemented in the calling
**       routine.)
**
** Return 0 if no changes are made and non-zero if one or more WHERE clause
** terms are duplicated into the subquery.
*/
static int pushDownWhereTerms(
  Parse *pParse,        /* Parse context (for malloc() and error reporting) */
  Select *pSubq,        /* The subquery whose WHERE clause is to be augmented */
  Expr *pWhere,         /* The WHERE clause of the outer query */
  int iCursor,          /* Cursor number of the subquery */
  int isLeftJoin        /* True if pSubq is the right term of a LEFT JOIN */
){
  Expr *pNew;
  int nChng = 0;

  if( pWhere==0 ) return 0;
  if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ) return 0;

#ifndef SQLITE_OMIT_WINDOWFUNC
  if( pSubq->pPrior ){
    Select *pSel;
    for(pSel=pSubq; pSel; pSel=pSel->pPrior){
      if( pSel->pWin ) return 0;    /* restriction (6b) */
    }
  }else{
    if( pSubq->pWin && pSubq->pWin->pPartition==0 ) return 0;
  }
#endif

#ifdef SQLITE_DEBUG
  /* Only the first term of a compound can have a WITH clause.  But make
  ** sure no other terms are marked SF_Recursive in case something changes
  ** in the future.
4505
4506
4507
4508
4509
4510
4511

4512
4513
4514
4515
4516
4517
4518
4519
4520
4521








4522
4523
4524
4525
4526
4527
4528
    return 0; /* restriction (4) */
  }
  if( ExprHasProperty(pWhere,EP_FromJoin) && pWhere->iRightJoinTable!=iCursor ){
    return 0; /* restriction (5) */
  }
  if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
    nChng++;

    while( pSubq ){
      SubstContext x;
      pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
      unsetJoinExpr(pNew, -1);
      x.pParse = pParse;
      x.iTable = iCursor;
      x.iNewTable = iCursor;
      x.isLeftJoin = 0;
      x.pEList = pSubq->pEList;
      pNew = substExpr(&x, pNew);








      if( pSubq->selFlags & SF_Aggregate ){
        pSubq->pHaving = sqlite3ExprAnd(pParse, pSubq->pHaving, pNew);
      }else{
        pSubq->pWhere = sqlite3ExprAnd(pParse, pSubq->pWhere, pNew);
      }
      pSubq = pSubq->pPrior;
    }







>










>
>
>
>
>
>
>
>







4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
    return 0; /* restriction (4) */
  }
  if( ExprHasProperty(pWhere,EP_FromJoin) && pWhere->iRightJoinTable!=iCursor ){
    return 0; /* restriction (5) */
  }
  if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
    nChng++;
    pSubq->selFlags |= SF_PushDown;
    while( pSubq ){
      SubstContext x;
      pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
      unsetJoinExpr(pNew, -1);
      x.pParse = pParse;
      x.iTable = iCursor;
      x.iNewTable = iCursor;
      x.isLeftJoin = 0;
      x.pEList = pSubq->pEList;
      pNew = substExpr(&x, pNew);
#ifndef SQLITE_OMIT_WINDOWFUNC
      if( pSubq->pWin && 0==pushDownWindowCheck(pParse, pSubq, pNew) ){
        /* Restriction 6c has prevented push-down in this case */
        sqlite3ExprDelete(pParse->db, pNew);
        nChng--;
        break;
      }
#endif
      if( pSubq->selFlags & SF_Aggregate ){
        pSubq->pHaving = sqlite3ExprAnd(pParse, pSubq->pHaving, pNew);
      }else{
        pSubq->pWhere = sqlite3ExprAnd(pParse, pSubq->pWhere, pNew);
      }
      pSubq = pSubq->pPrior;
    }
4553
4554
4555
4556
4557
4558
4559


4560


4561
4562
4563
4564
4565
4566
4567
  const char *zFunc;                    /* Name of aggregate function pFunc */
  ExprList *pOrderBy;
  u8 sortFlags = 0;

  assert( *ppMinMax==0 );
  assert( pFunc->op==TK_AGG_FUNCTION );
  assert( !IsWindowFunc(pFunc) );


  if( pEList==0 || pEList->nExpr!=1 || ExprHasProperty(pFunc, EP_WinFunc) ){


    return eRet;
  }
  zFunc = pFunc->u.zToken;
  if( sqlite3StrICmp(zFunc, "min")==0 ){
    eRet = WHERE_ORDERBY_MIN;
    if( sqlite3ExprCanBeNull(pEList->a[0].pExpr) ){
      sortFlags = KEYINFO_ORDER_BIGNULL;







>
>
|
>
>







4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
  const char *zFunc;                    /* Name of aggregate function pFunc */
  ExprList *pOrderBy;
  u8 sortFlags = 0;

  assert( *ppMinMax==0 );
  assert( pFunc->op==TK_AGG_FUNCTION );
  assert( !IsWindowFunc(pFunc) );
  if( pEList==0 
   || pEList->nExpr!=1
   || ExprHasProperty(pFunc, EP_WinFunc)
   || OptimizationDisabled(db, SQLITE_MinMaxOpt)
  ){
    return eRet;
  }
  zFunc = pFunc->u.zToken;
  if( sqlite3StrICmp(zFunc, "min")==0 ){
    eRet = WHERE_ORDERBY_MIN;
    if( sqlite3ExprCanBeNull(pEList->a[0].pExpr) ){
      sortFlags = KEYINFO_ORDER_BIGNULL;
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627



4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640

4641
4642
4643
4644
4645
4646
4647
/*
** If the source-list item passed as an argument was augmented with an
** INDEXED BY clause, then try to locate the specified index. If there
** was such a clause and the named index cannot be found, return 
** SQLITE_ERROR and leave an error in pParse. Otherwise, populate 
** pFrom->pIndex and return SQLITE_OK.
*/
int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){
  if( pFrom->pTab && pFrom->fg.isIndexedBy ){
    Table *pTab = pFrom->pTab;
    char *zIndexedBy = pFrom->u1.zIndexedBy;
    Index *pIdx;



    for(pIdx=pTab->pIndex; 
        pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy); 
        pIdx=pIdx->pNext
    );
    if( !pIdx ){
      sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0);
      pParse->checkSchema = 1;
      return SQLITE_ERROR;
    }
    pFrom->pIBIndex = pIdx;
  }
  return SQLITE_OK;
}

/*
** Detect compound SELECT statements that use an ORDER BY clause with 
** an alternative collating sequence.
**
**    SELECT ... FROM t1 EXCEPT SELECT ... FROM t2 ORDER BY .. COLLATE ...
**
** These are rewritten as a subquery:







|
<
|
|
|
>
>
>
|
|
|
|
|
|
|
|
|
|
<


>







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
/*
** If the source-list item passed as an argument was augmented with an
** INDEXED BY clause, then try to locate the specified index. If there
** was such a clause and the named index cannot be found, return 
** SQLITE_ERROR and leave an error in pParse. Otherwise, populate 
** pFrom->pIndex and return SQLITE_OK.
*/
int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){

  Table *pTab = pFrom->pTab;
  char *zIndexedBy = pFrom->u1.zIndexedBy;
  Index *pIdx;
  assert( pTab!=0 );
  assert( pFrom->fg.isIndexedBy!=0 );

  for(pIdx=pTab->pIndex; 
      pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy); 
      pIdx=pIdx->pNext
  );
  if( !pIdx ){
    sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0);
    pParse->checkSchema = 1;
    return SQLITE_ERROR;
  }
  pFrom->u2.pIBIndex = pIdx;

  return SQLITE_OK;
}

/*
** Detect compound SELECT statements that use an ORDER BY clause with 
** an alternative collating sequence.
**
**    SELECT ... FROM t1 EXCEPT SELECT ... FROM t2 ORDER BY .. COLLATE ...
**
** These are rewritten as a subquery:
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
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
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
}

/*
** Check to see if the FROM clause term pFrom has table-valued function
** arguments.  If it does, leave an error message in pParse and return
** non-zero, since pFrom is not allowed to be a table-valued function.
*/
static int cannotBeFunction(Parse *pParse, struct SrcList_item *pFrom){
  if( pFrom->fg.isTabFunc ){
    sqlite3ErrorMsg(pParse, "'%s' is not a function", pFrom->zName);
    return 1;
  }
  return 0;
}

#ifndef SQLITE_OMIT_CTE
/*
** Argument pWith (which may be NULL) points to a linked list of nested 
** WITH contexts, from inner to outermost. If the table identified by 
** FROM clause element pItem is really a common-table-expression (CTE) 
** then return a pointer to the CTE definition for that table. Otherwise
** return NULL.
**
** If a non-NULL value is returned, set *ppContext to point to the With
** object that the returned CTE belongs to.
*/
static struct Cte *searchWith(
  With *pWith,                    /* Current innermost WITH clause */
  struct SrcList_item *pItem,     /* FROM clause element to resolve */
  With **ppContext                /* OUT: WITH clause return value belongs to */
){
  const char *zName;
  if( pItem->zDatabase==0 && (zName = pItem->zName)!=0 ){
    With *p;


    for(p=pWith; p; p=p->pOuter){
      int i;
      for(i=0; i<p->nCte; i++){
        if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){
          *ppContext = p;
          return &p->a[i];
        }
      }
    }
  }
  return 0;
}

/* The code generator maintains a stack of active WITH clauses
** with the inner-most WITH clause being at the top of the stack.
**
** This routine pushes the WITH clause passed as the second argument
** onto the top of the stack. If argument bFree is true, then this
** WITH clause will never be popped from the stack. In this case it
** should be freed along with the Parse object. In other cases, when
** bFree==0, the With object will be freed along with the SELECT 
** statement with which it is associated.
*/
void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){
  assert( bFree==0 || (pParse->pWith==0 && pParse->pWithToFree==0) );
  if( pWith ){
    assert( pParse->pWith!=pWith );
    pWith->pOuter = pParse->pWith;
    pParse->pWith = pWith;
    if( bFree ) pParse->pWithToFree = pWith;





  }
}

/*
** This function checks if argument pFrom refers to a CTE declared by 
** a WITH clause on the stack currently maintained by the parser. And,
** if currently processing a CTE expression, if it is a recursive

** reference to the current CTE.
**
** If pFrom falls into either of the two categories above, pFrom->pTab
** and other fields are populated accordingly. The caller should check
** (pFrom->pTab!=0) to determine whether or not a successful match
** was found.
**

** Whether or not a match is found, SQLITE_OK is returned if no error
** occurs. If an error does occur, an error message is stored in the
** parser and some error code other than SQLITE_OK returned.
*/
static int withExpand(

  Walker *pWalker, 
  struct SrcList_item *pFrom
){
  Parse *pParse = pWalker->pParse;
  sqlite3 *db = pParse->db;
  struct Cte *pCte;               /* Matched CTE (or NULL if no match) */
  With *pWith;                    /* WITH clause that pCte belongs to */

  assert( pFrom->pTab==0 );
  if( pParse->nErr ){

    return SQLITE_ERROR;
  }





  pCte = searchWith(pParse->pWith, pFrom, &pWith);
  if( pCte ){

    Table *pTab;
    ExprList *pEList;
    Select *pSel;
    Select *pLeft;                /* Left-most SELECT statement */
    Select *pRecTerm;             /* Left-most recursive term */
    int bMayRecursive;            /* True if compound joined by UNION [ALL] */
    With *pSavedWith;             /* Initial value of pParse->pWith */
    int iRecTab = -1;             /* Cursor for recursive table */


    /* If pCte->zCteErr is non-NULL at this point, then this is an illegal
    ** recursive reference to CTE pCte. Leave an error in pParse and return
    ** early. If pCte->zCteErr is NULL, then this is not a recursive reference.
    ** In this case, proceed.  */
    if( pCte->zCteErr ){
      sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName);
      return SQLITE_ERROR;
    }
    if( cannotBeFunction(pParse, pFrom) ) return SQLITE_ERROR;

    assert( pFrom->pTab==0 );
    pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
    if( pTab==0 ) return WRC_Abort;












    pTab->nTabRef = 1;
    pTab->zName = sqlite3DbStrDup(db, pCte->zName);
    pTab->iPKey = -1;
    pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
    pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
    pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
    if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
    assert( pFrom->pSelect );







    /* Check if this is a recursive CTE. */
    pRecTerm = pSel = pFrom->pSelect;
    bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION );
    while( bMayRecursive && pRecTerm->op==pSel->op ){
      int i;
      SrcList *pSrc = pRecTerm->pSrc;
      assert( pRecTerm->pPrior!=0 );
      for(i=0; i<pSrc->nSrc; i++){
        struct SrcList_item *pItem = &pSrc->a[i];
        if( pItem->zDatabase==0 
         && pItem->zName!=0 
         && 0==sqlite3StrICmp(pItem->zName, pCte->zName)
        ){
          pItem->pTab = pTab;
          pTab->nTabRef++;
          pItem->fg.isRecursive = 1;
          if( pRecTerm->selFlags & SF_Recursive ){
            sqlite3ErrorMsg(pParse,
               "multiple references to recursive table: %s", pCte->zName
            );
            return SQLITE_ERROR;
          }
          pRecTerm->selFlags |= SF_Recursive;
          if( iRecTab<0 ) iRecTab = pParse->nTab++;
          pItem->iCursor = iRecTab;
        }
      }
      if( (pRecTerm->selFlags & SF_Recursive)==0 ) break;







|




















|


|
<
|
>
>
|
|
|
|
|
|
<

















<




|
>
>
>
>
>





|
|
>
|

|
|
<
<

>
|
|
<

|
>
|
|

<
<
|
|


|
>
|

>
>
>
>
|


>








>







|

|


|
|
>
>
>
>
>
>
>
>
>
>
>
>






|

>
>
>
>
>
>









|











|







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
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
}

/*
** Check to see if the FROM clause term pFrom has table-valued function
** arguments.  If it does, leave an error message in pParse and return
** non-zero, since pFrom is not allowed to be a table-valued function.
*/
static int cannotBeFunction(Parse *pParse, SrcItem *pFrom){
  if( pFrom->fg.isTabFunc ){
    sqlite3ErrorMsg(pParse, "'%s' is not a function", pFrom->zName);
    return 1;
  }
  return 0;
}

#ifndef SQLITE_OMIT_CTE
/*
** Argument pWith (which may be NULL) points to a linked list of nested 
** WITH contexts, from inner to outermost. If the table identified by 
** FROM clause element pItem is really a common-table-expression (CTE) 
** then return a pointer to the CTE definition for that table. Otherwise
** return NULL.
**
** If a non-NULL value is returned, set *ppContext to point to the With
** object that the returned CTE belongs to.
*/
static struct Cte *searchWith(
  With *pWith,                    /* Current innermost WITH clause */
  SrcItem *pItem,                 /* FROM clause element to resolve */
  With **ppContext                /* OUT: WITH clause return value belongs to */
){
  const char *zName = pItem->zName;

  With *p;
  assert( pItem->zDatabase==0 );
  assert( zName!=0 );
  for(p=pWith; p; p=p->pOuter){
    int i;
    for(i=0; i<p->nCte; i++){
      if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){
        *ppContext = p;
        return &p->a[i];

      }
    }
  }
  return 0;
}

/* The code generator maintains a stack of active WITH clauses
** with the inner-most WITH clause being at the top of the stack.
**
** This routine pushes the WITH clause passed as the second argument
** onto the top of the stack. If argument bFree is true, then this
** WITH clause will never be popped from the stack. In this case it
** should be freed along with the Parse object. In other cases, when
** bFree==0, the With object will be freed along with the SELECT 
** statement with which it is associated.
*/
void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){

  if( pWith ){
    assert( pParse->pWith!=pWith );
    pWith->pOuter = pParse->pWith;
    pParse->pWith = pWith;
    if( bFree ){
      sqlite3ParserAddCleanup(pParse, 
         (void(*)(sqlite3*,void*))sqlite3WithDelete,
         pWith);
      testcase( pParse->earlyCleanup );
    }
  }
}

/*
** This function checks if argument pFrom refers to a CTE declared by 
** a WITH clause on the stack currently maintained by the parser (on the
** pParse->pWith linked list).  And if currently processing a CTE
** CTE expression, through routine checks to see if the reference is
** a recursive reference to the CTE.
**
** If pFrom matches a CTE according to either of these two above, pFrom->pTab
** and other fields are populated accordingly.


**
** Return 0 if no match is found. 
** Return 1 if a match is found.
** Return 2 if an error condition is detected.

*/
static int resolveFromTermToCte(
  Parse *pParse,                  /* The parsing context */
  Walker *pWalker,                /* Current tree walker */
  SrcItem *pFrom                  /* The FROM clause term to check */
){


  Cte *pCte;               /* Matched CTE (or NULL if no match) */
  With *pWith;             /* The matching WITH */

  assert( pFrom->pTab==0 );
  if( pParse->pWith==0 ){
    /* There are no WITH clauses in the stack.  No match is possible */
    return 0;
  }
  if( pFrom->zDatabase!=0 ){
    /* The FROM term contains a schema qualifier (ex: main.t1) and so
    ** it cannot possibly be a CTE reference. */
    return 0;
  }
  pCte = searchWith(pParse->pWith, pFrom, &pWith);
  if( pCte ){
    sqlite3 *db = pParse->db;
    Table *pTab;
    ExprList *pEList;
    Select *pSel;
    Select *pLeft;                /* Left-most SELECT statement */
    Select *pRecTerm;             /* Left-most recursive term */
    int bMayRecursive;            /* True if compound joined by UNION [ALL] */
    With *pSavedWith;             /* Initial value of pParse->pWith */
    int iRecTab = -1;             /* Cursor for recursive table */
    CteUse *pCteUse;

    /* If pCte->zCteErr is non-NULL at this point, then this is an illegal
    ** recursive reference to CTE pCte. Leave an error in pParse and return
    ** early. If pCte->zCteErr is NULL, then this is not a recursive reference.
    ** In this case, proceed.  */
    if( pCte->zCteErr ){
      sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName);
      return 2;
    }
    if( cannotBeFunction(pParse, pFrom) ) return 2;

    assert( pFrom->pTab==0 );
    pTab = sqlite3DbMallocZero(db, sizeof(Table));
    if( pTab==0 ) return 2;
    pCteUse = pCte->pUse;
    if( pCteUse==0 ){
      pCte->pUse = pCteUse = sqlite3DbMallocZero(db, sizeof(pCteUse[0]));
      if( pCteUse==0
       || sqlite3ParserAddCleanup(pParse,sqlite3DbFree,pCteUse)==0
      ){
        sqlite3DbFree(db, pTab);
        return 2;
      }
      pCteUse->eM10d = pCte->eM10d;
    }
    pFrom->pTab = pTab;
    pTab->nTabRef = 1;
    pTab->zName = sqlite3DbStrDup(db, pCte->zName);
    pTab->iPKey = -1;
    pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
    pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
    pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
    if( db->mallocFailed ) return 2;
    assert( pFrom->pSelect );
    pFrom->fg.isCte = 1;
    pFrom->u2.pCteUse = pCteUse;
    pCteUse->nUse++;
    if( pCteUse->nUse>=2 && pCteUse->eM10d==M10d_Any ){
      pCteUse->eM10d = M10d_Yes;
    }

    /* Check if this is a recursive CTE. */
    pRecTerm = pSel = pFrom->pSelect;
    bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION );
    while( bMayRecursive && pRecTerm->op==pSel->op ){
      int i;
      SrcList *pSrc = pRecTerm->pSrc;
      assert( pRecTerm->pPrior!=0 );
      for(i=0; i<pSrc->nSrc; i++){
        SrcItem *pItem = &pSrc->a[i];
        if( pItem->zDatabase==0 
         && pItem->zName!=0 
         && 0==sqlite3StrICmp(pItem->zName, pCte->zName)
        ){
          pItem->pTab = pTab;
          pTab->nTabRef++;
          pItem->fg.isRecursive = 1;
          if( pRecTerm->selFlags & SF_Recursive ){
            sqlite3ErrorMsg(pParse,
               "multiple references to recursive table: %s", pCte->zName
            );
            return 2;
          }
          pRecTerm->selFlags |= SF_Recursive;
          if( iRecTab<0 ) iRecTab = pParse->nTab++;
          pItem->iCursor = iRecTab;
        }
      }
      if( (pRecTerm->selFlags & SF_Recursive)==0 ) break;
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
    pEList = pLeft->pEList;
    if( pCte->pCols ){
      if( pEList && pEList->nExpr!=pCte->pCols->nExpr ){
        sqlite3ErrorMsg(pParse, "table %s has %d values for %d columns",
            pCte->zName, pEList->nExpr, pCte->pCols->nExpr
        );
        pParse->pWith = pSavedWith;
        return SQLITE_ERROR;
      }
      pEList = pCte->pCols;
    }

    sqlite3ColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol);
    if( bMayRecursive ){
      if( pSel->selFlags & SF_Recursive ){
        pCte->zCteErr = "multiple recursive references: %s";
      }else{
        pCte->zCteErr = "recursive reference in a subquery: %s";
      }
      sqlite3WalkSelect(pWalker, pSel);
    }
    pCte->zCteErr = 0;
    pParse->pWith = pSavedWith;

  }

  return SQLITE_OK;
}
#endif

#ifndef SQLITE_OMIT_CTE
/*
** If the SELECT passed as the second argument has an associated WITH 
** clause, pop it from the stack stored as part of the Parse object.







|















>

|
<







5075
5076
5077
5078
5079
5080
5081
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
    pEList = pLeft->pEList;
    if( pCte->pCols ){
      if( pEList && pEList->nExpr!=pCte->pCols->nExpr ){
        sqlite3ErrorMsg(pParse, "table %s has %d values for %d columns",
            pCte->zName, pEList->nExpr, pCte->pCols->nExpr
        );
        pParse->pWith = pSavedWith;
        return 2;
      }
      pEList = pCte->pCols;
    }

    sqlite3ColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol);
    if( bMayRecursive ){
      if( pSel->selFlags & SF_Recursive ){
        pCte->zCteErr = "multiple recursive references: %s";
      }else{
        pCte->zCteErr = "recursive reference in a subquery: %s";
      }
      sqlite3WalkSelect(pWalker, pSel);
    }
    pCte->zCteErr = 0;
    pParse->pWith = pSavedWith;
    return 1;  /* Success */
  }
  return 0;  /* No match */

}
#endif

#ifndef SQLITE_OMIT_CTE
/*
** If the SELECT passed as the second argument has an associated WITH 
** clause, pop it from the stack stored as part of the Parse object.
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
/*
** The SrcList_item structure passed as the second argument represents a
** sub-query in the FROM clause of a SELECT statement. This function
** allocates and populates the SrcList_item.pTab object. If successful,
** SQLITE_OK is returned. Otherwise, if an OOM error is encountered,
** SQLITE_NOMEM.
*/
int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFrom){
  Select *pSel = pFrom->pSelect;
  Table *pTab;

  assert( pSel );
  pFrom->pTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table));
  if( pTab==0 ) return SQLITE_NOMEM;
  pTab->nTabRef = 1;







|







5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
/*
** The SrcList_item structure passed as the second argument represents a
** sub-query in the FROM clause of a SELECT statement. This function
** allocates and populates the SrcList_item.pTab object. If successful,
** SQLITE_OK is returned. Otherwise, if an OOM error is encountered,
** SQLITE_NOMEM.
*/
int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){
  Select *pSel = pFrom->pSelect;
  Table *pTab;

  assert( pSel );
  pFrom->pTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table));
  if( pTab==0 ) return SQLITE_NOMEM;
  pTab->nTabRef = 1;
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
**         for instances of the "*" operator or the TABLE.* operator.
**         If found, expand each "*" to be every column in every table
**         and TABLE.* to be every column in TABLE.
**
*/
static int selectExpander(Walker *pWalker, Select *p){
  Parse *pParse = pWalker->pParse;
  int i, j, k;
  SrcList *pTabList;
  ExprList *pEList;
  struct SrcList_item *pFrom;
  sqlite3 *db = pParse->db;
  Expr *pE, *pRight, *pExpr;
  u16 selFlags = p->selFlags;
  u32 elistFlags = 0;

  p->selFlags |= SF_Expanded;
  if( db->mallocFailed  ){







|


|







5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
**         for instances of the "*" operator or the TABLE.* operator.
**         If found, expand each "*" to be every column in every table
**         and TABLE.* to be every column in TABLE.
**
*/
static int selectExpander(Walker *pWalker, Select *p){
  Parse *pParse = pWalker->pParse;
  int i, j, k, rc;
  SrcList *pTabList;
  ExprList *pEList;
  SrcItem *pFrom;
  sqlite3 *db = pParse->db;
  Expr *pE, *pRight, *pExpr;
  u16 selFlags = p->selFlags;
  u32 elistFlags = 0;

  p->selFlags |= SF_Expanded;
  if( db->mallocFailed  ){
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
  ** then create a transient table structure to describe the subquery.
  */
  for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
    Table *pTab;
    assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 );
    if( pFrom->pTab ) continue;
    assert( pFrom->fg.isRecursive==0 );
#ifndef SQLITE_OMIT_CTE
    if( withExpand(pWalker, pFrom) ) return WRC_Abort;
    if( pFrom->pTab ) {} else
#endif
    if( pFrom->zName==0 ){
#ifndef SQLITE_OMIT_SUBQUERY
      Select *pSel = pFrom->pSelect;
      /* A sub-query in the FROM clause of a SELECT */
      assert( pSel!=0 );
      assert( pFrom->pTab==0 );
      if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort;
      if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort;
#endif






    }else{
      /* An ordinary table or view name in the FROM clause */
      assert( pFrom->pTab==0 );
      pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
      if( pTab==0 ) return WRC_Abort;
      if( pTab->nTabRef>=0xffff ){
        sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535",







<
<
<
<









>
>
>
>
>
>







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
  ** then create a transient table structure to describe the subquery.
  */
  for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
    Table *pTab;
    assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 );
    if( pFrom->pTab ) continue;
    assert( pFrom->fg.isRecursive==0 );




    if( pFrom->zName==0 ){
#ifndef SQLITE_OMIT_SUBQUERY
      Select *pSel = pFrom->pSelect;
      /* A sub-query in the FROM clause of a SELECT */
      assert( pSel!=0 );
      assert( pFrom->pTab==0 );
      if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort;
      if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort;
#endif
#ifndef SQLITE_OMIT_CTE
    }else if( (rc = resolveFromTermToCte(pParse, pWalker, pFrom))!=0 ){
      if( rc>1 ) return WRC_Abort;
      pTab = pFrom->pTab;
      assert( pTab!=0 );
#endif
    }else{
      /* An ordinary table or view name in the FROM clause */
      assert( pFrom->pTab==0 );
      pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
      if( pTab==0 ) return WRC_Abort;
      if( pTab->nTabRef>=0xffff ){
        sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535",
5071
5072
5073
5074
5075
5076
5077

5078


5079
5080
5081
5082
5083
5084
5085
      }
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
      if( IsVirtual(pTab) || pTab->pSelect ){
        i16 nCol;
        u8 eCodeOrig = pWalker->eCode;
        if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
        assert( pFrom->pSelect==0 );

        if( pTab->pSelect && (db->flags & SQLITE_EnableView)==0 ){


          sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited",
            pTab->zName);
        }
#ifndef SQLITE_OMIT_VIRTUALTABLE
        if( IsVirtual(pTab)
         && pFrom->fg.fromDDL
         && ALWAYS(pTab->pVTable!=0)







>
|
>
>







5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
      }
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
      if( IsVirtual(pTab) || pTab->pSelect ){
        i16 nCol;
        u8 eCodeOrig = pWalker->eCode;
        if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
        assert( pFrom->pSelect==0 );
        if( pTab->pSelect
         && (db->flags & SQLITE_EnableView)==0
         && pTab->pSchema!=db->aDb[1].pSchema
        ){
          sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited",
            pTab->zName);
        }
#ifndef SQLITE_OMIT_VIRTUALTABLE
        if( IsVirtual(pTab)
         && pFrom->fg.fromDDL
         && ALWAYS(pTab->pVTable!=0)
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
        pWalker->eCode = eCodeOrig;
        pTab->nCol = nCol;
      }
#endif
    }

    /* Locate the index named by the INDEXED BY clause, if any. */
    if( sqlite3IndexedByLookup(pParse, pFrom) ){
      return WRC_Abort;
    }
  }

  /* Process NATURAL keywords, and ON and USING clauses of joins.
  */
  if( pParse->nErr || db->mallocFailed || sqliteProcessJoin(pParse, p) ){







|







5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
        pWalker->eCode = eCodeOrig;
        pTab->nCol = nCol;
      }
#endif
    }

    /* Locate the index named by the INDEXED BY clause, if any. */
    if( pFrom->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pFrom) ){
      return WRC_Abort;
    }
  }

  /* Process NATURAL keywords, and ON and USING clauses of joins.
  */
  if( pParse->nErr || db->mallocFailed || sqliteProcessJoin(pParse, p) ){
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
** at that point because identifiers had not yet been resolved.  This
** routine is called after identifier resolution.
*/
static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
  Parse *pParse;
  int i;
  SrcList *pTabList;
  struct SrcList_item *pFrom;

  assert( p->selFlags & SF_Resolved );
  if( p->selFlags & SF_HasTypeInfo ) return;
  p->selFlags |= SF_HasTypeInfo;
  pParse = pWalker->pParse;
  pTabList = p->pSrc;
  for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){







|







5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
** at that point because identifiers had not yet been resolved.  This
** routine is called after identifier resolution.
*/
static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
  Parse *pParse;
  int i;
  SrcList *pTabList;
  SrcItem *pFrom;

  assert( p->selFlags & SF_Resolved );
  if( p->selFlags & SF_HasTypeInfo ) return;
  p->selFlags |= SF_HasTypeInfo;
  pParse = pWalker->pParse;
  pTabList = p->pSrc;
  for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
5611
5612
5613
5614
5615
5616
5617
5618


5619
5620
5621
5622
5623
5624
5625
** sub-expression matches the criteria for being moved to the WHERE
** clause. If so, add it to the WHERE clause and replace the sub-expression
** within the HAVING expression with a constant "1".
*/
static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
  if( pExpr->op!=TK_AND ){
    Select *pS = pWalker->u.pSelect;
    if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) ){


      sqlite3 *db = pWalker->pParse->db;
      Expr *pNew = sqlite3Expr(db, TK_INTEGER, "1");
      if( pNew ){
        Expr *pWhere = pS->pWhere;
        SWAP(Expr, *pNew, *pExpr);
        pNew = sqlite3ExprAnd(pWalker->pParse, pWhere, pNew);
        pS->pWhere = pNew;







|
>
>







5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
** sub-expression matches the criteria for being moved to the WHERE
** clause. If so, add it to the WHERE clause and replace the sub-expression
** within the HAVING expression with a constant "1".
*/
static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
  if( pExpr->op!=TK_AND ){
    Select *pS = pWalker->u.pSelect;
    if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) 
     && ExprAlwaysFalse(pExpr)==0
    ){
      sqlite3 *db = pWalker->pParse->db;
      Expr *pNew = sqlite3Expr(db, TK_INTEGER, "1");
      if( pNew ){
        Expr *pWhere = pS->pWhere;
        SWAP(Expr, *pNew, *pExpr);
        pNew = sqlite3ExprAnd(pWalker->pParse, pWhere, pNew);
        pS->pWhere = pNew;
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673


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
  Walker sWalker;
  memset(&sWalker, 0, sizeof(sWalker));
  sWalker.pParse = pParse;
  sWalker.xExprCallback = havingToWhereExprCb;
  sWalker.u.pSelect = p;
  sqlite3WalkExpr(&sWalker, p->pHaving);
#if SELECTTRACE_ENABLED
  if( sWalker.eCode && (sqlite3_unsupported_selecttrace & 0x100)!=0 ){
    SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif
}

/*
** Check to see if the pThis entry of pTabList is a self-join of a prior view.
** If it is, then return the SrcList_item for the prior view.  If it is not,
** then return 0.
*/
static struct SrcList_item *isSelfJoinView(
  SrcList *pTabList,           /* Search for self-joins in this FROM clause */
  struct SrcList_item *pThis   /* Search for prior reference to this subquery */
){
  struct SrcList_item *pItem;


  for(pItem = pTabList->a; pItem<pThis; pItem++){
    Select *pS1;
    if( pItem->pSelect==0 ) continue;
    if( pItem->fg.viaCoroutine ) continue;
    if( pItem->zName==0 ) continue;
    assert( pItem->pTab!=0 );
    assert( pThis->pTab!=0 );
    if( pItem->pTab->pSchema!=pThis->pTab->pSchema ) continue;
    if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
    pS1 = pItem->pSelect;
    if( pItem->pTab->pSchema==0 && pThis->pSelect->selId!=pS1->selId ){
      /* The query flattener left two different CTE tables with identical
      ** names in the same FROM clause. */
      continue;
    }
    if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1)
     || sqlite3ExprCompare(0, pThis->pSelect->pHaving, pS1->pHaving, -1) 
    ){
      /* The view was modified by some other optimization such as
      ** pushDownWhereTerms() */
      continue;
    }
    return pItem;
  }
  return 0;
}










#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION
/*
** Attempt to transform a query of the form
**
**    SELECT count(*) FROM (SELECT x FROM t1 UNION ALL SELECT y FROM t2)
**







|











|

|

|
>
>















|
<
<








>
>
>
>
>
>
>
>
>







5834
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
5875


5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
  Walker sWalker;
  memset(&sWalker, 0, sizeof(sWalker));
  sWalker.pParse = pParse;
  sWalker.xExprCallback = havingToWhereExprCb;
  sWalker.u.pSelect = p;
  sqlite3WalkExpr(&sWalker, p->pHaving);
#if SELECTTRACE_ENABLED
  if( sWalker.eCode && (sqlite3SelectTrace & 0x100)!=0 ){
    SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif
}

/*
** Check to see if the pThis entry of pTabList is a self-join of a prior view.
** If it is, then return the SrcList_item for the prior view.  If it is not,
** then return 0.
*/
static SrcItem *isSelfJoinView(
  SrcList *pTabList,           /* Search for self-joins in this FROM clause */
  SrcItem *pThis               /* Search for prior reference to this subquery */
){
  SrcItem *pItem;
  assert( pThis->pSelect!=0 );
  if( pThis->pSelect->selFlags & SF_PushDown ) return 0;
  for(pItem = pTabList->a; pItem<pThis; pItem++){
    Select *pS1;
    if( pItem->pSelect==0 ) continue;
    if( pItem->fg.viaCoroutine ) continue;
    if( pItem->zName==0 ) continue;
    assert( pItem->pTab!=0 );
    assert( pThis->pTab!=0 );
    if( pItem->pTab->pSchema!=pThis->pTab->pSchema ) continue;
    if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
    pS1 = pItem->pSelect;
    if( pItem->pTab->pSchema==0 && pThis->pSelect->selId!=pS1->selId ){
      /* The query flattener left two different CTE tables with identical
      ** names in the same FROM clause. */
      continue;
    }
    if( pItem->pSelect->selFlags & SF_PushDown ){


      /* The view was modified by some other optimization such as
      ** pushDownWhereTerms() */
      continue;
    }
    return pItem;
  }
  return 0;
}

/*
** Deallocate a single AggInfo object
*/
static void agginfoFree(sqlite3 *db, AggInfo *p){
  sqlite3DbFree(db, p->aCol);
  sqlite3DbFree(db, p->aFunc);
  sqlite3DbFreeNN(db, p);
}

#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION
/*
** Attempt to transform a query of the form
**
**    SELECT count(*) FROM (SELECT x FROM t1 UNION ALL SELECT y FROM t2)
**
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
    }
    pSub = pPrior;
  }
  p->pEList->a[0].pExpr = pExpr;
  p->selFlags &= ~SF_Aggregate;

#if SELECTTRACE_ENABLED
  if( sqlite3_unsupported_selecttrace & 0x400 ){
    SELECTTRACE(0x400,pParse,p,("After count-of-view optimization:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif
  return 1;
}
#endif /* SQLITE_COUNTOFVIEW_OPTIMIZATION */







|







5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
    }
    pSub = pPrior;
  }
  p->pEList->a[0].pExpr = pExpr;
  p->selFlags &= ~SF_Aggregate;

#if SELECTTRACE_ENABLED
  if( sqlite3SelectTrace & 0x400 ){
    SELECTTRACE(0x400,pParse,p,("After count-of-view optimization:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif
  return 1;
}
#endif /* SQLITE_COUNTOFVIEW_OPTIMIZATION */
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
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
5875
5876
5877
  v = sqlite3GetVdbe(pParse);
  if( p==0 || db->mallocFailed || pParse->nErr ){
    return 1;
  }
  if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
#if SELECTTRACE_ENABLED
  SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
  if( sqlite3_unsupported_selecttrace & 0x100 ){
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif

  assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo );
  assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
  assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
  assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue );
  if( IgnorableDistinct(pDest) ){
    assert(pDest->eDest==SRT_Exists     || pDest->eDest==SRT_Union || 
           pDest->eDest==SRT_Except     || pDest->eDest==SRT_Discard ||
           pDest->eDest==SRT_DistQueue  || pDest->eDest==SRT_DistFifo );
    /* All of these destinations are also able to ignore the ORDER BY clause */









    sqlite3ExprListDelete(db, p->pOrderBy);

    p->pOrderBy = 0;

    p->selFlags &= ~SF_Distinct;
    p->selFlags |= SF_NoopOrderBy;
  }
  sqlite3SelectPrep(pParse, p, 0);
  if( pParse->nErr || db->mallocFailed ){
    goto select_end;
  }
  assert( p->pEList!=0 );
#if SELECTTRACE_ENABLED
  if( sqlite3_unsupported_selecttrace & 0x104 ){
    SELECTTRACE(0x104,pParse,p, ("after name resolution:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif

  /* If the SF_UpdateFrom flag is set, then this function is being called
  ** as part of populating the temp table for an UPDATE...FROM statement.
  ** In this case, it is an error if the target object (pSrc->a[0]) name 
  ** or alias is duplicated within FROM clause (pSrc->a[1..n]).  */
  if( p->selFlags & SF_UpdateFrom ){
    struct SrcList_item *p0 = &p->pSrc->a[0];
    for(i=1; i<p->pSrc->nSrc; i++){
      struct SrcList_item *p1 = &p->pSrc->a[i];
      if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){
        sqlite3ErrorMsg(pParse, 
            "target object/alias may not appear in FROM clause: %s", 
            p0->zAlias ? p0->zAlias : p0->pTab->zName
        );
        goto select_end;
      }







|













>
>
>
>
>
>
>
>
>
|
>
|
>









|










|

|







6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
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
  v = sqlite3GetVdbe(pParse);
  if( p==0 || db->mallocFailed || pParse->nErr ){
    return 1;
  }
  if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
#if SELECTTRACE_ENABLED
  SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
  if( sqlite3SelectTrace & 0x100 ){
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif

  assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo );
  assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
  assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
  assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue );
  if( IgnorableDistinct(pDest) ){
    assert(pDest->eDest==SRT_Exists     || pDest->eDest==SRT_Union || 
           pDest->eDest==SRT_Except     || pDest->eDest==SRT_Discard ||
           pDest->eDest==SRT_DistQueue  || pDest->eDest==SRT_DistFifo );
    /* All of these destinations are also able to ignore the ORDER BY clause */
    if( p->pOrderBy ){
#if SELECTTRACE_ENABLED
      SELECTTRACE(1,pParse,p, ("dropping superfluous ORDER BY:\n"));
      if( sqlite3SelectTrace & 0x100 ){
        sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY");
      }
#endif    
      sqlite3ParserAddCleanup(pParse,
        (void(*)(sqlite3*,void*))sqlite3ExprListDelete,
        p->pOrderBy);
      testcase( pParse->earlyCleanup );
      p->pOrderBy = 0;
    }
    p->selFlags &= ~SF_Distinct;
    p->selFlags |= SF_NoopOrderBy;
  }
  sqlite3SelectPrep(pParse, p, 0);
  if( pParse->nErr || db->mallocFailed ){
    goto select_end;
  }
  assert( p->pEList!=0 );
#if SELECTTRACE_ENABLED
  if( sqlite3SelectTrace & 0x104 ){
    SELECTTRACE(0x104,pParse,p, ("after name resolution:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif

  /* If the SF_UpdateFrom flag is set, then this function is being called
  ** as part of populating the temp table for an UPDATE...FROM statement.
  ** In this case, it is an error if the target object (pSrc->a[0]) name 
  ** or alias is duplicated within FROM clause (pSrc->a[1..n]).  */
  if( p->selFlags & SF_UpdateFrom ){
    SrcItem *p0 = &p->pSrc->a[0];
    for(i=1; i<p->pSrc->nSrc; i++){
      SrcItem *p1 = &p->pSrc->a[i];
      if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){
        sqlite3ErrorMsg(pParse, 
            "target object/alias may not appear in FROM clause: %s", 
            p0->zAlias ? p0->zAlias : p0->pTab->zName
        );
        goto select_end;
      }
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
#ifndef SQLITE_OMIT_WINDOWFUNC
  rc = sqlite3WindowRewrite(pParse, p);
  if( rc ){
    assert( db->mallocFailed || pParse->nErr>0 );
    goto select_end;
  }
#if SELECTTRACE_ENABLED
  if( p->pWin && (sqlite3_unsupported_selecttrace & 0x108)!=0 ){
    SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif
#endif /* SQLITE_OMIT_WINDOWFUNC */
  pTabList = p->pSrc;
  isAgg = (p->selFlags & SF_Aggregate)!=0;
  memset(&sSort, 0, sizeof(sSort));
  sSort.pOrderBy = p->pOrderBy;

  /* Try to do various optimizations (flattening subqueries, and strength
  ** reduction of join operators) in the FROM clause up into the main query
  */
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
  for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
    struct SrcList_item *pItem = &pTabList->a[i];
    Select *pSub = pItem->pSelect;
    Table *pTab = pItem->pTab;

    /* The expander should have already created transient Table objects
    ** even for FROM clause elements such as subqueries that do not correspond
    ** to a real table */
    assert( pTab!=0 );







|















|







6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
#ifndef SQLITE_OMIT_WINDOWFUNC
  rc = sqlite3WindowRewrite(pParse, p);
  if( rc ){
    assert( db->mallocFailed || pParse->nErr>0 );
    goto select_end;
  }
#if SELECTTRACE_ENABLED
  if( p->pWin && (sqlite3SelectTrace & 0x108)!=0 ){
    SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif
#endif /* SQLITE_OMIT_WINDOWFUNC */
  pTabList = p->pSrc;
  isAgg = (p->selFlags & SF_Aggregate)!=0;
  memset(&sSort, 0, sizeof(sSort));
  sSort.pOrderBy = p->pOrderBy;

  /* Try to do various optimizations (flattening subqueries, and strength
  ** reduction of join operators) in the FROM clause up into the main query
  */
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
  for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
    SrcItem *pItem = &pTabList->a[i];
    Select *pSub = pItem->pSelect;
    Table *pTab = pItem->pTab;

    /* The expander should have already created transient Table objects
    ** even for FROM clause elements such as subqueries that do not correspond
    ** to a real table */
    assert( pTab!=0 );
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
  /* Handle compound SELECT statements using the separate multiSelect()
  ** procedure.
  */
  if( p->pPrior ){
    rc = multiSelect(pParse, p, pDest);
#if SELECTTRACE_ENABLED
    SELECTTRACE(0x1,pParse,p,("end compound-select processing\n"));
    if( (sqlite3_unsupported_selecttrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
      sqlite3TreeViewSelect(0, p, 0);
    }
#endif
    if( p->pNext==0 ) ExplainQueryPlanPop(pParse);
    return rc;
  }
#endif

  /* Do the WHERE-clause constant propagation optimization if this is
  ** a join.  No need to speed time on this operation for non-join queries
  ** as the equivalent optimization will be handled by query planner in
  ** sqlite3WhereBegin().
  */
  if( pTabList->nSrc>1
   && OptimizationEnabled(db, SQLITE_PropagateConst)
   && propagateConstants(pParse, p)
  ){
#if SELECTTRACE_ENABLED
    if( sqlite3_unsupported_selecttrace & 0x100 ){
      SELECTTRACE(0x100,pParse,p,("After constant propagation:\n"));
      sqlite3TreeViewSelect(0, p, 0);
    }
#endif
  }else{
    SELECTTRACE(0x100,pParse,p,("Constant propagation not helpful\n"));
  }







|


















|







6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
  /* Handle compound SELECT statements using the separate multiSelect()
  ** procedure.
  */
  if( p->pPrior ){
    rc = multiSelect(pParse, p, pDest);
#if SELECTTRACE_ENABLED
    SELECTTRACE(0x1,pParse,p,("end compound-select processing\n"));
    if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
      sqlite3TreeViewSelect(0, p, 0);
    }
#endif
    if( p->pNext==0 ) ExplainQueryPlanPop(pParse);
    return rc;
  }
#endif

  /* Do the WHERE-clause constant propagation optimization if this is
  ** a join.  No need to speed time on this operation for non-join queries
  ** as the equivalent optimization will be handled by query planner in
  ** sqlite3WhereBegin().
  */
  if( pTabList->nSrc>1
   && OptimizationEnabled(db, SQLITE_PropagateConst)
   && propagateConstants(pParse, p)
  ){
#if SELECTTRACE_ENABLED
    if( sqlite3SelectTrace & 0x100 ){
      SELECTTRACE(0x100,pParse,p,("After constant propagation:\n"));
      sqlite3TreeViewSelect(0, p, 0);
    }
#endif
  }else{
    SELECTTRACE(0x100,pParse,p,("Constant propagation not helpful\n"));
  }
6035
6036
6037
6038
6039
6040
6041
6042

6043
6044
6045
6046
6047
6048
6049
#endif

  /* For each term in the FROM clause, do two things:
  ** (1) Authorized unreferenced tables
  ** (2) Generate code for all sub-queries
  */
  for(i=0; i<pTabList->nSrc; i++){
    struct SrcList_item *pItem = &pTabList->a[i];

    SelectDest dest;
    Select *pSub;
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
    const char *zSavedAuthContext;
#endif

    /* Issue SQLITE_READ authorizations with a fake column name for any







|
>







6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
#endif

  /* For each term in the FROM clause, do two things:
  ** (1) Authorized unreferenced tables
  ** (2) Generate code for all sub-queries
  */
  for(i=0; i<pTabList->nSrc; i++){
    SrcItem *pItem = &pTabList->a[i];
    SrcItem *pPrior;
    SelectDest dest;
    Select *pSub;
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
    const char *zSavedAuthContext;
#endif

    /* Issue SQLITE_READ authorizations with a fake column name for any
6095
6096
6097
6098
6099
6100
6101

6102
6103
6104
6105
6106
6107
6108
6109
6110
6111

6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123

6124
6125
6126
6127
6128
6129
6130

6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149



















6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
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
6211
6212
6213
    */
    pParse->nHeight += sqlite3SelectExprHeight(p);

    /* Make copies of constant WHERE-clause terms in the outer query down
    ** inside the subquery.  This can help the subquery to run more efficiently.
    */
    if( OptimizationEnabled(db, SQLITE_PushDown)

     && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor,
                           (pItem->fg.jointype & JT_OUTER)!=0)
    ){
#if SELECTTRACE_ENABLED
      if( sqlite3_unsupported_selecttrace & 0x100 ){
        SELECTTRACE(0x100,pParse,p,
            ("After WHERE-clause push-down into subquery %d:\n", pSub->selId));
        sqlite3TreeViewSelect(0, p, 0);
      }
#endif

    }else{
      SELECTTRACE(0x100,pParse,p,("Push-down not possible\n"));
    }

    zSavedAuthContext = pParse->zAuthContext;
    pParse->zAuthContext = pItem->zName;

    /* Generate code to implement the subquery
    **
    ** The subquery is implemented as a co-routine if the subquery is
    ** guaranteed to be the outer loop (so that it does not need to be
    ** computed more than once)

    **
    ** TODO: Are there other reasons beside (1) to use a co-routine
    ** implementation?
    */
    if( i==0
     && (pTabList->nSrc==1
            || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0)  /* (1) */

    ){
      /* Implement a co-routine that will return a single row of the result
      ** set on each invocation.
      */
      int addrTop = sqlite3VdbeCurrentAddr(v)+1;
     
      pItem->regReturn = ++pParse->nMem;
      sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop);
      VdbeComment((v, "%s", pItem->pTab->zName));
      pItem->addrFillSub = addrTop;
      sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
      ExplainQueryPlan((pParse, 1, "CO-ROUTINE %u", pSub->selId));
      sqlite3Select(pParse, pSub, &dest);
      pItem->pTab->nRowLogEst = pSub->nSelectRow;
      pItem->fg.viaCoroutine = 1;
      pItem->regResult = dest.iSdst;
      sqlite3VdbeEndCoroutine(v, pItem->regReturn);
      sqlite3VdbeJumpHere(v, addrTop-1);
      sqlite3ClearTempRegCache(pParse);



















    }else{
      /* Generate a subroutine that will fill an ephemeral table with
      ** the content of this subquery.  pItem->addrFillSub will point
      ** to the address of the generated subroutine.  pItem->regReturn
      ** is a register allocated to hold the subroutine return address
      */
      int topAddr;
      int onceAddr = 0;
      int retAddr;
      struct SrcList_item *pPrior;

      testcase( pItem->addrFillSub==0 ); /* Ticket c52b09c7f38903b1311 */
      pItem->regReturn = ++pParse->nMem;
      topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
      pItem->addrFillSub = topAddr+1;
      if( pItem->fg.isCorrelated==0 ){
        /* If the subquery is not correlated and if we are not inside of
        ** a trigger, then we only need to compute the value of the subquery
        ** once. */
        onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
        VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName));
      }else{
        VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName));
      }
      pPrior = isSelfJoinView(pTabList, pItem);
      if( pPrior ){
        sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor);
        assert( pPrior->pSelect!=0 );
        pSub->nSelectRow = pPrior->pSelect->nSelectRow;
      }else{
        sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
        ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId));
        sqlite3Select(pParse, pSub, &dest);
      }
      pItem->pTab->nRowLogEst = pSub->nSelectRow;
      if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
      retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
      VdbeComment((v, "end %s", pItem->pTab->zName));
      sqlite3VdbeChangeP1(v, topAddr, retAddr);
      sqlite3ClearTempRegCache(pParse);







    }
    if( db->mallocFailed ) goto select_end;
    pParse->nHeight -= sqlite3SelectExprHeight(p);
    pParse->zAuthContext = zSavedAuthContext;
#endif
  }

  /* Various elements of the SELECT copied into local variables for
  ** convenience */
  pEList = p->pEList;
  pWhere = p->pWhere;
  pGroupBy = p->pGroupBy;
  pHaving = p->pHaving;
  sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0;

#if SELECTTRACE_ENABLED
  if( sqlite3_unsupported_selecttrace & 0x400 ){
    SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif

  /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and 
  ** if the select-list is the same as the ORDER BY list, then this query







>




|





>









|
|
|
>

|





>



















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
<
<
<
<



<














<
<
<
<
<
<
|
|
|
<






>
>
>
>
>
>
>
















|







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
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
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
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
    */
    pParse->nHeight += sqlite3SelectExprHeight(p);

    /* Make copies of constant WHERE-clause terms in the outer query down
    ** inside the subquery.  This can help the subquery to run more efficiently.
    */
    if( OptimizationEnabled(db, SQLITE_PushDown)
     && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes)
     && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor,
                           (pItem->fg.jointype & JT_OUTER)!=0)
    ){
#if SELECTTRACE_ENABLED
      if( sqlite3SelectTrace & 0x100 ){
        SELECTTRACE(0x100,pParse,p,
            ("After WHERE-clause push-down into subquery %d:\n", pSub->selId));
        sqlite3TreeViewSelect(0, p, 0);
      }
#endif
      assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 );
    }else{
      SELECTTRACE(0x100,pParse,p,("Push-down not possible\n"));
    }

    zSavedAuthContext = pParse->zAuthContext;
    pParse->zAuthContext = pItem->zName;

    /* Generate code to implement the subquery
    **
    ** The subquery is implemented as a co-routine if:
    **    (1)  the subquery is guaranteed to be the outer loop (so that
    **         it does not need to be computed more than once), and
    **    (2)  the subquery is not a CTE that should be materialized
    **
    ** TODO: Are there other reasons beside (1) and (2) to use a co-routine
    ** implementation?
    */
    if( i==0
     && (pTabList->nSrc==1
            || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0)  /* (1) */
     && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes)  /* (2) */
    ){
      /* Implement a co-routine that will return a single row of the result
      ** set on each invocation.
      */
      int addrTop = sqlite3VdbeCurrentAddr(v)+1;
     
      pItem->regReturn = ++pParse->nMem;
      sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop);
      VdbeComment((v, "%s", pItem->pTab->zName));
      pItem->addrFillSub = addrTop;
      sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
      ExplainQueryPlan((pParse, 1, "CO-ROUTINE %u", pSub->selId));
      sqlite3Select(pParse, pSub, &dest);
      pItem->pTab->nRowLogEst = pSub->nSelectRow;
      pItem->fg.viaCoroutine = 1;
      pItem->regResult = dest.iSdst;
      sqlite3VdbeEndCoroutine(v, pItem->regReturn);
      sqlite3VdbeJumpHere(v, addrTop-1);
      sqlite3ClearTempRegCache(pParse);
    }else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){
      /* This is a CTE for which materialization code has already been
      ** generated.  Invoke the subroutine to compute the materialization,
      ** the make the pItem->iCursor be a copy of the ephemerial table that
      ** holds the result of the materialization. */
      CteUse *pCteUse = pItem->u2.pCteUse;
      sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e);
      if( pItem->iCursor!=pCteUse->iCur ){
        sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pCteUse->iCur);
      }
      pSub->nSelectRow = pCteUse->nRowEst;
    }else if( (pPrior = isSelfJoinView(pTabList, pItem))!=0 ){
      /* This view has already been materialized by a prior entry in
      ** this same FROM clause.  Reuse it. */
      if( pPrior->addrFillSub ){
        sqlite3VdbeAddOp2(v, OP_Gosub, pPrior->regReturn, pPrior->addrFillSub);
      }
      sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor);
      pSub->nSelectRow = pPrior->pSelect->nSelectRow;
    }else{
      /* Generate a subroutine that will materialize the view. */




      int topAddr;
      int onceAddr = 0;
      int retAddr;


      testcase( pItem->addrFillSub==0 ); /* Ticket c52b09c7f38903b1311 */
      pItem->regReturn = ++pParse->nMem;
      topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
      pItem->addrFillSub = topAddr+1;
      if( pItem->fg.isCorrelated==0 ){
        /* If the subquery is not correlated and if we are not inside of
        ** a trigger, then we only need to compute the value of the subquery
        ** once. */
        onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
        VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName));
      }else{
        VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName));
      }






      sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
      ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId));
      sqlite3Select(pParse, pSub, &dest);

      pItem->pTab->nRowLogEst = pSub->nSelectRow;
      if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
      retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
      VdbeComment((v, "end %s", pItem->pTab->zName));
      sqlite3VdbeChangeP1(v, topAddr, retAddr);
      sqlite3ClearTempRegCache(pParse);
      if( pItem->fg.isCte ){
        CteUse *pCteUse = pItem->u2.pCteUse;
        pCteUse->addrM9e = pItem->addrFillSub;
        pCteUse->regRtn = pItem->regReturn;
        pCteUse->iCur = pItem->iCursor;
        pCteUse->nRowEst = pSub->nSelectRow;
      }
    }
    if( db->mallocFailed ) goto select_end;
    pParse->nHeight -= sqlite3SelectExprHeight(p);
    pParse->zAuthContext = zSavedAuthContext;
#endif
  }

  /* Various elements of the SELECT copied into local variables for
  ** convenience */
  pEList = p->pEList;
  pWhere = p->pWhere;
  pGroupBy = p->pGroupBy;
  pHaving = p->pHaving;
  sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0;

#if SELECTTRACE_ENABLED
  if( sqlite3SelectTrace & 0x400 ){
    SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif

  /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and 
  ** if the select-list is the same as the ORDER BY list, then this query
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
    p->selFlags |= SF_Aggregate;
    /* Notice that even thought SF_Distinct has been cleared from p->selFlags,
    ** the sDistinct.isTnct is still set.  Hence, isTnct represents the
    ** original setting of the SF_Distinct flag, not the current setting */
    assert( sDistinct.isTnct );

#if SELECTTRACE_ENABLED
    if( sqlite3_unsupported_selecttrace & 0x400 ){
      SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
      sqlite3TreeViewSelect(0, p, 0);
    }
#endif
  }

  /* If there is an ORDER BY clause, then create an ephemeral index to







|







6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
    p->selFlags |= SF_Aggregate;
    /* Notice that even thought SF_Distinct has been cleared from p->selFlags,
    ** the sDistinct.isTnct is still set.  Hence, isTnct represents the
    ** original setting of the SF_Distinct flag, not the current setting */
    assert( sDistinct.isTnct );

#if SELECTTRACE_ENABLED
    if( sqlite3SelectTrace & 0x400 ){
      SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
      sqlite3TreeViewSelect(0, p, 0);
    }
#endif
  }

  /* If there is an ORDER BY clause, then create an ephemeral index to
6327
6328
6329
6330
6331
6332
6333

6334
6335
6336
6337
6338
6339
6340
    if( sSort.pOrderBy ){
      sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo);
      sSort.labelOBLopt = sqlite3WhereOrderByLimitOptLabel(pWInfo);
      if( sSort.nOBSat==sSort.pOrderBy->nExpr ){
        sSort.pOrderBy = 0;
      }
    }


    /* If sorting index that was created by a prior OP_OpenEphemeral 
    ** instruction ended up not being needed, then change the OP_OpenEphemeral
    ** into an OP_Noop.
    */
    if( sSort.addrSortIndex>=0 && sSort.pOrderBy==0 ){
      sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex);







>







6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
    if( sSort.pOrderBy ){
      sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo);
      sSort.labelOBLopt = sqlite3WhereOrderByLimitOptLabel(pWInfo);
      if( sSort.nOBSat==sSort.pOrderBy->nExpr ){
        sSort.pOrderBy = 0;
      }
    }
    SELECTTRACE(1,pParse,p,("WhereBegin returns\n"));

    /* If sorting index that was created by a prior OP_OpenEphemeral 
    ** instruction ended up not being needed, then change the OP_OpenEphemeral
    ** into an OP_Noop.
    */
    if( sSort.addrSortIndex>=0 && sSort.pOrderBy==0 ){
      sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex);
6365
6366
6367
6368
6369
6370
6371

6372
6373
6374
6375
6376
6377
6378
      /* Use the standard inner loop. */
      selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest,
          sqlite3WhereContinueLabel(pWInfo),
          sqlite3WhereBreakLabel(pWInfo));

      /* End the database scan loop.
      */

      sqlite3WhereEnd(pWInfo);
    }
  }else{
    /* This case when there exist aggregate functions or a GROUP BY clause
    ** or both */
    NameContext sNC;    /* Name context for processing aggregate information */
    int iAMem;          /* First Mem address for storing current GROUP BY */







>







6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
      /* Use the standard inner loop. */
      selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest,
          sqlite3WhereContinueLabel(pWInfo),
          sqlite3WhereBreakLabel(pWInfo));

      /* End the database scan loop.
      */
      SELECTTRACE(1,pParse,p,("WhereEnd\n"));
      sqlite3WhereEnd(pWInfo);
    }
  }else{
    /* This case when there exist aggregate functions or a GROUP BY clause
    ** or both */
    NameContext sNC;    /* Name context for processing aggregate information */
    int iAMem;          /* First Mem address for storing current GROUP BY */
6435
6436
6437
6438
6439
6440
6441
6442





6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
    addrEnd = sqlite3VdbeMakeLabel(pParse);

    /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in
    ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the
    ** SELECT statement.
    */
    pAggInfo = sqlite3DbMallocZero(db, sizeof(*pAggInfo) );
    if( pAggInfo==0 ){





      goto select_end;
    }
    pAggInfo->pNext = pParse->pAggList;
    pParse->pAggList = pAggInfo;
    pAggInfo->selId = p->selId;
    memset(&sNC, 0, sizeof(sNC));
    sNC.pParse = pParse;
    sNC.pSrcList = pTabList;
    sNC.uNC.pAggInfo = pAggInfo;
    VVA_ONLY( sNC.ncFlags = NC_UAggInfo; )
    pAggInfo->mnReg = pParse->nMem+1;







|
>
>
>
>
>


<
<







6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674


6675
6676
6677
6678
6679
6680
6681
    addrEnd = sqlite3VdbeMakeLabel(pParse);

    /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in
    ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the
    ** SELECT statement.
    */
    pAggInfo = sqlite3DbMallocZero(db, sizeof(*pAggInfo) );
    if( pAggInfo ){
      sqlite3ParserAddCleanup(pParse,
          (void(*)(sqlite3*,void*))agginfoFree, pAggInfo);
      testcase( pParse->earlyCleanup );
    }
    if( db->mallocFailed ){
      goto select_end;
    }


    pAggInfo->selId = p->selId;
    memset(&sNC, 0, sizeof(sNC));
    sNC.pParse = pParse;
    sNC.pSrcList = pTabList;
    sNC.uNC.pAggInfo = pAggInfo;
    VVA_ONLY( sNC.ncFlags = NC_UAggInfo; )
    pAggInfo->mnReg = pParse->nMem+1;
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493




6494
6495
6496
6497
6498
6499
6500
      }
#endif
      sNC.ncFlags &= ~NC_InAggFunc;
    }
    pAggInfo->mxReg = pParse->nMem;
    if( db->mallocFailed ) goto select_end;
#if SELECTTRACE_ENABLED
    if( sqlite3_unsupported_selecttrace & 0x400 ){
      int ii;
      SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", pAggInfo));
      sqlite3TreeViewSelect(0, p, 0);




      for(ii=0; ii<pAggInfo->nColumn; ii++){
        sqlite3DebugPrintf("agg-column[%d] iMem=%d\n",
            ii, pAggInfo->aCol[ii].iMem);
        sqlite3TreeViewExpr(0, pAggInfo->aCol[ii].pCExpr, 0);
      }
      for(ii=0; ii<pAggInfo->nFunc; ii++){
        sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n",







|



>
>
>
>







6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
      }
#endif
      sNC.ncFlags &= ~NC_InAggFunc;
    }
    pAggInfo->mxReg = pParse->nMem;
    if( db->mallocFailed ) goto select_end;
#if SELECTTRACE_ENABLED
    if( sqlite3SelectTrace & 0x400 ){
      int ii;
      SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", pAggInfo));
      sqlite3TreeViewSelect(0, p, 0);
      if( minMaxFlag ){
        sqlite3DebugPrintf("MIN/MAX Optimization (0x%02x) adds:\n", minMaxFlag);
        sqlite3TreeViewExprList(0, pMinMaxOrderBy, 0, "ORDERBY");
      }
      for(ii=0; ii<pAggInfo->nColumn; ii++){
        sqlite3DebugPrintf("agg-column[%d] iMem=%d\n",
            ii, pAggInfo->aCol[ii].iMem);
        sqlite3TreeViewExpr(0, pAggInfo->aCol[ii].pCExpr, 0);
      }
      for(ii=0; ii<pAggInfo->nFunc; ii++){
        sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n",
6554
6555
6556
6557
6558
6559
6560

6561
6562
6563
6564
6565
6566
6567
      */
      sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
      SELECTTRACE(1,pParse,p,("WhereBegin\n"));
      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0,
          WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0
      );
      if( pWInfo==0 ) goto select_end;

      if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){
        /* The optimizer is able to deliver rows in group by order so
        ** we do not have to sort.  The OP_OpenEphemeral table will be
        ** cancelled later because we still need to use the pKeyInfo
        */
        groupBySort = 0;
      }else{







>







6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
      */
      sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
      SELECTTRACE(1,pParse,p,("WhereBegin\n"));
      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0,
          WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0
      );
      if( pWInfo==0 ) goto select_end;
      SELECTTRACE(1,pParse,p,("WhereBegin returns\n"));
      if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){
        /* The optimizer is able to deliver rows in group by order so
        ** we do not have to sort.  The OP_OpenEphemeral table will be
        ** cancelled later because we still need to use the pKeyInfo
        */
        groupBySort = 0;
      }else{
6602
6603
6604
6605
6606
6607
6608

6609
6610
6611
6612
6613
6614
6615
          }
        }
        regRecord = sqlite3GetTempReg(pParse);
        sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord);
        sqlite3VdbeAddOp2(v, OP_SorterInsert, pAggInfo->sortingIdx, regRecord);
        sqlite3ReleaseTempReg(pParse, regRecord);
        sqlite3ReleaseTempRange(pParse, regBase, nCol);

        sqlite3WhereEnd(pWInfo);
        pAggInfo->sortingIdxPTab = sortPTab = pParse->nTab++;
        sortOut = sqlite3GetTempReg(pParse);
        sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol);
        sqlite3VdbeAddOp2(v, OP_SorterSort, pAggInfo->sortingIdx, addrEnd);
        VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v);
        pAggInfo->useSortingIdx = 1;







>







6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
          }
        }
        regRecord = sqlite3GetTempReg(pParse);
        sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord);
        sqlite3VdbeAddOp2(v, OP_SorterInsert, pAggInfo->sortingIdx, regRecord);
        sqlite3ReleaseTempReg(pParse, regRecord);
        sqlite3ReleaseTempRange(pParse, regBase, nCol);
        SELECTTRACE(1,pParse,p,("WhereEnd\n"));
        sqlite3WhereEnd(pWInfo);
        pAggInfo->sortingIdxPTab = sortPTab = pParse->nTab++;
        sortOut = sqlite3GetTempReg(pParse);
        sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol);
        sqlite3VdbeAddOp2(v, OP_SorterSort, pAggInfo->sortingIdx, addrEnd);
        VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v);
        pAggInfo->useSortingIdx = 1;
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685

6686
6687
6688
6689
6690
6691
6692
      updateAccumulator(pParse, iUseFlag, pAggInfo);
      sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag);
      VdbeComment((v, "indicate data in accumulator"));

      /* End of the loop
      */
      if( groupBySort ){
        sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx, addrTopOfLoop);
        VdbeCoverage(v);
      }else{

        sqlite3WhereEnd(pWInfo);
        sqlite3VdbeChangeToNoop(v, addrSortingIdx);
      }

      /* Output the final row of result
      */
      sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);







|


>







6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
      updateAccumulator(pParse, iUseFlag, pAggInfo);
      sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag);
      VdbeComment((v, "indicate data in accumulator"));

      /* End of the loop
      */
      if( groupBySort ){
        sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx,addrTopOfLoop);
        VdbeCoverage(v);
      }else{
        SELECTTRACE(1,pParse,p,("WhereEnd\n"));
        sqlite3WhereEnd(pWInfo);
        sqlite3VdbeChangeToNoop(v, addrSortingIdx);
      }

      /* Output the final row of result
      */
      sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
          sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO);
        }
        sqlite3VdbeAddOp2(v, OP_Count, iCsr, pAggInfo->aFunc[0].iMem);
        sqlite3VdbeAddOp1(v, OP_Close, iCsr);
        explainSimpleCount(pParse, pTab, pBest);
      }else{
        int regAcc = 0;           /* "populate accumulators" flag */
        int addrSkip;

        /* If there are accumulator registers but no min() or max() functions
        ** without FILTER clauses, allocate register regAcc. Register regAcc
        ** will contain 0 the first time the inner loop runs, and 1 thereafter.
        ** The code generated by updateAccumulator() uses this to ensure
        ** that the accumulator registers are (a) updated only once if
        ** there are no min() or max functions or (b) always updated for the







<







7023
7024
7025
7026
7027
7028
7029

7030
7031
7032
7033
7034
7035
7036
          sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO);
        }
        sqlite3VdbeAddOp2(v, OP_Count, iCsr, pAggInfo->aFunc[0].iMem);
        sqlite3VdbeAddOp1(v, OP_Close, iCsr);
        explainSimpleCount(pParse, pTab, pBest);
      }else{
        int regAcc = 0;           /* "populate accumulators" flag */


        /* If there are accumulator registers but no min() or max() functions
        ** without FILTER clauses, allocate register regAcc. Register regAcc
        ** will contain 0 the first time the inner loop runs, and 1 thereafter.
        ** The code generated by updateAccumulator() uses this to ensure
        ** that the accumulator registers are (a) updated only once if
        ** there are no min() or max functions or (b) always updated for the
6835
6836
6837
6838
6839
6840
6841

6842
6843
6844
6845
6846
6847

6848
6849
6850
6851
6852
6853
6854

        SELECTTRACE(1,pParse,p,("WhereBegin\n"));
        pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy,
                                   0, minMaxFlag, 0);
        if( pWInfo==0 ){
          goto select_end;
        }

        updateAccumulator(pParse, regAcc, pAggInfo);
        if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc);
        addrSkip = sqlite3WhereOrderByLimitOptLabel(pWInfo);
        if( addrSkip!=sqlite3WhereContinueLabel(pWInfo) ){
          sqlite3VdbeGoto(v, addrSkip);
        }

        sqlite3WhereEnd(pWInfo);
        finalizeAggFunctions(pParse, pAggInfo);
      }

      sSort.pOrderBy = 0;
      sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
      selectInnerLoop(pParse, p, -1, 0, 0, 







>


<
|
|

>







7069
7070
7071
7072
7073
7074
7075
7076
7077
7078

7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089

        SELECTTRACE(1,pParse,p,("WhereBegin\n"));
        pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy,
                                   0, minMaxFlag, 0);
        if( pWInfo==0 ){
          goto select_end;
        }
        SELECTTRACE(1,pParse,p,("WhereBegin returns\n"));
        updateAccumulator(pParse, regAcc, pAggInfo);
        if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc);

        if( minMaxFlag ){
          sqlite3WhereMinMaxOptEarlyOut(v, pWInfo);
        }
        SELECTTRACE(1,pParse,p,("WhereEnd\n"));
        sqlite3WhereEnd(pWInfo);
        finalizeAggFunctions(pParse, pAggInfo);
      }

      sSort.pOrderBy = 0;
      sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
      selectInnerLoop(pParse, p, -1, 0, 0, 
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
  */
select_end:
  sqlite3ExprListDelete(db, pMinMaxOrderBy);
#ifdef SQLITE_DEBUG
  if( pAggInfo && !db->mallocFailed ){
    for(i=0; i<pAggInfo->nColumn; i++){
      Expr *pExpr = pAggInfo->aCol[i].pCExpr;
      assert( pExpr!=0 || db->mallocFailed );
      if( pExpr==0 ) continue;
      assert( pExpr->pAggInfo==pAggInfo );
      assert( pExpr->iAgg==i );
    }
    for(i=0; i<pAggInfo->nFunc; i++){
      Expr *pExpr = pAggInfo->aFunc[i].pFExpr;
      assert( pExpr!=0 || db->mallocFailed );
      if( pExpr==0 ) continue;
      assert( pExpr->pAggInfo==pAggInfo );
      assert( pExpr->iAgg==i );
    }
  }
#endif

#if SELECTTRACE_ENABLED
  SELECTTRACE(0x1,pParse,p,("end processing\n"));
  if( (sqlite3_unsupported_selecttrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif
  ExplainQueryPlanPop(pParse);
  return rc;
}







|
<





|
<








|






7120
7121
7122
7123
7124
7125
7126
7127

7128
7129
7130
7131
7132
7133

7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
  */
select_end:
  sqlite3ExprListDelete(db, pMinMaxOrderBy);
#ifdef SQLITE_DEBUG
  if( pAggInfo && !db->mallocFailed ){
    for(i=0; i<pAggInfo->nColumn; i++){
      Expr *pExpr = pAggInfo->aCol[i].pCExpr;
      assert( pExpr!=0 );

      assert( pExpr->pAggInfo==pAggInfo );
      assert( pExpr->iAgg==i );
    }
    for(i=0; i<pAggInfo->nFunc; i++){
      Expr *pExpr = pAggInfo->aFunc[i].pFExpr;
      assert( pExpr!=0 );

      assert( pExpr->pAggInfo==pAggInfo );
      assert( pExpr->iAgg==i );
    }
  }
#endif

#if SELECTTRACE_ENABLED
  SELECTTRACE(0x1,pParse,p,("end processing\n"));
  if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif
  ExplainQueryPlanPop(pParse);
  return rc;
}
Changes to src/shell.c.in.
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093

1094
1095
1096
1097
1098
1099
1100
typedef struct ShellState ShellState;
struct ShellState {
  sqlite3 *db;           /* The database */
  u8 autoExplain;        /* Automatically turn on .explain mode */
  u8 autoEQP;            /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
  u8 autoEQPtest;        /* autoEQP is in test mode */
  u8 autoEQPtrace;       /* autoEQP is in trace mode */
  u8 statsOn;            /* True to display memory stats before each finalize */
  u8 scanstatsOn;        /* True to display scan stats before each finalize */
  u8 openMode;           /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */
  u8 doXdgOpen;          /* Invoke start/open/xdg-open in output_reset() */
  u8 nEqpLevel;          /* Depth of the EQP output graph */
  u8 eTraceType;         /* SHELL_TRACE_* value for type of trace */

  unsigned mEqpLines;    /* Mask of veritical lines in the EQP output graph */
  int outCount;          /* Revert to stdout when reaching zero */
  int cnt;               /* Number of records displayed so far */
  int lineno;            /* Line number of last line read from in */
  int openFlags;         /* Additional flags to open.  (SQLITE_OPEN_NOFOLLOW) */
  FILE *in;              /* Read commands from this stream */
  FILE *out;             /* Write results here */







<





>







1081
1082
1083
1084
1085
1086
1087

1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
typedef struct ShellState ShellState;
struct ShellState {
  sqlite3 *db;           /* The database */
  u8 autoExplain;        /* Automatically turn on .explain mode */
  u8 autoEQP;            /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
  u8 autoEQPtest;        /* autoEQP is in test mode */
  u8 autoEQPtrace;       /* autoEQP is in trace mode */

  u8 scanstatsOn;        /* True to display scan stats before each finalize */
  u8 openMode;           /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */
  u8 doXdgOpen;          /* Invoke start/open/xdg-open in output_reset() */
  u8 nEqpLevel;          /* Depth of the EQP output graph */
  u8 eTraceType;         /* SHELL_TRACE_* value for type of trace */
  unsigned statsOn;      /* True to display memory stats before each finalize */
  unsigned mEqpLines;    /* Mask of veritical lines in the EQP output graph */
  int outCount;          /* Revert to stdout when reaching zero */
  int cnt;               /* Number of records displayed so far */
  int lineno;            /* Line number of last line read from in */
  int openFlags;         /* Additional flags to open.  (SQLITE_OPEN_NOFOLLOW) */
  FILE *in;              /* Read commands from this stream */
  FILE *out;             /* Write results here */
2023
2024
2025
2026
2027
2028
2029

2030
2031
2032
2033
2034
2035
2036
          print_dashes(p->out, w);
          fputs(i==nArg-1 ? "\n" : "  ", p->out);
        }
      }
      if( azArg==0 ) break;
      for(i=0; i<nArg; i++){
        int w = aExplainWidth[i];

        if( azArg[i] && strlenChar(azArg[i])>w ){
          w = strlenChar(azArg[i]);
        }
        if( i==1 && p->aiIndent && p->pStmt ){
          if( p->iIndent<p->nIndent ){
            utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
          }







>







2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
          print_dashes(p->out, w);
          fputs(i==nArg-1 ? "\n" : "  ", p->out);
        }
      }
      if( azArg==0 ) break;
      for(i=0; i<nArg; i++){
        int w = aExplainWidth[i];
        if( i==nArg-1 ) w = 0;
        if( azArg[i] && strlenChar(azArg[i])>w ){
          w = strlenChar(azArg[i]);
        }
        if( i==1 && p->aiIndent && p->pStmt ){
          if( p->iIndent<p->nIndent ){
            utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
          }
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
){
  int iCur;
  int iHiwtr;
  FILE *out;
  if( pArg==0 || pArg->out==0 ) return 0;
  out = pArg->out;

  if( pArg->pStmt && (pArg->statsOn & 2) ){
    int nCol, i, x;
    sqlite3_stmt *pStmt = pArg->pStmt;
    char z[100];
    nCol = sqlite3_column_count(pStmt);
    raw_printf(out, "%-36s %d\n", "Number of output columns:", nCol);
    for(i=0; i<nCol; i++){
      sqlite3_snprintf(sizeof(z),z,"Column %d %nname:", i, &x);







|







2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
){
  int iCur;
  int iHiwtr;
  FILE *out;
  if( pArg==0 || pArg->out==0 ) return 0;
  out = pArg->out;

  if( pArg->pStmt && pArg->statsOn==2 ){
    int nCol, i, x;
    sqlite3_stmt *pStmt = pArg->pStmt;
    char z[100];
    nCol = sqlite3_column_count(pStmt);
    raw_printf(out, "%-36s %d\n", "Number of output columns:", nCol);
    for(i=0; i<nCol; i++){
      sqlite3_snprintf(sizeof(z),z,"Column %d %nname:", i, &x);
2610
2611
2612
2613
2614
2615
2616








2617
2618
2619
2620
2621
2622
2623
      sqlite3_snprintf(30, z+x, "table name:");
      utf8_printf(out, "%-36s %s\n", z, sqlite3_column_table_name(pStmt,i));
      sqlite3_snprintf(30, z+x, "origin name:");
      utf8_printf(out, "%-36s %s\n", z, sqlite3_column_origin_name(pStmt,i));
#endif
    }
  }









  displayStatLine(pArg, "Memory Used:",
     "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset);
  displayStatLine(pArg, "Number of Outstanding Allocations:",
     "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset);
  if( pArg->shellFlgs & SHFLG_Pagecache ){
    displayStatLine(pArg, "Number of Pcache Pages Used:",







>
>
>
>
>
>
>
>







2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
      sqlite3_snprintf(30, z+x, "table name:");
      utf8_printf(out, "%-36s %s\n", z, sqlite3_column_table_name(pStmt,i));
      sqlite3_snprintf(30, z+x, "origin name:");
      utf8_printf(out, "%-36s %s\n", z, sqlite3_column_origin_name(pStmt,i));
#endif
    }
  }

  if( pArg->statsOn==3 ){
    if( pArg->pStmt ){
      iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
      raw_printf(pArg->out, "VM-steps: %d\n", iCur);
    }
    return 0;
  }

  displayStatLine(pArg, "Memory Used:",
     "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset);
  displayStatLine(pArg, "Number of Outstanding Allocations:",
     "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset);
  if( pArg->shellFlgs & SHFLG_Pagecache ){
    displayStatLine(pArg, "Number of Pcache Pages Used:",
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
  p->nIndent = 0;
  p->iIndent = 0;
}

/*
** Disable and restore .wheretrace and .selecttrace settings.
*/
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
extern unsigned int sqlite3_unsupported_selecttrace;
static int savedSelectTrace;
#endif
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
extern int sqlite3WhereTrace;
static int savedWhereTrace;
#endif
static void disable_debug_trace_modes(void){
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)

  savedSelectTrace = sqlite3_unsupported_selecttrace;
  sqlite3_unsupported_selecttrace = 0;
#endif
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
  savedWhereTrace = sqlite3WhereTrace;
  sqlite3WhereTrace = 0;
#endif
}
static void restore_debug_trace_modes(void){
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
  sqlite3_unsupported_selecttrace = savedSelectTrace;
#endif
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
  sqlite3WhereTrace = savedWhereTrace;
#endif
}

/* Create the TEMP table used to store parameter bindings */
static void bind_table_init(ShellState *p){
  int wrSchema = 0;
  int defensiveMode = 0;
  sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, -1, &defensiveMode);







<
<
|
<
<
<
|
<

<
>
|
|
<
<
|
|
<


<
|
<
<
|
<







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
  p->nIndent = 0;
  p->iIndent = 0;
}

/*
** Disable and restore .wheretrace and .selecttrace settings.
*/


static unsigned int savedSelectTrace;



static unsigned int savedWhereTrace;

static void disable_debug_trace_modes(void){

  unsigned int zero = 0;
  sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 0, &savedSelectTrace);
  sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &zero);


  sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 2, &savedWhereTrace);
  sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &zero);

}
static void restore_debug_trace_modes(void){

  sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &savedSelectTrace);


  sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &savedWhereTrace);

}

/* Create the TEMP table used to store parameter bindings */
static void bind_table_init(ShellState *p){
  int wrSchema = 0;
  int defensiveMode = 0;
  sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, -1, &defensiveMode);
4056
4057
4058
4059
4060
4061
4062
4063




4064
4065
4066
4067
4068
4069
4070
  "      --sha3-384            Use the sha3-384 algorithm",
  "      --sha3-512            Use the sha3-512 algorithm",
  "    Any other argument is a LIKE pattern for tables to hash",
#ifndef SQLITE_NOHAVE_SYSTEM
  ".shell CMD ARGS...       Run CMD ARGS... in a system shell",
#endif
  ".show                    Show the current values for various settings",
  ".stats ?on|off?          Show stats or turn stats on or off",




#ifndef SQLITE_NOHAVE_SYSTEM
  ".system CMD ARGS...      Run CMD ARGS... in a system shell",
#endif
  ".tables ?TABLE?          List names of tables matching LIKE pattern TABLE",
  ".testcase NAME           Begin redirecting output to 'testcase-out.txt'",
  ".testctrl CMD ...        Run various sqlite3_test_control() operations",
  "                           Run \".testctrl\" with no arguments for details",







|
>
>
>
>







4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
  "      --sha3-384            Use the sha3-384 algorithm",
  "      --sha3-512            Use the sha3-512 algorithm",
  "    Any other argument is a LIKE pattern for tables to hash",
#ifndef SQLITE_NOHAVE_SYSTEM
  ".shell CMD ARGS...       Run CMD ARGS... in a system shell",
#endif
  ".show                    Show the current values for various settings",
  ".stats ?ARG?             Show stats or turn stats on or off",
  "   off                      Turn off automatic stat display",
  "   on                       Turn on automatic stat display",
  "   stmt                     Show statement stats",
  "   vmstep                   Show the virtual machine step count only",
#ifndef SQLITE_NOHAVE_SYSTEM
  ".system CMD ARGS...      Run CMD ARGS... in a system shell",
#endif
  ".tables ?TABLE?          List names of tables matching LIKE pattern TABLE",
  ".testcase NAME           Begin redirecting output to 'testcase-out.txt'",
  ".testctrl CMD ...        Run various sqlite3_test_control() operations",
  "                           Run \".testctrl\" with no arguments for details",
7872
7873
7874
7875
7876
7877
7878
7879
7880
7881


7882

7883
7884

7885
7886
7887
7888
7889
7890
7891
7892
7893
7894
7895

  if( c=='f' && strncmp(azArg[0], "filectrl", n)==0 ){
    static const struct {
       const char *zCtrlName;   /* Name of a test-control option */
       int ctrlCode;            /* Integer code for that option */
       const char *zUsage;      /* Usage notes */
    } aCtrl[] = {
      { "size_limit",     SQLITE_FCNTL_SIZE_LIMIT,      "[LIMIT]"        },
      { "chunk_size",     SQLITE_FCNTL_CHUNK_SIZE,      "SIZE"           },
   /* { "win32_av_retry", SQLITE_FCNTL_WIN32_AV_RETRY,  "COUNT DELAY"    },*/


      { "persist_wal",    SQLITE_FCNTL_PERSIST_WAL,     "[BOOLEAN]"      },

      { "psow",       SQLITE_FCNTL_POWERSAFE_OVERWRITE, "[BOOLEAN]"      },
   /* { "pragma",         SQLITE_FCNTL_PRAGMA,          "NAME ARG"       },*/

      { "tempfilename",   SQLITE_FCNTL_TEMPFILENAME,    ""               },
      { "has_moved",      SQLITE_FCNTL_HAS_MOVED,       ""               },  
      { "lock_timeout",   SQLITE_FCNTL_LOCK_TIMEOUT,    "MILLISEC"       },
      { "reserve_bytes",  SQLITE_FCNTL_RESERVE_BYTES,   "[N]"            },
    };
    int filectrl = -1;
    int iCtrl = -1;
    sqlite3_int64 iRes = 0;  /* Integer result to display if rc2==1 */
    int isOk = 0;            /* 0: usage  1: %lld  2: no-result */
    int n2, i;
    const char *zCmd = 0;







<

|
>
>

>

|
>

|
<
<







7872
7873
7874
7875
7876
7877
7878

7879
7880
7881
7882
7883
7884
7885
7886
7887
7888
7889


7890
7891
7892
7893
7894
7895
7896

  if( c=='f' && strncmp(azArg[0], "filectrl", n)==0 ){
    static const struct {
       const char *zCtrlName;   /* Name of a test-control option */
       int ctrlCode;            /* Integer code for that option */
       const char *zUsage;      /* Usage notes */
    } aCtrl[] = {

      { "chunk_size",     SQLITE_FCNTL_CHUNK_SIZE,      "SIZE"           },
      { "data_version",   SQLITE_FCNTL_DATA_VERSION,    ""               },
      { "has_moved",      SQLITE_FCNTL_HAS_MOVED,       ""               },  
      { "lock_timeout",   SQLITE_FCNTL_LOCK_TIMEOUT,    "MILLISEC"       },
      { "persist_wal",    SQLITE_FCNTL_PERSIST_WAL,     "[BOOLEAN]"      },
   /* { "pragma",         SQLITE_FCNTL_PRAGMA,          "NAME ARG"       },*/
      { "psow",       SQLITE_FCNTL_POWERSAFE_OVERWRITE, "[BOOLEAN]"      },
      { "reserve_bytes",  SQLITE_FCNTL_RESERVE_BYTES,   "[N]"            },
      { "size_limit",     SQLITE_FCNTL_SIZE_LIMIT,      "[LIMIT]"        },
      { "tempfilename",   SQLITE_FCNTL_TEMPFILENAME,    ""               },
   /* { "win32_av_retry", SQLITE_FCNTL_WIN32_AV_RETRY,  "COUNT DELAY"    },*/


    };
    int filectrl = -1;
    int iCtrl = -1;
    sqlite3_int64 iRes = 0;  /* Integer result to display if rc2==1 */
    int isOk = 0;            /* 0: usage  1: %lld  2: no-result */
    int n2, i;
    const char *zCmd = 0;
7968
7969
7970
7971
7972
7973
7974

7975
7976
7977
7978
7979
7980
7981
          if( nArg!=2 && nArg!=3 ) break;
          x = nArg==3 ? booleanValue(azArg[2]) : -1;
          sqlite3_file_control(p->db, zSchema, filectrl, &x);
          iRes = x;
          isOk = 1;
          break;
        }

        case SQLITE_FCNTL_HAS_MOVED: {
          int x;
          if( nArg!=2 ) break;
          sqlite3_file_control(p->db, zSchema, filectrl, &x);
          iRes = x;
          isOk = 1;
          break;







>







7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
          if( nArg!=2 && nArg!=3 ) break;
          x = nArg==3 ? booleanValue(azArg[2]) : -1;
          sqlite3_file_control(p->db, zSchema, filectrl, &x);
          iRes = x;
          isOk = 1;
          break;
        }
        case SQLITE_FCNTL_DATA_VERSION:
        case SQLITE_FCNTL_HAS_MOVED: {
          int x;
          if( nArg!=2 ) break;
          sqlite3_file_control(p->db, zSchema, filectrl, &x);
          iRes = x;
          isOk = 1;
          break;
8676
8677
8678
8679
8680
8681
8682
8683
8684
8685
8686
8687
8688
8689
8690
8691
8692
8693
8694
8695
8696
8697
8698
8699
8700
8701
8702
8703
8704
      raw_printf(p->out, "oomCounter = %d\n", oomCounter);
      raw_printf(p->out, "oomRepeat  = %d\n", oomRepeat);
    }
  }else
#endif /* SQLITE_DEBUG */

  if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
    char *zNewFilename;  /* Name of the database file to open */
    int iName = 1;       /* Index in azArg[] of the filename */
    int newFlag = 0;     /* True to delete file before opening */
    /* Close the existing database */
    session_close_all(p);
    close_db(p->db);
    p->db = 0;
    p->zDbFilename = 0;
    sqlite3_free(p->zFreeOnClose);
    p->zFreeOnClose = 0;
    p->openMode = SHELL_OPEN_UNSPEC;
    p->openFlags = 0;
    p->szMax = 0;
    /* Check for command-line arguments */
    for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
      const char *z = azArg[iName];
      if( optionMatch(z,"new") ){
        newFlag = 1;
#ifdef SQLITE_HAVE_ZLIB
      }else if( optionMatch(z, "zip") ){
        p->openMode = SHELL_OPEN_ZIPFILE;
#endif







|
|
|











|







8678
8679
8680
8681
8682
8683
8684
8685
8686
8687
8688
8689
8690
8691
8692
8693
8694
8695
8696
8697
8698
8699
8700
8701
8702
8703
8704
8705
8706
      raw_printf(p->out, "oomCounter = %d\n", oomCounter);
      raw_printf(p->out, "oomRepeat  = %d\n", oomRepeat);
    }
  }else
#endif /* SQLITE_DEBUG */

  if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
    char *zNewFilename = 0;  /* Name of the database file to open */
    int iName = 1;           /* Index in azArg[] of the filename */
    int newFlag = 0;         /* True to delete file before opening */
    /* Close the existing database */
    session_close_all(p);
    close_db(p->db);
    p->db = 0;
    p->zDbFilename = 0;
    sqlite3_free(p->zFreeOnClose);
    p->zFreeOnClose = 0;
    p->openMode = SHELL_OPEN_UNSPEC;
    p->openFlags = 0;
    p->szMax = 0;
    /* Check for command-line arguments */
    for(iName=1; iName<nArg; iName++){
      const char *z = azArg[iName];
      if( optionMatch(z,"new") ){
        newFlag = 1;
#ifdef SQLITE_HAVE_ZLIB
      }else if( optionMatch(z, "zip") ){
        p->openMode = SHELL_OPEN_ZIPFILE;
#endif
8716
8717
8718
8719
8720
8721
8722






8723
8724
8725
8726
8727
8728
8729
8730
8731
8732
8733
      }else if( optionMatch(z, "maxsize") && iName+1<nArg ){
        p->szMax = integerValue(azArg[++iName]);
#endif /* SQLITE_ENABLE_DESERIALIZE */
      }else if( z[0]=='-' ){
        utf8_printf(stderr, "unknown option: %s\n", z);
        rc = 1;
        goto meta_command_exit;






      }
    }
    /* If a filename is specified, try to open it first */
    zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0;
    if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){
      if( newFlag ) shellDeleteFile(zNewFilename);
      p->zDbFilename = zNewFilename;
      open_db(p, OPEN_DB_KEEPALIVE);
      if( p->db==0 ){
        utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
        sqlite3_free(zNewFilename);







>
>
>
>
>
>



<







8718
8719
8720
8721
8722
8723
8724
8725
8726
8727
8728
8729
8730
8731
8732
8733

8734
8735
8736
8737
8738
8739
8740
      }else if( optionMatch(z, "maxsize") && iName+1<nArg ){
        p->szMax = integerValue(azArg[++iName]);
#endif /* SQLITE_ENABLE_DESERIALIZE */
      }else if( z[0]=='-' ){
        utf8_printf(stderr, "unknown option: %s\n", z);
        rc = 1;
        goto meta_command_exit;
      }else if( zNewFilename ){
        utf8_printf(stderr, "extra argument: \"%s\"\n", z);
        rc = 1;
        goto meta_command_exit;
      }else{
        zNewFilename = sqlite3_mprintf("%s", z);
      }
    }
    /* If a filename is specified, try to open it first */

    if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){
      if( newFlag ) shellDeleteFile(zNewFilename);
      p->zDbFilename = zNewFilename;
      open_db(p, OPEN_DB_KEEPALIVE);
      if( p->db==0 ){
        utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
        sqlite3_free(zNewFilename);
8742
8743
8744
8745
8746
8747
8748
8749
8750
8751
8752
8753
8754
8755
8756
    }
  }else

  if( (c=='o'
        && (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0))
   || (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
  ){
    const char *zFile = 0;
    int bTxtMode = 0;
    int i;
    int eMode = 0;
    int bBOM = 0;
    int bOnce = 0;  /* 0: .output, 1: .once, 2: .excel */

    if( c=='e' ){







|







8749
8750
8751
8752
8753
8754
8755
8756
8757
8758
8759
8760
8761
8762
8763
    }
  }else

  if( (c=='o'
        && (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0))
   || (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
  ){
    char *zFile = 0;
    int bTxtMode = 0;
    int i;
    int eMode = 0;
    int bBOM = 0;
    int bOnce = 0;  /* 0: .output, 1: .once, 2: .excel */

    if( c=='e' ){
8772
8773
8774
8775
8776
8777
8778
8779
8780




8781
8782
8783
8784
8785

8786
8787
8788
8789
8790
8791
8792
8793
8794
8795
8796
        }else{
          utf8_printf(p->out, "ERROR: unknown option: \"%s\".  Usage:\n",
                      azArg[i]);
          showHelp(p->out, azArg[0]);
          rc = 1;
          goto meta_command_exit;
        }
      }else if( zFile==0 ){
        zFile = z;




      }else{
        utf8_printf(p->out,"ERROR: extra parameter: \"%s\".  Usage:\n",
                    azArg[i]);
        showHelp(p->out, azArg[0]);
        rc = 1;

        goto meta_command_exit;
      }
    }
    if( zFile==0 ) zFile = "stdout";
    if( bOnce ){
      p->outCount = 2;
    }else{
      p->outCount = 0;
    }
    output_reset(p);
#ifndef SQLITE_NOHAVE_SYSTEM







|
|
>
>
>
>





>



|







8779
8780
8781
8782
8783
8784
8785
8786
8787
8788
8789
8790
8791
8792
8793
8794
8795
8796
8797
8798
8799
8800
8801
8802
8803
8804
8805
8806
8807
8808
        }else{
          utf8_printf(p->out, "ERROR: unknown option: \"%s\".  Usage:\n",
                      azArg[i]);
          showHelp(p->out, azArg[0]);
          rc = 1;
          goto meta_command_exit;
        }
      }else if( zFile==0 && eMode!='e' && eMode!='x' ){
        zFile = sqlite3_mprintf("%s", z);
        if( zFile[0]=='|' ){
          while( i+1<nArg ) zFile = sqlite3_mprintf("%z %s", zFile, azArg[++i]);
          break;
        }
      }else{
        utf8_printf(p->out,"ERROR: extra parameter: \"%s\".  Usage:\n",
                    azArg[i]);
        showHelp(p->out, azArg[0]);
        rc = 1;
        sqlite3_free(zFile);
        goto meta_command_exit;
      }
    }
    if( zFile==0 ) zFile = sqlite3_mprintf("stdout");
    if( bOnce ){
      p->outCount = 2;
    }else{
      p->outCount = 0;
    }
    output_reset(p);
#ifndef SQLITE_NOHAVE_SYSTEM
8805
8806
8807
8808
8809
8810
8811

8812
8813
8814
8815
8816
8817
8818
8819
        sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
        sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
      }else{
        /* text editor mode */
        newTempFile(p, "txt");
        bTxtMode = 1;
      }

      zFile = p->zTempFile;
    }
#endif /* SQLITE_NOHAVE_SYSTEM */
    if( zFile[0]=='|' ){
#ifdef SQLITE_OMIT_POPEN
      raw_printf(stderr, "Error: pipes are not supported in this OS\n");
      rc = 1;
      p->out = stdout;







>
|







8817
8818
8819
8820
8821
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
        sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
        sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
      }else{
        /* text editor mode */
        newTempFile(p, "txt");
        bTxtMode = 1;
      }
      sqlite3_free(zFile);
      zFile = sqlite3_mprintf("%s", p->zTempFile);
    }
#endif /* SQLITE_NOHAVE_SYSTEM */
    if( zFile[0]=='|' ){
#ifdef SQLITE_OMIT_POPEN
      raw_printf(stderr, "Error: pipes are not supported in this OS\n");
      rc = 1;
      p->out = stdout;
8837
8838
8839
8840
8841
8842
8843

8844
8845
8846
8847
8848
8849
8850
        p->out = stdout;
        rc = 1;
      } else {
        if( bBOM ) fprintf(p->out,"\357\273\277");
        sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
      }
    }

  }else

  if( c=='p' && n>=3 && strncmp(azArg[0], "parameter", n)==0 ){
    open_db(p,0);
    if( nArg<=1 ) goto parameter_syntax_error;

    /* .parameter clear







>







8850
8851
8852
8853
8854
8855
8856
8857
8858
8859
8860
8861
8862
8863
8864
        p->out = stdout;
        rc = 1;
      } else {
        if( bBOM ) fprintf(p->out,"\357\273\277");
        sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
      }
    }
    sqlite3_free(zFile);
  }else

  if( c=='p' && n>=3 && strncmp(azArg[0], "parameter", n)==0 ){
    open_db(p,0);
    if( nArg<=1 ) goto parameter_syntax_error;

    /* .parameter clear
9242
9243
9244
9245
9246
9247
9248
9249
9250
9251

9252
9253
9254
9255
9256
9257
9258
9259
9260
      raw_printf(stderr,"Error: querying schema information\n");
      rc = 1;
    }else{
      rc = 0;
    }
  }else

#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
  if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
    sqlite3_unsupported_selecttrace = nArg>=2 ? (int)integerValue(azArg[1]) : 0xffff;

  }else
#endif

#if defined(SQLITE_ENABLE_SESSION)
  if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
    OpenSession *pSession = &p->aSession[0];
    char **azCmd = &azArg[1];
    int iSes = 0;
    int nCmd = nArg - 1;







<

|
>

<







9256
9257
9258
9259
9260
9261
9262

9263
9264
9265
9266

9267
9268
9269
9270
9271
9272
9273
      raw_printf(stderr,"Error: querying schema information\n");
      rc = 1;
    }else{
      rc = 0;
    }
  }else


  if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
    unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
    sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x);
  }else


#if defined(SQLITE_ENABLE_SESSION)
  if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
    OpenSession *pSession = &p->aSession[0];
    char **azCmd = &azArg[1];
    int iSes = 0;
    int nCmd = nArg - 1;
9727
9728
9729
9730
9731
9732
9733

9734
9735
9736
9737
9738
9739
9740
    sqlite3_free(zCmd);
    if( x ) raw_printf(stderr, "System command returns %d\n", x);
  }else
#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */

  if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
    static const char *azBool[] = { "off", "on", "trigger", "full"};

    int i;
    if( nArg!=1 ){
      raw_printf(stderr, "Usage: .show\n");
      rc = 1;
      goto meta_command_exit;
    }
    utf8_printf(p->out, "%12.12s: %s\n","echo",







>







9740
9741
9742
9743
9744
9745
9746
9747
9748
9749
9750
9751
9752
9753
9754
    sqlite3_free(zCmd);
    if( x ) raw_printf(stderr, "System command returns %d\n", x);
  }else
#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */

  if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
    static const char *azBool[] = { "off", "on", "trigger", "full"};
    const char *zOut;
    int i;
    if( nArg!=1 ){
      raw_printf(stderr, "Usage: .show\n");
      rc = 1;
      goto meta_command_exit;
    }
    utf8_printf(p->out, "%12.12s: %s\n","echo",
9751
9752
9753
9754
9755
9756
9757






9758
9759
9760
9761
9762
9763
9764
9765
9766
9767
9768
9769





9770

9771
9772
9773
9774
9775
9776
9777
9778
9779
9780
9781
            strlen30(p->outfile) ? p->outfile : "stdout");
    utf8_printf(p->out,"%12.12s: ", "colseparator");
      output_c_string(p->out, p->colSeparator);
      raw_printf(p->out, "\n");
    utf8_printf(p->out,"%12.12s: ", "rowseparator");
      output_c_string(p->out, p->rowSeparator);
      raw_printf(p->out, "\n");






    utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]);
    utf8_printf(p->out, "%12.12s: ", "width");
    for (i=0;i<p->nWidth;i++) {
      raw_printf(p->out, "%d ", p->colWidth[i]);
    }
    raw_printf(p->out, "\n");
    utf8_printf(p->out, "%12.12s: %s\n", "filename",
                p->zDbFilename ? p->zDbFilename : "");
  }else

  if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
    if( nArg==2 ){





      p->statsOn = (u8)booleanValue(azArg[1]);

    }else if( nArg==1 ){
      display_stats(p->db, p, 0);
    }else{
      raw_printf(stderr, "Usage: .stats ?on|off?\n");
      rc = 1;
    }
  }else

  if( (c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0)
   || (c=='i' && (strncmp(azArg[0], "indices", n)==0
                 || strncmp(azArg[0], "indexes", n)==0) )







>
>
>
>
>
>
|











>
>
>
>
>
|
>



|







9765
9766
9767
9768
9769
9770
9771
9772
9773
9774
9775
9776
9777
9778
9779
9780
9781
9782
9783
9784
9785
9786
9787
9788
9789
9790
9791
9792
9793
9794
9795
9796
9797
9798
9799
9800
9801
9802
9803
9804
9805
9806
9807
            strlen30(p->outfile) ? p->outfile : "stdout");
    utf8_printf(p->out,"%12.12s: ", "colseparator");
      output_c_string(p->out, p->colSeparator);
      raw_printf(p->out, "\n");
    utf8_printf(p->out,"%12.12s: ", "rowseparator");
      output_c_string(p->out, p->rowSeparator);
      raw_printf(p->out, "\n");
    switch( p->statsOn ){
      case 0:  zOut = "off";     break;
      default: zOut = "on";      break;
      case 2:  zOut = "stmt";    break;
      case 3:  zOut = "vmstep";  break;
    }
    utf8_printf(p->out, "%12.12s: %s\n","stats", zOut);
    utf8_printf(p->out, "%12.12s: ", "width");
    for (i=0;i<p->nWidth;i++) {
      raw_printf(p->out, "%d ", p->colWidth[i]);
    }
    raw_printf(p->out, "\n");
    utf8_printf(p->out, "%12.12s: %s\n", "filename",
                p->zDbFilename ? p->zDbFilename : "");
  }else

  if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
    if( nArg==2 ){
      if( strcmp(azArg[1],"stmt")==0 ){
        p->statsOn = 2;
      }else if( strcmp(azArg[1],"vmstep")==0 ){
        p->statsOn = 3;
      }else{
        p->statsOn = (u8)booleanValue(azArg[1]);
      }
    }else if( nArg==1 ){
      display_stats(p->db, p, 0);
    }else{
      raw_printf(stderr, "Usage: .stats ?on|off|stmt|vmstep?\n");
      rc = 1;
    }
  }else

  if( (c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0)
   || (c=='i' && (strncmp(azArg[0], "indices", n)==0
                 || strncmp(azArg[0], "indexes", n)==0) )
9972
9973
9974
9975
9976
9977
9978
9979
9980
9981
9982
9983
9984
9985
9986
                         "Use \".testctrl --help\" for help\n", zCmd);
    }else{
      switch(testctrl){

        /* sqlite3_test_control(int, db, int) */
        case SQLITE_TESTCTRL_OPTIMIZATIONS:
          if( nArg==3 ){
            int opt = (int)strtol(azArg[2], 0, 0);
            rc2 = sqlite3_test_control(testctrl, p->db, opt);
            isOk = 3;
          }
          break;

        /* sqlite3_test_control(int) */
        case SQLITE_TESTCTRL_PRNG_SAVE:







|







9998
9999
10000
10001
10002
10003
10004
10005
10006
10007
10008
10009
10010
10011
10012
                         "Use \".testctrl --help\" for help\n", zCmd);
    }else{
      switch(testctrl){

        /* sqlite3_test_control(int, db, int) */
        case SQLITE_TESTCTRL_OPTIMIZATIONS:
          if( nArg==3 ){
            unsigned int opt = (unsigned int)strtol(azArg[2], 0, 0);
            rc2 = sqlite3_test_control(testctrl, p->db, opt);
            isOk = 3;
          }
          break;

        /* sqlite3_test_control(int) */
        case SQLITE_TESTCTRL_PRNG_SAVE:
10301
10302
10303
10304
10305
10306
10307
10308
10309
10310

10311
10312
10313
10314
10315
10316
10317
10318
10319
      if( zVfsName ){
        utf8_printf(p->out, "%s\n", zVfsName);
        sqlite3_free(zVfsName);
      }
    }
  }else

#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
  if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
    sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;

  }else
#endif

  if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
    int j;
    assert( nArg<=ArraySize(azArg) );
    p->nWidth = nArg-1;
    p->colWidth = realloc(p->colWidth, p->nWidth*sizeof(int)*2);
    if( p->colWidth==0 && p->nWidth>0 ) shell_out_of_memory();







<

|
>

<







10327
10328
10329
10330
10331
10332
10333

10334
10335
10336
10337

10338
10339
10340
10341
10342
10343
10344
      if( zVfsName ){
        utf8_printf(p->out, "%s\n", zVfsName);
        sqlite3_free(zVfsName);
      }
    }
  }else


  if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
    unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
    sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &x);
  }else


  if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
    int j;
    assert( nArg<=ArraySize(azArg) );
    p->nWidth = nArg-1;
    p->colWidth = realloc(p->colWidth, p->nWidth*sizeof(int)*2);
    if( p->colWidth==0 && p->nWidth>0 ) shell_out_of_memory();
10794
10795
10796
10797
10798
10799
10800
10801

10802
10803
10804
10805
10806
10807
10808
            argv[0], argv[argc-1]);
    exit(1);
  }
  return argv[i];
}

#ifndef SQLITE_SHELL_IS_UTF8
#  if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)

#    define SQLITE_SHELL_IS_UTF8          (0)
#  else
#    define SQLITE_SHELL_IS_UTF8          (1)
#  endif
#endif

#if SQLITE_SHELL_IS_UTF8







|
>







10819
10820
10821
10822
10823
10824
10825
10826
10827
10828
10829
10830
10831
10832
10833
10834
            argv[0], argv[argc-1]);
    exit(1);
  }
  return argv[i];
}

#ifndef SQLITE_SHELL_IS_UTF8
#  if (defined(_WIN32) || defined(WIN32)) \
   && (defined(_MSC_VER) || (defined(UNICODE) && defined(__GNUC__)))
#    define SQLITE_SHELL_IS_UTF8          (0)
#  else
#    define SQLITE_SHELL_IS_UTF8          (1)
#  endif
#endif

#if SQLITE_SHELL_IS_UTF8
Changes to src/sqlite.h.in.
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
** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
** There should be two additional arguments.
** The first argument is an integer which is 0 to disable triggers,
** positive to enable triggers or negative to leave the setting unchanged.
** The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether triggers are disabled or enabled
** following this call.  The second parameter may be a NULL pointer, in
** which case the trigger setting is not reported back. </dd>






**
** [[SQLITE_DBCONFIG_ENABLE_VIEW]]
** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt>
** <dd> ^This option is used to enable or disable [CREATE VIEW | views].
** There should be two additional arguments.
** The first argument is an integer which is 0 to disable views,
** positive to enable views or negative to leave the setting unchanged.
** The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether views are disabled or enabled
** following this call.  The second parameter may be a NULL pointer, in
** which case the view setting is not reported back. </dd>






**
** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
** <dd> ^This option is used to enable or disable the
** [fts3_tokenizer()] function which is part of the
** [FTS3] full-text search engine extension.
** There should be two additional arguments.







|
>
>
>
>
>
>










|
>
>
>
>
>
>







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
** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
** There should be two additional arguments.
** The first argument is an integer which is 0 to disable triggers,
** positive to enable triggers or negative to leave the setting unchanged.
** The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether triggers are disabled or enabled
** following this call.  The second parameter may be a NULL pointer, in
** which case the trigger setting is not reported back.
**
** <p>Originally this option disabled all triggers.  ^(However, since
** SQLite version 3.35.0, TEMP triggers are still allowed even if
** this option is off.  So, in other words, this option now only disables
** triggers in the main database schema or in the schemas of ATTACH-ed
** databases.)^ </dd>
**
** [[SQLITE_DBCONFIG_ENABLE_VIEW]]
** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt>
** <dd> ^This option is used to enable or disable [CREATE VIEW | views].
** There should be two additional arguments.
** The first argument is an integer which is 0 to disable views,
** positive to enable views or negative to leave the setting unchanged.
** The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether views are disabled or enabled
** following this call.  The second parameter may be a NULL pointer, in
** which case the view setting is not reported back.
**
** <p>Originally this option disabled all views.  ^(However, since
** SQLite version 3.35.0, TEMP views are still allowed even if
** this option is off.  So, in other words, this option now only disables
** views in the main database schema or in the schemas of ATTACH-ed
** databases.)^ </dd>
**
** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
** <dd> ^This option is used to enable or disable the
** [fts3_tokenizer()] function which is part of the
** [FTS3] full-text search engine extension.
** There should be two additional arguments.
3495
3496
3497
3498
3499
3500
3501

3502
3503
3504
3505
3506
3507
3508
**          Regardless of whether or not shared-cache mode is enabled by
**          default, use a private cache.
** <tr><td> file:/home/fred/data.db?vfs=unix-dotfile <td>
**          Open file "/home/fred/data.db". Use the special VFS "unix-dotfile"
**          that uses dot-files in place of posix advisory locking.
** <tr><td> file:data.db?mode=readonly <td> 
**          An error. "readonly" is not a valid option for the "mode" parameter.

** </table>
**
** ^URI hexadecimal escape sequences (%HH) are supported within the path and
** query components of a URI. A hexadecimal escape sequence consists of a
** percent sign - "%" - followed by exactly two hexadecimal digits 
** specifying an octet value. ^Before the path or query components of a
** URI filename are interpreted, they are encoded using UTF-8 and all 







>







3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
**          Regardless of whether or not shared-cache mode is enabled by
**          default, use a private cache.
** <tr><td> file:/home/fred/data.db?vfs=unix-dotfile <td>
**          Open file "/home/fred/data.db". Use the special VFS "unix-dotfile"
**          that uses dot-files in place of posix advisory locking.
** <tr><td> file:data.db?mode=readonly <td> 
**          An error. "readonly" is not a valid option for the "mode" parameter.
**          Use "ro" instead:  "file:data.db?mode=ro".
** </table>
**
** ^URI hexadecimal escape sequences (%HH) are supported within the path and
** query components of a URI. A hexadecimal escape sequence consists of a
** percent sign - "%" - followed by exactly two hexadecimal digits 
** specifying an octet value. ^Before the path or query components of a
** URI filename are interpreted, they are encoded using UTF-8 and all 
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
** The sqlite3_free_filename(Y) routine releases a memory allocation
** previously obtained from sqlite3_create_filename().  Invoking
** sqlite3_free_filename(Y) where Y is a NULL pointer is a harmless no-op.
**
** If the Y parameter to sqlite3_free_filename(Y) is anything other
** than a NULL pointer or a pointer previously acquired from
** sqlite3_create_filename(), then bad things such as heap
** corruption or segfaults may occur. The value Y should be 
** used again after sqlite3_free_filename(Y) has been called.  This means
** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y,
** then the corresponding [sqlite3_module.xClose() method should also be
** invoked prior to calling sqlite3_free_filename(Y).
*/
char *sqlite3_create_filename(
  const char *zDatabase,







|







3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
** The sqlite3_free_filename(Y) routine releases a memory allocation
** previously obtained from sqlite3_create_filename().  Invoking
** sqlite3_free_filename(Y) where Y is a NULL pointer is a harmless no-op.
**
** If the Y parameter to sqlite3_free_filename(Y) is anything other
** than a NULL pointer or a pointer previously acquired from
** sqlite3_create_filename(), then bad things such as heap
** corruption or segfaults may occur. The value Y should not be 
** used again after sqlite3_free_filename(Y) has been called.  This means
** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y,
** then the corresponding [sqlite3_module.xClose() method should also be
** invoked prior to calling sqlite3_free_filename(Y).
*/
char *sqlite3_create_filename(
  const char *zDatabase,
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
** Applications should not use any of these parameters or the
** [sqlite3_test_control()] interface.
*/
#define SQLITE_TESTCTRL_FIRST                    5
#define SQLITE_TESTCTRL_PRNG_SAVE                5
#define SQLITE_TESTCTRL_PRNG_RESTORE             6
#define SQLITE_TESTCTRL_PRNG_RESET               7  /* NOT USED */
#define SQLITE_TESTCTRL_SEEK_COUNT               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  /* NOT USED */







<







7749
7750
7751
7752
7753
7754
7755

7756
7757
7758
7759
7760
7761
7762
** Applications should not use any of these parameters or the
** [sqlite3_test_control()] interface.
*/
#define SQLITE_TESTCTRL_FIRST                    5
#define SQLITE_TESTCTRL_PRNG_SAVE                5
#define SQLITE_TESTCTRL_PRNG_RESTORE             6
#define SQLITE_TESTCTRL_PRNG_RESET               7  /* NOT USED */

#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  /* NOT USED */
7761
7762
7763
7764
7765
7766
7767


7768
7769
7770
7771
7772
7773
7774
7775
#define SQLITE_TESTCTRL_ISINIT                  23
#define SQLITE_TESTCTRL_SORTER_MMAP             24
#define SQLITE_TESTCTRL_IMPOSTER                25
#define SQLITE_TESTCTRL_PARSER_COVERAGE         26
#define SQLITE_TESTCTRL_RESULT_INTREAL          27
#define SQLITE_TESTCTRL_PRNG_SEED               28
#define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS     29


#define SQLITE_TESTCTRL_LAST                    29  /* Largest TESTCTRL */

/*
** CAPI3REF: SQL Keyword Checking
**
** These routines provide access to the set of SQL language keywords 
** recognized by SQLite.  Applications can uses these routines to determine
** whether or not a specific identifier needs to be escaped (for example,







>
>
|







7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
7789
#define SQLITE_TESTCTRL_ISINIT                  23
#define SQLITE_TESTCTRL_SORTER_MMAP             24
#define SQLITE_TESTCTRL_IMPOSTER                25
#define SQLITE_TESTCTRL_PARSER_COVERAGE         26
#define SQLITE_TESTCTRL_RESULT_INTREAL          27
#define SQLITE_TESTCTRL_PRNG_SEED               28
#define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS     29
#define SQLITE_TESTCTRL_SEEK_COUNT              30
#define SQLITE_TESTCTRL_TRACEFLAGS              31
#define SQLITE_TESTCTRL_LAST                    31  /* Largest TESTCTRL */

/*
** CAPI3REF: SQL Keyword Checking
**
** These routines provide access to the set of SQL language keywords 
** recognized by SQLite.  Applications can uses these routines to determine
** whether or not a specific identifier needs to be escaped (for example,
Changes to src/sqliteInt.h.
115
116
117
118
119
120
121












122
123
124
125
126
127
128
#endif
#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
# define MSVC_VERSION _MSC_VER
#else
# define MSVC_VERSION 0
#endif













/* Needed for various definitions... */
#if defined(__GNUC__) && !defined(_GNU_SOURCE)
# define _GNU_SOURCE
#endif

#if defined(__OpenBSD__) && !defined(_BSD_SOURCE)
# define _BSD_SOURCE







>
>
>
>
>
>
>
>
>
>
>
>







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
#endif
#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
# define MSVC_VERSION _MSC_VER
#else
# define MSVC_VERSION 0
#endif

/*
** Some C99 functions in "math.h" are only present for MSVC when its version
** is associated with Visual Studio 2013 or higher.
*/
#ifndef SQLITE_HAVE_C99_MATH_FUNCS
# if MSVC_VERSION==0 || MSVC_VERSION>=1800
#  define SQLITE_HAVE_C99_MATH_FUNCS (1)
# else
#  define SQLITE_HAVE_C99_MATH_FUNCS (0)
# endif
#endif

/* Needed for various definitions... */
#if defined(__GNUC__) && !defined(_GNU_SOURCE)
# define _GNU_SOURCE
#endif

#if defined(__OpenBSD__) && !defined(_BSD_SOURCE)
# define _BSD_SOURCE
198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
/*
** WAL mode depends on atomic aligned 32-bit loads and stores in a few
** places.  The following macros try to make this explicit.
*/
#ifndef __has_extension
# define __has_extension(x) 0     /* compatibility with non-clang compilers */
#endif
#if GCC_VERSION>=4007000 || __has_extension(c_atomic)

# define AtomicLoad(PTR)       __atomic_load_n((PTR),__ATOMIC_RELAXED)
# define AtomicStore(PTR,VAL)  __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED)
#else
# define AtomicLoad(PTR)       (*(PTR))
# define AtomicStore(PTR,VAL)  (*(PTR) = (VAL))
#endif








|
>







210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/*
** WAL mode depends on atomic aligned 32-bit loads and stores in a few
** places.  The following macros try to make this explicit.
*/
#ifndef __has_extension
# define __has_extension(x) 0     /* compatibility with non-clang compilers */
#endif
#if GCC_VERSION>=4007000 || \
    (__has_extension(c_atomic) && __has_extension(c_atomic_store_n))
# define AtomicLoad(PTR)       __atomic_load_n((PTR),__ATOMIC_RELAXED)
# define AtomicStore(PTR,VAL)  __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED)
#else
# define AtomicLoad(PTR)       (*(PTR))
# define AtomicStore(PTR,VAL)  (*(PTR) = (VAL))
#endif

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
# define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE
#endif

/*
** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not
** the Select query generator tracing logic is turned on.
*/
#if defined(SQLITE_ENABLE_SELECTTRACE)
# define SELECTTRACE_ENABLED 1
#else
# define SELECTTRACE_ENABLED 0
#endif
#if defined(SQLITE_ENABLE_SELECTTRACE)

# define SELECTTRACE_ENABLED 1
# define SELECTTRACE(K,P,S,X)  \
  if(sqlite3_unsupported_selecttrace&(K))   \
    sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\
    sqlite3DebugPrintf X
#else
# define SELECTTRACE(K,P,S,X)
# define SELECTTRACE_ENABLED 0
#endif














/*
** An instance of the following structure is used to store the busy-handler
** callback for a given sqlite handle.
**
** The sqlite.busyHandler member of the sqlite struct contains the busy
** callback for the database handle. Each pager opened via the sqlite







|
<
|
<

|
>


|






>
>
>
>
>
>
>
>
>
>
>
>
>







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
# define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE
#endif

/*
** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not
** the Select query generator tracing logic is turned on.
*/
#if !defined(SQLITE_AMALGAMATION)

extern u32 sqlite3SelectTrace;

#endif
#if defined(SQLITE_DEBUG) \
    && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE))
# define SELECTTRACE_ENABLED 1
# define SELECTTRACE(K,P,S,X)  \
  if(sqlite3SelectTrace&(K))   \
    sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\
    sqlite3DebugPrintf X
#else
# define SELECTTRACE(K,P,S,X)
# define SELECTTRACE_ENABLED 0
#endif

/*
** Macros for "wheretrace"
*/
extern u32 sqlite3WhereTrace;
#if defined(SQLITE_DEBUG) \
    && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE))
# define WHERETRACE(K,X)  if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X
# define WHERETRACE_ENABLED 1
#else
# define WHERETRACE(K,X)
#endif


/*
** An instance of the following structure is used to store the busy-handler
** callback for a given sqlite handle.
**
** The sqlite.busyHandler member of the sqlite struct contains the busy
** callback for the database handle. Each pager opened via the sqlite
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
*/
typedef struct AggInfo AggInfo;
typedef struct AuthContext AuthContext;
typedef struct AutoincInfo AutoincInfo;
typedef struct Bitvec Bitvec;
typedef struct CollSeq CollSeq;
typedef struct Column Column;


typedef struct Db Db;

typedef struct Schema Schema;
typedef struct Expr Expr;
typedef struct ExprList ExprList;
typedef struct FastPrng FastPrng;
typedef struct FKey FKey;
typedef struct FuncDestructor FuncDestructor;
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 PreUpdate PreUpdate;
typedef struct PrintfArguments PrintfArguments;
typedef struct RenameToken RenameToken;

typedef struct RowSet RowSet;
typedef struct Savepoint Savepoint;
typedef struct Select Select;
typedef struct SQLiteThread SQLiteThread;
typedef struct SelectDest SelectDest;

typedef struct SrcList SrcList;
typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */
typedef struct Table Table;
typedef struct TableLock TableLock;
typedef struct Token Token;
typedef struct TreeView TreeView;
typedef struct Trigger Trigger;







>
>

>


















>



>





>







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
*/
typedef struct AggInfo AggInfo;
typedef struct AuthContext AuthContext;
typedef struct AutoincInfo AutoincInfo;
typedef struct Bitvec Bitvec;
typedef struct CollSeq CollSeq;
typedef struct Column Column;
typedef struct Cte Cte;
typedef struct CteUse CteUse;
typedef struct Db Db;
typedef struct DbFixer DbFixer;
typedef struct Schema Schema;
typedef struct Expr Expr;
typedef struct ExprList ExprList;
typedef struct FastPrng FastPrng;
typedef struct FKey FKey;
typedef struct FuncDestructor FuncDestructor;
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 ParseCleanup ParseCleanup;
typedef struct PreUpdate PreUpdate;
typedef struct PrintfArguments PrintfArguments;
typedef struct RenameToken RenameToken;
typedef struct Returning Returning;
typedef struct RowSet RowSet;
typedef struct Savepoint Savepoint;
typedef struct Select Select;
typedef struct SQLiteThread SQLiteThread;
typedef struct SelectDest SelectDest;
typedef struct SrcItem SrcItem;
typedef struct SrcList SrcList;
typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */
typedef struct Table Table;
typedef struct TableLock TableLock;
typedef struct Token Token;
typedef struct TreeView TreeView;
typedef struct Trigger Trigger;
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
  u8 *aLimit;
  int nRef;                     /* Number of pointers to this structure */
  KeyInfo *pKeyInfo;            /* KeyInfo structure for indexes */
  CursorScan *pNext;            /* Next CursorScan object in list */
};








/*
** Each database connection is an instance of the following structure.
*/
struct sqlite3 {
  sqlite3_vfs *pVfs;            /* OS Interface */
  struct Vdbe *pVdbe;           /* List of active virtual machines */
  CollSeq *pDfltColl;           /* BINARY collseq for the database encoding */
  sqlite3_mutex *mutex;         /* Connection mutex */
  Db *aDb;                      /* All backends */
  int nDb;                      /* Number of backends currently in use */
  u32 mDbFlags;                 /* flags recording internal state */
  u64 flags;                    /* flags settable by pragmas. See below */
  i64 lastRowid;                /* ROWID of most recent insert (see above) */
  i64 szMmap;                   /* Default mmap_size setting */
  u32 nSchemaLock;              /* Do not reset the schema when non-zero */
  unsigned int openFlags;       /* Flags passed to sqlite3_vfs.xOpen() */
  int errCode;                  /* Most recent error code (SQLITE_*) */
  int errMask;                  /* & result codes with this before returning */
  int iSysErrno;                /* Errno value from last system error */
  u16 dbOptFlags;               /* Flags to enable/disable optimizations */
  u8 enc;                       /* Text encoding */
  u8 autoCommit;                /* The auto-commit flag. */
  u8 eConcurrent;               /* CONCURRENT_* value */
  u8 bConcurrentReport;         /* Concurrent transaction reports enabled */
  CursorScan *pCScanList;
  char *zBCReport;
  u8 temp_store;                /* 1: file 2: memory 0: default */







>
>
>
>
>
>



















|







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
  u8 *aLimit;
  int nRef;                     /* Number of pointers to this structure */
  KeyInfo *pKeyInfo;            /* KeyInfo structure for indexes */
  CursorScan *pNext;            /* Next CursorScan object in list */
};


/*
** Maximum number of sqlite3.aDb[] entries.  This is the number of attached
** databases plus 2 for "main" and "temp".
*/
#define SQLITE_MAX_DB (SQLITE_MAX_ATTACHED+2)

/*
** Each database connection is an instance of the following structure.
*/
struct sqlite3 {
  sqlite3_vfs *pVfs;            /* OS Interface */
  struct Vdbe *pVdbe;           /* List of active virtual machines */
  CollSeq *pDfltColl;           /* BINARY collseq for the database encoding */
  sqlite3_mutex *mutex;         /* Connection mutex */
  Db *aDb;                      /* All backends */
  int nDb;                      /* Number of backends currently in use */
  u32 mDbFlags;                 /* flags recording internal state */
  u64 flags;                    /* flags settable by pragmas. See below */
  i64 lastRowid;                /* ROWID of most recent insert (see above) */
  i64 szMmap;                   /* Default mmap_size setting */
  u32 nSchemaLock;              /* Do not reset the schema when non-zero */
  unsigned int openFlags;       /* Flags passed to sqlite3_vfs.xOpen() */
  int errCode;                  /* Most recent error code (SQLITE_*) */
  int errMask;                  /* & result codes with this before returning */
  int iSysErrno;                /* Errno value from last system error */
  u32 dbOptFlags;               /* Flags to enable/disable optimizations */
  u8 enc;                       /* Text encoding */
  u8 autoCommit;                /* The auto-commit flag. */
  u8 eConcurrent;               /* CONCURRENT_* value */
  u8 bConcurrentReport;         /* Concurrent transaction reports enabled */
  CursorScan *pCScanList;
  char *zBCReport;
  u8 temp_store;                /* 1: file 2: memory 0: default */
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
#define DBFLAG_EncodingFixed  0x0040  /* No longer possible to change enc. */

/*
** Bits of the sqlite3.dbOptFlags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
** selectively disable various optimizations.
*/
#define SQLITE_QueryFlattener 0x0001   /* Query flattening */
#define SQLITE_WindowFunc     0x0002   /* Use xInverse for window functions */
#define SQLITE_GroupByOrder   0x0004   /* GROUPBY cover of ORDERBY */
#define SQLITE_FactorOutConst 0x0008   /* Constant factoring */
#define SQLITE_DistinctOpt    0x0010   /* DISTINCT using indexes */
#define SQLITE_CoverIdxScan   0x0020   /* Covering index scans */
#define SQLITE_OrderByIdxJoin 0x0040   /* ORDER BY of joins via index */
#define SQLITE_Transitive     0x0080   /* Transitive constraints */
#define SQLITE_OmitNoopJoin   0x0100   /* Omit unused tables in joins */
#define SQLITE_CountOfView    0x0200   /* The count-of-view optimization */
#define SQLITE_CursorHints    0x0400   /* Add OP_CursorHint opcodes */
#define SQLITE_Stat4          0x0800   /* Use STAT4 data */
   /* TH3 expects the Stat4   ^^^^^^ value to be 0x0800.  Don't change it */
#define SQLITE_PushDown       0x1000   /* The push-down optimization */
#define SQLITE_SimplifyJoin   0x2000   /* Convert LEFT JOIN to JOIN */
#define SQLITE_SkipScan       0x4000   /* Skip-scans */
#define SQLITE_PropagateConst 0x8000   /* The constant propagation opt */


#define SQLITE_AllOpts        0xffff   /* All optimizations */

/*
** Macros for testing whether or not optimizations are enabled or disabled.
*/
#define OptimizationDisabled(db, mask)  (((db)->dbOptFlags&(mask))!=0)
#define OptimizationEnabled(db, mask)   (((db)->dbOptFlags&(mask))==0)








|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
|







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
#define DBFLAG_EncodingFixed  0x0040  /* No longer possible to change enc. */

/*
** Bits of the sqlite3.dbOptFlags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
** selectively disable various optimizations.
*/
#define SQLITE_QueryFlattener 0x00000001 /* Query flattening */
#define SQLITE_WindowFunc     0x00000002 /* Use xInverse for window functions */
#define SQLITE_GroupByOrder   0x00000004 /* GROUPBY cover of ORDERBY */
#define SQLITE_FactorOutConst 0x00000008 /* Constant factoring */
#define SQLITE_DistinctOpt    0x00000010 /* DISTINCT using indexes */
#define SQLITE_CoverIdxScan   0x00000020 /* Covering index scans */
#define SQLITE_OrderByIdxJoin 0x00000040 /* ORDER BY of joins via index */
#define SQLITE_Transitive     0x00000080 /* Transitive constraints */
#define SQLITE_OmitNoopJoin   0x00000100 /* Omit unused tables in joins */
#define SQLITE_CountOfView    0x00000200 /* The count-of-view optimization */
#define SQLITE_CursorHints    0x00000400 /* Add OP_CursorHint opcodes */
#define SQLITE_Stat4          0x00000800 /* Use STAT4 data */
   /* TH3 expects this value  ^^^^^^^^^^ to be 0x0000800. Don't change it */
#define SQLITE_PushDown       0x00001000 /* The push-down optimization */
#define SQLITE_SimplifyJoin   0x00002000 /* Convert LEFT JOIN to JOIN */
#define SQLITE_SkipScan       0x00004000 /* Skip-scans */
#define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */
#define SQLITE_MinMaxOpt      0x00010000 /* The min/max optimization */
#define SQLITE_ExistsToIN     0x00020000 /* The EXISTS-to-IN optimization */
#define SQLITE_AllOpts        0xffffffff /* All optimizations */

/*
** Macros for testing whether or not optimizations are enabled or disabled.
*/
#define OptimizationDisabled(db, mask)  (((db)->dbOptFlags&(mask))!=0)
#define OptimizationEnabled(db, mask)   (((db)->dbOptFlags&(mask))==0)

1900
1901
1902
1903
1904
1905
1906



1907
1908
1909
1910
1911
1912
1913
**   DFUNCTION(zName, nArg, iArg, bNC, xFunc)
**     Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag and
**     adds the SQLITE_FUNC_SLOCHNG flag.  Used for date & time functions
**     and functions like sqlite_version() that can change, but not during
**     a single query.  The iArg is ignored.  The user-data is always set
**     to a NULL pointer.  The bNC parameter is not used.
**



**   PURE_DATE(zName, nArg, iArg, bNC, xFunc)
**     Used for "pure" date/time functions, this macro is like DFUNCTION
**     except that it does set the SQLITE_FUNC_CONSTANT flags.  iArg is
**     ignored and the user-data for these functions is set to an 
**     arbitrary non-NULL pointer.  The bNC parameter is not used.
**
**   AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal)







>
>
>







1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
**   DFUNCTION(zName, nArg, iArg, bNC, xFunc)
**     Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag and
**     adds the SQLITE_FUNC_SLOCHNG flag.  Used for date & time functions
**     and functions like sqlite_version() that can change, but not during
**     a single query.  The iArg is ignored.  The user-data is always set
**     to a NULL pointer.  The bNC parameter is not used.
**
**   MFUNCTION(zName, nArg, xPtr, xFunc)
**     For math-library functions.  xPtr is an arbitrary pointer.
**
**   PURE_DATE(zName, nArg, iArg, bNC, xFunc)
**     Used for "pure" date/time functions, this macro is like DFUNCTION
**     except that it does set the SQLITE_FUNC_CONSTANT flags.  iArg is
**     ignored and the user-data for these functions is set to an 
**     arbitrary non-NULL pointer.  The bNC parameter is not used.
**
**   AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal)
1935
1936
1937
1938
1939
1940
1941



1942
1943
1944
1945
1946
1947
1948
   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
#define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \
  {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
#define SFUNCTION(zName, nArg, iArg, bNC, xFunc) \
  {nArg, SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \
   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }



#define INLINE_FUNC(zName, nArg, iArg, mFlags) \
  {nArg, SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \
   SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} }
#define TEST_FUNC(zName, nArg, iArg, mFlags) \
  {nArg, SQLITE_UTF8|SQLITE_FUNC_INTERNAL|SQLITE_FUNC_TEST| \
         SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \
   SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} }







>
>
>







1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
#define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \
  {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
#define SFUNCTION(zName, nArg, iArg, bNC, xFunc) \
  {nArg, SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \
   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
#define MFUNCTION(zName, nArg, xPtr, xFunc) \
  {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \
   xPtr, 0, xFunc, 0, 0, 0, #zName, {0} }
#define INLINE_FUNC(zName, nArg, iArg, mFlags) \
  {nArg, SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \
   SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} }
#define TEST_FUNC(zName, nArg, iArg, mFlags) \
  {nArg, SQLITE_UTF8|SQLITE_FUNC_INTERNAL|SQLITE_FUNC_TEST| \
         SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \
   SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} }
2029
2030
2031
2032
2033
2034
2035
2036





2037
2038
2039
2040
2041
2042
2043
  u8 notNull;      /* An OE_ code for handling a NOT NULL constraint */
  char affinity;   /* One of the SQLITE_AFF_... values */
  u8 szEst;        /* Estimated size of value in this column. sizeof(INT)==1 */
  u8 hName;        /* Column name hash for faster lookup */
  u16 colFlags;    /* Boolean properties.  See COLFLAG_ defines below */
};

/* Allowed values for Column.colFlags:





*/
#define COLFLAG_PRIMKEY   0x0001   /* Column is part of the primary key */
#define COLFLAG_HIDDEN    0x0002   /* A hidden column in a virtual table */
#define COLFLAG_HASTYPE   0x0004   /* Type name follows column name */
#define COLFLAG_UNIQUE    0x0008   /* Column def contains "UNIQUE" or "PK" */
#define COLFLAG_SORTERREF 0x0010   /* Use sorter-refs with this column */
#define COLFLAG_VIRTUAL   0x0020   /* GENERATED ALWAYS AS ... VIRTUAL */







|
>
>
>
>
>







2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
  u8 notNull;      /* An OE_ code for handling a NOT NULL constraint */
  char affinity;   /* One of the SQLITE_AFF_... values */
  u8 szEst;        /* Estimated size of value in this column. sizeof(INT)==1 */
  u8 hName;        /* Column name hash for faster lookup */
  u16 colFlags;    /* Boolean properties.  See COLFLAG_ defines below */
};

/* Allowed values for Column.colFlags.
**
** Constraints:
**         TF_HasVirtual == COLFLAG_VIRTUAL
**         TF_HasStored  == COLFLAG_STORED
**         TF_HasHidden  == COLFLAG_HIDDEN
*/
#define COLFLAG_PRIMKEY   0x0001   /* Column is part of the primary key */
#define COLFLAG_HIDDEN    0x0002   /* A hidden column in a virtual table */
#define COLFLAG_HASTYPE   0x0004   /* Type name follows column name */
#define COLFLAG_UNIQUE    0x0008   /* Column def contains "UNIQUE" or "PK" */
#define COLFLAG_SORTERREF 0x0010   /* Use sorter-refs with this column */
#define COLFLAG_VIRTUAL   0x0020   /* GENERATED ALWAYS AS ... VIRTUAL */
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
#ifndef SQLITE_OMIT_VIRTUALTABLE
  int nModuleArg;      /* Number of arguments to the module */
  char **azModuleArg;  /* 0: module 1: schema 2: vtab name 3...: args */
  VTable *pVTable;     /* List of VTable objects. */
#endif
  Trigger *pTrigger;   /* List of triggers stored in pSchema */
  Schema *pSchema;     /* Schema that contains this table */
  Table *pNextZombie;  /* Next on the Parse.pZombieTab list */
};

/*
** Allowed values for Table.tabFlags.
**
** TF_OOOHidden applies to tables or view that have hidden columns that are
** followed by non-hidden columns.  Example:  "CREATE VIRTUAL TABLE x USING
** vtab1(a HIDDEN, b);".  Since "b" is a non-hidden column but "a" is hidden,
** the TF_OOOHidden attribute would apply in this case.  Such tables require
** special handling during INSERT processing. The "OOO" means "Out Of Order".
**
** Constraints:
**
**         TF_HasVirtual == COLFLAG_Virtual
**         TF_HasStored  == COLFLAG_Stored

*/
#define TF_Readonly        0x0001    /* Read-only system table */
#define TF_Ephemeral       0x0002    /* An ephemeral table */
#define TF_HasPrimaryKey   0x0004    /* Table has a primary key */
#define TF_Autoincrement   0x0008    /* Integer primary key is autoincrement */
#define TF_HasStat1        0x0010    /* nRowLogEst set from sqlite_stat1 */
#define TF_HasVirtual      0x0020    /* Has one or more VIRTUAL columns */
#define TF_HasStored       0x0040    /* Has one or more STORED columns */
#define TF_HasGenerated    0x0060    /* Combo: HasVirtual + HasStored */
#define TF_WithoutRowid    0x0080    /* No rowid.  PRIMARY KEY is the key */
#define TF_StatsUsed       0x0100    /* Query planner decisions affected by
                                     ** Index.aiRowLogEst[] values */
#define TF_NoVisibleRowid  0x0200    /* No user-visible "rowid" column */
#define TF_OOOHidden       0x0400    /* Out-of-Order hidden columns */
#define TF_HasNotNull      0x0800    /* Contains NOT NULL constraints */
#define TF_Shadow          0x1000    /* True for a shadow table */
#define TF_HasStat4        0x2000    /* STAT4 info available for this table */


/*
** Test to see whether or not a table is a virtual table.  This is
** done as a macro so that it will be optimized out when virtual
** table support is omitted from the build.
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE







<













|
|
>


|














>







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
#ifndef SQLITE_OMIT_VIRTUALTABLE
  int nModuleArg;      /* Number of arguments to the module */
  char **azModuleArg;  /* 0: module 1: schema 2: vtab name 3...: args */
  VTable *pVTable;     /* List of VTable objects. */
#endif
  Trigger *pTrigger;   /* List of triggers stored in pSchema */
  Schema *pSchema;     /* Schema that contains this table */

};

/*
** Allowed values for Table.tabFlags.
**
** TF_OOOHidden applies to tables or view that have hidden columns that are
** followed by non-hidden columns.  Example:  "CREATE VIRTUAL TABLE x USING
** vtab1(a HIDDEN, b);".  Since "b" is a non-hidden column but "a" is hidden,
** the TF_OOOHidden attribute would apply in this case.  Such tables require
** special handling during INSERT processing. The "OOO" means "Out Of Order".
**
** Constraints:
**
**         TF_HasVirtual == COLFLAG_VIRTUAL
**         TF_HasStored  == COLFLAG_STORED
**         TF_HasHidden  == COLFLAG_HIDDEN
*/
#define TF_Readonly        0x0001    /* Read-only system table */
#define TF_HasHidden       0x0002    /* Has one or more hidden columns */
#define TF_HasPrimaryKey   0x0004    /* Table has a primary key */
#define TF_Autoincrement   0x0008    /* Integer primary key is autoincrement */
#define TF_HasStat1        0x0010    /* nRowLogEst set from sqlite_stat1 */
#define TF_HasVirtual      0x0020    /* Has one or more VIRTUAL columns */
#define TF_HasStored       0x0040    /* Has one or more STORED columns */
#define TF_HasGenerated    0x0060    /* Combo: HasVirtual + HasStored */
#define TF_WithoutRowid    0x0080    /* No rowid.  PRIMARY KEY is the key */
#define TF_StatsUsed       0x0100    /* Query planner decisions affected by
                                     ** Index.aiRowLogEst[] values */
#define TF_NoVisibleRowid  0x0200    /* No user-visible "rowid" column */
#define TF_OOOHidden       0x0400    /* Out-of-Order hidden columns */
#define TF_HasNotNull      0x0800    /* Contains NOT NULL constraints */
#define TF_Shadow          0x1000    /* True for a shadow table */
#define TF_HasStat4        0x2000    /* STAT4 info available for this table */
#define TF_Ephemeral       0x4000    /* An ephemeral table */

/*
** Test to see whether or not a table is a virtual table.  This is
** done as a macro so that it will be optimized out when virtual
** table support is omitted from the build.
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
2334
2335
2336
2337
2338
2339
2340


2341
2342
2343
2344

2345
2346
2347
2348



2349
2350
2351
2352
2353
2354
2355
2356
2357
** the operation in progress stops and returns an error code.  But prior
** changes due to the same operation are not backed out and no rollback
** occurs.  IGNORE means that the particular row that caused the constraint
** error is not inserted or updated.  Processing continues and no error
** is returned.  REPLACE means that preexisting database rows that caused
** a UNIQUE constraint violation are removed so that the new insert or
** update can proceed.  Processing continues and no error is reported.


**
** RESTRICT, SETNULL, and CASCADE actions apply only to foreign keys.
** RESTRICT is the same as ABORT for IMMEDIATE foreign keys and the
** same as ROLLBACK for DEFERRED keys.  SETNULL means that the foreign

** key is set to NULL.  CASCADE means that a DELETE or UPDATE of the
** referenced table row is propagated into the row that holds the
** foreign key.
**



** The following symbolic values are used to record which type
** of action to take.
*/
#define OE_None     0   /* There is no constraint to check */
#define OE_Rollback 1   /* Fail the operation and rollback the transaction */
#define OE_Abort    2   /* Back out changes but do no rollback transaction */
#define OE_Fail     3   /* Stop the operation but leave all prior changes */
#define OE_Ignore   4   /* Ignore the error. Do not do the INSERT or UPDATE */
#define OE_Replace  5   /* Delete existing record, then do INSERT or UPDATE */







>
>

|


>
|



>
>
>

|







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
** the operation in progress stops and returns an error code.  But prior
** changes due to the same operation are not backed out and no rollback
** occurs.  IGNORE means that the particular row that caused the constraint
** error is not inserted or updated.  Processing continues and no error
** is returned.  REPLACE means that preexisting database rows that caused
** a UNIQUE constraint violation are removed so that the new insert or
** update can proceed.  Processing continues and no error is reported.
** UPDATE applies to insert operations only and means that the insert
** is omitted and the DO UPDATE clause of an upsert is run instead.
**
** RESTRICT, SETNULL, SETDFLT, and CASCADE actions apply only to foreign keys.
** RESTRICT is the same as ABORT for IMMEDIATE foreign keys and the
** same as ROLLBACK for DEFERRED keys.  SETNULL means that the foreign
** key is set to NULL.  SETDFLT means that the foreign key is set
** to its default value.  CASCADE means that a DELETE or UPDATE of the
** referenced table row is propagated into the row that holds the
** foreign key.
**
** The OE_Default value is a place holder that means to use whatever
** conflict resolution algorthm is required from context.
**
** The following symbolic values are used to record which type
** of conflict resolution action to take.
*/
#define OE_None     0   /* There is no constraint to check */
#define OE_Rollback 1   /* Fail the operation and rollback the transaction */
#define OE_Abort    2   /* Back out changes but do no rollback transaction */
#define OE_Fail     3   /* Stop the operation but leave all prior changes */
#define OE_Ignore   4   /* Ignore the error. Do not do the INSERT or UPDATE */
#define OE_Replace  5   /* Delete existing record, then do INSERT or UPDATE */
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
    Expr *pFExpr;            /* Expression encoding the function */
    FuncDef *pFunc;          /* The aggregate function implementation */
    int iMem;                /* Memory location that acts as accumulator */
    int iDistinct;           /* Ephemeral table used to enforce DISTINCT */
  } *aFunc;
  int nFunc;              /* Number of entries in aFunc[] */
  u32 selId;              /* Select to which this AggInfo belongs */
  AggInfo *pNext;         /* Next in list of them all */
};

/*
** 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







<







2657
2658
2659
2660
2661
2662
2663

2664
2665
2666
2667
2668
2669
2670
    Expr *pFExpr;            /* Expression encoding the function */
    FuncDef *pFunc;          /* The aggregate function implementation */
    int iMem;                /* Memory location that acts as accumulator */
    int iDistinct;           /* Ephemeral table used to enforce DISTINCT */
  } *aFunc;
  int nFunc;              /* Number of entries in aFunc[] */
  u32 selId;              /* Select to which this AggInfo belongs */

};

/*
** 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
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
                         ** TK_IN: ephemerial table holding RHS
                         ** TK_SELECT_COLUMN: Number of columns on the LHS
                         ** TK_SELECT: 1st register of result vector */
  ynVar iColumn;         /* TK_COLUMN: column index.  -1 for rowid.
                         ** TK_VARIABLE: variable number (always >= 1).
                         ** TK_SELECT_COLUMN: column of the result vector */
  i16 iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
  i16 iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
  AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
  union {
    Table *pTab;           /* TK_COLUMN: Table containing column. Can be NULL
                           ** for a column of an index on an expression */
    Window *pWin;          /* EP_WinFunc: Window/Filter defn for a function */
    struct {               /* TK_IN, TK_SELECT, and TK_EXISTS */
      int iAddr;             /* Subroutine entry address */







|







2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
                         ** TK_IN: ephemerial table holding RHS
                         ** TK_SELECT_COLUMN: Number of columns on the LHS
                         ** TK_SELECT: 1st register of result vector */
  ynVar iColumn;         /* TK_COLUMN: column index.  -1 for rowid.
                         ** TK_VARIABLE: variable number (always >= 1).
                         ** TK_SELECT_COLUMN: column of the result vector */
  i16 iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
  int iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
  AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
  union {
    Table *pTab;           /* TK_COLUMN: Table containing column. Can be NULL
                           ** for a column of an index on an expression */
    Window *pWin;          /* EP_WinFunc: Window/Filter defn for a function */
    struct {               /* TK_IN, TK_SELECT, and TK_EXISTS */
      int iAddr;             /* Subroutine entry address */
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
#define EP_Win        0x008000 /* Contains window functions */
#define EP_MemToken   0x010000 /* Need to sqlite3DbFree() Expr.zToken */
#define EP_IfNullRow  0x020000 /* The TK_IF_NULL_ROW opcode */
#define EP_Unlikely   0x040000 /* unlikely() or likelihood() function */
#define EP_ConstFunc  0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
#define EP_CanBeNull  0x100000 /* Can be null despite NOT NULL constraint */
#define EP_Subquery   0x200000 /* Tree contains a TK_SELECT operator */
#define EP_Alias      0x400000 /* Is an alias for a result set column */
#define EP_Leaf       0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
#define EP_WinFunc   0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
#define EP_Subrtn    0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
#define EP_Quoted    0x4000000 /* TK_ID was originally quoted */
#define EP_Static    0x8000000 /* Held in memory not obtained from malloc() */
#define EP_IsTrue   0x10000000 /* Always has boolean value of TRUE */
#define EP_IsFalse  0x20000000 /* Always has boolean value of FALSE */







|







2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
#define EP_Win        0x008000 /* Contains window functions */
#define EP_MemToken   0x010000 /* Need to sqlite3DbFree() Expr.zToken */
#define EP_IfNullRow  0x020000 /* The TK_IF_NULL_ROW opcode */
#define EP_Unlikely   0x040000 /* unlikely() or likelihood() function */
#define EP_ConstFunc  0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
#define EP_CanBeNull  0x100000 /* Can be null despite NOT NULL constraint */
#define EP_Subquery   0x200000 /* Tree contains a TK_SELECT operator */
                 /*   0x400000 // Available */
#define EP_Leaf       0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
#define EP_WinFunc   0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
#define EP_Subrtn    0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
#define EP_Quoted    0x4000000 /* TK_ID was originally quoted */
#define EP_Static    0x8000000 /* Held in memory not obtained from malloc() */
#define EP_IsTrue   0x10000000 /* Always has boolean value of TRUE */
#define EP_IsFalse  0x20000000 /* Always has boolean value of FALSE */
2919
2920
2921
2922
2923
2924
2925







































2926
2927
2928
2929
2930
2931
2932
  struct IdList_item {
    char *zName;      /* Name of the identifier */
    int idx;          /* Index in some Table.aCol[] of a column named zName */
  } *a;
  int nId;         /* Number of identifiers on the list */
};








































/*
** The following structure describes the FROM clause of a SELECT statement.
** Each table or subquery in the FROM clause is a separate element of
** the SrcList.a[] array.
**
** With the addition of multiple database support, the following structure
** can also be used to describe a particular table such as the table that







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
3026
3027
  struct IdList_item {
    char *zName;      /* Name of the identifier */
    int idx;          /* Index in some Table.aCol[] of a column named zName */
  } *a;
  int nId;         /* Number of identifiers on the list */
};

/*
** The SrcItem object represents a single term in the FROM clause of a query.
** The SrcList object is mostly an array of SrcItems.
*/
struct SrcItem {
  Schema *pSchema;  /* Schema to which this item is fixed */
  char *zDatabase;  /* Name of database holding this table */
  char *zName;      /* Name of the table */
  char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
  Table *pTab;      /* An SQL table corresponding to zName */
  Select *pSelect;  /* A SELECT statement used in place of a table name */
  int addrFillSub;  /* Address of subroutine to manifest a subquery */
  int regReturn;    /* Register holding return address of addrFillSub */
  int regResult;    /* Registers holding results of a co-routine */
  struct {
    u8 jointype;      /* Type of join between this table and the previous */
    unsigned notIndexed :1;    /* True if there is a NOT INDEXED clause */
    unsigned isIndexedBy :1;   /* True if there is an INDEXED BY clause */
    unsigned isTabFunc :1;     /* True if table-valued-function syntax */
    unsigned isCorrelated :1;  /* True if sub-query is correlated */
    unsigned viaCoroutine :1;  /* Implemented as a co-routine */
    unsigned isRecursive :1;   /* True for recursive reference in WITH */
    unsigned fromDDL :1;       /* Comes from sqlite_schema */
    unsigned isCte :1;         /* This is a CTE */
  } fg;
  int iCursor;      /* The VDBE cursor number used to access this table */
  Expr *pOn;        /* The ON clause of a join */
  IdList *pUsing;   /* The USING clause of a join */
  Bitmask colUsed;  /* Bit N (1<<N) set if column N of pTab is used */
  union {
    char *zIndexedBy;    /* Identifier from "INDEXED BY <zIndex>" clause */
    ExprList *pFuncArg;  /* Arguments to table-valued-function */
  } u1;
  union {
    Index *pIBIndex;  /* Index structure corresponding to u1.zIndexedBy */
    CteUse *pCteUse;  /* CTE Usage info info fg.isCte is true */
  } u2;
};

/*
** The following structure describes the FROM clause of a SELECT statement.
** Each table or subquery in the FROM clause is a separate element of
** the SrcList.a[] array.
**
** With the addition of multiple database support, the following structure
** can also be used to describe a particular table such as the table that
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
**
** In the colUsed field, the high-order bit (bit 63) is set if the table
** contains more than 63 columns and the 64-th or later column is used.
*/
struct SrcList {
  int nSrc;        /* Number of tables or subqueries in the FROM clause */
  u32 nAlloc;      /* Number of entries allocated in a[] below */
  struct SrcList_item {
    Schema *pSchema;  /* Schema to which this item is fixed */
    char *zDatabase;  /* Name of database holding this table */
    char *zName;      /* Name of the table */
    char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
    Table *pTab;      /* An SQL table corresponding to zName */
    Select *pSelect;  /* A SELECT statement used in place of a table name */
    int addrFillSub;  /* Address of subroutine to manifest a subquery */
    int regReturn;    /* Register holding return address of addrFillSub */
    int regResult;    /* Registers holding results of a co-routine */
    struct {
      u8 jointype;      /* Type of join between this table and the previous */
      unsigned notIndexed :1;    /* True if there is a NOT INDEXED clause */
      unsigned isIndexedBy :1;   /* True if there is an INDEXED BY clause */
      unsigned isTabFunc :1;     /* True if table-valued-function syntax */
      unsigned isCorrelated :1;  /* True if sub-query is correlated */
      unsigned viaCoroutine :1;  /* Implemented as a co-routine */
      unsigned isRecursive :1;   /* True for recursive reference in WITH */
      unsigned fromDDL :1;       /* Comes from sqlite_schema */
    } fg;
    int iCursor;      /* The VDBE cursor number used to access this table */
    Expr *pOn;        /* The ON clause of a join */
    IdList *pUsing;   /* The USING clause of a join */
    Bitmask colUsed;  /* Bit N (1<<N) set if column N of pTab is used */
    union {
      char *zIndexedBy;    /* Identifier from "INDEXED BY <zIndex>" clause */
      ExprList *pFuncArg;  /* Arguments to table-valued-function */
    } u1;
    Index *pIBIndex;  /* Index structure corresponding to u1.zIndexedBy */
  } a[1];             /* One entry for each identifier on the list */
};

/*
** Permitted values of the SrcList.a.jointype field
*/
#define JT_INNER     0x0001    /* Any kind of inner or cross join */
#define JT_CROSS     0x0002    /* Explicit use of the CROSS keyword */







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|







3036
3037
3038
3039
3040
3041
3042





























3043
3044
3045
3046
3047
3048
3049
3050
**
** In the colUsed field, the high-order bit (bit 63) is set if the table
** contains more than 63 columns and the 64-th or later column is used.
*/
struct SrcList {
  int nSrc;        /* Number of tables or subqueries in the FROM clause */
  u32 nAlloc;      /* Number of entries allocated in a[] below */





























  SrcItem a[1];    /* One entry for each identifier on the list */
};

/*
** Permitted values of the SrcList.a.jointype field
*/
#define JT_INNER     0x0001    /* Any kind of inner or cross join */
#define JT_CROSS     0x0002    /* Explicit use of the CROSS keyword */
3046
3047
3048
3049
3050
3051
3052

3053
3054
3055
3056
3057
3058
3059
struct NameContext {
  Parse *pParse;       /* The parser */
  SrcList *pSrcList;   /* One or more tables used to resolve names */
  union {
    ExprList *pEList;    /* Optional list of result-set columns */
    AggInfo *pAggInfo;   /* Information about aggregates at this level */
    Upsert *pUpsert;     /* ON CONFLICT clause information from an upsert */

  } uNC;
  NameContext *pNext;  /* Next outer name context.  NULL for outermost */
  int nRef;            /* Number of names resolved by this context */
  int nErr;            /* Number of errors encountered while resolving names */
  int ncFlags;         /* Zero or more NC_* flags defined below */
  Select *pWinSelect;  /* SELECT statement for any window functions */
};







>







3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
struct NameContext {
  Parse *pParse;       /* The parser */
  SrcList *pSrcList;   /* One or more tables used to resolve names */
  union {
    ExprList *pEList;    /* Optional list of result-set columns */
    AggInfo *pAggInfo;   /* Information about aggregates at this level */
    Upsert *pUpsert;     /* ON CONFLICT clause information from an upsert */
    int iBaseReg;        /* For TK_REGISTER when parsing RETURNING */
  } uNC;
  NameContext *pNext;  /* Next outer name context.  NULL for outermost */
  int nRef;            /* Number of names resolved by this context */
  int nErr;            /* Number of errors encountered while resolving names */
  int ncFlags;         /* Zero or more NC_* flags defined below */
  Select *pWinSelect;  /* SELECT statement for any window functions */
};
3074
3075
3076
3077
3078
3079
3080

3081
3082
3083
3084
3085
3086
3087
#define NC_HasAgg    0x00010  /* One or more aggregate functions seen */
#define NC_IdxExpr   0x00020  /* True if resolving columns of CREATE INDEX */
#define NC_SelfRef   0x0002e  /* Combo: PartIdx, isCheck, GenCol, and IdxExpr */
#define NC_VarSelect 0x00040  /* A correlated subquery has been seen */
#define NC_UEList    0x00080  /* True if uNC.pEList is used */
#define NC_UAggInfo  0x00100  /* True if uNC.pAggInfo is used */
#define NC_UUpsert   0x00200  /* True if uNC.pUpsert is used */

#define NC_MinMaxAgg 0x01000  /* min/max aggregates seen.  See note above */
#define NC_Complex   0x02000  /* True if a function or subquery seen */
#define NC_AllowWin  0x04000  /* Window functions are allowed here */
#define NC_HasWin    0x08000  /* One or more window functions seen */
#define NC_IsDDL     0x10000  /* Resolving names in a CREATE statement */
#define NC_InAggFunc 0x20000  /* True if analyzing arguments to an agg func */
#define NC_FromDDL   0x40000  /* SQL text comes from sqlite_schema */







>







3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
#define NC_HasAgg    0x00010  /* One or more aggregate functions seen */
#define NC_IdxExpr   0x00020  /* True if resolving columns of CREATE INDEX */
#define NC_SelfRef   0x0002e  /* Combo: PartIdx, isCheck, GenCol, and IdxExpr */
#define NC_VarSelect 0x00040  /* A correlated subquery has been seen */
#define NC_UEList    0x00080  /* True if uNC.pEList is used */
#define NC_UAggInfo  0x00100  /* True if uNC.pAggInfo is used */
#define NC_UUpsert   0x00200  /* True if uNC.pUpsert is used */
#define NC_UBaseReg  0x00400  /* True if uNC.iBaseReg is used */
#define NC_MinMaxAgg 0x01000  /* min/max aggregates seen.  See note above */
#define NC_Complex   0x02000  /* True if a function or subquery seen */
#define NC_AllowWin  0x04000  /* Window functions are allowed here */
#define NC_HasWin    0x08000  /* One or more window functions seen */
#define NC_IsDDL     0x10000  /* Resolving names in a CREATE statement */
#define NC_InAggFunc 0x20000  /* True if analyzing arguments to an agg func */
#define NC_FromDDL   0x40000  /* SQL text comes from sqlite_schema */
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107


3108



3109
3110
3111


3112
3113
3114
3115
3116
3117
3118
3119
**
** pUpsertSet is the list of column=expr terms of the UPDATE statement. 
** The pUpsertSet field is NULL for a ON CONFLICT DO NOTHING.  The
** pUpsertWhere is the WHERE clause for the UPDATE and is NULL if the
** WHERE clause is omitted.
*/
struct Upsert {
  ExprList *pUpsertTarget;  /* Optional description of conflicting index */
  Expr *pUpsertTargetWhere; /* WHERE clause for partial index targets */
  ExprList *pUpsertSet;     /* The SET clause from an ON CONFLICT UPDATE */
  Expr *pUpsertWhere;       /* WHERE clause for the ON CONFLICT UPDATE */


  /* The fields above comprise the parse tree for the upsert clause.



  ** The fields below are used to transfer information from the INSERT
  ** processing down into the UPDATE processing while generating code.
  ** Upsert owns the memory allocated above, but not the memory below. */


  Index *pUpsertIdx;        /* Constraint that pUpsertTarget identifies */
  SrcList *pUpsertSrc;      /* Table to be updated */
  int regData;              /* First register holding array of VALUES */
  int iDataCur;             /* Index of the data cursor */
  int iIdxCur;              /* Index of the first index cursor */
};

/*







|



>
>
|
>
>
>
|
|
<
>
>
|







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
**
** pUpsertSet is the list of column=expr terms of the UPDATE statement. 
** The pUpsertSet field is NULL for a ON CONFLICT DO NOTHING.  The
** pUpsertWhere is the WHERE clause for the UPDATE and is NULL if the
** WHERE clause is omitted.
*/
struct Upsert {
  ExprList *pUpsertTarget;  /* Optional description of conflict target */
  Expr *pUpsertTargetWhere; /* WHERE clause for partial index targets */
  ExprList *pUpsertSet;     /* The SET clause from an ON CONFLICT UPDATE */
  Expr *pUpsertWhere;       /* WHERE clause for the ON CONFLICT UPDATE */
  Upsert *pNextUpsert;      /* Next ON CONFLICT clause in the list */
  u8 isDoUpdate;            /* True for DO UPDATE.  False for DO NOTHING */
  /* Above this point is the parse tree for the ON CONFLICT clauses.
  ** The next group of fields stores intermediate data. */
  void *pToFree;            /* Free memory when deleting the Upsert object */
  /* All fields above are owned by the Upsert object and must be freed
  ** when the Upsert is destroyed.  The fields below are used to transfer
  ** information from the INSERT processing down into the UPDATE processing

  ** while generating code.  The fields below are owned by the INSERT
  ** statement and will be freed by INSERT processing. */
  Index *pUpsertIdx;        /* UNIQUE constraint specified by pUpsertTarget */
  SrcList *pUpsertSrc;      /* Table to be updated */
  int regData;              /* First register holding array of VALUES */
  int iDataCur;             /* Index of the data cursor */
  int iIdxCur;              /* Index of the first index cursor */
};

/*
3185
3186
3187
3188
3189
3190
3191


3192
3193
3194
3195
3196
3197
3198
#define SF_IncludeHidden 0x0020000 /* Include hidden columns in output */
#define SF_ComplexResult 0x0040000 /* Result contains subquery or function */
#define SF_WhereBegin    0x0080000 /* Really a WhereBegin() call.  Debug Only */
#define SF_WinRewrite    0x0100000 /* Window function rewrite accomplished */
#define SF_View          0x0200000 /* SELECT statement is a view */
#define SF_NoopOrderBy   0x0400000 /* ORDER BY is ignored for this query */
#define SF_UpdateFrom    0x0800000 /* Statement is an UPDATE...FROM */



/*
** The results of a SELECT can be distributed in several ways, as defined
** by one of the following macros.  The "SRT" prefix means "SELECT Result
** Type".
**
**     SRT_Union       Store results as a key in a temporary index







>
>







3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
#define SF_IncludeHidden 0x0020000 /* Include hidden columns in output */
#define SF_ComplexResult 0x0040000 /* Result contains subquery or function */
#define SF_WhereBegin    0x0080000 /* Really a WhereBegin() call.  Debug Only */
#define SF_WinRewrite    0x0100000 /* Window function rewrite accomplished */
#define SF_View          0x0200000 /* SELECT statement is a view */
#define SF_NoopOrderBy   0x0400000 /* ORDER BY is ignored for this query */
#define SF_UpdateFrom    0x0800000 /* Statement is an UPDATE...FROM */
#define SF_PushDown      0x1000000 /* SELECT has be modified by push-down opt */
#define SF_MultiPart     0x2000000 /* Has multiple incompatible PARTITIONs */

/*
** The results of a SELECT can be distributed in several ways, as defined
** by one of the following macros.  The "SRT" prefix means "SELECT Result
** Type".
**
**     SRT_Union       Store results as a key in a temporary index
3355
3356
3357
3358
3359
3360
3361











3362
3363
3364
3365
3366
3367
3368
# define DbMaskTest(M,I)    (((M)&(((yDbMask)1)<<(I)))!=0)
# define DbMaskZero(M)      (M)=0
# define DbMaskSet(M,I)     (M)|=(((yDbMask)1)<<(I))
# define DbMaskAllZero(M)   (M)==0
# define DbMaskNonZero(M)   (M)!=0
#endif












/*
** 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







>
>
>
>
>
>
>
>
>
>
>







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
# define DbMaskTest(M,I)    (((M)&(((yDbMask)1)<<(I)))!=0)
# define DbMaskZero(M)      (M)=0
# define DbMaskSet(M,I)     (M)|=(((yDbMask)1)<<(I))
# define DbMaskAllZero(M)   (M)==0
# define DbMaskNonZero(M)   (M)!=0
#endif

/*
** An instance of the ParseCleanup object specifies an operation that
** should be performed after parsing to deallocation resources obtained
** during the parse and which are no longer needed.
*/
struct ParseCleanup {
  ParseCleanup *pNext;               /* Next cleanup task */
  void *pPtr;                        /* Pointer to object to deallocate */
  void (*xCleanup)(sqlite3*,void*);  /* Deallocation routine */
};

/*
** 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
3386
3387
3388
3389
3390
3391
3392



3393
3394
3395
3396
3397
3398
3399
  u8 nTempReg;         /* Number of temporary registers in aTempReg[] */
  u8 isMultiWrite;     /* True if statement may modify/insert multiple rows */
  u8 mayAbort;         /* True if statement may throw an ABORT exception */
  u8 hasCompound;      /* Need to invoke convertCompoundSelectToSubquery() */
  u8 okConstFactor;    /* OK to factor out constants */
  u8 disableLookaside; /* Number of times lookaside has been disabled */
  u8 disableVtab;      /* Disable all virtual tables for this parse */



  int nRangeReg;       /* Size of the temporary register block */
  int iRangeReg;       /* First register in temporary register block */
  int nErr;            /* Number of errors seen */
  int nTab;            /* Number of previously allocated VDBE cursors */
  int nMem;            /* Number of memory cells used so far */
  int szOpAlloc;       /* Bytes of memory space allocated for Vdbe.aOp[] */
  int iSelfTab;        /* Table associated with an index on expr, or negative







>
>
>







3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
  u8 nTempReg;         /* Number of temporary registers in aTempReg[] */
  u8 isMultiWrite;     /* True if statement may modify/insert multiple rows */
  u8 mayAbort;         /* True if statement may throw an ABORT exception */
  u8 hasCompound;      /* Need to invoke convertCompoundSelectToSubquery() */
  u8 okConstFactor;    /* OK to factor out constants */
  u8 disableLookaside; /* Number of times lookaside has been disabled */
  u8 disableVtab;      /* Disable all virtual tables for this parse */
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
  u8 earlyCleanup;     /* OOM inside sqlite3ParserAddCleanup() */
#endif
  int nRangeReg;       /* Size of the temporary register block */
  int iRangeReg;       /* First register in temporary register block */
  int nErr;            /* Number of errors seen */
  int nTab;            /* Number of previously allocated VDBE cursors */
  int nMem;            /* Number of memory cells used so far */
  int szOpAlloc;       /* Bytes of memory space allocated for Vdbe.aOp[] */
  int iSelfTab;        /* Table associated with an index on expr, or negative
3413
3414
3415
3416
3417
3418
3419
3420
3421


3422
3423
3424
3425

3426
3427
3428
3429
3430
3431
3432
  int nTableLock;        /* Number of locks in aTableLock */
  TableLock *aTableLock; /* Required table locks for shared-cache mode */
#endif
  AutoincInfo *pAinc;  /* Information about AUTOINCREMENT counters */
  Parse *pToplevel;    /* Parse structure for main program (or NULL) */
  Table *pTriggerTab;  /* Table triggers are being coded for */
  Parse *pParentParse; /* Parent parser if this parser is nested */
  AggInfo *pAggList;   /* List of all AggInfo objects */
  int addrCrTab;       /* Address of OP_CreateBtree opcode on CREATE TABLE */


  u32 nQueryLoop;      /* Est number of iterations of a query (10*log2(N)) */
  u32 oldmask;         /* Mask of old.* columns referenced */
  u32 newmask;         /* Mask of new.* 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 */

  /**************************************************************************
  ** Fields above must be initialized to zero.  The fields that follow,
  ** down to the beginning of the recursive section, do not need to be
  ** initialized as they will be set before being used.  The boundary is







|
|
>
>




>







3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
  int nTableLock;        /* Number of locks in aTableLock */
  TableLock *aTableLock; /* Required table locks for shared-cache mode */
#endif
  AutoincInfo *pAinc;  /* Information about AUTOINCREMENT counters */
  Parse *pToplevel;    /* Parse structure for main program (or NULL) */
  Table *pTriggerTab;  /* Table triggers are being coded for */
  Parse *pParentParse; /* Parent parser if this parser is nested */
  union {
    int addrCrTab;         /* Address of OP_CreateBtree on CREATE TABLE */
    Returning *pReturning; /* The RETURNING clause */
  } u1;
  u32 nQueryLoop;      /* Est number of iterations of a query (10*log2(N)) */
  u32 oldmask;         /* Mask of old.* columns referenced */
  u32 newmask;         /* Mask of new.* columns referenced */
  u8 eTriggerOp;       /* TK_UPDATE, TK_INSERT or TK_DELETE */
  u8 bReturning;       /* Coding a RETURNING trigger */
  u8 eOrconf;          /* Default ON CONFLICT policy for trigger steps */
  u8 disableTriggers;  /* True to disable triggers */

  /**************************************************************************
  ** Fields above must be initialized to zero.  The fields that follow,
  ** down to the beginning of the recursive section, do not need to be
  ** initialized as they will be set before being used.  The boundary is
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474

3475
3476
3477
3478
3479
3480
3481
                            ** during a RENAME COLUMN */
  Trigger *pNewTrigger;     /* Trigger under construct by a CREATE TRIGGER */
  const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
#ifndef SQLITE_OMIT_VIRTUALTABLE
  Token sArg;               /* Complete text of a module argument */
  Table **apVtabLock;       /* Pointer to virtual tables needing locking */
#endif
  Table *pZombieTab;        /* List of Table objects to delete after code gen */
  TriggerPrg *pTriggerPrg;  /* Linked list of coded triggers */
  With *pWith;              /* Current WITH clause, or NULL */
  With *pWithToFree;        /* Free this WITH object at the end of the parse */

#ifndef SQLITE_OMIT_ALTERTABLE
  RenameToken *pRename;     /* Tokens subject to renaming by ALTER TABLE */
#endif
};

#define PARSE_MODE_NORMAL        0
#define PARSE_MODE_DECLARE_VTAB  1







<


<
>







3557
3558
3559
3560
3561
3562
3563

3564
3565

3566
3567
3568
3569
3570
3571
3572
3573
                            ** during a RENAME COLUMN */
  Trigger *pNewTrigger;     /* Trigger under construct by a CREATE TRIGGER */
  const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
#ifndef SQLITE_OMIT_VIRTUALTABLE
  Token sArg;               /* Complete text of a module argument */
  Table **apVtabLock;       /* Pointer to virtual tables needing locking */
#endif

  TriggerPrg *pTriggerPrg;  /* Linked list of coded triggers */
  With *pWith;              /* Current WITH clause, or NULL */

  ParseCleanup *pCleanup;   /* List of cleanup operations to run after parse */
#ifndef SQLITE_OMIT_ALTERTABLE
  RenameToken *pRename;     /* Tokens subject to renaming by ALTER TABLE */
#endif
};

#define PARSE_MODE_NORMAL        0
#define PARSE_MODE_DECLARE_VTAB  1
3547
3548
3549
3550
3551
3552
3553

3554
3555
3556
3557
3558
3559
3560
#define OPFLAG_SEEKEQ        0x02    /* OP_Open** cursor uses EQ seek only */
#define OPFLAG_FORDELETE     0x08    /* OP_Open should use BTREE_FORDELETE */
#define OPFLAG_P2ISREG       0x10    /* P2 to OP_Open** is a register number */
#define OPFLAG_PERMUTE       0x01    /* OP_Compare: use the permutation */
#define OPFLAG_SAVEPOSITION  0x02    /* OP_Delete/Insert: save cursor pos */
#define OPFLAG_AUXDELETE     0x04    /* OP_Delete: index in a DELETE op */
#define OPFLAG_NOCHNG_MAGIC  0x6d    /* OP_MakeRecord: serialtype 10 is ok */


/*
 * 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







>







3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
#define OPFLAG_SEEKEQ        0x02    /* OP_Open** cursor uses EQ seek only */
#define OPFLAG_FORDELETE     0x08    /* OP_Open should use BTREE_FORDELETE */
#define OPFLAG_P2ISREG       0x10    /* P2 to OP_Open** is a register number */
#define OPFLAG_PERMUTE       0x01    /* OP_Compare: use the permutation */
#define OPFLAG_SAVEPOSITION  0x02    /* OP_Delete/Insert: save cursor pos */
#define OPFLAG_AUXDELETE     0x04    /* OP_Delete: index in a DELETE op */
#define OPFLAG_NOCHNG_MAGIC  0x6d    /* OP_MakeRecord: serialtype 10 is ok */
#define OPFLAG_PREFORMAT     0x80    /* OP_Insert uses preformatted cell */ 

/*
 * 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
3568
3569
3570
3571
3572
3573
3574

3575
3576
3577
3578
3579
3580
3581
 * containing the SQL statements specified as the trigger program.
 */
struct 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 */
  Schema *pTabSchema;     /* Schema containing the table */
  TriggerStep *step_list; /* Link list of trigger program steps             */
  Trigger *pNext;         /* Next trigger associated with the table */







>







3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
 * containing the SQL statements specified as the trigger program.
 */
struct 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 */
  u8 bReturning;          /* This trigger implements a RETURNING clause */
  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 */
  Schema *pTabSchema;     /* Schema containing the table */
  TriggerStep *step_list; /* Link list of trigger program steps             */
  Trigger *pNext;         /* Next trigger associated with the table */
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
 *              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 {
  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;     /* SELECT statement or RHS of INSERT INTO SELECT ... */
  char *zTarget;       /* Target table for DELETE, UPDATE, INSERT */
  SrcList *pFrom;      /* FROM clause for UPDATE statement (if any) */
  Expr *pWhere;        /* The WHERE clause for DELETE or UPDATE steps */
  ExprList *pExprList; /* SET clause for UPDATE */
  IdList *pIdList;     /* Column names for INSERT */
  Upsert *pUpsert;     /* Upsert clauses on an INSERT */
  char *zSpan;         /* Original SQL text of this command */
  TriggerStep *pNext;  /* Next in the link-list */
  TriggerStep *pLast;  /* Last element in link-list. Valid for 1st elem only */
};

/*
** 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 {
  Parse *pParse;      /* The parsing context.  Error messages written here */



  Schema *pSchema;    /* Fix items to this schema */
  u8 bTemp;           /* True for TEMP schema entries */
  const char *zDb;    /* Make sure all objects are contained in this database */
  const char *zType;  /* Type of the container - used for error messages */
  const Token *pName; /* Name of the container - used for error messages */
};

/*
** An objected used to accumulate the text of a string where we
** do not necessarily know how big the string will be in the end.
*/
struct sqlite3_str {







|
>






|








|
<
<

<
|
|
>
>
>
|
|
|
<
<







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
 *              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 {
  u8 op;               /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT,
                       ** or TK_RETURNING */
  u8 orconf;           /* OE_Rollback etc. */
  Trigger *pTrig;      /* The trigger that this step is a part of */
  Select *pSelect;     /* SELECT statement or RHS of INSERT INTO SELECT ... */
  char *zTarget;       /* Target table for DELETE, UPDATE, INSERT */
  SrcList *pFrom;      /* FROM clause for UPDATE statement (if any) */
  Expr *pWhere;        /* The WHERE clause for DELETE or UPDATE steps */
  ExprList *pExprList; /* SET clause for UPDATE, or RETURNING clause */
  IdList *pIdList;     /* Column names for INSERT */
  Upsert *pUpsert;     /* Upsert clauses on an INSERT */
  char *zSpan;         /* Original SQL text of this command */
  TriggerStep *pNext;  /* Next in the link-list */
  TriggerStep *pLast;  /* Last element in link-list. Valid for 1st elem only */
};

/*
** Information about a RETURNING clause


*/

struct Returning {
  Parse *pParse;        /* The parse that includes the RETURNING clause */
  ExprList *pReturnEL;  /* List of expressions to return */
  Trigger retTrig;      /* The transient trigger that implements RETURNING */
  TriggerStep retTStep; /* The trigger step */
  int iRetCur;          /* Transient table holding RETURNING results */
  int nRetCol;          /* Number of in pReturnEL after expansion */
  int iRetReg;          /* Register array for holding a row of RETURNING */


};

/*
** An objected used to accumulate the text of a string where we
** do not necessarily know how big the string will be in the end.
*/
struct sqlite3_str {
3693
3694
3695
3696
3697
3698
3699
3700

3701
3702
3703
3704
3705
3706
3707
  u32 nInitRow;       /* Number of rows processed */
  Pgno mxPage;        /* Maximum page number.  0 for no limit. */
} InitData;

/*
** Allowed values for mInitFlags
*/
#define INITFLAG_AlterTable   0x0001  /* This is a reparse after ALTER TABLE */


/*
** Structure containing global configuration data for the SQLite library.
**
** This structure also contains some state information.
*/
struct Sqlite3Config {







|
>







3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
  u32 nInitRow;       /* Number of rows processed */
  Pgno mxPage;        /* Maximum page number.  0 for no limit. */
} InitData;

/*
** Allowed values for mInitFlags
*/
#define INITFLAG_AlterRename   0x0001  /* Reparse after a RENAME */
#define INITFLAG_AlterDrop     0x0002  /* Reparse after a DROP COLUMN */

/*
** Structure containing global configuration data for the SQLite library.
**
** This structure also contains some state information.
*/
struct Sqlite3Config {
3805
3806
3807
3808
3809
3810
3811
3812

3813
3814















3815
3816
3817
3818
3819
3820
3821
    struct IdxExprTrans *pIdxTrans;           /* Convert idxed expr to column */
    ExprList *pGroupBy;                       /* GROUP BY clause */
    Select *pSelect;                          /* HAVING to WHERE clause ctx */
    struct WindowRewrite *pRewrite;           /* Window rewrite context */
    struct WhereConst *pConst;                /* WHERE clause constants */
    struct RenameCtx *pRename;                /* RENAME COLUMN context */
    struct Table *pTab;                       /* Table of generated column */
    struct SrcList_item *pSrcItem;            /* A single FROM clause item */

  } u;
};
















/* Forward declarations */
int sqlite3WalkExpr(Walker*, Expr*);
int sqlite3WalkExprList(Walker*, ExprList*);
int sqlite3WalkSelect(Walker*, Select*);
int sqlite3WalkSelectExpr(Walker*, Select*);
int sqlite3WalkSelectFrom(Walker*, Select*);







|
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    struct IdxExprTrans *pIdxTrans;           /* Convert idxed expr to column */
    ExprList *pGroupBy;                       /* GROUP BY clause */
    Select *pSelect;                          /* HAVING to WHERE clause ctx */
    struct WindowRewrite *pRewrite;           /* Window rewrite context */
    struct WhereConst *pConst;                /* WHERE clause constants */
    struct RenameCtx *pRename;                /* RENAME COLUMN context */
    struct Table *pTab;                       /* Table of generated column */
    SrcItem *pSrcItem;                        /* A single FROM clause item */
    DbFixer *pFix;
  } u;
};

/*
** The following structure contains information used by the sqliteFix...
** routines as they walk the parse tree to make database references
** explicit.
*/
struct DbFixer {
  Parse *pParse;      /* The parsing context.  Error messages written here */
  Walker w;           /* Walker object */
  Schema *pSchema;    /* Fix items to this schema */
  u8 bTemp;           /* True for TEMP schema entries */
  const char *zDb;    /* Make sure all objects are contained in this database */
  const char *zType;  /* Type of the container - used for error messages */
  const Token *pName; /* Name of the container - used for error messages */
};

/* Forward declarations */
int sqlite3WalkExpr(Walker*, Expr*);
int sqlite3WalkExprList(Walker*, ExprList*);
int sqlite3WalkSelect(Walker*, Select*);
int sqlite3WalkSelectExpr(Walker*, Select*);
int sqlite3WalkSelectFrom(Walker*, Select*);
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
** callbacks.
*/
#define WRC_Continue    0   /* Continue down into children */
#define WRC_Prune       1   /* Omit children but continue walking siblings */
#define WRC_Abort       2   /* Abandon the tree walk */

/*










** An instance of this structure represents a set of one or more CTEs









** (common table expressions) created by a single WITH clause.
*/
struct With {
  int nCte;                       /* Number of CTEs in the WITH clause */
  With *pOuter;                   /* Containing WITH clause, or NULL */
  struct Cte {                    /* For each CTE in the WITH clause.... */

    char *zName;                    /* Name of this CTE */












    ExprList *pCols;                /* List of explicit column names, or NULL */


    Select *pSelect;                /* The definition of this CTE */

    const char *zCteErr;            /* Error message for circular references */
  } a[1];
};


#ifdef SQLITE_DEBUG
/*
** An instance of the TreeView object is used for printing the content of
** data structures on sqlite3DebugPrintf() using a tree-like view.
*/
struct TreeView {







>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
|


|
|
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
|
<

>







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
** callbacks.
*/
#define WRC_Continue    0   /* Continue down into children */
#define WRC_Prune       1   /* Omit children but continue walking siblings */
#define WRC_Abort       2   /* Abandon the tree walk */

/*
** A single common table expression
*/
struct Cte {
  char *zName;            /* Name of this CTE */
  ExprList *pCols;        /* List of explicit column names, or NULL */
  Select *pSelect;        /* The definition of this CTE */
  const char *zCteErr;    /* Error message for circular references */
  CteUse *pUse;           /* Usage information for this CTE */
  u8 eM10d;               /* The MATERIALIZED flag */
};

/*
** Allowed values for the materialized flag (eM10d):
*/
#define M10d_Yes       0  /* AS MATERIALIZED */
#define M10d_Any       1  /* Not specified.  Query planner's choice */
#define M10d_No        2  /* AS NOT MATERIALIZED */

/*
** An instance of the With object represents a WITH clause containing
** one or more CTEs (common table expressions).
*/
struct With {
  int nCte;               /* Number of CTEs in the WITH clause */
  With *pOuter;           /* Containing WITH clause, or NULL */
  Cte a[1];               /* For each CTE in the WITH clause.... */
};

/*
** The Cte object is not guaranteed to persist for the entire duration
** of code generation.  (The query flattener or other parser tree
** edits might delete it.)  The following object records information
** about each Common Table Expression that must be preserved for the
** duration of the parse.
**
** The CteUse objects are freed using sqlite3ParserAddCleanup() rather
** than sqlite3SelectDelete(), which is what enables them to persist
** until the end of code generation.
*/
struct CteUse {
  int nUse;              /* Number of users of this CTE */
  int addrM9e;           /* Start of subroutine to compute materialization */
  int regRtn;            /* Return address register for addrM9e subroutine */
  int iCur;              /* Ephemeral table holding the materialization */
  LogEst nRowEst;        /* Estimated number of rows in the table */
  u8 eM10d;              /* The MATERIALIZED flag */

};


#ifdef SQLITE_DEBUG
/*
** An instance of the TreeView object is used for printing the content of
** data structures on sqlite3DebugPrintf() using a tree-like view.
*/
struct TreeView {
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8);
void sqlite3WindowAttach(Parse*, Expr*, Window*);
void sqlite3WindowLink(Select *pSel, Window *pWin);
int sqlite3WindowCompare(Parse*, Window*, Window*, int);
void sqlite3WindowCodeInit(Parse*, Select*);
void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int);
int sqlite3WindowRewrite(Parse*, Select*);
int sqlite3ExpandSubquery(Parse*, struct SrcList_item*);
void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*);
Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p);
Window *sqlite3WindowListDup(sqlite3 *db, Window *p);
void sqlite3WindowFunctions(void);
void sqlite3WindowChain(Parse*, Window*, Window*);
Window *sqlite3WindowAssemble(Parse*, Window*, ExprList*, ExprList*, Token*);
#else







<







4070
4071
4072
4073
4074
4075
4076

4077
4078
4079
4080
4081
4082
4083
Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8);
void sqlite3WindowAttach(Parse*, Expr*, Window*);
void sqlite3WindowLink(Select *pSel, Window *pWin);
int sqlite3WindowCompare(Parse*, Window*, Window*, int);
void sqlite3WindowCodeInit(Parse*, Select*);
void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int);
int sqlite3WindowRewrite(Parse*, Select*);

void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*);
Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p);
Window *sqlite3WindowListDup(sqlite3 *db, Window *p);
void sqlite3WindowFunctions(void);
void sqlite3WindowChain(Parse*, Window*, Window*);
Window *sqlite3WindowAssemble(Parse*, Window*, ExprList*, ExprList*, Token*);
#else
4242
4243
4244
4245
4246
4247
4248

4249
4250
4251
4252
4253
4254
4255
void sqlite3AddNotNull(Parse*, int);
void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
void sqlite3AddCheckConstraint(Parse*, Expr*, const char*, const char*);
void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*);
void sqlite3AddCollateType(Parse*, Token*);
void sqlite3AddGenerated(Parse*,Expr*,Token*);
void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);

int sqlite3ParseUri(const char*,const char*,unsigned int*,
                    sqlite3_vfs**,char**,char **);
#define sqlite3CodecQueryParameters(A,B,C) 0
Btree *sqlite3DbNameToBtree(sqlite3*,const char*);

#ifdef SQLITE_UNTESTABLE
# define sqlite3FaultSim(X) SQLITE_OK







>







4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
void sqlite3AddNotNull(Parse*, int);
void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
void sqlite3AddCheckConstraint(Parse*, Expr*, const char*, const char*);
void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*);
void sqlite3AddCollateType(Parse*, Token*);
void sqlite3AddGenerated(Parse*,Expr*,Token*);
void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
void sqlite3AddReturning(Parse*,ExprList*);
int sqlite3ParseUri(const char*,const char*,unsigned int*,
                    sqlite3_vfs**,char**,char **);
#define sqlite3CodecQueryParameters(A,B,C) 0
Btree *sqlite3DbNameToBtree(sqlite3*,const char*);

#ifdef SQLITE_UNTESTABLE
# define sqlite3FaultSim(X) SQLITE_OK
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int);
SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2);
SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*);
SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
                                      Token*, Select*, Expr*, IdList*);
void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*);
int sqlite3IndexedByLookup(Parse *, struct SrcList_item *);
void sqlite3SrcListShiftJoinType(SrcList*);
void sqlite3SrcListAssignCursors(Parse*, SrcList*);
void sqlite3IdListDelete(sqlite3*, IdList*);
void sqlite3SrcListDelete(sqlite3*, SrcList*);
Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**);
void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
                          Expr*, int, int, u8);







|







4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int);
SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2);
SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*);
SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
                                      Token*, Select*, Expr*, IdList*);
void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*);
int sqlite3IndexedByLookup(Parse *, SrcItem *);
void sqlite3SrcListShiftJoinType(SrcList*);
void sqlite3SrcListAssignCursors(Parse*, SrcList*);
void sqlite3IdListDelete(sqlite3*, IdList*);
void sqlite3SrcListDelete(sqlite3*, SrcList*);
Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**);
void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
                          Expr*, int, int, u8);
4336
4337
4338
4339
4340
4341
4342

4343
4344
4345
4346
4347
4348
4349
                   Upsert*);
WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
void sqlite3WhereEnd(WhereInfo*);
LogEst sqlite3WhereOutputRowCount(WhereInfo*);
int sqlite3WhereIsDistinct(WhereInfo*);
int sqlite3WhereIsOrdered(WhereInfo*);
int sqlite3WhereOrderByLimitOptLabel(WhereInfo*);

int sqlite3WhereIsSorted(WhereInfo*);
int sqlite3WhereContinueLabel(WhereInfo*);
int sqlite3WhereBreakLabel(WhereInfo*);
int sqlite3WhereOkOnePass(WhereInfo*, int*);
#define ONEPASS_OFF      0        /* Use of ONEPASS not allowed */
#define ONEPASS_SINGLE   1        /* ONEPASS valid for a single row update */
#define ONEPASS_MULTI    2        /* ONEPASS is valid for multiple rows */







>







4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
                   Upsert*);
WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
void sqlite3WhereEnd(WhereInfo*);
LogEst sqlite3WhereOutputRowCount(WhereInfo*);
int sqlite3WhereIsDistinct(WhereInfo*);
int sqlite3WhereIsOrdered(WhereInfo*);
int sqlite3WhereOrderByLimitOptLabel(WhereInfo*);
void sqlite3WhereMinMaxOptEarlyOut(Vdbe*,WhereInfo*);
int sqlite3WhereIsSorted(WhereInfo*);
int sqlite3WhereContinueLabel(WhereInfo*);
int sqlite3WhereBreakLabel(WhereInfo*);
int sqlite3WhereOkOnePass(WhereInfo*, int*);
#define ONEPASS_OFF      0        /* Use of ONEPASS not allowed */
#define ONEPASS_SINGLE   1        /* ONEPASS valid for a single row update */
#define ONEPASS_MULTI    2        /* ONEPASS is valid for multiple rows */
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int);
Table *sqlite3FindTable(sqlite3*,const char*, const char*);
#define LOCATE_VIEW    0x01
#define LOCATE_NOERR   0x02
Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*);
Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_item *);
Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
void sqlite3Vacuum(Parse*,Token*,Expr*);
int sqlite3RunVacuum(char**, sqlite3*, int, sqlite3_value*);
char *sqlite3NameFromToken(sqlite3*, Token*);
int sqlite3ExprCompare(Parse*,Expr*, Expr*, int);







|







4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int);
Table *sqlite3FindTable(sqlite3*,const char*, const char*);
#define LOCATE_VIEW    0x01
#define LOCATE_NOERR   0x02
Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*);
Table *sqlite3LocateTableItem(Parse*,u32 flags,SrcItem *);
Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
void sqlite3Vacuum(Parse*,Token*,Expr*);
int sqlite3RunVacuum(char**, sqlite3*, int, sqlite3_value*);
char *sqlite3NameFromToken(sqlite3*, Token*);
int sqlite3ExprCompare(Parse*,Expr*, Expr*, int);
4499
4500
4501
4502
4503
4504
4505

4506
4507
4508
4509
4510
4511
4512
# define sqlite3ParseToplevel(p) p
# define sqlite3IsToplevel(p) 1
# define sqlite3TriggerColmask(A,B,C,D,E,F,G) 0
# define sqlite3TriggerStepSrc(A,B) 0
#endif

int sqlite3JoinType(Parse*, Token*, Token*, Token*);

void sqlite3SetJoinExpr(Expr*,int);
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*);







>







4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
# define sqlite3ParseToplevel(p) p
# define sqlite3IsToplevel(p) 1
# define sqlite3TriggerColmask(A,B,C,D,E,F,G) 0
# define sqlite3TriggerStepSrc(A,B) 0
#endif

int sqlite3JoinType(Parse*, Token*, Token*, Token*);
int sqlite3ColumnIndex(Table *pTab, const char *zCol);
void sqlite3SetJoinExpr(Expr*,int);
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*);
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName);
void sqlite3Attach(Parse*, Expr*, Expr*, Expr*);
void sqlite3Detach(Parse*, Expr*);
void 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*);
int sqlite3RealSameAsInt(double,sqlite3_int64);
void sqlite3Int64ToText(i64,char*);
int sqlite3AtoF(const char *z, double*, int, u8);
int sqlite3GetInt32(const char *, int*);
int sqlite3GetUInt32(const char*, u32*);
int sqlite3Atoi(const char*);







<







4668
4669
4670
4671
4672
4673
4674

4675
4676
4677
4678
4679
4680
4681
int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName);
void sqlite3Attach(Parse*, Expr*, Expr*, Expr*);
void sqlite3Detach(Parse*, Expr*);
void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
int sqlite3FixSrcList(DbFixer*, SrcList*);
int sqlite3FixSelect(DbFixer*, Select*);
int sqlite3FixExpr(DbFixer*, Expr*);

int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
int sqlite3RealSameAsInt(double,sqlite3_int64);
void sqlite3Int64ToText(i64,char*);
int sqlite3AtoF(const char *z, double*, int, u8);
int sqlite3GetInt32(const char *, int*);
int sqlite3GetUInt32(const char*, u32*);
int sqlite3Atoi(const char*);
4584
4585
4586
4587
4588
4589
4590

4591
4592
4593
4594
4595
4596
4597
int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity);
char sqlite3TableColumnAffinity(Table*,int);
char sqlite3ExprAffinity(const Expr *pExpr);
int sqlite3Atoi64(const char*, i64*, int, u8);
int sqlite3DecOrHexToI64(const char*, i64*);
void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
void sqlite3Error(sqlite3*,int);

void sqlite3SystemError(sqlite3*,int);
void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
u8 sqlite3HexToInt(int h);
int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);

#if defined(SQLITE_NEED_ERR_NAME)
const char *sqlite3ErrName(int);







>







4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity);
char sqlite3TableColumnAffinity(Table*,int);
char sqlite3ExprAffinity(const Expr *pExpr);
int sqlite3Atoi64(const char*, i64*, int, u8);
int sqlite3DecOrHexToI64(const char*, i64*);
void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
void sqlite3Error(sqlite3*,int);
void sqlite3ErrorClear(sqlite3*);
void sqlite3SystemError(sqlite3*,int);
void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
u8 sqlite3HexToInt(int h);
int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);

#if defined(SQLITE_NEED_ERR_NAME)
const char *sqlite3ErrName(int);
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672

4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689

4690
4691
4692
4693
4694
4695
4696
#ifndef SQLITE_AMALGAMATION
extern const unsigned char sqlite3OpcodeProperty[];
extern const char sqlite3StrBINARY[];
extern const unsigned char sqlite3UpperToLower[];
extern const unsigned char sqlite3CtypeMap[];
extern SQLITE_WSD struct Sqlite3Config sqlite3Config;
extern FuncDefHash sqlite3BuiltinFunctions;
extern u32 sqlite3_unsupported_selecttrace;
#ifndef SQLITE_OMIT_WSD
extern int sqlite3PendingByte;
#endif
#endif /* SQLITE_AMALGAMATION */
#ifdef VDBE_PROFILE
extern sqlite3_uint64 sqlite3NProfileCnt;
#endif
void sqlite3RootPageMoved(sqlite3*, int, Pgno, Pgno);
void sqlite3Reindex(Parse*, Token*, Token*);
void sqlite3AlterFunctions(void);
void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
int sqlite3GetToken(const unsigned char *, int *);
void sqlite3NestedParse(Parse*, const char*, ...);
void sqlite3ExpirePreparedStatements(sqlite3*, int);
void sqlite3CodeRhsOfIN(Parse*, Expr*, int);
int sqlite3CodeSubselect(Parse*, Expr*);
void sqlite3SelectPrep(Parse*, Select*, NameContext*);

void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
int sqlite3MatchEName(
  const struct ExprList_item*,
  const char*,
  const char*,
  const char*
);
Bitmask sqlite3ExprColUsed(Expr*);
u8 sqlite3StrIHash(const char*);
int sqlite3ResolveExprNames(NameContext*, Expr*);
int sqlite3ResolveExprListNames(NameContext*, ExprList*);
void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
int sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
void sqlite3AlterFinishAddColumn(Parse *, Token *);
void sqlite3AlterBeginAddColumn(Parse *, SrcList *);

void *sqlite3RenameTokenMap(Parse*, void*, Token*);
void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom);
void sqlite3RenameExprUnmap(Parse*, Expr*);
void sqlite3RenameExprlistUnmap(Parse*, ExprList*);
CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
char sqlite3AffinityType(const char*, Column*);
void sqlite3Analyze(Parse*, Token*, Token*);







<


















>

















>







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
#ifndef SQLITE_AMALGAMATION
extern const unsigned char sqlite3OpcodeProperty[];
extern const char sqlite3StrBINARY[];
extern const unsigned char sqlite3UpperToLower[];
extern const unsigned char sqlite3CtypeMap[];
extern SQLITE_WSD struct Sqlite3Config sqlite3Config;
extern FuncDefHash sqlite3BuiltinFunctions;

#ifndef SQLITE_OMIT_WSD
extern int sqlite3PendingByte;
#endif
#endif /* SQLITE_AMALGAMATION */
#ifdef VDBE_PROFILE
extern sqlite3_uint64 sqlite3NProfileCnt;
#endif
void sqlite3RootPageMoved(sqlite3*, int, Pgno, Pgno);
void sqlite3Reindex(Parse*, Token*, Token*);
void sqlite3AlterFunctions(void);
void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
int sqlite3GetToken(const unsigned char *, int *);
void sqlite3NestedParse(Parse*, const char*, ...);
void sqlite3ExpirePreparedStatements(sqlite3*, int);
void sqlite3CodeRhsOfIN(Parse*, Expr*, int);
int sqlite3CodeSubselect(Parse*, Expr*);
void sqlite3SelectPrep(Parse*, Select*, NameContext*);
int sqlite3ExpandSubquery(Parse*, SrcItem*);
void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
int sqlite3MatchEName(
  const struct ExprList_item*,
  const char*,
  const char*,
  const char*
);
Bitmask sqlite3ExprColUsed(Expr*);
u8 sqlite3StrIHash(const char*);
int sqlite3ResolveExprNames(NameContext*, Expr*);
int sqlite3ResolveExprListNames(NameContext*, ExprList*);
void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
int sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
void sqlite3AlterFinishAddColumn(Parse *, Token *);
void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
void sqlite3AlterDropColumn(Parse*, SrcList*, Token*);
void *sqlite3RenameTokenMap(Parse*, void*, Token*);
void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom);
void sqlite3RenameExprUnmap(Parse*, Expr*);
void sqlite3RenameExprlistUnmap(Parse*, ExprList*);
CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
char sqlite3AffinityType(const char*, Column*);
void sqlite3Analyze(Parse*, Token*, Token*);
4706
4707
4708
4709
4710
4711
4712

4713
4714
4715
4716
4717
4718
4719
Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int);
void sqlite3KeyInfoUnref(KeyInfo*);
KeyInfo *sqlite3KeyInfoRef(KeyInfo*);
KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*);
KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int);

int sqlite3HasExplicitNulls(Parse*, ExprList*);

#ifdef SQLITE_DEBUG
int sqlite3KeyInfoIsWriteable(KeyInfo*);
#endif
int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
  void (*)(sqlite3_context*,int,sqlite3_value **),







>







4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int);
void sqlite3KeyInfoUnref(KeyInfo*);
KeyInfo *sqlite3KeyInfoRef(KeyInfo*);
KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*);
KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int);
const char *sqlite3SelectOpName(int);
int sqlite3HasExplicitNulls(Parse*, ExprList*);

#ifdef SQLITE_DEBUG
int sqlite3KeyInfoIsWriteable(KeyInfo*);
#endif
int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
  void (*)(sqlite3_context*,int,sqlite3_value **),
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
int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
int sqlite3VtabBegin(sqlite3 *, VTable *);
FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
void sqlite3ParserReset(Parse*);

#ifdef SQLITE_ENABLE_NORMALIZE
char *sqlite3Normalize(Vdbe*, const char*);
#endif
int sqlite3Reprepare(Vdbe*);
void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
CollSeq *sqlite3ExprCompareCollSeq(Parse*,const Expr*);
CollSeq *sqlite3BinaryCompareCollSeq(Parse *, const Expr*, const Expr*);
int sqlite3TempInMemory(const sqlite3*);
const char *sqlite3JournalModename(int);
#ifndef SQLITE_OMIT_WAL
  int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
  int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
#endif
#ifndef SQLITE_OMIT_CTE


  With *sqlite3WithAdd(Parse*,With*,Token*,ExprList*,Select*);
  void sqlite3WithDelete(sqlite3*,With*);
  void sqlite3WithPush(Parse*, With*, u8);
#else

#define sqlite3WithPush(x,y,z)

#define sqlite3WithDelete(x,y)

#endif
#ifndef SQLITE_OMIT_UPSERT
  Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*);
  void sqlite3UpsertDelete(sqlite3*,Upsert*);
  Upsert *sqlite3UpsertDup(sqlite3*,Upsert*);
  int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*);
  void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int);


#else
#define sqlite3UpsertNew(v,w,x,y,z) ((Upsert*)0)
#define sqlite3UpsertDelete(x,y)
#define sqlite3UpsertDup(x,y)       ((Upsert*)0)


#endif


/* 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







>














>
>
|



>
|
>
|
>


|




>
>

|

|
>
>







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
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
int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
int sqlite3VtabBegin(sqlite3 *, VTable *);
FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
void sqlite3ParserReset(Parse*);
void *sqlite3ParserAddCleanup(Parse*,void(*)(sqlite3*,void*),void*);
#ifdef SQLITE_ENABLE_NORMALIZE
char *sqlite3Normalize(Vdbe*, const char*);
#endif
int sqlite3Reprepare(Vdbe*);
void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
CollSeq *sqlite3ExprCompareCollSeq(Parse*,const Expr*);
CollSeq *sqlite3BinaryCompareCollSeq(Parse *, const Expr*, const Expr*);
int sqlite3TempInMemory(const sqlite3*);
const char *sqlite3JournalModename(int);
#ifndef SQLITE_OMIT_WAL
  int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
  int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
#endif
#ifndef SQLITE_OMIT_CTE
  Cte *sqlite3CteNew(Parse*,Token*,ExprList*,Select*,u8);
  void sqlite3CteDelete(sqlite3*,Cte*);
  With *sqlite3WithAdd(Parse*,With*,Cte*);
  void sqlite3WithDelete(sqlite3*,With*);
  void sqlite3WithPush(Parse*, With*, u8);
#else
# define sqlite3CteNew(P,T,E,S)   ((void*)0)
# define sqlite3CteDelete(D,C)
# define sqlite3CteWithAdd(P,W,C) ((void*)0)
# define sqlite3WithDelete(x,y)
# define sqlite3WithPush(x,y,z)
#endif
#ifndef SQLITE_OMIT_UPSERT
  Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*);
  void sqlite3UpsertDelete(sqlite3*,Upsert*);
  Upsert *sqlite3UpsertDup(sqlite3*,Upsert*);
  int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*);
  void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int);
  Upsert *sqlite3UpsertOfIndex(Upsert*,Index*);
  int sqlite3UpsertNextIsIPK(Upsert*);
#else
#define sqlite3UpsertNew(u,v,w,x,y,z) ((Upsert*)0)
#define sqlite3UpsertDelete(x,y)
#define sqlite3UpsertDup(x,y)         ((Upsert*)0)
#define sqlite3UpsertOfIndex(x,y)     ((Upsert*)0)
#define sqlite3UpsertNextIsIPK(x)     0
#endif


/* 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
Changes to src/test1.c.
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
){
  int i = 0;
  sqlite3 *db = 0;
  if( objc!=2 && objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "SEED ?DB?");
    return TCL_ERROR;
  }
  if( Tcl_GetIntFromObj(interp,objv[0],&i) ) return TCL_ERROR;
  if( objc==3 && getDbPointer(interp, Tcl_GetString(objv[2]), &db) ){
    return TCL_ERROR;
  }
  sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, i, db);
  return TCL_OK;
}








|







6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
){
  int i = 0;
  sqlite3 *db = 0;
  if( objc!=2 && objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "SEED ?DB?");
    return TCL_ERROR;
  }
  if( Tcl_GetIntFromObj(interp,objv[1],&i) ) return TCL_ERROR;
  if( objc==3 && getDbPointer(interp, Tcl_GetString(objv[2]), &db) ){
    return TCL_ERROR;
  }
  sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, i, db);
  return TCL_OK;
}

7490
7491
7492
7493
7494
7495
7496

7497
7498
7499
7500
7501
7502
7503
static int SQLITE_TCLAPI tclLoadStaticExtensionCmd(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  extern int sqlite3_amatch_init(sqlite3*,char**,const sqlite3_api_routines*);

  extern int sqlite3_carray_init(sqlite3*,char**,const sqlite3_api_routines*);
  extern int sqlite3_closure_init(sqlite3*,char**,const sqlite3_api_routines*);
  extern int sqlite3_csv_init(sqlite3*,char**,const sqlite3_api_routines*);
  extern int sqlite3_eval_init(sqlite3*,char**,const sqlite3_api_routines*);
  extern int sqlite3_explain_init(sqlite3*,char**,const sqlite3_api_routines*);
  extern int sqlite3_fileio_init(sqlite3*,char**,const sqlite3_api_routines*);
  extern int sqlite3_decimal_init(sqlite3*,char**,const sqlite3_api_routines*);







>







7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
static int SQLITE_TCLAPI tclLoadStaticExtensionCmd(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  extern int sqlite3_amatch_init(sqlite3*,char**,const sqlite3_api_routines*);
  extern int sqlite3_appendvfs_init(sqlite3*,char**,const sqlite3_api_routines*);
  extern int sqlite3_carray_init(sqlite3*,char**,const sqlite3_api_routines*);
  extern int sqlite3_closure_init(sqlite3*,char**,const sqlite3_api_routines*);
  extern int sqlite3_csv_init(sqlite3*,char**,const sqlite3_api_routines*);
  extern int sqlite3_eval_init(sqlite3*,char**,const sqlite3_api_routines*);
  extern int sqlite3_explain_init(sqlite3*,char**,const sqlite3_api_routines*);
  extern int sqlite3_fileio_init(sqlite3*,char**,const sqlite3_api_routines*);
  extern int sqlite3_decimal_init(sqlite3*,char**,const sqlite3_api_routines*);
7519
7520
7521
7522
7523
7524
7525

7526
7527
7528
7529
7530
7531
7532
  extern int sqlite3_zipfile_init(sqlite3*,char**,const sqlite3_api_routines*);
#endif
  static const struct {
    const char *zExtName;
    int (*pInit)(sqlite3*,char**,const sqlite3_api_routines*);
  } aExtension[] = {
    { "amatch",                sqlite3_amatch_init               },

    { "carray",                sqlite3_carray_init               },
    { "closure",               sqlite3_closure_init              },
    { "csv",                   sqlite3_csv_init                  },
    { "decimal",               sqlite3_decimal_init              },
    { "eval",                  sqlite3_eval_init                 },
    { "explain",               sqlite3_explain_init              },
    { "fileio",                sqlite3_fileio_init               },







>







7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
  extern int sqlite3_zipfile_init(sqlite3*,char**,const sqlite3_api_routines*);
#endif
  static const struct {
    const char *zExtName;
    int (*pInit)(sqlite3*,char**,const sqlite3_api_routines*);
  } aExtension[] = {
    { "amatch",                sqlite3_amatch_init               },
    { "appendvfs",             sqlite3_appendvfs_init            },
    { "carray",                sqlite3_carray_init               },
    { "closure",               sqlite3_closure_init              },
    { "csv",                   sqlite3_csv_init                  },
    { "decimal",               sqlite3_decimal_init              },
    { "eval",                  sqlite3_eval_init                 },
    { "explain",               sqlite3_explain_init              },
    { "fileio",                sqlite3_fileio_init               },
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
      return TCL_ERROR;
    }
    if( aExtension[i].pInit ){
      rc = aExtension[i].pInit(db, &zErrMsg, 0);
    }else{
      rc = SQLITE_OK;
    }
    if( rc!=SQLITE_OK || zErrMsg ){
      Tcl_AppendResult(interp, "initialization of ", zName, " failed: ", zErrMsg,
                       (char*)0);
      sqlite3_free(zErrMsg);
      return TCL_ERROR;
    }
  }
  return TCL_OK;







|







7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
      return TCL_ERROR;
    }
    if( aExtension[i].pInit ){
      rc = aExtension[i].pInit(db, &zErrMsg, 0);
    }else{
      rc = SQLITE_OK;
    }
    if( (rc!=SQLITE_OK && rc!=SQLITE_OK_LOAD_PERMANENTLY) || zErrMsg ){
      Tcl_AppendResult(interp, "initialization of ", zName, " failed: ", zErrMsg,
                       (char*)0);
      sqlite3_free(zErrMsg);
      return TCL_ERROR;
    }
  }
  return TCL_OK;
8593
8594
8595
8596
8597
8598
8599
8600
8601
8602
8603
8604
8605
8606
8607
8608
8609
8610
8611
8612
8613
8614
8615
8616
8617
8618
  extern int sqlite3_pager_readdb_count;
  extern int sqlite3_pager_writedb_count;
  extern int sqlite3_pager_writej_count;
#if SQLITE_OS_WIN
  extern LONG volatile sqlite3_os_type;
#endif
#ifdef SQLITE_DEBUG
  extern int sqlite3WhereTrace;
  extern int sqlite3OSTrace;
  extern int sqlite3WalTrace;
#endif
#ifdef SQLITE_TEST
#ifdef SQLITE_ENABLE_FTS3
  extern int sqlite3_fts3_enable_parentheses;
#endif
#endif
#if defined(SQLITE_ENABLE_SELECTTRACE)
  extern u32 sqlite3_unsupported_selecttrace;
#endif

  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }
  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, 
        aObjCmd[i].xProc, aObjCmd[i].clientData, 0);







|








<
<
<







8595
8596
8597
8598
8599
8600
8601
8602
8603
8604
8605
8606
8607
8608
8609
8610



8611
8612
8613
8614
8615
8616
8617
  extern int sqlite3_pager_readdb_count;
  extern int sqlite3_pager_writedb_count;
  extern int sqlite3_pager_writej_count;
#if SQLITE_OS_WIN
  extern LONG volatile sqlite3_os_type;
#endif
#ifdef SQLITE_DEBUG
  extern u32 sqlite3WhereTrace;
  extern int sqlite3OSTrace;
  extern int sqlite3WalTrace;
#endif
#ifdef SQLITE_TEST
#ifdef SQLITE_ENABLE_FTS3
  extern int sqlite3_fts3_enable_parentheses;
#endif
#endif




  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }
  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, 
        aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
8692
8693
8694
8695
8696
8697
8698
8699
8700
8701
8702
8703
8704
8705
8706
      (char*)&longdouble_size, TCL_LINK_INT|TCL_LINK_READ_ONLY);
  Tcl_LinkVar(interp, "sqlite_sync_count",
      (char*)&sqlite3_sync_count, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_fullsync_count",
      (char*)&sqlite3_fullsync_count, TCL_LINK_INT);
#if defined(SQLITE_ENABLE_SELECTTRACE)
  Tcl_LinkVar(interp, "sqlite3_unsupported_selecttrace",
      (char*)&sqlite3_unsupported_selecttrace, TCL_LINK_INT);
#endif
#if defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_TEST)
  Tcl_LinkVar(interp, "sqlite_fts3_enable_parentheses",
      (char*)&sqlite3_fts3_enable_parentheses, TCL_LINK_INT);
#endif
  return TCL_OK;
}







|







8691
8692
8693
8694
8695
8696
8697
8698
8699
8700
8701
8702
8703
8704
8705
      (char*)&longdouble_size, TCL_LINK_INT|TCL_LINK_READ_ONLY);
  Tcl_LinkVar(interp, "sqlite_sync_count",
      (char*)&sqlite3_sync_count, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_fullsync_count",
      (char*)&sqlite3_fullsync_count, TCL_LINK_INT);
#if defined(SQLITE_ENABLE_SELECTTRACE)
  Tcl_LinkVar(interp, "sqlite3_unsupported_selecttrace",
      (char*)&sqlite3SelectTrace, TCL_LINK_INT);
#endif
#if defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_TEST)
  Tcl_LinkVar(interp, "sqlite_fts3_enable_parentheses",
      (char*)&sqlite3_fts3_enable_parentheses, TCL_LINK_INT);
#endif
  return TCL_OK;
}
Changes to src/test_config.c.
149
150
151
152
153
154
155






156
157
158
159
160
161
162
#endif

#ifdef SQLITE_ENABLE_DESERIALIZE
  Tcl_SetVar2(interp, "sqlite_options", "deserialize", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "deserialize", "0", TCL_GLOBAL_ONLY);
#endif







#ifdef SQLITE_ENABLE_MEMSYS3
  Tcl_SetVar2(interp, "sqlite_options", "mem3", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "mem3", "0", TCL_GLOBAL_ONLY);
#endif








>
>
>
>
>
>







149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#endif

#ifdef SQLITE_ENABLE_DESERIALIZE
  Tcl_SetVar2(interp, "sqlite_options", "deserialize", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "deserialize", "0", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_ENABLE_MATH_FUNCTIONS
  Tcl_SetVar2(interp, "sqlite_options", "mathlib", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "mathlib", "0", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_ENABLE_MEMSYS3
  Tcl_SetVar2(interp, "sqlite_options", "mem3", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "mem3", "0", TCL_GLOBAL_ONLY);
#endif

Changes to src/tokenize.c.
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
** In the sqlite3GetToken() function, a switch() on aiClass[c] is implemented
** using a lookup table, whereas a switch() directly on c uses a binary search.
** The lookup table is much faster.  To maximize speed, and to ensure that
** a lookup table is used, all of the classes need to be small integers and
** all of them need to be used within the switch.
*/
#define CC_X          0    /* The letter 'x', or start of BLOB literal */

#define CC_KYWD       1    /* Alphabetics or '_'.  Usable in a keyword */
#define CC_ID         2    /* unicode characters usable in IDs */
#define CC_DIGIT      3    /* Digits */
#define CC_DOLLAR     4    /* '$' */
#define CC_VARALPHA   5    /* '@', '#', ':'.  Alphabetic SQL variables */
#define CC_VARNUM     6    /* '?'.  Numeric SQL variables */
#define CC_SPACE      7    /* Space characters */
#define CC_QUOTE      8    /* '"', '\'', or '`'.  String literals, quoted ids */
#define CC_QUOTE2     9    /* '['.   [...] style quoted ids */







>
|
<







23
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
** In the sqlite3GetToken() function, a switch() on aiClass[c] is implemented
** using a lookup table, whereas a switch() directly on c uses a binary search.
** The lookup table is much faster.  To maximize speed, and to ensure that
** a lookup table is used, all of the classes need to be small integers and
** all of them need to be used within the switch.
*/
#define CC_X          0    /* The letter 'x', or start of BLOB literal */
#define CC_KYWD0      1    /* First letter of a keyword */
#define CC_KYWD       2    /* Alphabetics or '_'.  Usable in a keyword */

#define CC_DIGIT      3    /* Digits */
#define CC_DOLLAR     4    /* '$' */
#define CC_VARALPHA   5    /* '@', '#', ':'.  Alphabetic SQL variables */
#define CC_VARNUM     6    /* '?'.  Numeric SQL variables */
#define CC_SPACE      7    /* Space characters */
#define CC_QUOTE      8    /* '"', '\'', or '`'.  String literals, quoted ids */
#define CC_QUOTE2     9    /* '['.   [...] style quoted ids */
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
#define CC_PLUS      20    /* '+' */
#define CC_STAR      21    /* '*' */
#define CC_PERCENT   22    /* '%' */
#define CC_COMMA     23    /* ',' */
#define CC_AND       24    /* '&' */
#define CC_TILDA     25    /* '~' */
#define CC_DOT       26    /* '.' */

#define CC_ILLEGAL   27    /* Illegal character */
#define CC_NUL       28    /* 0x00 */

static const unsigned char aiClass[] = {
#ifdef SQLITE_ASCII
/*         x0  x1  x2  x3  x4  x5  x6  x7  x8  x9  xa  xb  xc  xd  xe  xf */
/* 0x */   28, 27, 27, 27, 27, 27, 27, 27, 27,  7,  7, 27,  7,  7, 27, 27,
/* 1x */   27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
/* 2x */    7, 15,  8,  5,  4, 22, 24,  8, 17, 18, 21, 20, 23, 11, 26, 16,
/* 3x */    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  5, 19, 12, 14, 13,  6,
/* 4x */    5,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
/* 5x */    1,  1,  1,  1,  1,  1,  1,  1,  0,  1,  1,  9, 27, 27, 27,  1,
/* 6x */    8,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
/* 7x */    1,  1,  1,  1,  1,  1,  1,  1,  0,  1,  1, 27, 10, 27, 25, 27,
/* 8x */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
/* 9x */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
/* Ax */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
/* Bx */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
/* Cx */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
/* Dx */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
/* Ex */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
/* Fx */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2
#endif
#ifdef SQLITE_EBCDIC
/*         x0  x1  x2  x3  x4  x5  x6  x7  x8  x9  xa  xb  xc  xd  xe  xf */
/* 0x */   27, 27, 27, 27, 27,  7, 27, 27, 27, 27, 27, 27,  7,  7, 27, 27,
/* 1x */   27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
/* 2x */   27, 27, 27, 27, 27,  7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
/* 3x */   27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
/* 4x */    7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 12, 17, 20, 10,
/* 5x */   24, 27, 27, 27, 27, 27, 27, 27, 27, 27, 15,  4, 21, 18, 19, 27,
/* 6x */   11, 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, 23, 22,  1, 13,  6,
/* 7x */   27, 27, 27, 27, 27, 27, 27, 27, 27,  8,  5,  5,  5,  8, 14,  8,
/* 8x */   27,  1,  1,  1,  1,  1,  1,  1,  1,  1, 27, 27, 27, 27, 27, 27,
/* 9x */   27,  1,  1,  1,  1,  1,  1,  1,  1,  1, 27, 27, 27, 27, 27, 27,
/* Ax */   27, 25,  1,  1,  1,  1,  1,  0,  1,  1, 27, 27, 27, 27, 27, 27,
/* Bx */   27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  9, 27, 27, 27, 27, 27,
/* Cx */   27,  1,  1,  1,  1,  1,  1,  1,  1,  1, 27, 27, 27, 27, 27, 27,
/* Dx */   27,  1,  1,  1,  1,  1,  1,  1,  1,  1, 27, 27, 27, 27, 27, 27,
/* Ex */   27, 27,  1,  1,  1,  1,  1,  0,  1,  1, 27, 27, 27, 27, 27, 27,
/* Fx */    3,  3,  3,  3,  3,  3,  3,  3,  3,  3, 27, 27, 27, 27, 27, 27,
#endif
};

/*
** The charMap() macro maps alphabetic characters (only) into their
** lower-case ASCII equivalent.  On ASCII machines, this is just
** an upper-to-lower case map.  On EBCDIC machines we also need







>
|
|




|
|



|

|











|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







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
#define CC_PLUS      20    /* '+' */
#define CC_STAR      21    /* '*' */
#define CC_PERCENT   22    /* '%' */
#define CC_COMMA     23    /* ',' */
#define CC_AND       24    /* '&' */
#define CC_TILDA     25    /* '~' */
#define CC_DOT       26    /* '.' */
#define CC_ID        27    /* unicode characters usable in IDs */
#define CC_ILLEGAL   28    /* Illegal character */
#define CC_NUL       29    /* 0x00 */

static const unsigned char aiClass[] = {
#ifdef SQLITE_ASCII
/*         x0  x1  x2  x3  x4  x5  x6  x7  x8  x9  xa  xb  xc  xd  xe  xf */
/* 0x */   29, 28, 28, 28, 28, 28, 28, 28, 28,  7,  7, 28,  7,  7, 28, 28,
/* 1x */   28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
/* 2x */    7, 15,  8,  5,  4, 22, 24,  8, 17, 18, 21, 20, 23, 11, 26, 16,
/* 3x */    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  5, 19, 12, 14, 13,  6,
/* 4x */    5,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
/* 5x */    1,  1,  1,  1,  1,  1,  1,  1,  0,  2,  2,  9, 28, 28, 28,  2,
/* 6x */    8,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
/* 7x */    1,  1,  1,  1,  1,  1,  1,  1,  0,  2,  2, 28, 10, 28, 25, 28,
/* 8x */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
/* 9x */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
/* Ax */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
/* Bx */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
/* Cx */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
/* Dx */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
/* Ex */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
/* Fx */    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2
#endif
#ifdef SQLITE_EBCDIC
/*         x0  x1  x2  x3  x4  x5  x6  x7  x8  x9  xa  xb  xc  xd  xe  xf */
/* 0x */   29, 28, 28, 28, 28,  7, 28, 28, 28, 28, 28, 28,  7,  7, 28, 28,
/* 1x */   28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
/* 2x */   28, 28, 28, 28, 28,  7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
/* 3x */   28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
/* 4x */    7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 26, 12, 17, 20, 10,
/* 5x */   24, 28, 28, 28, 28, 28, 28, 28, 28, 28, 15,  4, 21, 18, 19, 28,
/* 6x */   11, 16, 28, 28, 28, 28, 28, 28, 28, 28, 28, 23, 22,  2, 13,  6,
/* 7x */   28, 28, 28, 28, 28, 28, 28, 28, 28,  8,  5,  5,  5,  8, 14,  8,
/* 8x */   28,  1,  1,  1,  1,  1,  1,  1,  1,  1, 28, 28, 28, 28, 28, 28,
/* 9x */   28,  1,  1,  1,  1,  1,  1,  1,  1,  1, 28, 28, 28, 28, 28, 28,
/* Ax */   28, 25,  1,  1,  1,  1,  1,  0,  2,  2, 28, 28, 28, 28, 28, 28,
/* Bx */   28, 28, 28, 28, 28, 28, 28, 28, 28, 28,  9, 28, 28, 28, 28, 28,
/* Cx */   28,  1,  1,  1,  1,  1,  1,  1,  1,  1, 28, 28, 28, 28, 28, 28,
/* Dx */   28,  1,  1,  1,  1,  1,  1,  1,  1,  1, 28, 28, 28, 28, 28, 28,
/* Ex */   28, 28,  1,  1,  1,  1,  1,  0,  2,  2, 28, 28, 28, 28, 28, 28,
/* Fx */    3,  3,  3,  3,  3,  3,  3,  3,  3,  3, 28, 28, 28, 28, 28, 28,
#endif
};

/*
** The charMap() macro maps alphabetic characters (only) into their
** lower-case ASCII equivalent.  On ASCII machines, this is just
** an upper-to-lower case map.  On EBCDIC machines we also need
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
        }else{
          break;
        }
      }
      if( n==0 ) *tokenType = TK_ILLEGAL;
      return i;
    }
    case CC_KYWD: {
      for(i=1; aiClass[z[i]]<=CC_KYWD; i++){}
      if( IdChar(z[i]) ){
        /* This token started out using characters that can appear in keywords,
        ** but z[i] is a character not allowed within keywords, so this must
        ** be an identifier instead */
        i++;
        break;







|







496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
        }else{
          break;
        }
      }
      if( n==0 ) *tokenType = TK_ILLEGAL;
      return i;
    }
    case CC_KYWD0: {
      for(i=1; aiClass[z[i]]<=CC_KYWD; i++){}
      if( IdChar(z[i]) ){
        /* This token started out using characters that can appear in keywords,
        ** but z[i] is a character not allowed within keywords, so this must
        ** be an identifier instead */
        i++;
        break;
525
526
527
528
529
530
531

532
533
534
535
536
537
538
        return i;
      }
#endif
      /* If it is not a BLOB literal, then it must be an ID, since no
      ** SQL keywords start with the letter 'x'.  Fall through */
      /* no break */ deliberate_fall_through
    }

    case CC_ID: {
      i = 1;
      break;
    }
    case CC_NUL: {
      *tokenType = TK_ILLEGAL;
      return 0;







>







526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
        return i;
      }
#endif
      /* If it is not a BLOB literal, then it must be an ID, since no
      ** SQL keywords start with the letter 'x'.  Fall through */
      /* no break */ deliberate_fall_through
    }
    case CC_KYWD:
    case CC_ID: {
      i = 1;
      break;
    }
    case CC_NUL: {
      *tokenType = TK_ILLEGAL;
      return 0;
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
    ** will take responsibility for freeing the Table structure.
    */
    sqlite3DeleteTable(db, pParse->pNewTable);
  }
  if( !IN_RENAME_OBJECT ){
    sqlite3DeleteTrigger(db, pParse->pNewTrigger);
  }

  if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree);
  sqlite3DbFree(db, pParse->pVList);
  while( pParse->pAinc ){
    AutoincInfo *p = pParse->pAinc;
    pParse->pAinc = p->pNext;
    sqlite3DbFreeNN(db, p);
  }
  while( pParse->pZombieTab ){
    Table *p = pParse->pZombieTab;
    pParse->pZombieTab = p->pNextZombie;
    sqlite3DeleteTable(db, p);
  }
  db->pParse = pParse->pParentParse;
  pParse->pParentParse = 0;
  assert( nErr==0 || pParse->rc!=SQLITE_OK );
  return nErr;
}









<
<

<
<
<
<
<
<
<
<
<
<







709
710
711
712
713
714
715


716










717
718
719
720
721
722
723
    ** will take responsibility for freeing the Table structure.
    */
    sqlite3DeleteTable(db, pParse->pNewTable);
  }
  if( !IN_RENAME_OBJECT ){
    sqlite3DeleteTrigger(db, pParse->pNewTrigger);
  }


  sqlite3DbFree(db, pParse->pVList);










  db->pParse = pParse->pParentParse;
  pParse->pParentParse = 0;
  assert( nErr==0 || pParse->rc!=SQLITE_OK );
  return nErr;
}


Changes to src/treeview.c.
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
        int j;
        for(j=0; j<pCte->pCols->nExpr; j++){
          sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zEName);
          cSep = ',';
        }
        sqlite3_str_appendf(&x, ")");
      }

      sqlite3_str_appendf(&x, " AS");


      sqlite3StrAccumFinish(&x);
      sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
      sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
      sqlite3TreeViewPop(pView);
    }
    sqlite3TreeViewPop(pView);
  }
}

/*
** Generate a human-readable description of a SrcList object.
*/
void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){
  int i;
  for(i=0; i<pSrc->nSrc; i++){
    const struct SrcList_item *pItem = &pSrc->a[i];
    StrAccum x;
    char zLine[100];
    sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
    sqlite3_str_appendf(&x, "{%d:*}", pItem->iCursor);
    if( pItem->zDatabase ){
      sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
    }else if( pItem->zName ){







>
|
>
>















|







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
        int j;
        for(j=0; j<pCte->pCols->nExpr; j++){
          sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zEName);
          cSep = ',';
        }
        sqlite3_str_appendf(&x, ")");
      }
      if( pCte->pUse ){
        sqlite3_str_appendf(&x, " (pUse=0x%p, nUse=%d)", pCte->pUse,
                 pCte->pUse->nUse);
      }
      sqlite3StrAccumFinish(&x);
      sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
      sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
      sqlite3TreeViewPop(pView);
    }
    sqlite3TreeViewPop(pView);
  }
}

/*
** Generate a human-readable description of a SrcList object.
*/
void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){
  int i;
  for(i=0; i<pSrc->nSrc; i++){
    const SrcItem *pItem = &pSrc->a[i];
    StrAccum x;
    char zLine[100];
    sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
    sqlite3_str_appendf(&x, "{%d:*}", pItem->iCursor);
    if( pItem->zDatabase ){
      sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
    }else if( pItem->zName ){
146
147
148
149
150
151
152



153
154
155
156
157
158
159
    }
    if( pItem->fg.jointype & JT_LEFT ){
      sqlite3_str_appendf(&x, " LEFT-JOIN");
    }
    if( pItem->fg.fromDDL ){
      sqlite3_str_appendf(&x, " DDL");
    }



    sqlite3StrAccumFinish(&x);
    sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1); 
    if( pItem->pSelect ){
      sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
    }
    if( pItem->fg.isTabFunc ){
      sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");







>
>
>







149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
    }
    if( pItem->fg.jointype & JT_LEFT ){
      sqlite3_str_appendf(&x, " LEFT-JOIN");
    }
    if( pItem->fg.fromDDL ){
      sqlite3_str_appendf(&x, " DDL");
    }
    if( pItem->fg.isCte ){
      sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse);
    }
    sqlite3StrAccumFinish(&x);
    sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1); 
    if( pItem->pSelect ){
      sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
    }
    if( pItem->fg.isTabFunc ){
      sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
Changes to src/trigger.c.
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
** and returns the combined list.
**
** 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;
    assert( sqlite3SchemaMutexHeld(pParse->db, 0, pTmpSchema) );
    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) 
      ){
        pTrig->pNext = (pList ? pList : pTab->pTrigger);
        pList = pTrig;







      }

    }
  }

  return (pList ? pList : pTab->pTrigger);
}

/*
** This is called by the parser when it sees a CREATE TRIGGER statement
** up to the point of the BEGIN before the trigger actions.  A Trigger
** structure is generated based on the information available and stored
** in pParse->pNewTrigger.  After the trigger actions have been parsed, the







|
|
>




>
>
>
>
|
>

|
<
<


|

|

>
>
>
>
>
>
>
|
>


<
|







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
** and returns the combined list.
**
** 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 *pTmpSchema;       /* Schema of the pTab table */
  Trigger *pList;           /* List of triggers to return */
  HashElem *p;              /* Loop variable for TEMP triggers */

  if( pParse->disableTriggers ){
    return 0;
  }
  pTmpSchema = pParse->db->aDb[1].pSchema;
  p = sqliteHashFirst(&pTmpSchema->trigHash);
  if( p==0 ){
    return pTab->pTrigger;
  }
  pList = pTab->pTrigger;
  if( pTmpSchema!=pTab->pSchema ){
    while( p ){


      Trigger *pTrig = (Trigger *)sqliteHashData(p);
      if( pTrig->pTabSchema==pTab->pSchema
       && 0==sqlite3StrICmp(pTrig->table, pTab->zName)
      ){
        pTrig->pNext = pList;
        pList = pTrig;
      }else if( pTrig->op==TK_RETURNING ){
        assert( pParse->bReturning );
        assert( &(pParse->u1.pReturning->retTrig) == pTrig );
        pTrig->table = pTab->zName;
        pTrig->pTabSchema = pTab->pSchema;
        pTrig->pNext = pList;
        pList = pTrig;
      }        
      p = sqliteHashNext(p);    
    }
  }

  return pList;  
}

/*
** This is called by the parser when it sees a CREATE TRIGGER statement
** up to the point of the BEGIN before the trigger actions.  A Trigger
** structure is generated based on the information available and stored
** in pParse->pNewTrigger.  After the trigger actions have been parsed, the
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
       "INSERT INTO %Q." DFLT_SCHEMA_TABLE
       " VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
       db->aDb[iDb].zDbSName, zName,
       pTrig->table, z);
    sqlite3DbFree(db, z);
    sqlite3ChangeCookie(pParse, iDb);
    sqlite3VdbeAddParseSchemaOp(v, iDb,
        sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName));
  }

  if( db->init.busy ){
    Trigger *pLink = pTrig;
    Hash *pHash = &db->aDb[iDb].pSchema->trigHash;
    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
    assert( pLink!=0 );







|







352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
       "INSERT INTO %Q." DFLT_SCHEMA_TABLE
       " VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
       db->aDb[iDb].zDbSName, zName,
       pTrig->table, z);
    sqlite3DbFree(db, z);
    sqlite3ChangeCookie(pParse, iDb);
    sqlite3VdbeAddParseSchemaOp(v, iDb,
        sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName), 0);
  }

  if( db->init.busy ){
    Trigger *pLink = pTrig;
    Hash *pHash = &db->aDb[iDb].pSchema->trigHash;
    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
    assert( pLink!=0 );
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
  return pTriggerStep;
}

/* 
** Recursively delete a Trigger structure
*/
void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){
  if( pTrigger==0 ) return;
  sqlite3DeleteTriggerStep(db, pTrigger->step_list);
  sqlite3DbFree(db, pTrigger->zName);
  sqlite3DbFree(db, pTrigger->table);
  sqlite3ExprDelete(db, pTrigger->pWhen);
  sqlite3IdListDelete(db, pTrigger->pColumns);
  sqlite3DbFree(db, pTrigger);
}







|







565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
  return pTriggerStep;
}

/* 
** Recursively delete a Trigger structure
*/
void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){
  if( pTrigger==0 || pTrigger->bReturning ) return;
  sqlite3DeleteTriggerStep(db, pTrigger->step_list);
  sqlite3DbFree(db, pTrigger->zName);
  sqlite3DbFree(db, pTrigger->table);
  sqlite3ExprDelete(db, pTrigger->pWhen);
  sqlite3IdListDelete(db, pTrigger->pColumns);
  sqlite3DbFree(db, pTrigger);
}
719
720
721
722
723
724
725





726






727

728
729

730



731
732










733



734










735
736
737
738
739
740
741
  ExprList *pChanges,     /* Columns that change in an UPDATE statement */
  int *pMask              /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
){
  int mask = 0;
  Trigger *pList = 0;
  Trigger *p;






  if( (pParse->db->flags & SQLITE_EnableTrigger)!=0 ){






    pList = sqlite3TriggerList(pParse, pTab);

  }
  assert( pList==0 || IsVirtual(pTab)==0 );

  for(p=pList; p; p=p->pNext){



    if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){
      mask |= p->tr_tm;










    }



  }










  if( pMask ){
    *pMask = mask;
  }
  return (mask ? pList : 0);
}

/*







>
>
>
>
>
|
>
>
>
>
>
>
|
>
|
<
>
|
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>







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
  ExprList *pChanges,     /* Columns that change in an UPDATE statement */
  int *pMask              /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
){
  int mask = 0;
  Trigger *pList = 0;
  Trigger *p;

  pList = sqlite3TriggerList(pParse, pTab);
  assert( pList==0 || IsVirtual(pTab)==0 
           || (pList->bReturning && pList->pNext==0) );
  if( pList!=0 ){
    p = pList;
    if( (pParse->db->flags & SQLITE_EnableTrigger)==0
     && pTab->pTrigger!=0
    ){
      /* The SQLITE_DBCONFIG_ENABLE_TRIGGER setting is off.  That means that
      ** only TEMP triggers are allowed.  Truncate the pList so that it
      ** includes only TEMP triggers */
      if( pList==pTab->pTrigger ){
        pList = 0;
        goto exit_triggers_exist;
      }

      while( ALWAYS(p->pNext) && p->pNext!=pTab->pTrigger ) p = p->pNext;
      p->pNext = 0;
      p = pList;
    }
    do{
      if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){
        mask |= p->tr_tm;
      }else if( p->op==TK_RETURNING ){
        /* The first time a RETURNING trigger is seen, the "op" value tells
        ** us what time of trigger it should be. */
        assert( sqlite3IsToplevel(pParse) );
        p->op = op;
        if( IsVirtual(pTab) ){
          if( op!=TK_INSERT ){
            sqlite3ErrorMsg(pParse,
              "%s RETURNING is not available on virtual tables",
              op==TK_DELETE ? "DELETE" : "UPDATE");
          }
          p->tr_tm = TRIGGER_BEFORE;
        }else{
          p->tr_tm = TRIGGER_AFTER;
        }
        mask |= p->tr_tm;
      }else if( p->bReturning && p->op==TK_INSERT && op==TK_UPDATE
                && sqlite3IsToplevel(pParse) ){
        /* Also fire a RETURNING trigger for an UPSERT */
        mask |= p->tr_tm;
      }
      p = p->pNext;
    }while( p );
  }
exit_triggers_exist:
  if( pMask ){
    *pMask = mask;
  }
  return (mask ? pList : 0);
}

/*
769
770
771
772
773
774
775









































































































776
777
778
779
780
781
782
      pSrc = sqlite3SrcListAppendList(pParse, pSrc, pDup);
    }
  }else{
    sqlite3DbFree(db, zName);
  }
  return pSrc;
}










































































































/*
** Generate VDBE code for the statements inside the body of a single 
** trigger.
*/
static int codeTriggerProgram(
  Parse *pParse,            /* The parser context */







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
      pSrc = sqlite3SrcListAppendList(pParse, pSrc, pDup);
    }
  }else{
    sqlite3DbFree(db, zName);
  }
  return pSrc;
}

/* The input list pList is the list of result set terms from a RETURNING
** clause.  The table that we are returning from is pTab.
**
** This routine makes a copy of the pList, and at the same time expands
** any "*" wildcards to be the complete set of columns from pTab.
*/
static ExprList *sqlite3ExpandReturning(
  Parse *pParse,        /* Parsing context */
  ExprList *pList,      /* The arguments to RETURNING */
  Table *pTab           /* The table being updated */
){
  ExprList *pNew = 0;
  sqlite3 *db = pParse->db;
  int i;

  for(i=0; i<pList->nExpr; i++){
    Expr *pOldExpr = pList->a[i].pExpr;
    if( ALWAYS(pOldExpr!=0) && pOldExpr->op==TK_ASTERISK ){
      int jj;
      for(jj=0; jj<pTab->nCol; jj++){
        Expr *pNewExpr;
        if( IsHiddenColumn(pTab->aCol+jj) ) continue;
        pNewExpr = sqlite3Expr(db, TK_ID, pTab->aCol[jj].zName);
        pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr);
        if( !db->mallocFailed ){
          struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1];
          pItem->zEName = sqlite3DbStrDup(db, pTab->aCol[jj].zName);
          pItem->eEName = ENAME_NAME;
        }
      }
    }else{
      Expr *pNewExpr = sqlite3ExprDup(db, pOldExpr, 0);
      pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr);
      if( !db->mallocFailed && ALWAYS(pList->a[i].zEName!=0) ){
        struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1];
        pItem->zEName = sqlite3DbStrDup(db, pList->a[i].zEName);
        pItem->eEName = pList->a[i].eEName;
      }
    }
  }
  if( !db->mallocFailed ){
    Vdbe *v = pParse->pVdbe;
    assert( v!=0 );
    sqlite3VdbeSetNumCols(v, pNew->nExpr);
    for(i=0; i<pNew->nExpr; i++){
      sqlite3VdbeSetColName(v, i, COLNAME_NAME, pNew->a[i].zEName,
                            SQLITE_TRANSIENT);
    }
  }
  return pNew;
}

/*
** Generate code for the RETURNING trigger.  Unlike other triggers
** that invoke a subprogram in the bytecode, the code for RETURNING
** is generated in-line.
*/
static void codeReturningTrigger(
  Parse *pParse,       /* Parse context */
  Trigger *pTrigger,   /* The trigger step that defines the RETURNING */
  Table *pTab,         /* The table to code triggers from */
  int regIn            /* The first in an array of registers */
){
  Vdbe *v = pParse->pVdbe;
  ExprList *pNew;
  Returning *pReturning;

  assert( v!=0 );
  assert( pParse->bReturning );
  pReturning = pParse->u1.pReturning;
  assert( pTrigger == &(pReturning->retTrig) );
  pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab);
  if( pNew ){
    NameContext sNC;
    memset(&sNC, 0, sizeof(sNC));
    if( pReturning->nRetCol==0 ){
      pReturning->nRetCol = pNew->nExpr;
      pReturning->iRetCur = pParse->nTab++;
    }
    sNC.pParse = pParse;
    sNC.uNC.iBaseReg = regIn;
    sNC.ncFlags = NC_UBaseReg;
    pParse->eTriggerOp = pTrigger->op;
    pParse->pTriggerTab = pTab;
    if( sqlite3ResolveExprListNames(&sNC, pNew)==SQLITE_OK ){
      int i;
      int nCol = pNew->nExpr;
      int reg = pParse->nMem+1;
      pParse->nMem += nCol+2;
      pReturning->iRetReg = reg;
      for(i=0; i<nCol; i++){
        sqlite3ExprCodeFactorable(pParse, pNew->a[i].pExpr, reg+i);
      }
      sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, i, reg+i);
      sqlite3VdbeAddOp2(v, OP_NewRowid, pReturning->iRetCur, reg+i+1);
      sqlite3VdbeAddOp3(v, OP_Insert, pReturning->iRetCur, reg+i, reg+i+1);
    }
    sqlite3ExprListDelete(pParse->db, pNew);
    pParse->eTriggerOp = 0;
    pParse->pTriggerTab = 0;
  }
}



/*
** Generate VDBE code for the statements inside the body of a single 
** trigger.
*/
static int codeTriggerProgram(
  Parse *pParse,            /* The parser context */
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
      case TK_UPDATE: {
        sqlite3Update(pParse, 
          sqlite3TriggerStepSrc(pParse, pStep),
          sqlite3ExprListDup(db, pStep->pExprList, 0), 
          sqlite3ExprDup(db, pStep->pWhere, 0), 
          pParse->eOrconf, 0, 0, 0
        );

        break;
      }
      case TK_INSERT: {
        sqlite3Insert(pParse, 
          sqlite3TriggerStepSrc(pParse, pStep),
          sqlite3SelectDup(db, pStep->pSelect, 0), 
          sqlite3IdListDup(db, pStep->pIdList), 
          pParse->eOrconf,
          sqlite3UpsertDup(db, pStep->pUpsert)
        );

        break;
      }
      case TK_DELETE: {
        sqlite3DeleteFrom(pParse, 
          sqlite3TriggerStepSrc(pParse, pStep),
          sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0
        );

        break;
      }
      default: assert( pStep->op==TK_SELECT ); {
        SelectDest sDest;
        Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0);
        sqlite3SelectDestInit(&sDest, SRT_Discard, 0);
        sqlite3Select(pParse, pSelect, &sDest);
        sqlite3SelectDelete(db, pSelect);
        break;
      }
    } 
    if( pStep->op!=TK_SELECT ){
      sqlite3VdbeAddOp0(v, OP_ResetCount);
    }
  }

  return 0;
}

#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
/*







>










>







>











<
<
<







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
      case TK_UPDATE: {
        sqlite3Update(pParse, 
          sqlite3TriggerStepSrc(pParse, pStep),
          sqlite3ExprListDup(db, pStep->pExprList, 0), 
          sqlite3ExprDup(db, pStep->pWhere, 0), 
          pParse->eOrconf, 0, 0, 0
        );
        sqlite3VdbeAddOp0(v, OP_ResetCount);
        break;
      }
      case TK_INSERT: {
        sqlite3Insert(pParse, 
          sqlite3TriggerStepSrc(pParse, pStep),
          sqlite3SelectDup(db, pStep->pSelect, 0), 
          sqlite3IdListDup(db, pStep->pIdList), 
          pParse->eOrconf,
          sqlite3UpsertDup(db, pStep->pUpsert)
        );
        sqlite3VdbeAddOp0(v, OP_ResetCount);
        break;
      }
      case TK_DELETE: {
        sqlite3DeleteFrom(pParse, 
          sqlite3TriggerStepSrc(pParse, pStep),
          sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0
        );
        sqlite3VdbeAddOp0(v, OP_ResetCount);
        break;
      }
      default: assert( pStep->op==TK_SELECT ); {
        SelectDest sDest;
        Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0);
        sqlite3SelectDestInit(&sDest, SRT_Discard, 0);
        sqlite3Select(pParse, pSelect, &sDest);
        sqlite3SelectDelete(db, pSelect);
        break;
      }
    } 



  }

  return 0;
}

#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
/*
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
    pProgram->nCsr = pSubParse->nTab;
    pProgram->token = (void *)pTrigger;
    pPrg->aColmask[0] = pSubParse->oldmask;
    pPrg->aColmask[1] = pSubParse->newmask;
    sqlite3VdbeDelete(v);
  }

  assert( !pSubParse->pAinc       && !pSubParse->pZombieTab );
  assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg );
  sqlite3ParserReset(pSubParse);
  sqlite3StackFree(db, pSubParse);

  return pPrg;
}
    







<







1150
1151
1152
1153
1154
1155
1156

1157
1158
1159
1160
1161
1162
1163
    pProgram->nCsr = pSubParse->nTab;
    pProgram->token = (void *)pTrigger;
    pPrg->aColmask[0] = pSubParse->oldmask;
    pPrg->aColmask[1] = pSubParse->newmask;
    sqlite3VdbeDelete(v);
  }


  assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg );
  sqlite3ParserReset(pSubParse);
  sqlite3StackFree(db, pSubParse);

  return pPrg;
}
    
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
**   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
**
** 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







|







1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
**   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        NEW.* value of left-most column of pTab
**   ...            ...
**   reg+N+N+1      NEW.* value of right-most column of pTab
**
** 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
1143
1144
1145
1146
1147
1148
1149
1150




1151
1152
1153
1154

1155



1156
1157
1158
1159
1160
1161
1162
    ** 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==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)
    ){

      sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump);



    }
  }
}

/*
** Triggers may access values stored in the old.* or new.* pseudo-table. 
** This function returns a 32-bit bitmask indicating which columns of the 







|
>
>
>
>
|



>
|
>
>
>







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
    ** 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==pParse->db->aDb[1].pSchema );

    /* Determine whether we should code this trigger.  One of two choices:
    **   1. The trigger is an exact match to the current DML statement
    **   2. This is a RETURNING trigger for INSERT but we are currently
    **      doing the UPDATE part of an UPSERT.
    */
    if( (p->op==op || (p->bReturning && p->op==TK_INSERT && op==TK_UPDATE))
     && p->tr_tm==tr_tm 
     && checkColumnOverlap(p->pColumns, pChanges)
    ){
      if( !p->bReturning ){
        sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump);
      }else if( sqlite3IsToplevel(pParse) ){
        codeReturningTrigger(pParse, p, pTab, reg);
      }
    }
  }
}

/*
** Triggers may access values stored in the old.* or new.* pseudo-table. 
** This function returns a 32-bit bitmask indicating which columns of the 
1193
1194
1195
1196
1197
1198
1199
1200

1201
1202



1203
1204
1205
1206

1207
1208
1209
1210
1211
1212
1213
1214
){
  const int op = pChanges ? TK_UPDATE : TK_DELETE;
  u32 mask = 0;
  Trigger *p;

  assert( isNew==1 || isNew==0 );
  for(p=pTrigger; p; p=p->pNext){
    if( p->op==op && (tr_tm&p->tr_tm)

     && checkColumnOverlap(p->pColumns,pChanges)
    ){



      TriggerPrg *pPrg;
      pPrg = getRowTrigger(pParse, p, pTab, orconf);
      if( pPrg ){
        mask |= pPrg->aColmask[isNew];

      }
    }
  }

  return mask;
}

#endif /* !defined(SQLITE_OMIT_TRIGGER) */







|
>


>
>
>
|
|
|
|
>








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
){
  const int op = pChanges ? TK_UPDATE : TK_DELETE;
  u32 mask = 0;
  Trigger *p;

  assert( isNew==1 || isNew==0 );
  for(p=pTrigger; p; p=p->pNext){
    if( p->op==op
     && (tr_tm&p->tr_tm)
     && checkColumnOverlap(p->pColumns,pChanges)
    ){
      if( p->bReturning ){
        mask = 0xffffffff;
      }else{
        TriggerPrg *pPrg;
        pPrg = getRowTrigger(pParse, p, pTab, orconf);
        if( pPrg ){
          mask |= pPrg->aColmask[isNew];
        }
      }
    }
  }

  return mask;
}

#endif /* !defined(SQLITE_OMIT_TRIGGER) */
Changes to src/update.c.
650
651
652
653
654
655
656

657
658
659
660
661
662
663
  labelContinue = labelBreak = sqlite3VdbeMakeLabel(pParse);

  /* Not an UPSERT.  Normal processing.  Begin by
  ** initialize the count of updated rows */
  if( (db->flags&SQLITE_CountRows)!=0
   && !pParse->pTriggerTab
   && !pParse->nested

   && pUpsert==0
  ){
    regRowCount = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
  }

  if( nChangeFrom==0 && HasRowid(pTab) ){







>







650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
  labelContinue = labelBreak = sqlite3VdbeMakeLabel(pParse);

  /* Not an UPSERT.  Normal processing.  Begin by
  ** initialize the count of updated rows */
  if( (db->flags&SQLITE_CountRows)!=0
   && !pParse->pTriggerTab
   && !pParse->nested
   && !pParse->bReturning
   && pUpsert==0
  ){
    regRowCount = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
  }

  if( nChangeFrom==0 && HasRowid(pTab) ){
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
  }

  /*
  ** Return the number of rows that were changed, if we are tracking
  ** that information.
  */
  if( regRowCount ){
    sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC);
  }

update_cleanup:
  sqlite3AuthContextPop(&sContext);
  sqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */







|







1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
  }

  /*
  ** Return the number of rows that were changed, if we are tracking
  ** that information.
  */
  if( regRowCount ){
    sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1);
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC);
  }

update_cleanup:
  sqlite3AuthContextPop(&sContext);
  sqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */
Changes to src/upsert.c.
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
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_UPSERT
/*
** Free a list of Upsert objects
*/
void sqlite3UpsertDelete(sqlite3 *db, Upsert *p){

  if( p ){
    sqlite3ExprListDelete(db, p->pUpsertTarget);
    sqlite3ExprDelete(db, p->pUpsertTargetWhere);
    sqlite3ExprListDelete(db, p->pUpsertSet);
    sqlite3ExprDelete(db, p->pUpsertWhere);

    sqlite3DbFree(db, p);


  }


}


/*
** Duplicate an Upsert object.
*/
Upsert *sqlite3UpsertDup(sqlite3 *db, Upsert *p){
  if( p==0 ) return 0;
  return sqlite3UpsertNew(db,
           sqlite3ExprListDup(db, p->pUpsertTarget, 0),
           sqlite3ExprDup(db, p->pUpsertTargetWhere, 0),
           sqlite3ExprListDup(db, p->pUpsertSet, 0),
           sqlite3ExprDup(db, p->pUpsertWhere, 0)

         );
}

/*
** Create a new Upsert object.
*/
Upsert *sqlite3UpsertNew(
  sqlite3 *db,           /* Determines which memory allocator to use */
  ExprList *pTarget,     /* Target argument to ON CONFLICT, or NULL */
  Expr *pTargetWhere,    /* Optional WHERE clause on the target */
  ExprList *pSet,        /* UPDATE columns, or NULL for a DO NOTHING */
  Expr *pWhere           /* WHERE clause for the ON CONFLICT UPDATE */

){
  Upsert *pNew;
  pNew = sqlite3DbMallocRaw(db, sizeof(Upsert));
  if( pNew==0 ){
    sqlite3ExprListDelete(db, pTarget);
    sqlite3ExprDelete(db, pTargetWhere);
    sqlite3ExprListDelete(db, pSet);
    sqlite3ExprDelete(db, pWhere);

    return 0;
  }else{
    pNew->pUpsertTarget = pTarget;
    pNew->pUpsertTargetWhere = pTargetWhere;
    pNew->pUpsertSet = pSet;
    pNew->pUpsertWhere = pWhere;

    pNew->pUpsertIdx = 0;
  }
  return pNew;
}

/*
** Analyze the ON CONFLICT clause described by pUpsert.  Resolve all
** symbols in the conflict-target.







|
>
|




>

>
>
|
>
>

>










|
>











|
>


|





>






>
|







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
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_UPSERT
/*
** Free a list of Upsert objects
*/
static void SQLITE_NOINLINE upsertDelete(sqlite3 *db, Upsert *p){
  do{
    Upsert *pNext = p->pNextUpsert;
    sqlite3ExprListDelete(db, p->pUpsertTarget);
    sqlite3ExprDelete(db, p->pUpsertTargetWhere);
    sqlite3ExprListDelete(db, p->pUpsertSet);
    sqlite3ExprDelete(db, p->pUpsertWhere);
    sqlite3DbFree(db, p->pToFree);
    sqlite3DbFree(db, p);
    p = pNext;
  }while( p );
}
void sqlite3UpsertDelete(sqlite3 *db, Upsert *p){
  if( p ) upsertDelete(db, p);
}


/*
** Duplicate an Upsert object.
*/
Upsert *sqlite3UpsertDup(sqlite3 *db, Upsert *p){
  if( p==0 ) return 0;
  return sqlite3UpsertNew(db,
           sqlite3ExprListDup(db, p->pUpsertTarget, 0),
           sqlite3ExprDup(db, p->pUpsertTargetWhere, 0),
           sqlite3ExprListDup(db, p->pUpsertSet, 0),
           sqlite3ExprDup(db, p->pUpsertWhere, 0),
           sqlite3UpsertDup(db, p->pNextUpsert)
         );
}

/*
** Create a new Upsert object.
*/
Upsert *sqlite3UpsertNew(
  sqlite3 *db,           /* Determines which memory allocator to use */
  ExprList *pTarget,     /* Target argument to ON CONFLICT, or NULL */
  Expr *pTargetWhere,    /* Optional WHERE clause on the target */
  ExprList *pSet,        /* UPDATE columns, or NULL for a DO NOTHING */
  Expr *pWhere,          /* WHERE clause for the ON CONFLICT UPDATE */
  Upsert *pNext          /* Next ON CONFLICT clause in the list */
){
  Upsert *pNew;
  pNew = sqlite3DbMallocZero(db, sizeof(Upsert));
  if( pNew==0 ){
    sqlite3ExprListDelete(db, pTarget);
    sqlite3ExprDelete(db, pTargetWhere);
    sqlite3ExprListDelete(db, pSet);
    sqlite3ExprDelete(db, pWhere);
    sqlite3UpsertDelete(db, pNext);
    return 0;
  }else{
    pNew->pUpsertTarget = pTarget;
    pNew->pUpsertTargetWhere = pTargetWhere;
    pNew->pUpsertSet = pSet;
    pNew->pUpsertWhere = pWhere;
    pNew->isDoUpdate = pSet!=0;
    pNew->pNextUpsert = pNext;
  }
  return pNew;
}

/*
** Analyze the ON CONFLICT clause described by pUpsert.  Resolve all
** symbols in the conflict-target.
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
  int rc;                 /* Result code */
  int iCursor;            /* Cursor used by pTab */
  Index *pIdx;            /* One of the indexes of pTab */
  ExprList *pTarget;      /* The conflict-target clause */
  Expr *pTerm;            /* One term of the conflict-target clause */
  NameContext sNC;        /* Context for resolving symbolic names */
  Expr sCol[2];           /* Index column converted into an Expr */


  assert( pTabList->nSrc==1 );
  assert( pTabList->a[0].pTab!=0 );
  assert( pUpsert!=0 );
  assert( pUpsert->pUpsertTarget!=0 );

  /* Resolve all symbolic names in the conflict-target clause, which
  ** includes both the list of columns and the optional partial-index
  ** WHERE clause.
  */
  memset(&sNC, 0, sizeof(sNC));
  sNC.pParse = pParse;
  sNC.pSrcList = pTabList;


  rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget);
  if( rc ) return rc;
  rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere);
  if( rc ) return rc;

  /* Check to see if the conflict target matches the rowid. */  
  pTab = pTabList->a[0].pTab;
  pTarget = pUpsert->pUpsertTarget;
  iCursor = pTabList->a[0].iCursor;
  if( HasRowid(pTab) 
   && pTarget->nExpr==1
   && (pTerm = pTarget->a[0].pExpr)->op==TK_COLUMN
   && pTerm->iColumn==XN_ROWID
  ){
    /* The conflict-target is the rowid of the primary table */
    assert( pUpsert->pUpsertIdx==0 );
    return SQLITE_OK;

  }

  /* Initialize sCol[0..1] to be an expression parse tree for a
  ** single column of an index.  The sCol[0] node will be the TK_COLLATE
  ** operator and sCol[1] will be the TK_COLUMN operator.  Code below
  ** will populate the specific collation and column number values
  ** prior to comparing against the conflict-target expression.
  */
  memset(sCol, 0, sizeof(sCol));
  sCol[0].op = TK_COLLATE;
  sCol[0].pLeft = &sCol[1];
  sCol[1].op = TK_COLUMN;
  sCol[1].iTable = pTabList->a[0].iCursor;

  /* Check for matches against other indexes */
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    int ii, jj, nn;
    if( !IsUniqueIndex(pIdx) ) continue;
    if( pTarget->nExpr!=pIdx->nKeyCol ) continue;
    if( pIdx->pPartIdxWhere ){
      if( pUpsert->pUpsertTargetWhere==0 ) continue;
      if( sqlite3ExprCompare(pParse, pUpsert->pUpsertTargetWhere,
                             pIdx->pPartIdxWhere, iCursor)!=0 ){
        continue;
      }
    }
    nn = pIdx->nKeyCol;
    for(ii=0; ii<nn; ii++){
      Expr *pExpr;
      sCol[0].u.zToken = (char*)pIdx->azColl[ii];
      if( pIdx->aiColumn[ii]==XN_EXPR ){
        assert( pIdx->aColExpr!=0 );
        assert( pIdx->aColExpr->nExpr>ii );
        pExpr = pIdx->aColExpr->a[ii].pExpr;
        if( pExpr->op!=TK_COLLATE ){
          sCol[0].pLeft = pExpr;
          pExpr = &sCol[0];
        }
      }else{
        sCol[0].pLeft = &sCol[1];
        sCol[1].iColumn = pIdx->aiColumn[ii];
        pExpr = &sCol[0];
      }
      for(jj=0; jj<nn; jj++){
        if( sqlite3ExprCompare(pParse, pTarget->a[jj].pExpr, pExpr,iCursor)<2 ){
          break;  /* Column ii of the index matches column jj of target */
        }
      }
      if( jj>=nn ){
        /* The target contains no match for column jj of the index */
        break;
      }
    }
    if( ii<nn ){
      /* Column ii of the index did not match any term of the conflict target.
      ** Continue the search with the next index. */
      continue;
    }
    pUpsert->pUpsertIdx = pIdx;
    return SQLITE_OK;
  }







  sqlite3ErrorMsg(pParse, "ON CONFLICT clause does not match any "
                          "PRIMARY KEY or UNIQUE constraint");
  return SQLITE_ERROR;



































}

/*
** Generate bytecode that does an UPDATE as part of an upsert.
**
** If pIdx is NULL, then the UNIQUE constraint that failed was the IPK.
** In this case parameter iCur is a cursor open on the table b-tree that







>













>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
  int rc;                 /* Result code */
  int iCursor;            /* Cursor used by pTab */
  Index *pIdx;            /* One of the indexes of pTab */
  ExprList *pTarget;      /* The conflict-target clause */
  Expr *pTerm;            /* One term of the conflict-target clause */
  NameContext sNC;        /* Context for resolving symbolic names */
  Expr sCol[2];           /* Index column converted into an Expr */
  int nClause = 0;        /* Counter of ON CONFLICT clauses */

  assert( pTabList->nSrc==1 );
  assert( pTabList->a[0].pTab!=0 );
  assert( pUpsert!=0 );
  assert( pUpsert->pUpsertTarget!=0 );

  /* Resolve all symbolic names in the conflict-target clause, which
  ** includes both the list of columns and the optional partial-index
  ** WHERE clause.
  */
  memset(&sNC, 0, sizeof(sNC));
  sNC.pParse = pParse;
  sNC.pSrcList = pTabList;
  for(; pUpsert && pUpsert->pUpsertTarget;
        pUpsert=pUpsert->pNextUpsert, nClause++){
    rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget);
    if( rc ) return rc;
    rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere);
    if( rc ) return rc;
  
    /* Check to see if the conflict target matches the rowid. */  
    pTab = pTabList->a[0].pTab;
    pTarget = pUpsert->pUpsertTarget;
    iCursor = pTabList->a[0].iCursor;
    if( HasRowid(pTab) 
     && pTarget->nExpr==1
     && (pTerm = pTarget->a[0].pExpr)->op==TK_COLUMN
     && pTerm->iColumn==XN_ROWID
    ){
      /* The conflict-target is the rowid of the primary table */
      assert( pUpsert->pUpsertIdx==0 );

      continue;
    }
  
    /* Initialize sCol[0..1] to be an expression parse tree for a
    ** single column of an index.  The sCol[0] node will be the TK_COLLATE
    ** operator and sCol[1] will be the TK_COLUMN operator.  Code below
    ** will populate the specific collation and column number values
    ** prior to comparing against the conflict-target expression.
    */
    memset(sCol, 0, sizeof(sCol));
    sCol[0].op = TK_COLLATE;
    sCol[0].pLeft = &sCol[1];
    sCol[1].op = TK_COLUMN;
    sCol[1].iTable = pTabList->a[0].iCursor;
  
    /* Check for matches against other indexes */
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      int ii, jj, nn;
      if( !IsUniqueIndex(pIdx) ) continue;
      if( pTarget->nExpr!=pIdx->nKeyCol ) continue;
      if( pIdx->pPartIdxWhere ){
        if( pUpsert->pUpsertTargetWhere==0 ) continue;
        if( sqlite3ExprCompare(pParse, pUpsert->pUpsertTargetWhere,
                               pIdx->pPartIdxWhere, iCursor)!=0 ){
          continue;
        }
      }
      nn = pIdx->nKeyCol;
      for(ii=0; ii<nn; ii++){
        Expr *pExpr;
        sCol[0].u.zToken = (char*)pIdx->azColl[ii];
        if( pIdx->aiColumn[ii]==XN_EXPR ){
          assert( pIdx->aColExpr!=0 );
          assert( pIdx->aColExpr->nExpr>ii );
          pExpr = pIdx->aColExpr->a[ii].pExpr;
          if( pExpr->op!=TK_COLLATE ){
            sCol[0].pLeft = pExpr;
            pExpr = &sCol[0];
          }
        }else{
          sCol[0].pLeft = &sCol[1];
          sCol[1].iColumn = pIdx->aiColumn[ii];
          pExpr = &sCol[0];
        }
        for(jj=0; jj<nn; jj++){
          if( sqlite3ExprCompare(pParse,pTarget->a[jj].pExpr,pExpr,iCursor)<2 ){
            break;  /* Column ii of the index matches column jj of target */
          }
        }
        if( jj>=nn ){
          /* The target contains no match for column jj of the index */
          break;
        }
      }
      if( ii<nn ){
        /* Column ii of the index did not match any term of the conflict target.
        ** Continue the search with the next index. */
        continue;
      }
      pUpsert->pUpsertIdx = pIdx;
      break;
    }
    if( pUpsert->pUpsertIdx==0 ){
      char zWhich[16];
      if( nClause==0 && pUpsert->pNextUpsert==0 ){
        zWhich[0] = 0;
      }else{
        sqlite3_snprintf(sizeof(zWhich),zWhich,"%r ", nClause+1);
      }
      sqlite3ErrorMsg(pParse, "%sON CONFLICT clause does not match any "
                              "PRIMARY KEY or UNIQUE constraint", zWhich);
      return SQLITE_ERROR;
    }
  }
  return SQLITE_OK;
}

/*
** Return true if pUpsert is the last ON CONFLICT clause with a
** conflict target, or if pUpsert is followed by another ON CONFLICT
** clause that targets the INTEGER PRIMARY KEY.
*/
int sqlite3UpsertNextIsIPK(Upsert *pUpsert){
  Upsert *pNext;
  if( NEVER(pUpsert==0) ) return 0;
  pNext = pUpsert->pNextUpsert;
  if( pNext==0 ) return 1;
  if( pNext->pUpsertTarget==0 ) return 1;
  if( pNext->pUpsertIdx==0 ) return 1;
  return 0;
}

/*
** Given the list of ON CONFLICT clauses described by pUpsert, and
** a particular index pIdx, return a pointer to the particular ON CONFLICT
** clause that applies to the index.  Or, if the index is not subject to
** any ON CONFLICT clause, return NULL.
*/
Upsert *sqlite3UpsertOfIndex(Upsert *pUpsert, Index *pIdx){
  while(
      pUpsert
   && pUpsert->pUpsertTarget!=0
   && pUpsert->pUpsertIdx!=pIdx
  ){
     pUpsert = pUpsert->pNextUpsert;
  }
  return pUpsert;
}

/*
** Generate bytecode that does an UPDATE as part of an upsert.
**
** If pIdx is NULL, then the UNIQUE constraint that failed was the IPK.
** In this case parameter iCur is a cursor open on the table b-tree that
202
203
204
205
206
207
208

209
210
211
212
213


214
215
216
217
218
219
220
  int iCur              /* Cursor for pIdx (or pTab if pIdx==NULL) */
){
  Vdbe *v = pParse->pVdbe;
  sqlite3 *db = pParse->db;
  SrcList *pSrc;            /* FROM clause for the UPDATE */
  int iDataCur;
  int i;


  assert( v!=0 );
  assert( pUpsert!=0 );
  VdbeNoopComment((v, "Begin DO UPDATE of UPSERT"));
  iDataCur = pUpsert->iDataCur;


  if( pIdx && iCur!=iDataCur ){
    if( HasRowid(pTab) ){
      int regRowid = sqlite3GetTempReg(pParse);
      sqlite3VdbeAddOp2(v, OP_IdxRowid, iCur, regRowid);
      sqlite3VdbeAddOp3(v, OP_SeekRowid, iDataCur, 0, regRowid);
      VdbeCoverage(v);
      sqlite3ReleaseTempReg(pParse, regRowid);







>



<

>
>







258
259
260
261
262
263
264
265
266
267
268

269
270
271
272
273
274
275
276
277
278
  int iCur              /* Cursor for pIdx (or pTab if pIdx==NULL) */
){
  Vdbe *v = pParse->pVdbe;
  sqlite3 *db = pParse->db;
  SrcList *pSrc;            /* FROM clause for the UPDATE */
  int iDataCur;
  int i;
  Upsert *pTop = pUpsert;

  assert( v!=0 );
  assert( pUpsert!=0 );

  iDataCur = pUpsert->iDataCur;
  pUpsert = sqlite3UpsertOfIndex(pTop, pIdx);
  VdbeNoopComment((v, "Begin DO UPDATE of UPSERT"));
  if( pIdx && iCur!=iDataCur ){
    if( HasRowid(pTab) ){
      int regRowid = sqlite3GetTempReg(pParse);
      sqlite3VdbeAddOp2(v, OP_IdxRowid, iCur, regRowid);
      sqlite3VdbeAddOp3(v, OP_SeekRowid, iDataCur, 0, regRowid);
      VdbeCoverage(v);
      sqlite3ReleaseTempReg(pParse, regRowid);
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
      VdbeCoverage(v);
      sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CORRUPT, OE_Abort, 0, 
            "corrupt database", P4_STATIC);
      sqlite3MayAbort(pParse);
      sqlite3VdbeJumpHere(v, i);
    }
  }
  /* pUpsert does not own pUpsertSrc - the outer INSERT statement does.  So
  ** we have to make a copy before passing it down into sqlite3Update() */
  pSrc = sqlite3SrcListDup(db, pUpsert->pUpsertSrc, 0);
  /* excluded.* columns of type REAL need to be converted to a hard real */
  for(i=0; i<pTab->nCol; i++){
    if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
      sqlite3VdbeAddOp1(v, OP_RealAffinity, pUpsert->regData+i);
    }
  }
  sqlite3Update(pParse, pSrc, pUpsert->pUpsertSet,
      pUpsert->pUpsertWhere, OE_Abort, 0, 0, pUpsert);
  pUpsert->pUpsertSet = 0;    /* Will have been deleted by sqlite3Update() */
  pUpsert->pUpsertWhere = 0;  /* Will have been deleted by sqlite3Update() */
  VdbeNoopComment((v, "End DO UPDATE of UPSERT"));
}

#endif /* SQLITE_OMIT_UPSERT */







|
|
|



|


|
|
<
<




294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311


312
313
314
315
      VdbeCoverage(v);
      sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CORRUPT, OE_Abort, 0, 
            "corrupt database", P4_STATIC);
      sqlite3MayAbort(pParse);
      sqlite3VdbeJumpHere(v, i);
    }
  }
  /* pUpsert does not own pTop->pUpsertSrc - the outer INSERT statement does.
  ** So we have to make a copy before passing it down into sqlite3Update() */
  pSrc = sqlite3SrcListDup(db, pTop->pUpsertSrc, 0);
  /* excluded.* columns of type REAL need to be converted to a hard real */
  for(i=0; i<pTab->nCol; i++){
    if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
      sqlite3VdbeAddOp1(v, OP_RealAffinity, pTop->regData+i);
    }
  }
  sqlite3Update(pParse, pSrc, sqlite3ExprListDup(db,pUpsert->pUpsertSet,0),
      sqlite3ExprDup(db,pUpsert->pUpsertWhere,0), OE_Abort, 0, 0, pUpsert);


  VdbeNoopComment((v, "End DO UPDATE of UPSERT"));
}

#endif /* SQLITE_OMIT_UPSERT */
Changes to src/util.c.
109
110
111
112
113
114
115










116
117
118
119
120
121
122
** that would be appropriate.
*/
void sqlite3Error(sqlite3 *db, int err_code){
  assert( db!=0 );
  db->errCode = err_code;
  if( err_code || db->pErr ) sqlite3ErrorFinish(db, err_code);
}











/*
** Load the sqlite3.iSysErrno field if that is an appropriate thing
** to do based on the SQLite error code in rc.
*/
void sqlite3SystemError(sqlite3 *db, int rc){
  if( rc==SQLITE_IOERR_NOMEM ) return;







>
>
>
>
>
>
>
>
>
>







109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
** that would be appropriate.
*/
void sqlite3Error(sqlite3 *db, int err_code){
  assert( db!=0 );
  db->errCode = err_code;
  if( err_code || db->pErr ) sqlite3ErrorFinish(db, err_code);
}

/*
** The equivalent of sqlite3Error(db, SQLITE_OK).  Clear the error state
** and error message.
*/
void sqlite3ErrorClear(sqlite3 *db){
  assert( db!=0 );
  db->errCode = SQLITE_OK;
  if( db->pErr ) sqlite3ValueSetNull(db->pErr);
}

/*
** Load the sqlite3.iSysErrno field if that is an appropriate thing
** to do based on the SQLite error code in rc.
*/
void sqlite3SystemError(sqlite3 *db, int rc){
  if( rc==SQLITE_IOERR_NOMEM ) return;
Changes to src/vdbe.c.
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
  Mem *pIn3 = 0;             /* 3rd input operand */
  Mem *pOut = 0;             /* Output operand */
#ifdef VDBE_PROFILE
  u64 start;                 /* CPU clock count at start of opcode */
#endif
  /*** INSERT STACK UNION HERE ***/

  assert( p->magic==VDBE_MAGIC_RUN );  /* sqlite3_step() verifies this */
  sqlite3VdbeEnter(p);
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  if( db->xProgress ){
    u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
    assert( 0 < db->nProgressOps );
    nProgressLimit = db->nProgressOps - (iPrior % db->nProgressOps);
  }else{







|







681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
  Mem *pIn3 = 0;             /* 3rd input operand */
  Mem *pOut = 0;             /* Output operand */
#ifdef VDBE_PROFILE
  u64 start;                 /* CPU clock count at start of opcode */
#endif
  /*** INSERT STACK UNION HERE ***/

  assert( p->iVdbeMagic==VDBE_MAGIC_RUN );  /* sqlite3_step() verifies this */
  sqlite3VdbeEnter(p);
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  if( db->xProgress ){
    u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
    assert( 0 < db->nProgressOps );
    nProgressLimit = db->nProgressOps - (iPrior % db->nProgressOps);
  }else{
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
case OP_IntCopy: {            /* out2 */
  pIn1 = &aMem[pOp->p1];
  assert( (pIn1->flags & MEM_Int)!=0 );
  pOut = &aMem[pOp->p2];
  sqlite3VdbeMemSetInt64(pOut, pIn1->u.i);
  break;
}





















/* Opcode: ResultRow P1 P2 * * *
** Synopsis: output=r[P1@P2]
**
** The registers P1 through P1+P2-1 contain a single row of
** results. This opcode causes the sqlite3_step() call to terminate
** with an SQLITE_ROW return code and it sets up the sqlite3_stmt
** structure to provide access to the r(P1)..r(P1+P2-1) values as
** the result row.
*/
case OP_ResultRow: {
  Mem *pMem;
  int i;
  assert( p->nResColumn==pOp->p2 );
  assert( pOp->p1>0 );
  assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+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 );
    goto abort_due_to_error;
  }

  /* 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
  ** opened by this VM before returning control to the user. This is to
  ** ensure that statement-transactions are always nested, not overlapping.
  ** If the open statement-transaction is not closed here, then the user
  ** may step another VM that opens its own statement transaction. This
  ** may lead to overlapping statement transactions.
  **
  ** The statement transaction is never a top-level transaction.  Hence
  ** the RELEASE call below can never fail.
  */
  assert( p->iStatement==0 || db->flags&SQLITE_CountRows );
  rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE);
  assert( rc==SQLITE_OK );

  /* Invalidate all ephemeral cursor row caches */
  p->cacheCtr = (p->cacheCtr + 2)|1;

  /* Make sure the results of the current row are \000 terminated
  ** and have an assigned type.  The results are de-ephemeralized as
  ** a side effect.
  */







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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
case OP_IntCopy: {            /* out2 */
  pIn1 = &aMem[pOp->p1];
  assert( (pIn1->flags & MEM_Int)!=0 );
  pOut = &aMem[pOp->p2];
  sqlite3VdbeMemSetInt64(pOut, pIn1->u.i);
  break;
}

/* Opcode: ChngCntRow P1 P2 * * *
** Synopsis: output=r[P1]
**
** Output value in register P1 as the chance count for a DML statement,
** due to the "PRAGMA count_changes=ON" setting.  Or, if there was a
** foreign key error in the statement, trigger the error now.
**
** This opcode is a variant of OP_ResultRow that checks the foreign key
** immediate constraint count and throws an error if the count is
** non-zero.  The P2 opcode must be 1.
*/
case OP_ChngCntRow: {
  assert( pOp->p2==1 );
  if( (rc = sqlite3VdbeCheckFk(p,0))!=SQLITE_OK ){
    goto abort_due_to_error;
  }
  /* Fall through to the next case, OP_ResultRow */
  /* no break */ deliberate_fall_through
}

/* Opcode: ResultRow P1 P2 * * *
** Synopsis: output=r[P1@P2]
**
** The registers P1 through P1+P2-1 contain a single row of
** results. This opcode causes the sqlite3_step() call to terminate
** with an SQLITE_ROW return code and it sets up the sqlite3_stmt
** structure to provide access to the r(P1)..r(P1+P2-1) values as
** the result row.
*/
case OP_ResultRow: {
  Mem *pMem;
  int i;
  assert( p->nResColumn==pOp->p2 );
  assert( pOp->p1>0 );
  assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 );





























  /* Invalidate all ephemeral cursor row caches */
  p->cacheCtr = (p->cacheCtr + 2)|1;

  /* Make sure the results of the current row are \000 terminated
  ** and have an assigned type.  The results are de-ephemeralized as
  ** a side effect.
  */
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
    assert( pOp->p2==0 ); /* Only used when number of columns is zero */
    assert( pOp->opcode==OP_OpenEphemeral );
    assert( aMem[pOp->p3].flags & MEM_Null );
    aMem[pOp->p3].n = 0;
    aMem[pOp->p3].z = "";
  }
  pCx = p->apCsr[pOp->p1];
  if( pCx && pCx->pBtx ){
    /* If the ephermeral table is already open, erase all existing content
    ** so that the table is empty again, rather than creating a new table. */
    assert( pCx->isEphemeral );
    pCx->seqCount = 0;
    pCx->cacheStatus = CACHE_STALE;
    rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
  }else{







|







3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
    assert( pOp->p2==0 ); /* Only used when number of columns is zero */
    assert( pOp->opcode==OP_OpenEphemeral );
    assert( aMem[pOp->p3].flags & MEM_Null );
    aMem[pOp->p3].n = 0;
    aMem[pOp->p3].z = "";
  }
  pCx = p->apCsr[pOp->p1];
  if( pCx && ALWAYS(pCx->pBtx) ){
    /* If the ephermeral table is already open, erase all existing content
    ** so that the table is empty again, rather than creating a new table. */
    assert( pCx->isEphemeral );
    pCx->seqCount = 0;
    pCx->cacheStatus = CACHE_STALE;
    rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
  }else{
4953
4954
4955
4956
4957
4958
4959

4960
4961

4962
4963
4964
4965
4966
4967
4968
** AUTOINCREMENT feature.
*/
case OP_NewRowid: {           /* out2 */
  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;
  pOut = out2Prerelease(p, pOp);
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );







>


>







4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
** AUTOINCREMENT feature.
*/
case OP_NewRowid: {           /* out2 */
  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 */
#ifndef SQLITE_OMIT_AUTOINCREMENT
  Mem *pMem;             /* Register holding largest rowid for AUTOINCREMENT */
  VdbeFrame *pFrame;     /* Root frame of VDBE */
#endif

  v = 0;
  res = 0;
  pOut = out2Prerelease(p, pOp);
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
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
  if( pData->flags & MEM_Zero ){
    x.nZero = pData->u.nZero;
  }else{
    x.nZero = 0;
  }
  x.pKey = 0;
  rc = sqlite3BtreeInsert(pC->uc.pCursor, &x,
      (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)), seekResult

  );
  pC->deferredMoveto = 0;
  pC->cacheStatus = CACHE_STALE;

  /* Invoke the update-hook if required. */
  if( rc ) goto abort_due_to_error;
  if( pTab ){
    assert( db->xUpdateCallback!=0 );
    assert( pTab->aCol!=0 );
    db->xUpdateCallback(db->pUpdateArg,
           (pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT,
           zDb, pTab->zName, x.nKey);
  }
  break;
}




























/* Opcode: Delete P1 P2 P3 P4 P5
**
** Delete the record at which the P1 cursor is currently pointing.
**
** If the OPFLAG_SAVEPOSITION bit of the P5 parameter is set, then
** the cursor will be left pointing at  either the next or the previous







|
>















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
  if( pData->flags & MEM_Zero ){
    x.nZero = pData->u.nZero;
  }else{
    x.nZero = 0;
  }
  x.pKey = 0;
  rc = sqlite3BtreeInsert(pC->uc.pCursor, &x,
      (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), 
      seekResult
  );
  pC->deferredMoveto = 0;
  pC->cacheStatus = CACHE_STALE;

  /* Invoke the update-hook if required. */
  if( rc ) goto abort_due_to_error;
  if( pTab ){
    assert( db->xUpdateCallback!=0 );
    assert( pTab->aCol!=0 );
    db->xUpdateCallback(db->pUpdateArg,
           (pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT,
           zDb, pTab->zName, x.nKey);
  }
  break;
}

/* Opcode: RowCell P1 P2 P3 * *
**
** P1 and P2 are both open cursors. Both must be opened on the same type
** of table - intkey or index. This opcode is used as part of copying
** the current row from P2 into P1. If the cursors are opened on intkey
** tables, register P3 contains the rowid to use with the new record in
** P1. If they are opened on index tables, P3 is not used.
**
** This opcode must be followed by either an Insert or InsertIdx opcode
** with the OPFLAG_PREFORMAT flag set to complete the insert operation.
*/
case OP_RowCell: {
  VdbeCursor *pDest;              /* Cursor to write to */
  VdbeCursor *pSrc;               /* Cursor to read from */
  i64 iKey;                       /* Rowid value to insert with */
  assert( pOp[1].opcode==OP_Insert || pOp[1].opcode==OP_IdxInsert );
  assert( pOp[1].opcode==OP_Insert    || pOp->p3==0 );
  assert( pOp[1].opcode==OP_IdxInsert || pOp->p3>0 );
  assert( pOp[1].p5 & OPFLAG_PREFORMAT );
  pDest = p->apCsr[pOp->p1];
  pSrc = p->apCsr[pOp->p2];
  iKey = pOp->p3 ? aMem[pOp->p3].u.i : 0;
  rc = sqlite3BtreeTransferRow(pDest->uc.pCursor, pSrc->uc.pCursor, iKey);
  if( rc!=SQLITE_OK ) goto abort_due_to_error;
  break;
};

/* Opcode: Delete P1 P2 P3 P4 P5
**
** Delete the record at which the P1 cursor is currently pointing.
**
** If the OPFLAG_SAVEPOSITION bit of the P5 parameter is set, then
** the cursor will be left pointing at  either the next or the previous
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  sqlite3VdbeIncrWriteCounter(p, pC);
  assert( pC!=0 );
  assert( !isSorter(pC) );
  pIn2 = &aMem[pOp->p2];
  assert( pIn2->flags & MEM_Blob );
  if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
  assert( pC->eCurType==CURTYPE_BTREE );
  assert( pC->isTable==0 );
  rc = ExpandBlob(pIn2);
  if( rc ) goto abort_due_to_error;
  x.nKey = pIn2->n;
  x.pKey = pIn2->z;
  x.aMem = aMem + pOp->p3;
  x.nMem = (u16)pOp->p4.i;
  rc = sqlite3BtreeInsert(pC->uc.pCursor, &x,
       (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)), 
      ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
      );
  assert( pC->deferredMoveto==0 );
  pC->cacheStatus = CACHE_STALE;
  if( rc) goto abort_due_to_error;
  break;
}







|










|







5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  sqlite3VdbeIncrWriteCounter(p, pC);
  assert( pC!=0 );
  assert( !isSorter(pC) );
  pIn2 = &aMem[pOp->p2];
  assert( (pIn2->flags & MEM_Blob) || (pOp->p5 & OPFLAG_PREFORMAT) );
  if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
  assert( pC->eCurType==CURTYPE_BTREE );
  assert( pC->isTable==0 );
  rc = ExpandBlob(pIn2);
  if( rc ) goto abort_due_to_error;
  x.nKey = pIn2->n;
  x.pKey = pIn2->z;
  x.aMem = aMem + pOp->p3;
  x.nMem = (u16)pOp->p4.i;
  rc = sqlite3BtreeInsert(pC->uc.pCursor, &x,
       (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), 
      ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
      );
  assert( pC->deferredMoveto==0 );
  pC->cacheStatus = CACHE_STALE;
  if( rc) goto abort_due_to_error;
  break;
}
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
  r.aMem = &aMem[pOp->p2];
  rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
  if( rc ) goto abort_due_to_error;
  if( res==0 ){
    rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
    if( rc ) goto abort_due_to_error;
  }else if( pOp->p5 ){
    rc = SQLITE_CORRUPT_INDEX;
    goto abort_due_to_error;
  }
  assert( pC->deferredMoveto==0 );
  pC->cacheStatus = CACHE_STALE;
  pC->seekResult = 0;
  break;
}







|







5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
  r.aMem = &aMem[pOp->p2];
  rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
  if( rc ) goto abort_due_to_error;
  if( res==0 ){
    rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
    if( rc ) goto abort_due_to_error;
  }else if( pOp->p5 ){
    rc = sqlite3ReportError(SQLITE_CORRUPT_INDEX, __LINE__, "index corruption");
    goto abort_due_to_error;
  }
  assert( pC->deferredMoveto==0 );
  pC->cacheStatus = CACHE_STALE;
  pC->seekResult = 0;
  break;
}
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
  assert( iDb>=0 && iDb<db->nDb );
  assert( DbHasProperty(db, iDb, DB_SchemaLoaded) );

#ifndef SQLITE_OMIT_ALTERTABLE
  if( pOp->p4.z==0 ){
    sqlite3SchemaClear(db->aDb[iDb].pSchema);
    db->mDbFlags &= ~DBFLAG_SchemaKnownOk;
    rc = sqlite3InitOne(db, iDb, &p->zErrMsg, INITFLAG_AlterTable);
    db->mDbFlags |= DBFLAG_SchemaChange;
    p->expired = 0;
  }else
#endif
  {
    zSchema = DFLT_SCHEMA_TABLE;
    initData.db = db;







|







6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
  assert( iDb>=0 && iDb<db->nDb );
  assert( DbHasProperty(db, iDb, DB_SchemaLoaded) );

#ifndef SQLITE_OMIT_ALTERTABLE
  if( pOp->p4.z==0 ){
    sqlite3SchemaClear(db->aDb[iDb].pSchema);
    db->mDbFlags &= ~DBFLAG_SchemaKnownOk;
    rc = sqlite3InitOne(db, iDb, &p->zErrMsg, pOp->p5);
    db->mDbFlags |= DBFLAG_SchemaChange;
    p->expired = 0;
  }else
#endif
  {
    zSchema = DFLT_SCHEMA_TABLE;
    initData.db = db;
Changes to src/vdbe.h.
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# define sqlite3ExplainBreakpoint(A,B) /*no-op*/
#endif
#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN)
  void sqlite3ExplainBreakpoint(const char*,const char*);
#else
# define sqlite3ExplainBreakpoint(A,B) /*no-op*/
#endif
void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
void sqlite3VdbeChangeOpcode(Vdbe*, int addr, u8);
void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3);
void sqlite3VdbeChangeP5(Vdbe*, u16 P5);
void sqlite3VdbeJumpHere(Vdbe*, int addr);
void sqlite3VdbeJumpHereOrPopInst(Vdbe*, int addr);







|







219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# define sqlite3ExplainBreakpoint(A,B) /*no-op*/
#endif
#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN)
  void sqlite3ExplainBreakpoint(const char*,const char*);
#else
# define sqlite3ExplainBreakpoint(A,B) /*no-op*/
#endif
void sqlite3VdbeAddParseSchemaOp(Vdbe*, int, char*, u16);
void sqlite3VdbeChangeOpcode(Vdbe*, int addr, u8);
void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3);
void sqlite3VdbeChangeP5(Vdbe*, u16 P5);
void sqlite3VdbeJumpHere(Vdbe*, int addr);
void sqlite3VdbeJumpHereOrPopInst(Vdbe*, int addr);
Changes to src/vdbeInt.h.
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
** is really a pointer to an instance of this structure.
*/
struct Vdbe {
  sqlite3 *db;            /* The database connection that owns this statement */
  Vdbe *pPrev,*pNext;     /* Linked list of VDBEs with the same Vdbe.db */
  Parse *pParse;          /* Parsing context used to create this Vdbe */
  ynVar nVar;             /* Number of entries in aVar[] */
  u32 magic;              /* Magic number for sanity checking */
  int nMem;               /* Number of memory locations currently allocated */
  int nCursor;            /* Number of slots in apCsr[] */
  u32 cacheCtr;           /* VdbeCursor row cache generation counter */
  int pc;                 /* The program counter */
  int rc;                 /* Value to return */
  int nChange;            /* Number of db changes made since last reset */
  int iStatement;         /* Statement number (or 0 if has no opened stmt) */







|







377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
** is really a pointer to an instance of this structure.
*/
struct Vdbe {
  sqlite3 *db;            /* The database connection that owns this statement */
  Vdbe *pPrev,*pNext;     /* Linked list of VDBEs with the same Vdbe.db */
  Parse *pParse;          /* Parsing context used to create this Vdbe */
  ynVar nVar;             /* Number of entries in aVar[] */
  u32 iVdbeMagic;         /* Magic number defining state of the SQL statement */
  int nMem;               /* Number of memory locations currently allocated */
  int nCursor;            /* Number of slots in apCsr[] */
  u32 cacheCtr;           /* VdbeCursor row cache generation counter */
  int pc;                 /* The program counter */
  int rc;                 /* Value to return */
  int nChange;            /* Number of db changes made since last reset */
  int iStatement;         /* Statement number (or 0 if has no opened stmt) */
Changes to src/vdbeapi.c.
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
** outer sqlite3_step() wrapper procedure.
*/
static int sqlite3Step(Vdbe *p){
  sqlite3 *db;
  int rc;

  assert(p);
  if( p->magic!=VDBE_MAGIC_RUN ){
    /* We used to require that sqlite3_reset() be called before retrying
    ** sqlite3_step() after any error or after SQLITE_DONE.  But beginning
    ** with version 3.7.0, we changed this so that sqlite3_reset() would
    ** be called automatically instead of throwing the SQLITE_MISUSE error.
    ** This "automatic-reset" change is not technically an incompatibility, 
    ** since any application that receives an SQLITE_MISUSE is broken by
    ** definition.







|







613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
** outer sqlite3_step() wrapper procedure.
*/
static int sqlite3Step(Vdbe *p){
  sqlite3 *db;
  int rc;

  assert(p);
  if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){
    /* We used to require that sqlite3_reset() be called before retrying
    ** sqlite3_step() after any error or after SQLITE_DONE.  But beginning
    ** with version 3.7.0, we changed this so that sqlite3_reset() would
    ** be called automatically instead of throwing the SQLITE_MISUSE error.
    ** This "automatic-reset" change is not technically an incompatibility, 
    ** since any application that receives an SQLITE_MISUSE is broken by
    ** definition.
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
*/
static int vdbeUnbind(Vdbe *p, int i){
  Mem *pVar;
  if( vdbeSafetyNotNull(p) ){
    return SQLITE_MISUSE_BKPT;
  }
  sqlite3_mutex_enter(p->db->mutex);
  if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){
    sqlite3Error(p->db, SQLITE_MISUSE);
    sqlite3_mutex_leave(p->db->mutex);
    sqlite3_log(SQLITE_MISUSE, 
        "bind on a busy prepared statement: [%s]", p->zSql);
    return SQLITE_MISUSE_BKPT;
  }
  if( i<1 || i>p->nVar ){







|







1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
*/
static int vdbeUnbind(Vdbe *p, int i){
  Mem *pVar;
  if( vdbeSafetyNotNull(p) ){
    return SQLITE_MISUSE_BKPT;
  }
  sqlite3_mutex_enter(p->db->mutex);
  if( p->iVdbeMagic!=VDBE_MAGIC_RUN || p->pc>=0 ){
    sqlite3Error(p->db, SQLITE_MISUSE);
    sqlite3_mutex_leave(p->db->mutex);
    sqlite3_log(SQLITE_MISUSE, 
        "bind on a busy prepared statement: [%s]", p->zSql);
    return SQLITE_MISUSE_BKPT;
  }
  if( i<1 || i>p->nVar ){
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
}

/*
** Return true if the prepared statement is in need of being reset.
*/
int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
  Vdbe *v = (Vdbe*)pStmt;
  return v!=0 && v->magic==VDBE_MAGIC_RUN && v->pc>=0;
}

/*
** Return a pointer to the next prepared statement after pStmt associated
** with database connection pDb.  If pStmt is NULL, return the first
** prepared statement for the database connection.  Return NULL if there
** are no more.







|







1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
}

/*
** Return true if the prepared statement is in need of being reset.
*/
int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
  Vdbe *v = (Vdbe*)pStmt;
  return v!=0 && v->iVdbeMagic==VDBE_MAGIC_RUN && v->pc>=0;
}

/*
** Return a pointer to the next prepared statement after pStmt associated
** with database connection pDb.  If pStmt is NULL, return the first
** prepared statement for the database connection.  Return NULL if there
** are no more.
Changes to src/vdbeaux.c.
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  p->db = db;
  if( db->pVdbe ){
    db->pVdbe->pPrev = p;
  }
  p->pNext = db->pVdbe;
  p->pPrev = 0;
  db->pVdbe = p;
  p->magic = VDBE_MAGIC_INIT;
  p->pParse = pParse;
  pParse->pVdbe = p;
  assert( pParse->aLabel==0 );
  assert( pParse->nLabel==0 );
  assert( p->nOpAlloc==0 );
  assert( pParse->szOpAlloc==0 );
  sqlite3VdbeAddOp2(p, OP_Init, 0, 1);







|







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  p->db = db;
  if( db->pVdbe ){
    db->pVdbe->pPrev = p;
  }
  p->pNext = db->pVdbe;
  p->pPrev = 0;
  db->pVdbe = p;
  p->iVdbeMagic = VDBE_MAGIC_INIT;
  p->pParse = pParse;
  pParse->pVdbe = p;
  assert( pParse->aLabel==0 );
  assert( pParse->nLabel==0 );
  assert( p->nOpAlloc==0 );
  assert( pParse->szOpAlloc==0 );
  sqlite3VdbeAddOp2(p, OP_Init, 0, 1);
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
  return sqlite3VdbeAddOp3(p, op, p1, p2, p3);
}
int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
  int i;
  VdbeOp *pOp;

  i = p->nOp;
  assert( p->magic==VDBE_MAGIC_INIT );
  assert( op>=0 && op<0xff );
  if( p->nOpAlloc<=i ){
    return growOp3(p, op, p1, p2, p3);
  }
  p->nOp++;
  pOp = &p->aOp[i];
  pOp->opcode = (u8)op;







|







232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
  return sqlite3VdbeAddOp3(p, op, p1, p2, p3);
}
int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
  int i;
  VdbeOp *pOp;

  i = p->nOp;
  assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
  assert( op>=0 && op<0xff );
  if( p->nOpAlloc<=i ){
    return growOp3(p, op, p1, p2, p3);
  }
  p->nOp++;
  pOp = &p->aOp[i];
  pOp->opcode = (u8)op;
467
468
469
470
471
472
473
474
475
476

477
478
479
480
481
482
483
** Add an OP_ParseSchema opcode.  This routine is broken out from
** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees
** as having been used.
**
** The zWhere string must have been obtained from sqlite3_malloc().
** This routine will take ownership of the allocated memory.
*/
void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere){
  int j;
  sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC);

  for(j=0; j<p->db->nDb; j++) sqlite3VdbeUsesBtree(p, j);
  sqlite3MayAbort(p->pParse);
}

/*
** Add an opcode that includes the p4 value as an integer.
*/







|


>







467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
** Add an OP_ParseSchema opcode.  This routine is broken out from
** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees
** as having been used.
**
** The zWhere string must have been obtained from sqlite3_malloc().
** This routine will take ownership of the allocated memory.
*/
void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere, u16 p5){
  int j;
  sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC);
  sqlite3VdbeChangeP5(p, p5);
  for(j=0; j<p->db->nDb; j++) sqlite3VdbeUsesBtree(p, j);
  sqlite3MayAbort(p->pParse);
}

/*
** Add an opcode that includes the p4 value as an integer.
*/
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
    p->nLabelAlloc = nNewSize;
    p->aLabel[j] = v->nOp;
  }
}
void sqlite3VdbeResolveLabel(Vdbe *v, int x){
  Parse *p = v->pParse;
  int j = ADDR(x);
  assert( v->magic==VDBE_MAGIC_INIT );
  assert( j<-p->nLabel );
  assert( j>=0 );
#ifdef SQLITE_DEBUG
  if( p->db->flags & SQLITE_VdbeAddopTrace ){
    printf("RESOLVE LABEL %d to %d\n", x, v->nOp);
  }
#endif







|







562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
    p->nLabelAlloc = nNewSize;
    p->aLabel[j] = v->nOp;
  }
}
void sqlite3VdbeResolveLabel(Vdbe *v, int x){
  Parse *p = v->pParse;
  int j = ADDR(x);
  assert( v->iVdbeMagic==VDBE_MAGIC_INIT );
  assert( j<-p->nLabel );
  assert( j>=0 );
#ifdef SQLITE_DEBUG
  if( p->db->flags & SQLITE_VdbeAddopTrace ){
    printf("RESOLVE LABEL %d to %d\n", x, v->nOp);
  }
#endif
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
  assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) );
}

/*
** Return the address of the next instruction to be inserted.
*/
int sqlite3VdbeCurrentAddr(Vdbe *p){
  assert( p->magic==VDBE_MAGIC_INIT );
  return p->nOp;
}

/*
** Verify that at least N opcode slots are available in p without
** having to malloc for more space (except when compiled using
** SQLITE_TEST_REALLOC_STRESS).  This interface is used during testing







|







887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
  assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) );
}

/*
** Return the address of the next instruction to be inserted.
*/
int sqlite3VdbeCurrentAddr(Vdbe *p){
  assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
  return p->nOp;
}

/*
** Verify that at least N opcode slots are available in p without
** having to malloc for more space (except when compiled using
** SQLITE_TEST_REALLOC_STRESS).  This interface is used during testing
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
  int nOp,                     /* Number of opcodes to add */
  VdbeOpList const *aOp,       /* The opcodes to be added */
  int iLineno                  /* Source-file line number of first opcode */
){
  int i;
  VdbeOp *pOut, *pFirst;
  assert( nOp>0 );
  assert( p->magic==VDBE_MAGIC_INIT );
  if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){
    return 0;
  }
  pFirst = pOut = &p->aOp[p->nOp];
  for(i=0; i<nOp; i++, aOp++, pOut++){
    pOut->opcode = aOp->opcode;
    pOut->p1 = aOp->p1;







|







972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
  int nOp,                     /* Number of opcodes to add */
  VdbeOpList const *aOp,       /* The opcodes to be added */
  int iLineno                  /* Source-file line number of first opcode */
){
  int i;
  VdbeOp *pOut, *pFirst;
  assert( nOp>0 );
  assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
  if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){
    return 0;
  }
  pFirst = pOut = &p->aOp[p->nOp];
  for(i=0; i<nOp; i++, aOp++, pOut++){
    pOut->opcode = aOp->opcode;
    pOut->p1 = aOp->p1;
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
  }
}
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 );
  assert( p->aOp!=0 || db->mallocFailed );
  if( db->mallocFailed ){
    if( n!=P4_VTAB ) freeP4(db, n, (void*)*(char**)&zP4);
    return;
  }
  assert( p->nOp>0 );
  assert( addr<p->nOp );







|







1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
  }
}
void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
  Op *pOp;
  sqlite3 *db;
  assert( p!=0 );
  db = p->db;
  assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
  assert( p->aOp!=0 || db->mallocFailed );
  if( db->mallocFailed ){
    if( n!=P4_VTAB ) freeP4(db, n, (void*)*(char**)&zP4);
    return;
  }
  assert( p->nOp>0 );
  assert( addr<p->nOp );
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
** dummy will never be written to.  This is verified by code inspection and
** by running with Valgrind.
*/
VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
  /* C89 specifies that the constant "dummy" will be initialized to all
  ** zeros, which is correct.  MSVC generates a warning, nevertheless. */
  static VdbeOp dummy;  /* Ignore the MSVC warning about no initializer */
  assert( p->magic==VDBE_MAGIC_INIT );
  if( addr<0 ){
    addr = p->nOp - 1;
  }
  assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed );
  if( p->db->mallocFailed ){
    return (VdbeOp*)&dummy;
  }else{







|







1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
** dummy will never be written to.  This is verified by code inspection and
** by running with Valgrind.
*/
VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
  /* C89 specifies that the constant "dummy" will be initialized to all
  ** zeros, which is correct.  MSVC generates a warning, nevertheless. */
  static VdbeOp dummy;  /* Ignore the MSVC warning about no initializer */
  assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
  if( addr<0 ){
    addr = p->nOp - 1;
  }
  assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed );
  if( p->db->mallocFailed ){
    return (VdbeOp*)&dummy;
  }else{
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
  int rc = SQLITE_OK;                  /* Return code */
  Mem *pMem = &p->aMem[1];             /* First Mem of result set */
  int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0);
  Op *aOp;                             /* Array of opcodes */
  Op *pOp;                             /* Current opcode */

  assert( p->explain );
  assert( p->magic==VDBE_MAGIC_RUN );
  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, 8);







|







2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
  int rc = SQLITE_OK;                  /* Return code */
  Mem *pMem = &p->aMem[1];             /* First Mem of result set */
  int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0);
  Op *aOp;                             /* Array of opcodes */
  Op *pOp;                             /* Current opcode */

  assert( p->explain );
  assert( p->iVdbeMagic==VDBE_MAGIC_RUN );
  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, 8);
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
** running it.
*/
void sqlite3VdbeRewind(Vdbe *p){
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
  int i;
#endif
  assert( p!=0 );
  assert( p->magic==VDBE_MAGIC_INIT || p->magic==VDBE_MAGIC_RESET );

  /* There should be at least one opcode.
  */
  assert( p->nOp>0 );

  /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */
  p->magic = VDBE_MAGIC_RUN;

#ifdef SQLITE_DEBUG
  for(i=0; i<p->nMem; i++){
    assert( p->aMem[i].db==p->db );
  }
#endif
  p->pc = -1;







|






|







2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
** running it.
*/
void sqlite3VdbeRewind(Vdbe *p){
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
  int i;
#endif
  assert( p!=0 );
  assert( p->iVdbeMagic==VDBE_MAGIC_INIT || p->iVdbeMagic==VDBE_MAGIC_RESET );

  /* There should be at least one opcode.
  */
  assert( p->nOp>0 );

  /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */
  p->iVdbeMagic = VDBE_MAGIC_RUN;

#ifdef SQLITE_DEBUG
  for(i=0; i<p->nMem; i++){
    assert( p->aMem[i].db==p->db );
  }
#endif
  p->pc = -1;
2352
2353
2354
2355
2356
2357
2358
2359
2360


2361
2362
2363
2364
2365
2366
2367
  int nArg;                      /* Number of arguments in subprograms */
  int n;                         /* Loop counter */
  struct ReusableSpace x;        /* Reusable bulk memory */

  assert( p!=0 );
  assert( p->nOp>0 );
  assert( pParse!=0 );
  assert( p->magic==VDBE_MAGIC_INIT );
  assert( pParse==p->pParse );


  db = p->db;
  assert( db->mallocFailed==0 );
  nVar = pParse->nVar;
  nMem = pParse->nMem;
  nCursor = pParse->nTab;
  nArg = pParse->nMaxArg;
  







|

>
>







2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
  int nArg;                      /* Number of arguments in subprograms */
  int n;                         /* Loop counter */
  struct ReusableSpace x;        /* Reusable bulk memory */

  assert( p!=0 );
  assert( p->nOp>0 );
  assert( pParse!=0 );
  assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
  assert( pParse==p->pParse );
  p->pVList = pParse->pVList;
  pParse->pVList =  0;
  db = p->db;
  assert( db->mallocFailed==0 );
  nVar = pParse->nVar;
  nMem = pParse->nMem;
  nCursor = pParse->nTab;
  nArg = pParse->nMaxArg;
  
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
      p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
      p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
#endif
    }
  }

  p->pVList = pParse->pVList;
  pParse->pVList =  0;
  if( db->mallocFailed ){
    p->nVar = 0;
    p->nCursor = 0;
    p->nMem = 0;
  }else{
    p->nCursor = nCursor;
    p->nVar = (ynVar)nVar;







<
<







2441
2442
2443
2444
2445
2446
2447


2448
2449
2450
2451
2452
2453
2454
      p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
      p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
#endif
    }
  }



  if( db->mallocFailed ){
    p->nVar = 0;
    p->nCursor = 0;
    p->nMem = 0;
  }else{
    p->nCursor = nCursor;
    p->nVar = (ynVar)nVar;
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
  **     SQLITE_INTERRUPT
  **
  ** Then the internal cache might have been left in an inconsistent
  ** state.  We need to rollback the statement transaction, if there is
  ** one, or the complete transaction if there is no statement transaction.
  */

  if( p->magic!=VDBE_MAGIC_RUN ){
    return SQLITE_OK;
  }
  if( db->mallocFailed ){
    p->rc = SQLITE_NOMEM_BKPT;
  }
  closeAllCursors(p);
  checkActiveVdbeCnt(db);







|







3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
  **     SQLITE_INTERRUPT
  **
  ** Then the internal cache might have been left in an inconsistent
  ** state.  We need to rollback the statement transaction, if there is
  ** one, or the complete transaction if there is no statement transaction.
  */

  if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){
    return SQLITE_OK;
  }
  if( db->mallocFailed ){
    p->rc = SQLITE_NOMEM_BKPT;
  }
  closeAllCursors(p);
  checkActiveVdbeCnt(db);
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
    db->nVdbeActive--;
    if( !p->readOnly ) db->nVdbeWrite--;
    if( p->bIsReader ) db->nVdbeRead--;
    assert( db->nVdbeActive>=db->nVdbeRead );
    assert( db->nVdbeRead>=db->nVdbeWrite );
    assert( db->nVdbeWrite>=0 );
  }
  p->magic = VDBE_MAGIC_HALT;
  checkActiveVdbeCnt(db);
  if( db->mallocFailed ){
    p->rc = SQLITE_NOMEM_BKPT;
  }

  /* If the auto-commit flag is set to true, then any locks that were held
  ** by connection db have now been released. Call sqlite3ConnectionUnlocked() 







|







3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
    db->nVdbeActive--;
    if( !p->readOnly ) db->nVdbeWrite--;
    if( p->bIsReader ) db->nVdbeRead--;
    assert( db->nVdbeActive>=db->nVdbeRead );
    assert( db->nVdbeRead>=db->nVdbeWrite );
    assert( db->nVdbeWrite>=0 );
  }
  p->iVdbeMagic = VDBE_MAGIC_HALT;
  checkActiveVdbeCnt(db);
  if( db->mallocFailed ){
    p->rc = SQLITE_NOMEM_BKPT;
  }

  /* If the auto-commit flag is set to true, then any locks that were held
  ** by connection db have now been released. Call sqlite3ConnectionUnlocked() 
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
        fprintf(out, "%s", zHdr);
        sqlite3VdbePrintOp(out, i, &p->aOp[i]);
      }
      fclose(out);
    }
  }
#endif
  p->magic = VDBE_MAGIC_RESET;
  return p->rc & db->errMask;
}
 
/*
** Clean up and delete a VDBE after execution.  Return an integer which is
** 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 );
  }
  sqlite3VdbeDelete(p);
  return rc;
}








|









|







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
        fprintf(out, "%s", zHdr);
        sqlite3VdbePrintOp(out, i, &p->aOp[i]);
      }
      fclose(out);
    }
  }
#endif
  p->iVdbeMagic = VDBE_MAGIC_RESET;
  return p->rc & db->errMask;
}
 
/*
** Clean up and delete a VDBE after execution.  Return an integer which is
** the result code.  Write any error message text into *pzErrMsg.
*/
int sqlite3VdbeFinalize(Vdbe *p){
  int rc = SQLITE_OK;
  if( p->iVdbeMagic==VDBE_MAGIC_RUN || p->iVdbeMagic==VDBE_MAGIC_HALT ){
    rc = sqlite3VdbeReset(p);
    assert( (rc & p->db->errMask)==rc );
  }
  sqlite3VdbeDelete(p);
  return rc;
}

3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
  assert( p->db==0 || p->db==db );
  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
  for(pSub=p->pProgram; pSub; pSub=pNext){
    pNext = pSub->pNext;
    vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
    sqlite3DbFree(db, pSub);
  }
  if( p->magic!=VDBE_MAGIC_INIT ){
    releaseMemArray(p->aVar, p->nVar);
    sqlite3DbFree(db, p->pVList);
    sqlite3DbFree(db, p->pFree);
  }
  vdbeFreeOpArray(db, p->aOp, p->nOp);
  sqlite3DbFree(db, p->aColName);
  sqlite3DbFree(db, p->zSql);







|







3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
  assert( p->db==0 || p->db==db );
  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
  for(pSub=p->pProgram; pSub; pSub=pNext){
    pNext = pSub->pNext;
    vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
    sqlite3DbFree(db, pSub);
  }
  if( p->iVdbeMagic!=VDBE_MAGIC_INIT ){
    releaseMemArray(p->aVar, p->nVar);
    sqlite3DbFree(db, p->pVList);
    sqlite3DbFree(db, p->pFree);
  }
  vdbeFreeOpArray(db, p->aOp, p->nOp);
  sqlite3DbFree(db, p->aColName);
  sqlite3DbFree(db, p->zSql);
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
  }else{
    assert( db->pVdbe==p );
    db->pVdbe = p->pNext;
  }
  if( p->pNext ){
    p->pNext->pPrev = p->pPrev;
  }
  p->magic = VDBE_MAGIC_DEAD;
  p->db = 0;
  sqlite3DbFreeNN(db, p);
}

/*
** The cursor "p" has a pending seek operation that has not yet been
** carried out.  Seek the cursor now.  If an error occurs, return







|







3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
  }else{
    assert( db->pVdbe==p );
    db->pVdbe = p->pNext;
  }
  if( p->pNext ){
    p->pNext->pPrev = p->pPrev;
  }
  p->iVdbeMagic = VDBE_MAGIC_DEAD;
  p->db = 0;
  sqlite3DbFreeNN(db, p);
}

/*
** The cursor "p" has a pending seek operation that has not yet been
** carried out.  Seek the cursor now.  If an error occurs, return
Changes to src/vdbetrace.c.
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
        testcase( zRawSql[0]=='$' );
        testcase( zRawSql[0]=='@' );
        testcase( zRawSql[0]=='#' );
        idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken);
        assert( idx>0 );
      }
      zRawSql += nToken;
      nextIndex = idx + 1;
      assert( idx>0 && idx<=p->nVar );
      pVar = &p->aVar[idx-1];
      if( pVar->flags & MEM_Null ){
        sqlite3_str_append(&out, "NULL", 4);
      }else if( pVar->flags & (MEM_Int|MEM_IntReal) ){
        sqlite3_str_appendf(&out, "%lld", pVar->u.i);
      }else if( pVar->flags & MEM_Real ){







|







121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
        testcase( zRawSql[0]=='$' );
        testcase( zRawSql[0]=='@' );
        testcase( zRawSql[0]=='#' );
        idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken);
        assert( idx>0 );
      }
      zRawSql += nToken;
      nextIndex = MAX(idx + 1, nextIndex);
      assert( idx>0 && idx<=p->nVar );
      pVar = &p->aVar[idx-1];
      if( pVar->flags & MEM_Null ){
        sqlite3_str_append(&out, "NULL", 4);
      }else if( pVar->flags & (MEM_Int|MEM_IntReal) ){
        sqlite3_str_appendf(&out, "%lld", pVar->u.i);
      }else if( pVar->flags & MEM_Real ){
Changes to src/vtab.c.
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
      pParse->regRowid
    );
    v = sqlite3GetVdbe(pParse);
    sqlite3ChangeCookie(pParse, iDb);

    sqlite3VdbeAddOp0(v, OP_Expire);
    zWhere = sqlite3MPrintf(db, "name=%Q AND sql=%Q", pTab->zName, zStmt);
    sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere);
    sqlite3DbFree(db, zStmt);

    iReg = ++pParse->nMem;
    sqlite3VdbeLoadString(v, iReg, pTab->zName);
    sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg);
  }








|







485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
      pParse->regRowid
    );
    v = sqlite3GetVdbe(pParse);
    sqlite3ChangeCookie(pParse, iDb);

    sqlite3VdbeAddOp0(v, OP_Expire);
    zWhere = sqlite3MPrintf(db, "name=%Q AND sql=%Q", pTab->zName, zStmt);
    sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere, 0);
    sqlite3DbFree(db, zStmt);

    iReg = ++pParse->nMem;
    sqlite3VdbeLoadString(v, iReg, pTab->zName);
    sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg);
  }

656
657
658
659
660
661
662

663
664
665
666
667
668
669
            zType[j] = zType[j+nDel];
          }
          if( zType[i]=='\0' && i>0 ){
            assert(zType[i-1]==' ');
            zType[i-1] = '\0';
          }
          pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN;

          oooHidden = TF_OOOHidden;
        }else{
          pTab->tabFlags |= oooHidden;
        }
      }
    }
  }







>







656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
            zType[j] = zType[j+nDel];
          }
          if( zType[i]=='\0' && i>0 ){
            assert(zType[i-1]==' ');
            zType[i-1] = '\0';
          }
          pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN;
          pTab->tabFlags |= TF_HasHidden;
          oooHidden = TF_OOOHidden;
        }else{
          pTab->tabFlags |= oooHidden;
        }
      }
    }
  }
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
   && !sParse.pNewTable->pSelect
   && !IsVirtual(sParse.pNewTable)
  ){
    if( !pTab->aCol ){
      Table *pNew = sParse.pNewTable;
      Index *pIdx;
      pTab->aCol = pNew->aCol;
      pTab->nCol = pNew->nCol;
      pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid);
      pNew->nCol = 0;
      pNew->aCol = 0;
      assert( pTab->pIndex==0 );
      assert( HasRowid(pNew) || sqlite3PrimaryKeyIndex(pNew)!=0 );
      if( !HasRowid(pNew)
       && pCtx->pVTable->pMod->pModule->xUpdate!=0







|







825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
   && !sParse.pNewTable->pSelect
   && !IsVirtual(sParse.pNewTable)
  ){
    if( !pTab->aCol ){
      Table *pNew = sParse.pNewTable;
      Index *pIdx;
      pTab->aCol = pNew->aCol;
      pTab->nNVCol = pTab->nCol = pNew->nCol;
      pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid);
      pNew->nCol = 0;
      pNew->aCol = 0;
      assert( pTab->pIndex==0 );
      assert( HasRowid(pNew) || sqlite3PrimaryKeyIndex(pNew)!=0 );
      if( !HasRowid(pNew)
       && pCtx->pVTable->pMod->pModule->xUpdate!=0
Changes to src/walker.c.
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


#if !defined(SQLITE_OMIT_WINDOWFUNC)
/*
** Walk all expressions linked into the list of Window objects passed
** as the second argument.
*/
static int walkWindowList(Walker *pWalker, Window *pList){
  Window *pWin;
  for(pWin=pList; pWin; pWin=pWin->pNextWin){
    int rc;
    rc = sqlite3WalkExprList(pWalker, pWin->pOrderBy);
    if( rc ) return WRC_Abort;
    rc = sqlite3WalkExprList(pWalker, pWin->pPartition);
    if( rc ) return WRC_Abort;
    rc = sqlite3WalkExpr(pWalker, pWin->pFilter);
    if( rc ) return WRC_Abort;

    /* The next two are purely for calls to sqlite3RenameExprUnmap()
    ** within sqlite3WindowOffsetExpr().  Because of constraints imposed
    ** by sqlite3WindowOffsetExpr(), they can never fail.  The results do
    ** not matter anyhow. */
    rc = sqlite3WalkExpr(pWalker, pWin->pStart);
    if( NEVER(rc) ) return WRC_Abort;
    rc = sqlite3WalkExpr(pWalker, pWin->pEnd);
    if( NEVER(rc) ) return WRC_Abort;

  }
  return WRC_Continue;
}
#endif

/*
** Walk an expression tree.  Invoke the callback once for each node







|


















>







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


#if !defined(SQLITE_OMIT_WINDOWFUNC)
/*
** Walk all expressions linked into the list of Window objects passed
** as the second argument.
*/
static int walkWindowList(Walker *pWalker, Window *pList, int bOneOnly){
  Window *pWin;
  for(pWin=pList; pWin; pWin=pWin->pNextWin){
    int rc;
    rc = sqlite3WalkExprList(pWalker, pWin->pOrderBy);
    if( rc ) return WRC_Abort;
    rc = sqlite3WalkExprList(pWalker, pWin->pPartition);
    if( rc ) return WRC_Abort;
    rc = sqlite3WalkExpr(pWalker, pWin->pFilter);
    if( rc ) return WRC_Abort;

    /* The next two are purely for calls to sqlite3RenameExprUnmap()
    ** within sqlite3WindowOffsetExpr().  Because of constraints imposed
    ** by sqlite3WindowOffsetExpr(), they can never fail.  The results do
    ** not matter anyhow. */
    rc = sqlite3WalkExpr(pWalker, pWin->pStart);
    if( NEVER(rc) ) return WRC_Abort;
    rc = sqlite3WalkExpr(pWalker, pWin->pEnd);
    if( NEVER(rc) ) return WRC_Abort;
    if( bOneOnly ) break;
  }
  return WRC_Continue;
}
#endif

/*
** Walk an expression tree.  Invoke the callback once for each node
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
        if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
      }else{
        if( pExpr->x.pList ){
          if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
        }
#ifndef SQLITE_OMIT_WINDOWFUNC
        if( ExprHasProperty(pExpr, EP_WinFunc) ){
          if( walkWindowList(pWalker, pExpr->y.pWin) ) return WRC_Abort;
        }
#endif
      }
    }
    break;
  }
  return WRC_Continue;







|







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
        if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
      }else{
        if( pExpr->x.pList ){
          if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
        }
#ifndef SQLITE_OMIT_WINDOWFUNC
        if( ExprHasProperty(pExpr, EP_WinFunc) ){
          if( walkWindowList(pWalker, pExpr->y.pWin, 1) ) return WRC_Abort;
        }
#endif
      }
    }
    break;
  }
  return WRC_Continue;
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
  if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort;
#if !defined(SQLITE_OMIT_WINDOWFUNC) && !defined(SQLITE_OMIT_ALTERTABLE)
  {
    Parse *pParse = pWalker->pParse;
    if( pParse && IN_RENAME_OBJECT ){
      /* The following may return WRC_Abort if there are unresolvable
      ** symbols (e.g. a table that does not exist) in a window definition. */
      int rc = walkWindowList(pWalker, p->pWinDefn);
      return rc;
    }
  }
#endif
  return WRC_Continue;
}

/*
** Walk the parse trees associated with all subqueries in the
** FROM clause of SELECT statement p.  Do not invoke the select
** callback on p, but do invoke it on each FROM clause subquery
** and on any subqueries further down in the tree.  Return 
** WRC_Abort or WRC_Continue;
*/
int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
  SrcList *pSrc;
  int i;
  struct SrcList_item *pItem;

  pSrc = p->pSrc;
  if( pSrc ){
    for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
      if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
        return WRC_Abort;
      }







|

















|







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
  if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort;
#if !defined(SQLITE_OMIT_WINDOWFUNC) && !defined(SQLITE_OMIT_ALTERTABLE)
  {
    Parse *pParse = pWalker->pParse;
    if( pParse && IN_RENAME_OBJECT ){
      /* The following may return WRC_Abort if there are unresolvable
      ** symbols (e.g. a table that does not exist) in a window definition. */
      int rc = walkWindowList(pWalker, p->pWinDefn, 0);
      return rc;
    }
  }
#endif
  return WRC_Continue;
}

/*
** Walk the parse trees associated with all subqueries in the
** FROM clause of SELECT statement p.  Do not invoke the select
** callback on p, but do invoke it on each FROM clause subquery
** and on any subqueries further down in the tree.  Return 
** WRC_Abort or WRC_Continue;
*/
int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
  SrcList *pSrc;
  int i;
  SrcItem *pItem;

  pSrc = p->pSrc;
  if( pSrc ){
    for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
      if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
        return WRC_Abort;
      }
Changes to src/where.c.
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
struct HiddenIndexInfo {
  WhereClause *pWC;   /* The Where clause being analyzed */
  Parse *pParse;      /* The parsing context */
};

/* Forward declaration of methods */
static int whereLoopResize(sqlite3*, WhereLoop*, int);

/* Test variable that can be set to enable WHERE tracing */
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
/***/ int sqlite3WhereTrace = 0;
#endif


/*
** Return the estimated number of output rows from a WHERE clause
*/
LogEst sqlite3WhereOutputRowCount(WhereInfo *pWInfo){
  return pWInfo->nRowOut;
}







<
<
<
<
<
<







32
33
34
35
36
37
38






39
40
41
42
43
44
45
struct HiddenIndexInfo {
  WhereClause *pWC;   /* The Where clause being analyzed */
  Parse *pParse;      /* The parsing context */
};

/* Forward declaration of methods */
static int whereLoopResize(sqlite3*, WhereLoop*, int);







/*
** Return the estimated number of output rows from a WHERE clause
*/
LogEst sqlite3WhereOutputRowCount(WhereInfo *pWInfo){
  return pWInfo->nRowOut;
}
100
101
102
103
104
105
106


























107
108
109
110
111
112
113
    ** continuation of the inner-most loop. */
    return pWInfo->iContinue;
  }
  pInner = &pWInfo->a[pWInfo->nLevel-1];
  assert( pInner->addrNxt!=0 );
  return pInner->addrNxt;
}



























/*
** Return the VDBE address or label to jump to in order to continue
** immediately with the next row of a WHERE clause.
*/
int sqlite3WhereContinueLabel(WhereInfo *pWInfo){
  assert( pWInfo->iContinue!=0 );







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    ** continuation of the inner-most loop. */
    return pWInfo->iContinue;
  }
  pInner = &pWInfo->a[pWInfo->nLevel-1];
  assert( pInner->addrNxt!=0 );
  return pInner->addrNxt;
}

/*
** While generating code for the min/max optimization, after handling
** the aggregate-step call to min() or max(), check to see if any
** additional looping is required.  If the output order is such that
** we are certain that the correct answer has already been found, then
** code an OP_Goto to by pass subsequent processing.
**
** Any extra OP_Goto that is coded here is an optimization.  The
** correct answer should be obtained regardless.  This OP_Goto just
** makes the answer appear faster.
*/
void sqlite3WhereMinMaxOptEarlyOut(Vdbe *v, WhereInfo *pWInfo){
  WhereLevel *pInner;
  int i;
  if( !pWInfo->bOrderedInnerLoop ) return;
  if( pWInfo->nOBSat==0 ) return;
  for(i=pWInfo->nLevel-1; i>=0; i--){
    pInner = &pWInfo->a[i];
    if( (pInner->pWLoop->wsFlags & WHERE_COLUMN_IN)!=0 ){
      sqlite3VdbeGoto(v, pInner->addrNxt);
      return;
    }
  }
  sqlite3VdbeGoto(v, pWInfo->iBreak);
}

/*
** Return the VDBE address or label to jump to in order to continue
** immediately with the next row of a WHERE clause.
*/
int sqlite3WhereContinueLabel(WhereInfo *pWInfo){
  assert( pWInfo->iContinue!=0 );
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
/*
** Return TRUE if the WHERE clause term pTerm is of a form where it
** could be used with an index to access pSrc, assuming an appropriate
** index existed.
*/
static int termCanDriveIndex(
  WhereTerm *pTerm,              /* WHERE clause term to check */
  struct SrcList_item *pSrc,     /* Table we are trying to access */
  Bitmask notReady               /* Tables in outer loops of the join */
){
  char aff;
  if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
  if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
  if( (pSrc->fg.jointype & JT_LEFT) 
   && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)







|







690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
/*
** Return TRUE if the WHERE clause term pTerm is of a form where it
** could be used with an index to access pSrc, assuming an appropriate
** index existed.
*/
static int termCanDriveIndex(
  WhereTerm *pTerm,              /* WHERE clause term to check */
  SrcItem *pSrc,                 /* Table we are trying to access */
  Bitmask notReady               /* Tables in outer loops of the join */
){
  char aff;
  if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
  if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
  if( (pSrc->fg.jointype & JT_LEFT) 
   && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
** Generate code to construct the Index object for an automatic index
** and to set up the WhereLevel object pLevel so that the code generator
** makes use of the automatic index.
*/
static void constructAutomaticIndex(
  Parse *pParse,              /* The parsing context */
  WhereClause *pWC,           /* The WHERE clause */
  struct SrcList_item *pSrc,  /* The FROM clause term to get the next index */
  Bitmask notReady,           /* Mask of cursors that are not available */
  WhereLevel *pLevel          /* Write new index here */
){
  int nKeyCol;                /* Number of columns in the constructed index */
  WhereTerm *pTerm;           /* A single term of the WHERE clause */
  WhereTerm *pWCEnd;          /* End of pWC->a[] */
  Index *pIdx;                /* Object describing the transient index */







|







724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
** Generate code to construct the Index object for an automatic index
** and to set up the WhereLevel object pLevel so that the code generator
** makes use of the automatic index.
*/
static void constructAutomaticIndex(
  Parse *pParse,              /* The parsing context */
  WhereClause *pWC,           /* The WHERE clause */
  SrcItem *pSrc,              /* The FROM clause term to get the next index */
  Bitmask notReady,           /* Mask of cursors that are not available */
  WhereLevel *pLevel          /* Write new index here */
){
  int nKeyCol;                /* Number of columns in the constructed index */
  WhereTerm *pTerm;           /* A single term of the WHERE clause */
  WhereTerm *pWCEnd;          /* End of pWC->a[] */
  Index *pIdx;                /* Object describing the transient index */
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
  WhereLoop *pLoop;           /* The Loop object */
  char *zNotUsed;             /* Extra space on the end of pIdx */
  Bitmask idxCols;            /* Bitmap of columns used for indexing */
  Bitmask extraCols;          /* Bitmap of additional columns */
  u8 sentWarning = 0;         /* True if a warnning has been issued */
  Expr *pPartial = 0;         /* Partial Index Expression */
  int iContinue = 0;          /* Jump here to skip excluded rows */
  struct SrcList_item *pTabItem;  /* FROM clause term being indexed */
  int addrCounter = 0;        /* Address where integer counter is initialized */
  int regBase;                /* Array of registers where record is assembled */

  /* Generate code to skip over the creation and initialization of the
  ** transient index on 2nd and subsequent iterations of the loop. */
  v = pParse->pVdbe;
  assert( v!=0 );







|







748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
  WhereLoop *pLoop;           /* The Loop object */
  char *zNotUsed;             /* Extra space on the end of pIdx */
  Bitmask idxCols;            /* Bitmap of columns used for indexing */
  Bitmask extraCols;          /* Bitmap of additional columns */
  u8 sentWarning = 0;         /* True if a warnning has been issued */
  Expr *pPartial = 0;         /* Partial Index Expression */
  int iContinue = 0;          /* Jump here to skip excluded rows */
  SrcItem *pTabItem;          /* FROM clause term being indexed */
  int addrCounter = 0;        /* Address where integer counter is initialized */
  int regBase;                /* Array of registers where record is assembled */

  /* Generate code to skip over the creation and initialization of the
  ** transient index on 2nd and subsequent iterations of the loop. */
  v = pParse->pVdbe;
  assert( v!=0 );
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
** responsibility of the caller to eventually release the structure
** by passing the pointer returned by this function to sqlite3_free().
*/
static sqlite3_index_info *allocateIndexInfo(
  Parse *pParse,                  /* The parsing context */
  WhereClause *pWC,               /* The WHERE clause being analyzed */
  Bitmask mUnusable,              /* Ignore terms with these prereqs */
  struct SrcList_item *pSrc,      /* The FROM clause term that is the vtab */
  ExprList *pOrderBy,             /* The ORDER BY clause */
  u16 *pmNoOmit                   /* Mask of terms not to omit */
){
  int i, j;
  int nTerm;
  struct sqlite3_index_constraint *pIdxCons;
  struct sqlite3_index_orderby *pIdxOrderBy;







|







932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
** responsibility of the caller to eventually release the structure
** by passing the pointer returned by this function to sqlite3_free().
*/
static sqlite3_index_info *allocateIndexInfo(
  Parse *pParse,                  /* The parsing context */
  WhereClause *pWC,               /* The WHERE clause being analyzed */
  Bitmask mUnusable,              /* Ignore terms with these prereqs */
  SrcItem *pSrc,                  /* The FROM clause term that is the vtab */
  ExprList *pOrderBy,             /* The ORDER BY clause */
  u16 *pmNoOmit                   /* Mask of terms not to omit */
){
  int i, j;
  int nTerm;
  struct sqlite3_index_constraint *pIdxCons;
  struct sqlite3_index_orderby *pIdxOrderBy;
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
#ifdef WHERETRACE_ENABLED
/*
** Print a WhereLoop object for debugging purposes
*/
void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){
  WhereInfo *pWInfo = pWC->pWInfo;
  int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
  struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab;
  Table *pTab = pItem->pTab;
  Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1;
  sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
                     p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
  sqlite3DebugPrintf(" %12s",
                     pItem->zAlias ? pItem->zAlias : pTab->zName);
  if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){







|







1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
#ifdef WHERETRACE_ENABLED
/*
** Print a WhereLoop object for debugging purposes
*/
void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){
  WhereInfo *pWInfo = pWC->pWInfo;
  int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
  SrcItem *pItem = pWInfo->pTabList->a + p->iTab;
  Table *pTab = pItem->pTab;
  Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1;
  sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
                     p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
  sqlite3DebugPrintf(" %12s",
                     pItem->zAlias ? pItem->zAlias : pTab->zName);
  if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
** function returns.
**
** If pProbe->idxType==SQLITE_IDXTYPE_IPK, that means pIndex is 
** a fake index used for the INTEGER PRIMARY KEY.
*/
static int whereLoopAddBtreeIndex(
  WhereLoopBuilder *pBuilder,     /* The WhereLoop factory */
  struct SrcList_item *pSrc,      /* FROM clause term being analyzed */
  Index *pProbe,                  /* An index on pSrc */
  LogEst nInMul                   /* log(Number of iterations due to IN) */
){
  WhereInfo *pWInfo = pBuilder->pWInfo;  /* WHERE analyse context */
  Parse *pParse = pWInfo->pParse;        /* Parsing context */
  sqlite3 *db = pParse->db;       /* Database connection malloc context */
  WhereLoop *pNew;                /* Template WhereLoop under construction */







|







2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
** function returns.
**
** If pProbe->idxType==SQLITE_IDXTYPE_IPK, that means pIndex is 
** a fake index used for the INTEGER PRIMARY KEY.
*/
static int whereLoopAddBtreeIndex(
  WhereLoopBuilder *pBuilder,     /* The WhereLoop factory */
  SrcItem *pSrc,                  /* FROM clause term being analyzed */
  Index *pProbe,                  /* An index on pSrc */
  LogEst nInMul                   /* log(Number of iterations due to IN) */
){
  WhereInfo *pWInfo = pBuilder->pWInfo;  /* WHERE analyse context */
  Parse *pParse = pWInfo->pParse;        /* Parsing context */
  sqlite3 *db = pParse->db;       /* Database connection malloc context */
  WhereLoop *pNew;                /* Template WhereLoop under construction */
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
      pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
      pNew->u.btree.nBtm = whereRangeVectorLen(
          pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm
      );
      pBtm = pTerm;
      pTop = 0;
      if( pTerm->wtFlags & TERM_LIKEOPT ){
        /* Range contraints that come from the LIKE optimization are
        ** always used in pairs. */
        pTop = &pTerm[1];
        assert( (pTop-(pTerm->pWC->a))<pTerm->pWC->nTerm );
        assert( pTop->wtFlags & TERM_LIKEOPT );
        assert( pTop->eOperator==WO_LT );
        if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
        pNew->aLTerm[pNew->nLTerm++] = pTop;







|







2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
      pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
      pNew->u.btree.nBtm = whereRangeVectorLen(
          pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm
      );
      pBtm = pTerm;
      pTop = 0;
      if( pTerm->wtFlags & TERM_LIKEOPT ){
        /* Range constraints that come from the LIKE optimization are
        ** always used in pairs. */
        pTop = &pTerm[1];
        assert( (pTop-(pTerm->pWC->a))<pTerm->pWC->nTerm );
        assert( pTop->wtFlags & TERM_LIKEOPT );
        assert( pTop->eOperator==WO_LT );
        if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
        pNew->aLTerm[pNew->nLTerm++] = pTop;
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
){
  WhereInfo *pWInfo;          /* WHERE analysis context */
  Index *pProbe;              /* An index we are evaluating */
  Index sPk;                  /* A fake index object for the primary key */
  LogEst aiRowEstPk[2];       /* The aiRowLogEst[] value for the sPk index */
  i16 aiColumnPk = -1;        /* The aColumn[] value for the sPk index */
  SrcList *pTabList;          /* The FROM clause */
  struct SrcList_item *pSrc;  /* The FROM clause btree term to add */
  WhereLoop *pNew;            /* Template WhereLoop object */
  int rc = SQLITE_OK;         /* Return code */
  int iSortIdx = 1;           /* Index number */
  int b;                      /* A boolean value */
  LogEst rSize;               /* number of rows in the table */
  LogEst rLogSize;            /* Logarithm of the number of rows in the table */
  WhereClause *pWC;           /* The parsed WHERE clause */
  Table *pTab;                /* Table being queried */
  
  pNew = pBuilder->pNew;
  pWInfo = pBuilder->pWInfo;
  pTabList = pWInfo->pTabList;
  pSrc = pTabList->a + pNew->iTab;
  pTab = pSrc->pTab;
  pWC = pBuilder->pWC;
  assert( !IsVirtual(pSrc->pTab) );

  if( pSrc->pIBIndex ){
    /* An INDEXED BY clause specifies a particular index to use */
    pProbe = pSrc->pIBIndex;
  }else if( !HasRowid(pTab) ){
    pProbe = pTab->pIndex;
  }else{
    /* There is no INDEXED BY clause.  Create a fake Index object in local
    ** variable sPk to represent the rowid primary key index.  Make this
    ** fake index the first in a chain of Index objects with all of the real
    ** indices to follow */







|

















|

|







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
){
  WhereInfo *pWInfo;          /* WHERE analysis context */
  Index *pProbe;              /* An index we are evaluating */
  Index sPk;                  /* A fake index object for the primary key */
  LogEst aiRowEstPk[2];       /* The aiRowLogEst[] value for the sPk index */
  i16 aiColumnPk = -1;        /* The aColumn[] value for the sPk index */
  SrcList *pTabList;          /* The FROM clause */
  SrcItem *pSrc;              /* The FROM clause btree term to add */
  WhereLoop *pNew;            /* Template WhereLoop object */
  int rc = SQLITE_OK;         /* Return code */
  int iSortIdx = 1;           /* Index number */
  int b;                      /* A boolean value */
  LogEst rSize;               /* number of rows in the table */
  LogEst rLogSize;            /* Logarithm of the number of rows in the table */
  WhereClause *pWC;           /* The parsed WHERE clause */
  Table *pTab;                /* Table being queried */
  
  pNew = pBuilder->pNew;
  pWInfo = pBuilder->pWInfo;
  pTabList = pWInfo->pTabList;
  pSrc = pTabList->a + pNew->iTab;
  pTab = pSrc->pTab;
  pWC = pBuilder->pWC;
  assert( !IsVirtual(pSrc->pTab) );

  if( pSrc->fg.isIndexedBy ){
    /* An INDEXED BY clause specifies a particular index to use */
    pProbe = pSrc->u2.pIBIndex;
  }else if( !HasRowid(pTab) ){
    pProbe = pTab->pIndex;
  }else{
    /* There is no INDEXED BY clause.  Create a fake Index object in local
    ** variable sPk to represent the rowid primary key index.  Make this
    ** fake index the first in a chain of Index objects with all of the real
    ** indices to follow */
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
  rLogSize = estLog(rSize);

#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
  /* Automatic indexes */
  if( !pBuilder->pOrSet      /* Not part of an OR optimization */
   && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0
   && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
   && pSrc->pIBIndex==0      /* Has no INDEXED BY clause */
   && !pSrc->fg.notIndexed   /* Has no NOT INDEXED clause */
   && HasRowid(pTab)         /* Not WITHOUT ROWID table. (FIXME: Why not?) */
   && !pSrc->fg.isCorrelated /* Not a correlated subquery */
   && !pSrc->fg.isRecursive  /* Not a recursive common table expression. */
  ){
    /* Generate auto-index WhereLoops */
    WhereTerm *pTerm;







|







2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
  rLogSize = estLog(rSize);

#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
  /* Automatic indexes */
  if( !pBuilder->pOrSet      /* Not part of an OR optimization */
   && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0
   && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
   && !pSrc->fg.isIndexedBy  /* Has no INDEXED BY clause */
   && !pSrc->fg.notIndexed   /* Has no NOT INDEXED clause */
   && HasRowid(pTab)         /* Not WITHOUT ROWID table. (FIXME: Why not?) */
   && !pSrc->fg.isCorrelated /* Not a correlated subquery */
   && !pSrc->fg.isRecursive  /* Not a recursive common table expression. */
  ){
    /* Generate auto-index WhereLoops */
    WhereTerm *pTerm;
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
    }
  }
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */

  /* Loop over all indices. If there was an INDEXED BY clause, then only 
  ** consider index pProbe.  */
  for(; rc==SQLITE_OK && pProbe; 
      pProbe=(pSrc->pIBIndex ? 0 : pProbe->pNext), iSortIdx++
  ){
    int isLeft = (pSrc->fg.jointype & JT_OUTER)!=0;
    if( pProbe->pPartIdxWhere!=0
     && !whereUsablePartialIndex(pSrc->iCursor, isLeft, pWC,
                                 pProbe->pPartIdxWhere)
    ){
      testcase( pNew->iTab!=pSrc->iCursor );  /* See ticket [98d973b8f5] */







|







3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
    }
  }
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */

  /* Loop over all indices. If there was an INDEXED BY clause, then only 
  ** consider index pProbe.  */
  for(; rc==SQLITE_OK && pProbe; 
      pProbe=(pSrc->fg.isIndexedBy ? 0 : pProbe->pNext), iSortIdx++
  ){
    int isLeft = (pSrc->fg.jointype & JT_OUTER)!=0;
    if( pProbe->pPartIdxWhere!=0
     && !whereUsablePartialIndex(pSrc->iCursor, isLeft, pWC,
                                 pProbe->pPartIdxWhere)
    ){
      testcase( pNew->iTab!=pSrc->iCursor );  /* See ticket [98d973b8f5] */
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
  struct sqlite3_index_constraint *pIdxCons;
  struct sqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage;
  int i;
  int mxTerm;
  int rc = SQLITE_OK;
  WhereLoop *pNew = pBuilder->pNew;
  Parse *pParse = pBuilder->pWInfo->pParse;
  struct SrcList_item *pSrc = &pBuilder->pWInfo->pTabList->a[pNew->iTab];
  int nConstraint = pIdxInfo->nConstraint;

  assert( (mUsable & mPrereq)==mPrereq );
  *pbIn = 0;
  pNew->prereq = mPrereq;

  /* Set the usable flag on the subset of constraints identified by 







|







3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
  struct sqlite3_index_constraint *pIdxCons;
  struct sqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage;
  int i;
  int mxTerm;
  int rc = SQLITE_OK;
  WhereLoop *pNew = pBuilder->pNew;
  Parse *pParse = pBuilder->pWInfo->pParse;
  SrcItem *pSrc = &pBuilder->pWInfo->pTabList->a[pNew->iTab];
  int nConstraint = pIdxInfo->nConstraint;

  assert( (mUsable & mPrereq)==mPrereq );
  *pbIn = 0;
  pNew->prereq = mPrereq;

  /* Set the usable flag on the subset of constraints identified by 
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
  Bitmask mPrereq,             /* Tables that must be scanned before this one */
  Bitmask mUnusable            /* Tables that must be scanned after this one */
){
  int rc = SQLITE_OK;          /* Return code */
  WhereInfo *pWInfo;           /* WHERE analysis context */
  Parse *pParse;               /* The parsing context */
  WhereClause *pWC;            /* The WHERE clause */
  struct SrcList_item *pSrc;   /* The FROM clause term to search */
  sqlite3_index_info *p;       /* Object to pass to xBestIndex() */
  int nConstraint;             /* Number of constraints in p */
  int bIn;                     /* True if plan uses IN(...) operator */
  WhereLoop *pNew;
  Bitmask mBest;               /* Tables used by best possible plan */
  u16 mNoOmit;








|







3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
  Bitmask mPrereq,             /* Tables that must be scanned before this one */
  Bitmask mUnusable            /* Tables that must be scanned after this one */
){
  int rc = SQLITE_OK;          /* Return code */
  WhereInfo *pWInfo;           /* WHERE analysis context */
  Parse *pParse;               /* The parsing context */
  WhereClause *pWC;            /* The WHERE clause */
  SrcItem *pSrc;               /* The FROM clause term to search */
  sqlite3_index_info *p;       /* Object to pass to xBestIndex() */
  int nConstraint;             /* Number of constraints in p */
  int bIn;                     /* True if plan uses IN(...) operator */
  WhereLoop *pNew;
  Bitmask mBest;               /* Tables used by best possible plan */
  u16 mNoOmit;

3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
  WhereLoop *pNew;
  WhereTerm *pTerm, *pWCEnd;
  int rc = SQLITE_OK;
  int iCur;
  WhereClause tempWC;
  WhereLoopBuilder sSubBuild;
  WhereOrSet sSum, sCur;
  struct SrcList_item *pItem;
  
  pWC = pBuilder->pWC;
  pWCEnd = pWC->a + pWC->nTerm;
  pNew = pBuilder->pNew;
  memset(&sSum, 0, sizeof(sSum));
  pItem = pWInfo->pTabList->a + pNew->iTab;
  iCur = pItem->iCursor;







|







3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
  WhereLoop *pNew;
  WhereTerm *pTerm, *pWCEnd;
  int rc = SQLITE_OK;
  int iCur;
  WhereClause tempWC;
  WhereLoopBuilder sSubBuild;
  WhereOrSet sSum, sCur;
  SrcItem *pItem;
  
  pWC = pBuilder->pWC;
  pWCEnd = pWC->a + pWC->nTerm;
  pNew = pBuilder->pNew;
  memset(&sSum, 0, sizeof(sSum));
  pItem = pWInfo->pTabList->a + pNew->iTab;
  iCur = pItem->iCursor;
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
*/
static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
  WhereInfo *pWInfo = pBuilder->pWInfo;
  Bitmask mPrereq = 0;
  Bitmask mPrior = 0;
  int iTab;
  SrcList *pTabList = pWInfo->pTabList;
  struct SrcList_item *pItem;
  struct SrcList_item *pEnd = &pTabList->a[pWInfo->nLevel];
  sqlite3 *db = pWInfo->pParse->db;
  int rc = SQLITE_OK;
  WhereLoop *pNew;

  /* Loop over the tables in the join, from left to right */
  pNew = pBuilder->pNew;
  whereLoopInit(pNew);







|
|







3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
*/
static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
  WhereInfo *pWInfo = pBuilder->pWInfo;
  Bitmask mPrereq = 0;
  Bitmask mPrior = 0;
  int iTab;
  SrcList *pTabList = pWInfo->pTabList;
  SrcItem *pItem;
  SrcItem *pEnd = &pTabList->a[pWInfo->nLevel];
  sqlite3 *db = pWInfo->pParse->db;
  int rc = SQLITE_OK;
  WhereLoop *pNew;

  /* Loop over the tables in the join, from left to right */
  pNew = pBuilder->pNew;
  whereLoopInit(pNew);
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
      ** right-hand-side of a LEFT or CROSS JOIN.  */
      mPrereq = mPrior;
    }else{
      mPrereq = 0;
    }
#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( IsVirtual(pItem->pTab) ){
      struct SrcList_item *p;
      for(p=&pItem[1]; p<pEnd; p++){
        if( mUnusable || (p->fg.jointype & (JT_LEFT|JT_CROSS)) ){
          mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor);
        }
      }
      rc = whereLoopAddVirtual(pBuilder, mPrereq, mUnusable);
    }else







|







3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
      ** right-hand-side of a LEFT or CROSS JOIN.  */
      mPrereq = mPrior;
    }else{
      mPrereq = 0;
    }
#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( IsVirtual(pItem->pTab) ){
      SrcItem *p;
      for(p=&pItem[1]; p<pEnd; p++){
        if( mUnusable || (p->fg.jointype & (JT_LEFT|JT_CROSS)) ){
          mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor);
        }
      }
      rc = whereLoopAddVirtual(pBuilder, mPrereq, mUnusable);
    }else
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
**
** Return non-zero on success, if this query can be handled by this
** no-frills query planner.  Return zero if this query needs the 
** general-purpose query planner.
*/
static int whereShortCut(WhereLoopBuilder *pBuilder){
  WhereInfo *pWInfo;
  struct SrcList_item *pItem;
  WhereClause *pWC;
  WhereTerm *pTerm;
  WhereLoop *pLoop;
  int iCur;
  int j;
  Table *pTab;
  Index *pIdx;







|







4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
**
** Return non-zero on success, if this query can be handled by this
** no-frills query planner.  Return zero if this query needs the 
** general-purpose query planner.
*/
static int whereShortCut(WhereLoopBuilder *pBuilder){
  WhereInfo *pWInfo;
  SrcItem *pItem;
  WhereClause *pWC;
  WhereTerm *pTerm;
  WhereLoop *pLoop;
  int iCur;
  int j;
  Table *pTab;
  Index *pIdx;
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
       wherePathSolver(pWInfo, pWInfo->nRowOut+1);
       if( db->mallocFailed ) goto whereBeginError;
    }
  }
  if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
     pWInfo->revMask = ALLBITS;
  }
  if( pParse->nErr || NEVER(db->mallocFailed) ){
    goto whereBeginError;
  }
#ifdef WHERETRACE_ENABLED
  if( sqlite3WhereTrace ){
    sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut);
    if( pWInfo->nOBSat>0 ){
      sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask);







|







4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
       wherePathSolver(pWInfo, pWInfo->nRowOut+1);
       if( db->mallocFailed ) goto whereBeginError;
    }
  }
  if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
     pWInfo->revMask = ALLBITS;
  }
  if( pParse->nErr || db->mallocFailed ){
    goto whereBeginError;
  }
#ifdef WHERETRACE_ENABLED
  if( sqlite3WhereTrace ){
    sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut);
    if( pWInfo->nOBSat>0 ){
      sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask);
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
    int i;
    Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet);
    if( sWLB.pOrderBy ){
      tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy);
    }
    for(i=pWInfo->nLevel-1; i>=1; i--){
      WhereTerm *pTerm, *pEnd;
      struct SrcList_item *pItem;
      pLoop = pWInfo->a[i].pWLoop;
      pItem = &pWInfo->pTabList->a[pLoop->iTab];
      if( (pItem->fg.jointype & JT_LEFT)==0 ) continue;
      if( (wctrlFlags & WHERE_WANT_DISTINCT)==0
       && (pLoop->wsFlags & WHERE_ONEROW)==0
      ){
        continue;







|







5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
    int i;
    Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet);
    if( sWLB.pOrderBy ){
      tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy);
    }
    for(i=pWInfo->nLevel-1; i>=1; i--){
      WhereTerm *pTerm, *pEnd;
      SrcItem *pItem;
      pLoop = pWInfo->a[i].pWLoop;
      pItem = &pWInfo->pTabList->a[pLoop->iTab];
      if( (pItem->fg.jointype & JT_LEFT)==0 ) continue;
      if( (wctrlFlags & WHERE_WANT_DISTINCT)==0
       && (pLoop->wsFlags & WHERE_ONEROW)==0
      ){
        continue;
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142

  /* Open all tables in the pTabList and any indices selected for
  ** searching those tables.
  */
  for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){
    Table *pTab;     /* Table to open */
    int iDb;         /* Index of database containing table/index */
    struct SrcList_item *pTabItem;

    pTabItem = &pTabList->a[pLevel->iFrom];
    pTab = pTabItem->pTab;
    iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
    pLoop = pLevel->pWLoop;
    if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){
      /* Do nothing */







|







5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162

  /* Open all tables in the pTabList and any indices selected for
  ** searching those tables.
  */
  for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){
    Table *pTab;     /* Table to open */
    int iDb;         /* Index of database containing table/index */
    SrcItem *pTabItem;

    pTabItem = &pTabList->a[pLevel->iFrom];
    pTab = pTabItem->pTab;
    iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
    pLoop = pLevel->pWLoop;
    if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){
      /* Do nothing */
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
  sqlite3VdbeResolveLabel(v, pWInfo->iBreak);

  assert( pWInfo->nLevel<=pTabList->nSrc );
  for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
    int k, last;
    VdbeOp *pOp, *pLastOp;
    Index *pIdx = 0;
    struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];
    Table *pTab = pTabItem->pTab;
    assert( pTab!=0 );
    pLoop = pLevel->pWLoop;

    /* For a co-routine, change all OP_Column references to the table of
    ** the co-routine into OP_Copy of result contained in a register.
    ** OP_Rowid becomes OP_Null.







|







5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
  sqlite3VdbeResolveLabel(v, pWInfo->iBreak);

  assert( pWInfo->nLevel<=pTabList->nSrc );
  for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
    int k, last;
    VdbeOp *pOp, *pLastOp;
    Index *pIdx = 0;
    SrcItem *pTabItem = &pTabList->a[pLevel->iFrom];
    Table *pTab = pTabItem->pTab;
    assert( pTab!=0 );
    pLoop = pLevel->pWLoop;

    /* For a co-routine, change all OP_Column references to the table of
    ** the co-routine into OP_Copy of result contained in a register.
    ** OP_Rowid becomes OP_Null.
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
      pOp = sqlite3VdbeGetOp(v, k - 1);
      assert( pOp->opcode!=OP_Column || pOp->p1!=pLevel->iTabCur );
      assert( pOp->opcode!=OP_Rowid  || pOp->p1!=pLevel->iTabCur );
      assert( pOp->opcode!=OP_IfNullRow || pOp->p1!=pLevel->iTabCur );
#endif
      pOp = sqlite3VdbeGetOp(v, k);
      pLastOp = pOp + (last - k);
      assert( pOp<pLastOp );
      do{
        if( pOp->p1!=pLevel->iTabCur ){
          /* no-op */
        }else if( pOp->opcode==OP_Column
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
         || pOp->opcode==OP_Offset
#endif







|







5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
      pOp = sqlite3VdbeGetOp(v, k - 1);
      assert( pOp->opcode!=OP_Column || pOp->p1!=pLevel->iTabCur );
      assert( pOp->opcode!=OP_Rowid  || pOp->p1!=pLevel->iTabCur );
      assert( pOp->opcode!=OP_IfNullRow || pOp->p1!=pLevel->iTabCur );
#endif
      pOp = sqlite3VdbeGetOp(v, k);
      pLastOp = pOp + (last - k);
      assert( pOp<pLastOp || (pParse->nErr>0 && pOp==pLastOp) );
      do{
        if( pOp->p1!=pLevel->iTabCur ){
          /* no-op */
        }else if( pOp->opcode==OP_Column
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
         || pOp->opcode==OP_Offset
#endif
Changes to src/whereInt.h.
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
** This file contains structure and macro definitions for the query
** planner logic in "where.c".  These definitions are broken out into
** a separate source file for easier editing.
*/
#ifndef SQLITE_WHEREINT_H
#define SQLITE_WHEREINT_H

/*
** Trace output macros
*/
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
/***/ extern int sqlite3WhereTrace;
#endif
#if defined(SQLITE_DEBUG) \
    && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE))
# define WHERETRACE(K,X)  if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X
# define WHERETRACE_ENABLED 1
#else
# define WHERETRACE(K,X)
#endif

/* Forward references
*/
typedef struct WhereClause WhereClause;
typedef struct WhereMaskSet WhereMaskSet;
typedef struct WhereOrInfo WhereOrInfo;
typedef struct WhereAndInfo WhereAndInfo;







<
<
<
<
<
<
<
<
<
<
<
<
<







13
14
15
16
17
18
19













20
21
22
23
24
25
26
** This file contains structure and macro definitions for the query
** planner logic in "where.c".  These definitions are broken out into
** a separate source file for easier editing.
*/
#ifndef SQLITE_WHEREINT_H
#define SQLITE_WHEREINT_H















/* Forward references
*/
typedef struct WhereClause WhereClause;
typedef struct WhereMaskSet WhereMaskSet;
typedef struct WhereOrInfo WhereOrInfo;
typedef struct WhereAndInfo WhereAndInfo;
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
#define TERM_DYNAMIC    0x0001 /* Need to call sqlite3ExprDelete(db, pExpr) */
#define TERM_VIRTUAL    0x0002 /* Added by the optimizer.  Do not code */
#define TERM_CODED      0x0004 /* This term is already coded */
#define TERM_COPIED     0x0008 /* Has a child */
#define TERM_ORINFO     0x0010 /* Need to free the WhereTerm.u.pOrInfo object */
#define TERM_ANDINFO    0x0020 /* Need to free the WhereTerm.u.pAndInfo obj */
#define TERM_OR_OK      0x0040 /* Used during OR-clause processing */
#ifdef SQLITE_ENABLE_STAT4
#  define TERM_VNULL    0x0080 /* Manufactured x>NULL or x<=NULL term */
#else
#  define TERM_VNULL    0x0000 /* Disabled if not using stat4 */
#endif
#define TERM_LIKEOPT    0x0100 /* Virtual terms from the LIKE optimization */
#define TERM_LIKECOND   0x0200 /* Conditionally this LIKE operator term */
#define TERM_LIKE       0x0400 /* The original LIKE operator */
#define TERM_IS         0x0800 /* Term.pExpr is an IS operator */
#define TERM_VARSELECT  0x1000 /* Term.pExpr contains a correlated sub-query */
#define TERM_HEURTRUTH  0x2000 /* Heuristic truthProb used */
#ifdef SQLITE_ENABLE_STAT4







<
|
<
<
<







266
267
268
269
270
271
272

273



274
275
276
277
278
279
280
#define TERM_DYNAMIC    0x0001 /* Need to call sqlite3ExprDelete(db, pExpr) */
#define TERM_VIRTUAL    0x0002 /* Added by the optimizer.  Do not code */
#define TERM_CODED      0x0004 /* This term is already coded */
#define TERM_COPIED     0x0008 /* Has a child */
#define TERM_ORINFO     0x0010 /* Need to free the WhereTerm.u.pOrInfo object */
#define TERM_ANDINFO    0x0020 /* Need to free the WhereTerm.u.pAndInfo obj */
#define TERM_OR_OK      0x0040 /* Used during OR-clause processing */

#define TERM_VNULL      0x0080 /* Manufactured x>NULL or x<=NULL term */



#define TERM_LIKEOPT    0x0100 /* Virtual terms from the LIKE optimization */
#define TERM_LIKECOND   0x0200 /* Conditionally this LIKE operator term */
#define TERM_LIKE       0x0400 /* The original LIKE operator */
#define TERM_IS         0x0800 /* Term.pExpr is an IS operator */
#define TERM_VARSELECT  0x1000 /* Term.pExpr contains a correlated sub-query */
#define TERM_HEURTRUTH  0x2000 /* Heuristic truthProb used */
#ifdef SQLITE_ENABLE_STAT4
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
void sqlite3WhereClauseInit(WhereClause*,WhereInfo*);
void sqlite3WhereClauseClear(WhereClause*);
void sqlite3WhereSplit(WhereClause*,Expr*,u8);
Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*);
Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*);
Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*);
void sqlite3WhereExprAnalyze(SrcList*, WhereClause*);
void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*);





/*
** Bitmasks for the operators on WhereTerm objects.  These are all







|







536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
void sqlite3WhereClauseInit(WhereClause*,WhereInfo*);
void sqlite3WhereClauseClear(WhereClause*);
void sqlite3WhereSplit(WhereClause*,Expr*,u8);
Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*);
Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*);
Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*);
void sqlite3WhereExprAnalyze(SrcList*, WhereClause*);
void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*);





/*
** Bitmasks for the operators on WhereTerm objects.  These are all
Changes to src/wherecode.c.
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
  u16 wctrlFlags                  /* Flags passed to sqlite3WhereBegin() */
){
  int ret = 0;
#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
  if( sqlite3ParseToplevel(pParse)->explain==2 )
#endif
  {
    struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
    Vdbe *v = pParse->pVdbe;      /* VM being constructed */
    sqlite3 *db = pParse->db;     /* Database handle */
    int isSearch;                 /* True for a SEARCH. False for SCAN. */
    WhereLoop *pLoop;             /* The controlling WhereLoop object */
    u32 flags;                    /* Flags that describe this loop */
    char *zMsg;                   /* Text to add to EQP output */
    StrAccum str;                 /* EQP output string */







|







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
  u16 wctrlFlags                  /* Flags passed to sqlite3WhereBegin() */
){
  int ret = 0;
#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
  if( sqlite3ParseToplevel(pParse)->explain==2 )
#endif
  {
    SrcItem *pItem = &pTabList->a[pLevel->iFrom];
    Vdbe *v = pParse->pVdbe;      /* VM being constructed */
    sqlite3 *db = pParse->db;     /* Database handle */
    int isSearch;                 /* True for a SEARCH. False for SCAN. */
    WhereLoop *pLoop;             /* The controlling WhereLoop object */
    u32 flags;                    /* Flags that describe this loop */
    char *zMsg;                   /* Text to add to EQP output */
    StrAccum str;                 /* EQP output string */
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
  return rc;
}

/*
** Insert an OP_CursorHint instruction if it is appropriate to do so.
*/
static void codeCursorHint(
  struct SrcList_item *pTabItem,  /* FROM clause item */
  WhereInfo *pWInfo,    /* The where clause */
  WhereLevel *pLevel,   /* Which loop to provide hints for */
  WhereTerm *pEndRange  /* Hint this end-of-scan boundary term if not NULL */
){
  Parse *pParse = pWInfo->pParse;
  sqlite3 *db = pParse->db;
  Vdbe *v = pParse->pVdbe;







|







918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
  return rc;
}

/*
** Insert an OP_CursorHint instruction if it is appropriate to do so.
*/
static void codeCursorHint(
  SrcItem *pTabItem,  /* FROM clause item */
  WhereInfo *pWInfo,    /* The where clause */
  WhereLevel *pLevel,   /* Which loop to provide hints for */
  WhereTerm *pEndRange  /* Hint this end-of-scan boundary term if not NULL */
){
  Parse *pParse = pWInfo->pParse;
  sqlite3 *db = pParse->db;
  Vdbe *v = pParse->pVdbe;
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
  int iCur;            /* The VDBE cursor for the table */
  int addrNxt;         /* Where to jump to continue with the next IN case */
  int bRev;            /* True if we need to scan in reverse order */
  WhereLoop *pLoop;    /* The WhereLoop object being coded */
  WhereClause *pWC;    /* Decomposition of the entire WHERE clause */
  WhereTerm *pTerm;               /* A WHERE clause term */
  sqlite3 *db;                    /* Database connection */
  struct SrcList_item *pTabItem;  /* FROM clause term being coded */
  int addrBrk;                    /* Jump here to break out of the loop */
  int addrHalt;                   /* addrBrk for the outermost loop */
  int addrCont;                   /* Jump here to continue with next cycle */
  int iRowidReg = 0;        /* Rowid is stored in this register, if not zero */
  int iReleaseReg = 0;      /* Temp register to free before returning */
  Index *pIdx = 0;          /* Index used by loop (if any) */
  int iLoop;                /* Iteration of constraint generator loop */







|







1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
  int iCur;            /* The VDBE cursor for the table */
  int addrNxt;         /* Where to jump to continue with the next IN case */
  int bRev;            /* True if we need to scan in reverse order */
  WhereLoop *pLoop;    /* The WhereLoop object being coded */
  WhereClause *pWC;    /* Decomposition of the entire WHERE clause */
  WhereTerm *pTerm;               /* A WHERE clause term */
  sqlite3 *db;                    /* Database connection */
  SrcItem *pTabItem;              /* FROM clause term being coded */
  int addrBrk;                    /* Jump here to break out of the loop */
  int addrHalt;                   /* addrBrk for the outermost loop */
  int addrCont;                   /* Jump here to continue with next cycle */
  int iRowidReg = 0;        /* Rowid is stored in this register, if not zero */
  int iReleaseReg = 0;      /* Temp register to free before returning */
  Index *pIdx = 0;          /* Index used by loop (if any) */
  int iLoop;                /* Iteration of constraint generator loop */
1739
1740
1741
1742
1743
1744
1745






1746
1747
1748
1749
1750
1751
1752
    if( (nEq<pIdx->nKeyCol && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
     || (bRev && pIdx->nKeyCol==nEq)
    ){
      SWAP(WhereTerm *, pRangeEnd, pRangeStart);
      SWAP(u8, bSeekPastNull, bStopAtNull);
      SWAP(u8, nBtm, nTop);
    }







    /* 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.
    */
    codeCursorHint(pTabItem, pWInfo, pLevel, pRangeEnd);
    regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);







>
>
>
>
>
>







1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
    if( (nEq<pIdx->nKeyCol && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
     || (bRev && pIdx->nKeyCol==nEq)
    ){
      SWAP(WhereTerm *, pRangeEnd, pRangeStart);
      SWAP(u8, bSeekPastNull, bStopAtNull);
      SWAP(u8, nBtm, nTop);
    }

    if( iLevel>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)!=0 ){
      /* In case OP_SeekScan is used, ensure that the index cursor does not
      ** point to a valid row for the first iteration of this loop. */
      sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur);
    }

    /* 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.
    */
    codeCursorHint(pTabItem, pWInfo, pLevel, pRangeEnd);
    regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090

    /* Set up a new SrcList in pOrTab containing the table being scanned
    ** by this loop in the a[0] slot and all notReady tables in a[1..] slots.
    ** This becomes the SrcList in the recursive call to sqlite3WhereBegin().
    */
    if( pWInfo->nLevel>1 ){
      int nNotReady;                 /* The number of notReady tables */
      struct SrcList_item *origSrc;     /* Original list of tables */
      nNotReady = pWInfo->nLevel - iLevel - 1;
      pOrTab = sqlite3StackAllocRaw(db,
                            sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0]));
      if( pOrTab==0 ) return notReady;
      pOrTab->nAlloc = (u8)(nNotReady + 1);
      pOrTab->nSrc = pOrTab->nAlloc;
      memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem));







|







2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096

    /* Set up a new SrcList in pOrTab containing the table being scanned
    ** by this loop in the a[0] slot and all notReady tables in a[1..] slots.
    ** This becomes the SrcList in the recursive call to sqlite3WhereBegin().
    */
    if( pWInfo->nLevel>1 ){
      int nNotReady;                 /* The number of notReady tables */
      SrcItem *origSrc;              /* Original list of tables */
      nNotReady = pWInfo->nLevel - iLevel - 1;
      pOrTab = sqlite3StackAllocRaw(db,
                            sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0]));
      if( pOrTab==0 ) return notReady;
      pOrTab->nAlloc = (u8)(nNotReady + 1);
      pOrTab->nSrc = pOrTab->nAlloc;
      memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem));
Changes to src/whereexpr.c.
1002
1003
1004
1005
1006
1007
1008














































































































































































































































































1009
1010
1011
1012
1013
1014
1015
    aiCurCol[1] = pExpr->iColumn;
    return 1;
  }
  if( mPrereq==0 ) return 0;                 /* No table references */
  if( (mPrereq&(mPrereq-1))!=0 ) return 0;   /* Refs more than one table */
  return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr);
}















































































































































































































































































/*
** The input to this routine is an WhereTerm structure with only the
** "pExpr" field filled in.  The job of this routine is to analyze the
** subexpression and populate all the other fields of the WhereTerm
** structure.
**







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    aiCurCol[1] = pExpr->iColumn;
    return 1;
  }
  if( mPrereq==0 ) return 0;                 /* No table references */
  if( (mPrereq&(mPrereq-1))!=0 ) return 0;   /* Refs more than one table */
  return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr);
}

/*
** Expression callback for exprUsesSrclist().
*/
static int exprUsesSrclistCb(Walker *p, Expr *pExpr){
  if( pExpr->op==TK_COLUMN ){
    SrcList *pSrc = p->u.pSrcList;
    int iCsr = pExpr->iTable;
    int ii;
    for(ii=0; ii<pSrc->nSrc; ii++){
      if( pSrc->a[ii].iCursor==iCsr ){
        return p->eCode ? WRC_Abort : WRC_Continue;
      }
    }
    return p->eCode ? WRC_Continue : WRC_Abort;
  }
  return WRC_Continue;
}

/*
** Select callback for exprUsesSrclist().
*/
static int exprUsesSrclistSelectCb(Walker *NotUsed1, Select *NotUsed2){
  UNUSED_PARAMETER(NotUsed1);
  UNUSED_PARAMETER(NotUsed2);
  return WRC_Abort;
}

/*
** This function always returns true if expression pExpr contains
** a sub-select.
**
** If there is no sub-select in pExpr, then return true if pExpr
** contains a TK_COLUMN node for a table that is (bUses==1)
** or is not (bUses==0) in pSrc.
**
** Said another way:
**
**   bUses      Return     Meaning
**   --------   ------     ------------------------------------------------
**
**   bUses==1   true       pExpr contains either a sub-select or a
**                         TK_COLUMN referencing pSrc.
**
**   bUses==1   false      pExpr contains no sub-selects and all TK_COLUMN
**                         nodes reference tables not found in pSrc
**
**   bUses==0   true       pExpr contains either a sub-select or a TK_COLUMN
**                         that references a table not in pSrc.
**
**   bUses==0   false      pExpr contains no sub-selects and all TK_COLUMN
**                         nodes reference pSrc
*/
static int exprUsesSrclist(SrcList *pSrc, Expr *pExpr, int bUses){
  Walker sWalker;
  memset(&sWalker, 0, sizeof(Walker));
  sWalker.eCode = bUses;
  sWalker.u.pSrcList = pSrc;
  sWalker.xExprCallback = exprUsesSrclistCb;
  sWalker.xSelectCallback = exprUsesSrclistSelectCb;
  return (sqlite3WalkExpr(&sWalker, pExpr)==WRC_Abort);
}

/*
** Context object used by exprExistsToInIter() as it iterates through an
** expression tree.
*/
struct ExistsToInCtx {
  SrcList *pSrc;    /* The tables in an EXISTS(SELECT ... FROM <here> ...) */
  Expr *pInLhs;     /* OUT:  Use this as the LHS of the IN operator */
  Expr *pEq;        /* OUT:  The == term that include pInLhs */
  Expr **ppAnd;     /* OUT:  The AND operator that includes pEq as a child */
  Expr **ppParent;  /* The AND operator currently being examined */
};

/*
** Iterate through all AND connected nodes in the expression tree
** headed by (*ppExpr), populating the structure passed as the first
** argument with the values required by exprAnalyzeExistsFindEq().
**
** This function returns non-zero if the expression tree does not meet
** the two conditions described by the header comment for
** exprAnalyzeExistsFindEq(), or zero if it does.
*/
static int exprExistsToInIter(struct ExistsToInCtx *p, Expr **ppExpr){
  Expr *pExpr = *ppExpr;
  switch( pExpr->op ){
    case TK_AND:
      p->ppParent = ppExpr;
      if( exprExistsToInIter(p, &pExpr->pLeft) ) return 1;
      p->ppParent = ppExpr;
      if( exprExistsToInIter(p, &pExpr->pRight) ) return 1;
      break;
    case TK_EQ: {
      int bLeft = exprUsesSrclist(p->pSrc, pExpr->pLeft, 0);
      int bRight = exprUsesSrclist(p->pSrc, pExpr->pRight, 0);
      if( bLeft || bRight ){
        if( (bLeft && bRight) || p->pInLhs ) return 1;
        p->pInLhs = bLeft ? pExpr->pLeft : pExpr->pRight;
        if( exprUsesSrclist(p->pSrc, p->pInLhs, 1) ) return 1;
        p->pEq = pExpr;
        p->ppAnd = p->ppParent;
      }
      break;
    }
    default:
      if( exprUsesSrclist(p->pSrc, pExpr, 0) ){
        return 1;
      }
      break;
  }

  return 0;
}

/*
** This function is used by exprAnalyzeExists() when creating virtual IN(...)
** terms equivalent to user-supplied EXIST(...) clauses. It splits the WHERE
** clause of the Select object passed as the first argument into one or more
** expressions joined by AND operators, and then tests if the following are
** true:
**
**   1. Exactly one of the AND separated terms refers to the outer
**      query, and it is an == (TK_EQ) expression.
**
**   2. Only one side of the == expression refers to the outer query, and 
**      it does not refer to any columns from the inner query.
**
** If both these conditions are true, then a pointer to the side of the ==
** expression that refers to the outer query is returned. The caller will
** use this expression as the LHS of the IN(...) virtual term. Or, if one
** or both of the above conditions are not true, NULL is returned.
**
** If non-NULL is returned and ppEq is non-NULL, *ppEq is set to point
** to the == expression node before returning. If pppAnd is non-NULL and
** the == node is not the root of the WHERE clause, then *pppAnd is set
** to point to the pointer to the AND node that is the parent of the ==
** node within the WHERE expression tree.
*/
static Expr *exprAnalyzeExistsFindEq(
  Select *pSel,                   /* The SELECT of the EXISTS */
  Expr **ppEq,                    /* OUT: == node from WHERE clause */
  Expr ***pppAnd                  /* OUT: Pointer to parent of ==, if any */
){
  struct ExistsToInCtx ctx;
  memset(&ctx, 0, sizeof(ctx));
  ctx.pSrc = pSel->pSrc;
  if( exprExistsToInIter(&ctx, &pSel->pWhere) ){
    return 0;
  }
  if( ppEq ) *ppEq = ctx.pEq;
  if( pppAnd ) *pppAnd = ctx.ppAnd;
  return ctx.pInLhs;
}

/*
** Term idxTerm of the WHERE clause passed as the second argument is an
** EXISTS expression with a correlated SELECT statement on the RHS.
** This function analyzes the SELECT statement, and if possible adds an
** equivalent "? IN(SELECT...)" virtual term to the WHERE clause. 
**
** For an EXISTS term such as the following:
**
**     EXISTS (SELECT ... FROM <srclist> WHERE <e1> = <e2> AND <e3>)
**
** The virtual IN() term added is:
**
**     <e1> IN (SELECT <e2> FROM <srclist> WHERE <e3>)
**
** The virtual term is only added if the following conditions are met:
**
**     1. The sub-select must not be an aggregate or use window functions,
**
**     2. The sub-select must not be a compound SELECT,
**
**     3. Expression <e1> must refer to at least one column from the outer
**        query, and must not refer to any column from the inner query 
**        (i.e. from <srclist>).
**
**     4. <e2> and <e3> must not refer to any values from the outer query.
**        In other words, once <e1> has been removed, the inner query
**        must not be correlated.
**
*/
static void exprAnalyzeExists(
  SrcList *pSrc,            /* the FROM clause */
  WhereClause *pWC,         /* the WHERE clause */
  int idxTerm               /* Index of the term to be analyzed */
){
  Parse *pParse = pWC->pWInfo->pParse;
  WhereTerm *pTerm = &pWC->a[idxTerm];
  Expr *pExpr = pTerm->pExpr;
  Select *pSel = pExpr->x.pSelect;
  Expr *pDup = 0;
  Expr *pEq = 0;
  Expr *pRet = 0;
  Expr *pInLhs = 0;
  Expr **ppAnd = 0;
  int idxNew;
  sqlite3 *db = pParse->db;

  assert( pExpr->op==TK_EXISTS );
  assert( (pExpr->flags & EP_VarSelect) && (pExpr->flags & EP_xIsSelect) );

  if( pSel->selFlags & SF_Aggregate ) return;
#ifndef SQLITE_OMIT_WINDOWFUNC
  if( pSel->pWin ) return;
#endif
  if( pSel->pPrior ) return;
  if( pSel->pWhere==0 ) return;
  if( 0==exprAnalyzeExistsFindEq(pSel, 0, 0) ) return;

  pDup = sqlite3ExprDup(db, pExpr, 0);
  if( db->mallocFailed ){
    sqlite3ExprDelete(db, pDup);
    return;
  }
  pSel = pDup->x.pSelect;
  sqlite3ExprListDelete(db, pSel->pEList);
  pSel->pEList = 0;

  pInLhs = exprAnalyzeExistsFindEq(pSel, &pEq, &ppAnd);
  assert( pInLhs && pEq );
  assert( pEq==pSel->pWhere || ppAnd );
  if( pInLhs==pEq->pLeft ){
    pRet = pEq->pRight;
  }else{
    CollSeq *p = sqlite3ExprCompareCollSeq(pParse, pEq);
    pInLhs = sqlite3ExprAddCollateString(pParse, pInLhs, p?p->zName:"BINARY");
    pRet = pEq->pLeft;
  }

  assert( pDup->pLeft==0 );
  pDup->op = TK_IN;
  pDup->pLeft = pInLhs;
  pDup->flags &= ~EP_VarSelect;
  if( pRet->op==TK_VECTOR ){
    pSel->pEList = pRet->x.pList;
    pRet->x.pList = 0;
    sqlite3ExprDelete(db, pRet);
  }else{
    pSel->pEList = sqlite3ExprListAppend(pParse, 0, pRet);
  }
  pEq->pLeft = 0;
  pEq->pRight = 0;
  if( ppAnd ){
    Expr *pAnd = *ppAnd;
    Expr *pOther = (pAnd->pLeft==pEq) ? pAnd->pRight : pAnd->pLeft;
    pAnd->pLeft = pAnd->pRight = 0;
    sqlite3ExprDelete(db, pAnd);
    *ppAnd = pOther;
  }else{
    assert( pSel->pWhere==pEq );
    pSel->pWhere = 0;
  }
  sqlite3ExprDelete(db, pEq);

#ifdef WHERETRACE_ENABLED  /* 0x20 */
  if( sqlite3WhereTrace & 0x20 ){
    sqlite3DebugPrintf("Convert EXISTS:\n");
    sqlite3TreeViewExpr(0, pExpr, 0);
    sqlite3DebugPrintf("into IN:\n");
    sqlite3TreeViewExpr(0, pDup, 0);
  }
#endif
  idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
  exprAnalyze(pSrc, pWC, idxNew);
  markTermAsChild(pWC, idxNew, idxTerm);
  pWC->a[idxTerm].wtFlags |= TERM_COPIED;
}

/*
** The input to this routine is an WhereTerm structure with only the
** "pExpr" field filled in.  The job of this routine is to analyze the
** subexpression and populate all the other fields of the WhereTerm
** structure.
**
1136
1137
1138
1139
1140
1141
1142






1143
1144
1145
1146
1147
1148
1149
      pNew->wtFlags |= exprCommute(pParse, pDup);
      pNew->leftCursor = aiCurCol[0];
      pNew->u.x.leftColumn = aiCurCol[1];
      testcase( (prereqLeft | extraRight) != prereqLeft );
      pNew->prereqRight = prereqLeft | extraRight;
      pNew->prereqAll = prereqAll;
      pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask;






    }
  }

#ifndef SQLITE_OMIT_BETWEEN_OPTIMIZATION
  /* If a term is the BETWEEN operator, create two new virtual terms
  ** that define the range that the BETWEEN implements.  For example:
  **







>
>
>
>
>
>







1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
      pNew->wtFlags |= exprCommute(pParse, pDup);
      pNew->leftCursor = aiCurCol[0];
      pNew->u.x.leftColumn = aiCurCol[1];
      testcase( (prereqLeft | extraRight) != prereqLeft );
      pNew->prereqRight = prereqLeft | extraRight;
      pNew->prereqAll = prereqAll;
      pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask;
    }else if( op==TK_ISNULL && 0==sqlite3ExprCanBeNull(pLeft) ){
      pExpr->op = TK_TRUEFALSE;
      pExpr->u.zToken = "false";
      ExprSetProperty(pExpr, EP_IsFalse);
      pTerm->prereqAll = 0;
      pTerm->eOperator = 0;
    }
  }

#ifndef SQLITE_OMIT_BETWEEN_OPTIMIZATION
  /* If a term is the BETWEEN operator, create two new virtual terms
  ** that define the range that the BETWEEN implements.  For example:
  **
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
  */
  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 case is not significant (the default
  ** for LIKE) then the lower-bound is made all uppercase and the upper-
  ** bound is made all lowercase so that the bounds also work when comparing
  ** BLOBs.
  */

  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;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>















>
|







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
  */
  else if( pExpr->op==TK_OR ){
    assert( pWC->op==TK_AND );
    exprAnalyzeOrTerm(pSrc, pWC, idxTerm);
    pTerm = &pWC->a[idxTerm];
  }
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */

  else if( pExpr->op==TK_EXISTS ){
    /* Perhaps treat an EXISTS operator as an IN operator */
    if( (pExpr->flags & EP_VarSelect)!=0
     && OptimizationEnabled(db, SQLITE_ExistsToIN)
    ){
      exprAnalyzeExists(pSrc, pWC, idxTerm);
    }
  }

  /* The form "x IS NOT NULL" can sometimes be evaluated more efficiently
  ** as "x>NULL" if x is not an INTEGER PRIMARY KEY.  So construct a
  ** virtual term of that form.
  **
  ** The virtual term must be tagged with TERM_VNULL.
  */
  else if( pExpr->op==TK_NOTNULL ){
    if( pExpr->pLeft->op==TK_COLUMN
     && pExpr->pLeft->iColumn>=0
     && !ExprHasProperty(pExpr, EP_FromJoin)
    ){
      Expr *pNewExpr;
      Expr *pLeft = pExpr->pLeft;
      int idxNew;
      WhereTerm *pNewTerm;
  
      pNewExpr = sqlite3PExpr(pParse, TK_GT,
                              sqlite3ExprDup(db, pLeft, 0),
                              sqlite3ExprAlloc(db, TK_NULL, 0, 0));
  
      idxNew = whereClauseInsert(pWC, pNewExpr,
                                TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL);
      if( idxNew ){
        pNewTerm = &pWC->a[idxNew];
        pNewTerm->prereqRight = 0;
        pNewTerm->leftCursor = pLeft->iTable;
        pNewTerm->u.x.leftColumn = pLeft->iColumn;
        pNewTerm->eOperator = WO_GT;
        markTermAsChild(pWC, idxNew, idxTerm);
        pTerm = &pWC->a[idxTerm];
        pTerm->wtFlags |= TERM_COPIED;
        pNewTerm->prereqAll = pTerm->prereqAll;
      }
    }
  }


#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 case is not significant (the default
  ** for LIKE) then the lower-bound is made all uppercase and the upper-
  ** bound is made all lowercase so that the bounds also work when comparing
  ** BLOBs.
  */
  else if( pExpr->op==TK_FUNCTION
   && 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;
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
    pTerm = &pWC->a[idxTerm];
    if( isComplete ){
      markTermAsChild(pWC, idxNew1, idxTerm);
      markTermAsChild(pWC, idxNew2, idxTerm);
    }
  }
#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */




























































#ifndef SQLITE_OMIT_VIRTUALTABLE
  /* Add a WO_AUX auxiliary term to the constraint set if the
  ** current expression is of the form "column OP expr" where OP
  ** is an operator that gets passed into virtual tables but which is
  ** not normally optimized for ordinary tables.  In other words, OP
  ** is one of MATCH, LIKE, GLOB, REGEXP, !=, IS, IS NOT, or NOT NULL.
  ** This information is used by the xBestIndex methods of
  ** virtual tables.  The native query optimizer does not attempt
  ** to do anything with MATCH functions.
  */
  if( pWC->op==TK_AND ){
    Expr *pRight = 0, *pLeft = 0;
    int res = isAuxiliaryVtabOperator(db, pExpr, &eOp2, &pLeft, &pRight);
    while( res-- > 0 ){
      int idxNew;
      WhereTerm *pNewTerm;
      Bitmask prereqColumn, prereqExpr;








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











|







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
    pTerm = &pWC->a[idxTerm];
    if( isComplete ){
      markTermAsChild(pWC, idxNew1, idxTerm);
      markTermAsChild(pWC, idxNew2, idxTerm);
    }
  }
#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */

  /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create
  ** new terms for each component comparison - "a = ?" and "b = ?".  The
  ** new terms completely replace the original vector comparison, which is
  ** no longer used.
  **
  ** This is only required if at least one side of the comparison operation
  ** is not a sub-select.  */
  if( (pExpr->op==TK_EQ || pExpr->op==TK_IS)
   && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1
   && sqlite3ExprVectorSize(pExpr->pRight)==nLeft
   && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 
     || (pExpr->pRight->flags & EP_xIsSelect)==0)
   && pWC->op==TK_AND
  ){
    int i;
    for(i=0; i<nLeft; i++){
      int idxNew;
      Expr *pNew;
      Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i);
      Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i);

      pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight);
      transferJoinMarkings(pNew, pExpr);
      idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
      exprAnalyze(pSrc, pWC, idxNew);
    }
    pTerm = &pWC->a[idxTerm];
    pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL;  /* Disable the original */
    pTerm->eOperator = 0;
  }

  /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
  ** a virtual term for each vector component. The expression object
  ** used by each such virtual term is pExpr (the full vector IN(...) 
  ** expression). The WhereTerm.u.x.iField variable identifies the index within
  ** the vector on the LHS that the virtual term represents.
  **
  ** This only works if the RHS is a simple SELECT (not a compound) that does
  ** not use window functions.
  */
  else if( pExpr->op==TK_IN
   && pTerm->u.x.iField==0
   && pExpr->pLeft->op==TK_VECTOR
   && pExpr->x.pSelect->pPrior==0
#ifndef SQLITE_OMIT_WINDOWFUNC
   && pExpr->x.pSelect->pWin==0
#endif
   && pWC->op==TK_AND
  ){
    int i;
    for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
      int idxNew;
      idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL);
      pWC->a[idxNew].u.x.iField = i+1;
      exprAnalyze(pSrc, pWC, idxNew);
      markTermAsChild(pWC, idxNew, idxTerm);
    }
  }

#ifndef SQLITE_OMIT_VIRTUALTABLE
  /* Add a WO_AUX auxiliary term to the constraint set if the
  ** current expression is of the form "column OP expr" where OP
  ** is an operator that gets passed into virtual tables but which is
  ** not normally optimized for ordinary tables.  In other words, OP
  ** is one of MATCH, LIKE, GLOB, REGEXP, !=, IS, IS NOT, or NOT NULL.
  ** This information is used by the xBestIndex methods of
  ** virtual tables.  The native query optimizer does not attempt
  ** to do anything with MATCH functions.
  */
  else if( pWC->op==TK_AND ){
    Expr *pRight = 0, *pLeft = 0;
    int res = isAuxiliaryVtabOperator(db, pExpr, &eOp2, &pLeft, &pRight);
    while( res-- > 0 ){
      int idxNew;
      WhereTerm *pNewTerm;
      Bitmask prereqColumn, prereqExpr;

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
        pNewTerm->prereqAll = pTerm->prereqAll;
      }
      SWAP(Expr*, pLeft, pRight);
    }
  }
#endif /* SQLITE_OMIT_VIRTUALTABLE */

  /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create
  ** new terms for each component comparison - "a = ?" and "b = ?".  The
  ** new terms completely replace the original vector comparison, which is
  ** no longer used.
  **
  ** This is only required if at least one side of the comparison operation
  ** is not a sub-select.  */
  if( pWC->op==TK_AND 
  && (pExpr->op==TK_EQ || pExpr->op==TK_IS)
  && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1
  && sqlite3ExprVectorSize(pExpr->pRight)==nLeft
  && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 
    || (pExpr->pRight->flags & EP_xIsSelect)==0)
  ){
    int i;
    for(i=0; i<nLeft; i++){
      int idxNew;
      Expr *pNew;
      Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i);
      Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i);

      pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight);
      transferJoinMarkings(pNew, pExpr);
      idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
      exprAnalyze(pSrc, pWC, idxNew);
    }
    pTerm = &pWC->a[idxTerm];
    pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL;  /* Disable the original */
    pTerm->eOperator = 0;
  }

  /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
  ** a virtual term for each vector component. The expression object
  ** used by each such virtual term is pExpr (the full vector IN(...) 
  ** expression). The WhereTerm.u.x.iField variable identifies the index within
  ** the vector on the LHS that the virtual term represents.
  **
  ** This only works if the RHS is a simple SELECT (not a compound) that does
  ** not use window functions.
  */
  if( pWC->op==TK_AND && pExpr->op==TK_IN && pTerm->u.x.iField==0
   && pExpr->pLeft->op==TK_VECTOR
   && pExpr->x.pSelect->pPrior==0
#ifndef SQLITE_OMIT_WINDOWFUNC
   && pExpr->x.pSelect->pWin==0
#endif
  ){
    int i;
    for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
      int idxNew;
      idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL);
      pWC->a[idxNew].u.x.iField = i+1;
      exprAnalyze(pSrc, pWC, idxNew);
      markTermAsChild(pWC, idxNew, idxTerm);
    }
  }

#ifdef SQLITE_ENABLE_STAT4
  /* When sqlite_stat4 histogram data is available an operator of the
  ** form "x IS NOT NULL" can sometimes be evaluated more efficiently
  ** as "x>NULL" if x is not an INTEGER PRIMARY KEY.  So construct a
  ** virtual term of that form.
  **
  ** Note that the virtual term must be tagged with TERM_VNULL.
  */
  if( pExpr->op==TK_NOTNULL
   && pExpr->pLeft->op==TK_COLUMN
   && pExpr->pLeft->iColumn>=0
   && !ExprHasProperty(pExpr, EP_FromJoin)
   && OptimizationEnabled(db, SQLITE_Stat4)
  ){
    Expr *pNewExpr;
    Expr *pLeft = pExpr->pLeft;
    int idxNew;
    WhereTerm *pNewTerm;

    pNewExpr = sqlite3PExpr(pParse, TK_GT,
                            sqlite3ExprDup(db, pLeft, 0),
                            sqlite3ExprAlloc(db, TK_NULL, 0, 0));

    idxNew = whereClauseInsert(pWC, pNewExpr,
                              TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL);
    if( idxNew ){
      pNewTerm = &pWC->a[idxNew];
      pNewTerm->prereqRight = 0;
      pNewTerm->leftCursor = pLeft->iTable;
      pNewTerm->u.x.leftColumn = pLeft->iColumn;
      pNewTerm->eOperator = WO_GT;
      markTermAsChild(pWC, idxNew, idxTerm);
      pTerm = &pWC->a[idxTerm];
      pTerm->wtFlags |= TERM_COPIED;
      pNewTerm->prereqAll = pTerm->prereqAll;
    }
  }
#endif /* SQLITE_ENABLE_STAT4 */

  /* Prevent ON clause terms of a LEFT JOIN from being used to drive
  ** an index for tables to the left of the join.
  */
  testcase( pTerm!=&pWC->a[idxTerm] );
  pTerm = &pWC->a[idxTerm];
  pTerm->prereqRight |= extraRight;
}







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1700
1701
1702
1703
1704
1705
1706
































































































1707
1708
1709
1710
1711
1712
1713
        pNewTerm->prereqAll = pTerm->prereqAll;
      }
      SWAP(Expr*, pLeft, pRight);
    }
  }
#endif /* SQLITE_OMIT_VIRTUALTABLE */

































































































  /* Prevent ON clause terms of a LEFT JOIN from being used to drive
  ** an index for tables to the left of the join.
  */
  testcase( pTerm!=&pWC->a[idxTerm] );
  pTerm = &pWC->a[idxTerm];
  pTerm->prereqRight |= extraRight;
}
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
** new WHERE clause terms.  
**
** Each function argument translates into an equality constraint against
** a HIDDEN column in the table.
*/
void sqlite3WhereTabFuncArgs(
  Parse *pParse,                    /* Parsing context */
  struct SrcList_item *pItem,       /* The FROM clause term to process */
  WhereClause *pWC                  /* Xfer function arguments to here */
){
  Table *pTab;
  int j, k;
  ExprList *pArgs;
  Expr *pColRef;
  Expr *pTerm;







|







1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
** new WHERE clause terms.  
**
** Each function argument translates into an equality constraint against
** a HIDDEN column in the table.
*/
void sqlite3WhereTabFuncArgs(
  Parse *pParse,                    /* Parsing context */
  SrcItem *pItem,                   /* The FROM clause term to process */
  WhereClause *pWC                  /* Xfer function arguments to here */
){
  Table *pTab;
  int j, k;
  ExprList *pArgs;
  Expr *pColRef;
  Expr *pTerm;
Changes to src/window.c.
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315





1316
1317
1318
1319
1320
1321
1322
/*
** Possibly link window pWin into the list at pSel->pWin (window functions
** to be processed as part of SELECT statement pSel). The window is linked
** in if either (a) there are no other windows already linked to this
** SELECT, or (b) the windows already linked use a compatible window frame.
*/
void sqlite3WindowLink(Select *pSel, Window *pWin){
  if( pSel!=0
   && (0==pSel->pWin || 0==sqlite3WindowCompare(0, pSel->pWin, pWin, 0))
  ){
    pWin->pNextWin = pSel->pWin;
    if( pSel->pWin ){
      pSel->pWin->ppThis = &pWin->pNextWin;
    }
    pSel->pWin = pWin;
    pWin->ppThis = &pSel->pWin;





  }
}

/*
** Return 0 if the two window objects are identical, 1 if they are
** different, or 2 if it cannot be determined if the objects are identical
** or not. Identical window objects can be processed in a single scan.







|
|
<
|
|
|
|
|
|
>
>
>
>
>







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
/*
** Possibly link window pWin into the list at pSel->pWin (window functions
** to be processed as part of SELECT statement pSel). The window is linked
** in if either (a) there are no other windows already linked to this
** SELECT, or (b) the windows already linked use a compatible window frame.
*/
void sqlite3WindowLink(Select *pSel, Window *pWin){
  if( pSel ){
    if( 0==pSel->pWin || 0==sqlite3WindowCompare(0, pSel->pWin, pWin, 0) ){

      pWin->pNextWin = pSel->pWin;
      if( pSel->pWin ){
        pSel->pWin->ppThis = &pWin->pNextWin;
      }
      pSel->pWin = pWin;
      pWin->ppThis = &pSel->pWin;
    }else{
      if( sqlite3ExprListCompare(pWin->pPartition, pSel->pWin->pPartition,-1) ){
        pSel->selFlags |= SF_MultiPart;
      }
    }
  }
}

/*
** Return 0 if the two window objects are identical, 1 if they are
** different, or 2 if it cannot be determined if the objects are identical
** or not. Identical window objects can be processed in a single scan.
2057
2058
2059
2060
2061
2062
2063

2064
2065
2066
2067
2068
2069
2070
  Vdbe *v = sqlite3GetVdbe(pParse);
  ExprList *pOrderBy = p->pMWin->pOrderBy;  /* ORDER BY clause for window */
  int reg1 = sqlite3GetTempReg(pParse);     /* Reg. for csr1.peerVal+regVal */
  int reg2 = sqlite3GetTempReg(pParse);     /* Reg. for csr2.peerVal */
  int regString = ++pParse->nMem;           /* Reg. for constant value '' */
  int arith = OP_Add;                       /* OP_Add or OP_Subtract */
  int addrGe;                               /* Jump destination */


  assert( op==OP_Ge || op==OP_Gt || op==OP_Le );
  assert( pOrderBy && pOrderBy->nExpr==1 );
  if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_DESC ){
    switch( op ){
      case OP_Ge: op = OP_Le; break;
      case OP_Gt: op = OP_Lt; break;







>







2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
  Vdbe *v = sqlite3GetVdbe(pParse);
  ExprList *pOrderBy = p->pMWin->pOrderBy;  /* ORDER BY clause for window */
  int reg1 = sqlite3GetTempReg(pParse);     /* Reg. for csr1.peerVal+regVal */
  int reg2 = sqlite3GetTempReg(pParse);     /* Reg. for csr2.peerVal */
  int regString = ++pParse->nMem;           /* Reg. for constant value '' */
  int arith = OP_Add;                       /* OP_Add or OP_Subtract */
  int addrGe;                               /* Jump destination */
  CollSeq *pColl;

  assert( op==OP_Ge || op==OP_Gt || op==OP_Le );
  assert( pOrderBy && pOrderBy->nExpr==1 );
  if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_DESC ){
    switch( op ){
      case OP_Ge: op = OP_Le; break;
      case OP_Gt: op = OP_Lt; break;
2147
2148
2149
2150
2151
2152
2153


2154
2155
2156
2157
2158
2159
2160
    }
  }

  /* Compare registers reg2 and reg1, taking the jump if required. Note that
  ** control skips over this test if the BIGNULL flag is set and either
  ** reg1 or reg2 contain a NULL value.  */
  sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v);


  sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);

  assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le );
  testcase(op==OP_Ge); VdbeCoverageIf(v, op==OP_Ge);
  testcase(op==OP_Lt); VdbeCoverageIf(v, op==OP_Lt);
  testcase(op==OP_Le); VdbeCoverageIf(v, op==OP_Le);
  testcase(op==OP_Gt); VdbeCoverageIf(v, op==OP_Gt);







>
>







2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
    }
  }

  /* Compare registers reg2 and reg1, taking the jump if required. Note that
  ** control skips over this test if the BIGNULL flag is set and either
  ** reg1 or reg2 contain a NULL value.  */
  sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v);
  pColl = sqlite3ExprNNCollSeq(pParse, pOrderBy->a[0].pExpr);
  sqlite3VdbeAppendP4(v, (void*)pColl, P4_COLLSEQ);
  sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);

  assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le );
  testcase(op==OP_Ge); VdbeCoverageIf(v, op==OP_Ge);
  testcase(op==OP_Lt); VdbeCoverageIf(v, op==OP_Lt);
  testcase(op==OP_Le); VdbeCoverageIf(v, op==OP_Le);
  testcase(op==OP_Gt); VdbeCoverageIf(v, op==OP_Gt);
Changes to test/alter.test.
898
899
900
901
902
903
904












905
906
      DELETE FROM t2 WHERE id = OLD.a;
    END;
    ALTER TABLE t1 RENAME TO t3;
    UPDATE t3 SET b='peach' WHERE a=2;
    SELECT * FROM t2 ORDER BY 1;
  } {1 1.0 2.0 3 1.5 3.5}
}













finish_test







>
>
>
>
>
>
>
>
>
>
>
>


898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
      DELETE FROM t2 WHERE id = OLD.a;
    END;
    ALTER TABLE t1 RENAME TO t3;
    UPDATE t3 SET b='peach' WHERE a=2;
    SELECT * FROM t2 ORDER BY 1;
  } {1 1.0 2.0 3 1.5 3.5}
}

# 2021-03-08 dbsqlfuzz 3f0a7245b69cd08617d7d7781ebaedb0fe765a93
reset_db
do_catchsql_test alter-18.1 {
  CREATE TABLE t1(a,b,c);
  CREATE TABLE log(a INTEGER PRIMARY KEY,b,c);
  CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
    INSERT INTO logx(a,b,c) VALUES(new.a,new.b,new.c)
    ON CONFLICT(a) DO UPDATE SET c=excluded.c, b=new.b;
  END;
  ALTER TABLE log RENAME COLUMN a TO x;
} {1 {error in trigger tr1: no such table: main.logx}}

finish_test
Changes to test/alterauth2.test.
90
91
92
93
94
95
96

















97
98
  {SQLITE_READ sqlite_temp_master name temp {}} 
  {SQLITE_READ sqlite_temp_master sql temp {}} 
  {SQLITE_READ sqlite_temp_master type temp {}} 
  {SQLITE_SELECT {} {} {} {}} 
  {SQLITE_UPDATE sqlite_master sql main {}} 
  {SQLITE_UPDATE sqlite_temp_master sql temp {}}
}


















finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


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
  {SQLITE_READ sqlite_temp_master name temp {}} 
  {SQLITE_READ sqlite_temp_master sql temp {}} 
  {SQLITE_READ sqlite_temp_master type temp {}} 
  {SQLITE_SELECT {} {} {} {}} 
  {SQLITE_UPDATE sqlite_master sql main {}} 
  {SQLITE_UPDATE sqlite_temp_master sql temp {}}
}

do_auth_test 1.3 {
  ALTER TABLE t2 DROP COLUMN c;
} {
  {SQLITE_FUNCTION {} like {} {}} 
  {SQLITE_FUNCTION {} sqlite_drop_column {} {}}
  {SQLITE_FUNCTION {} sqlite_rename_test {} {}} 
  {SQLITE_READ sqlite_master name main {}} 
  {SQLITE_READ sqlite_master sql main {}} 
  {SQLITE_READ sqlite_master tbl_name main {}} 
  {SQLITE_READ sqlite_master type main {}} 
  {SQLITE_READ sqlite_temp_master name temp {}} 
  {SQLITE_READ sqlite_temp_master sql temp {}} 
  {SQLITE_READ sqlite_temp_master type temp {}} 
  {SQLITE_SELECT {} {} {} {}} 
  {SQLITE_UPDATE sqlite_master sql main {}}
}

finish_test
Changes to test/altercol.test.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#
#*************************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing that SQLite can handle a subtle 
# file format change that may be used in the future to implement
# "ALTER TABLE ... RENAME COLUMN ... TO".
#
# $Id: alter4.test,v 1.1 2009/02/02 18:03:22 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix altercol

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {







<
<







9
10
11
12
13
14
15


16
17
18
19
20
21
22
#
#*************************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing that SQLite can handle a subtle 
# file format change that may be used in the future to implement
# "ALTER TABLE ... RENAME COLUMN ... TO".
#



set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix altercol

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {
800
801
802
803
804
805
806



















807
808
809
  CREATE TABLE t1(aa UNIQUE,bb UNIQUE,cc UNIQUE,UNIQUE(aA),PRIMARY KEY(bB),UNIQUE(cC));
  ALTER TABLE t1 RENAME aa TO xx;
  ALTER TABLE t1 RENAME bb TO yy;
  ALTER TABLE t1 RENAME cc TO zz;
  SELECT sql FROM sqlite_master WHERE name='t1';
} {{CREATE TABLE t1(xx UNIQUE,yy UNIQUE,zz UNIQUE,UNIQUE(xx),PRIMARY KEY(yy),UNIQUE(zz))}}






















finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



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
  CREATE TABLE t1(aa UNIQUE,bb UNIQUE,cc UNIQUE,UNIQUE(aA),PRIMARY KEY(bB),UNIQUE(cC));
  ALTER TABLE t1 RENAME aa TO xx;
  ALTER TABLE t1 RENAME bb TO yy;
  ALTER TABLE t1 RENAME cc TO zz;
  SELECT sql FROM sqlite_master WHERE name='t1';
} {{CREATE TABLE t1(xx UNIQUE,yy UNIQUE,zz UNIQUE,UNIQUE(xx),PRIMARY KEY(yy),UNIQUE(zz))}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 21.0 {
  CREATE TABLE t1(a, b, c NOT NULL);
  CREATE TRIGGER tr1 AFTER INSERT ON t1 WHEN new.c IS NOT NULL BEGIN
    SELECT c NOT NULL FROM t1;
  END;
}

do_execsql_test 21.1 {
  ALTER TABLE t1 RENAME c TO d;
}

do_execsql_test 21.2 {
  SELECT sql FROM sqlite_schema WHERE name IS 'tr1'
} {{CREATE TRIGGER tr1 AFTER INSERT ON t1 WHEN new.d IS NOT NULL BEGIN
    SELECT d NOT NULL FROM t1;
  END}
}


finish_test
Added test/altercorrupt.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
# 2019-01-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.
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix altercorrupt

database_may_be_corrupt

#--------------------------------------------------------------------------
reset_db
do_test 1.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 24576 pagesize 4096 filename crash-685346d89b5e5f.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 06   .....@  ........
|     32: 00 00 63 00 00 05 f0 00 00 00 00 04 10 00 00 04   ..c.............
|     48: 00 00 00 00 00 00 0f f0 00 00 00 01 00 00 00 00   ................
|     64: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|     96: 00 00 00 00 0d 0f f8 00 05 0e cf 00 0f 79 0f d3   .............y..
|    112: 0f 2e 0e f3 0e cf 00 00 00 00 00 00 00 00 00 00   ................
|   3776: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22   ................
|   3792: 05 06 17 11 11 01 31 74 61 62 6c 65 74 34 74 34   ......1tablet4t4
|   3808: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 34   .CREATE TABLE t4
|   3824: 28 7a 29 39 04 06 17 11 11 01 5f 74 61 62 6c 65   (z)9......_table
|   3840: 74 33 74 33 05 43 52 45 41 54 45 20 54 41 42 4c   t3t3.CREATE TABL
|   3856: 45 20 74 33 28 78 20 49 4e 54 45 47 45 52 20 50   E t3(x INTEGER P
|   3872: 52 49 4d 41 52 59 20 4b 45 59 2c 20 79 29 49 03   RIMARY KEY, y)I.
|   3888: 06 17 11 11 01 7f 74 61 62 6c 65 74 32 74 32 04   ......tablet2t2.
|   3904: 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 32 28   CREATE TABLE t2(
|   3920: 61 2c 62 2c 63 20 50 52 49 4d 41 52 59 20 4b 45   a,b,c PRIMARY KE
|   3936: 59 2c 20 64 2c 20 65 2c 20 66 29 20 57 49 54 48   Y, d, e, f) WITH
|   3952: 4f 55 54 20 52 4f 57 49 44 58 03 07 17 11 11 01   OUT ROWIDX......
|   3968: 81 1b 74 61 62 6c 65 74 31 74 31 02 43 52 45 41   ..tablet1t1.CREA
|   3984: 54 45 20 54 41 42 4c 45 20 74 31 28 61 2c 62 2c   TE TABLE t1(a,b,
|   4000: 63 20 41 53 20 28 2d 62 29 20 56 49 52 54 55 41   c AS (-b) VIRTUA
|   4016: 4c 2c 64 20 43 48 45 43 4b 28 64 3e 35 29 2c 65   L,d CHECK(d>5),e
|   4032: 20 55 4e 49 51 55 45 2c 20 66 20 41 53 20 28 2b    UNIQUE, f AS (+
|   4048: 62 29 29 23 02 06 17 37 11 01 00 69 6e 64 65 78   b))#...7...index
|   4064: 73 71 6c 69 74 65 5f 61 75 74 6f 69 6e 64 65 78   sqlite_autoindex
|   4080: 5f 74 31 5f 31 74 31 03 00 00 00 08 00 00 00 00   _t1_1t1.........
| page 2 offset 4096
|      0: 0d 00 00 00 0a 0f 93 00 0f f6 0f eb 0f e0 0f d5   ................
|     16: 0f ca 0f 8f 0f b4 0f a9 0f 9e 0f 93 00 00 00 00   ................
|   3984: 00 00 00 09 0a 05 01 01 01 01 0a 64 6e 14 09 09   ...........dn...
|   4000: 05 01 01 01 01 09 5a 6d 12 09 08 05 01 01 01 01   ......Zm........
|   4016: 08 50 6c 10 09 07 05 01 01 01 01 07 46 6b 0e 09   .Pl.........Fk..
|   4032: 06 05 01 01 01 01 06 3c 6a 0c 09 05 05 01 01 01   .......<j.......
|   4048: 01 05 32 69 0a 09 04 05 01 01 01 01 04 28 68 08   ..2i.........(h.
|   4064: 09 03 05 01 01 01 01 03 1e 67 06 09 02 05 01 01   .........g......
|   4080: 01 01 02 14 66 04 08 01 05 09 01 01 01 0a 65 02   ....f.........e.
| page 3 offset 8192
|      0: 0a 00 00 00 0a 0f c5 00 0f fb 0f f5 0f ef 0f e9   ................
|     16: 0f e3 0f dd 0f d7 0f d1 0f cb 0f c5 00 00 00 00   ................
|   4032: 00 00 00 00 00 05 03 01 01 14 0a 05 03 01 01 12   ................
|   4048: 09 05 03 01 01 10 08 05 03 01 01 0e 07 05 03 01   ................
|   4064: 01 0c 06 05 03 01 01 0a 05 05 03 01 01 08 04 05   ................
|   4080: 03 01 01 06 03 05 03 01 01 04 02 04 03 01 09 02   ................
| page 4 offset 12288
|      0: 0a 00 00 00 0a 0f 75 00 0f 75 0f 83 0f 91 0f 9f   ......u..u......
|     16: 0f ad 0f bb 0f 00 00 00 00 00 00 00 00 00 00 00   ................
|   3952: 00 00 00 00 00 0d 07 01 01 01 01 01 01 9c 0a 64   ...............d
|   3968: 6e 14 64 0d 07 02 01 01 01 01 01 a6 09 5a 6d 12   n.d..........Zm.
|   3984: 5a 0d 07 01 01 01 01 01 01 b0 08 50 6c 10 50 0d   Z..........Pl.P.
|   4000: 07 01 01 01 01 01 01 ba 07 46 6b 0e 46 0d 07 01   .........Fk.F...
|   4016: 01 01 01 01 01 c4 06 3c 6a 0c 3c 0d 07 01 01 01   .......<j.<.....
|   4032: 01 01 01 ce 05 32 69 0a 32 0d 07 01 01 01 01 01   .....2i.2.......
|   4048: 01 d8 04 28 68 08 28 0d 07 01 01 01 01 01 01 e2   ...(h.(.........
|   4064: 03 1e 67 06 1e 0d 07 01 01 01 01 01 01 ec 02 14   ..g.............
|   4080: 66 04 14 0c 07 01 09 01 01 01 01 f6 0a 65 02 0a   f............e..
| page 5 offset 16384
|      0: 0d 00 00 00 03 0f e9 00 0f e9 0f fb 0f f6 00 00   ................
|     16: 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   4064: 00 00 00 00 00 00 00 00 00 03 ff ff ff ff ff ff   ................
|   4080: ff ff 9c 03 00 00 03 64 03 00 00 03 01 03 00 00   .......d........
| page 6 offset 20480
|      0: 0d 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00   ................
| end crash-685346d89b5e5f.db
}]} {}

do_catchsql_test 1.1 {
  ALTER TABLE t2 DROP COLUMN e;
  ALTER TABLE t1 DROP COLUMN f;
} {1 {database disk image is malformed}}


#--------------------------------------------------------------------------
reset_db
do_test 2.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 24576 pagesize 4096 filename crash-0572db8f391431.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 06   .....@  ........
|     32: 00 00 63 00 10 05 f0 00 00 00 00 04 10 00 00 04   ..c.............
|     48: 00 00 00 00 00 00 0f f0 00 00 00 00 00 00 00 00   ................
|     96: 00 00 00 00 0d 0f f8 00 05 0e cf 00 0f 79 0f d3   .............y..
|    112: 0f 2e 0e f3 0e cf 00 00 00 00 00 00 00 00 00 00   ................
|   3776: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22   ................
|   3792: 05 06 17 11 11 01 31 74 61 62 6c 65 74 34 74 34   ......1tablet4t4
|   3808: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 34   .CREATE TABLE t4
|   3824: 28 7a 29 39 04 06 17 11 11 01 5f 74 61 62 6c 65   (z)9......_table
|   3840: 74 33 74 33 05 43 52 45 41 54 45 20 54 41 42 4c   t3t3.CREATE TABL
|   3856: 45 20 74 33 28 78 20 49 4e 54 55 47 45 52 20 50   E t3(x INTUGER P
|   3872: 52 49 4d 41 52 59 20 4b 45 59 2c 20 79 29 49 03   RIMARY KEY, y)I.
|   3888: 06 17 11 11 01 7f 74 61 62 6c 65 74 32 74 32 04   ......tablet2t2.
|   3904: 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 32 28   CREATE TABLE t2(
|   3920: 61 2c 62 2c 63 20 50 52 49 4d 41 52 59 20 4b 45   a,b,c PRIMARY KE
|   3936: 59 2c 20 64 2c 20 65 2c 20 66 29 20 57 49 54 48   Y, d, e, f) WITH
|   3952: 4f 55 54 20 52 4f 57 49 44 58 05 07 17 11 11 01   OUT ROWIDX......
|   3968: 81 1b 74 61 62 6c 65 74 31 74 31 02 43 52 45 41   ..tablet1t1.CREA
|   3984: 54 45 20 54 41 42 4c 45 20 74 31 28 61 2c 62 2c   TE TABLE t1(a,b,
|   4000: 63 20 41 53 20 28 2d 62 29 20 56 49 52 54 55 41   c AS (-b) VIRTUA
|   4016: 4c 2c 64 20 43 48 45 43 4b 28 64 3e 35 29 2c 65   L,d CHECK(d>5),e
|   4032: 20 55 4e 49 51 55 45 2c 20 66 20 41 53 20 28 2b    UNIQUE, f AS (+
|   4048: 62 29 29 23 02 06 17 37 11 01 00 69 6e 64 65 78   b))#...7...index
|   4064: 73 71 6c 69 74 65 5f 61 75 74 6f 69 6e 64 65 78   sqlite_autoindex
|   4080: 5f 74 31 5f 31 84 31 03 01 00 00 08 00 00 00 00   _t1_1.1.........
| page 2 offset 4096
|      0: 0d 00 00 00 0a 0f 93 00 0f f6 0f eb 0f e0 0f d5   ................
|     16: 0f ca 0f 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   3984: 00 00 00 09 0a 05 01 01 01 01 0a 64 6e 14 09 09   ...........dn...
|   4000: 05 01 01 01 01 09 5a 6d 12 09 08 05 01 00 f1 01   ......Zm........
|   4016: 08 50 6c 10 09 07 05 01 01 01 01 07 46 6b 0e 09   .Pl.........Fk..
|   4032: 06 05 01 00 f1 01 06 3c 6a 0c 09 05 05 01 01 01   .......<j.......
|   4048: 01 05 32 69 0a 09 04 05 01 01 01 01 04 28 68 08   ..2i.........(h.
|   4064: 57 03 05 01 01 01 01 03 1e 67 06 09 02 05 01 01   W........g......
|   4080: 01 01 02 14 66 04 08 01 05 09 01 01 01 0a 65 02   ....f.........e.
| page 3 offset 8192
|      0: 09 ff ff ff fa 0f c5 00 0f fb 0f f5 0f ef 0f e9   ................
|     16: 0f e3 0f dd 0f d7 00 00 00 00 00 00 00 00 00 00   ................
|   4032: 00 00 00 00 00 05 03 01 01 14 0a 05 03 01 01 12   ................
|   4048: 09 05 03 01 01 10 08 05 03 01 01 0e 07 05 03 01   ................
|   4064: 01 0c 06 05 03 01 01 0a 05 05 03 01 01 08 04 05   ................
|   4080: 03 01 01 06 03 05 03 01 01 04 02 04 03 01 09 02   ................
| page 4 offset 12288
|      0: 0a 00 00 00 0a 0f 75 00 0f 75 0f 83 0f 91 0f 9f   ......u..u......
|     16: 0f ad 0f bb 0f 00 00 00 00 00 01 00 00 00 00 00   ................
|   3952: 00 00 00 00 00 0d 07 01 01 01 01 01 01 9c 0a 64   ...............d
|   3968: 6e 14 64 0d 07 02 01 01 01 01 01 a6 09 5a 6d 12   n.d..........Zm.
|   3984: 5a 0d 07 01 01 01 01 d4 01 b0 08 50 6c 10 50 0d   Z..........Pl.P.
|   4000: 07 01 01 01 01 01 01 ba 07 46 6b 0e 46 0d 07 00   .........Fk.F...
|   4016: 01 01 01 01 01 c4 06 3c 6a 0c 3c 0d 07 01 01 01   .......<j.<.....
|   4032: 01 01 01 ce 05 32 69 0a 32 0d 07 01 01 01 01 01   .....2i.2.......
|   4048: 01 d8 04 28 68 08 28 0d 07 01 01 01 01 01 01 e2   ...(h.(.........
|   4064: 03 1e 67 06 1e 0d 07 01 01 01 01 01 01 ec 02 14   ..g.............
|   4080: 66 04 14 0c 07 01 09 01 01 00 f1 f6 0a 65 02 0a   f............e..
| page 5 offset 16384
|      0: 0d 00 00 00 03 0f e9 00 0f e9 0f fb 0f f6 00 00   ................
|   4064: 00 00 00 00 00 00 00 00 00 03 ff ff ff ff ff ff   ................
|   4080: ff ff 9c 03 00 00 03 64 03 00 01 03 01 03 00 00   .......d........
| page 6 offset 20480
|      0: 0d 00 10 00 00 10 01 00 00 00 00 00 00 00 00 00   ................
| end crash-0572db8f391431.db
}]} {}

do_catchsql_test 2.1 {
  ALTER TABLE t1 DROP COLUMN a;
} {1 {database disk image is malformed}}

finish_test
Added test/alterdropcol.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
# 2021 February 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.
#
#*************************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix alterdropcol

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {
  finish_test
  return
}

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b, c);
  CREATE VIEW v1 AS SELECT * FROM t1;

  CREATE TABLE t2(x INTEGER PRIMARY KEY, y, z UNIQUE);
  CREATE INDEX t2y ON t2(y);

  CREATE TABLE t3(q, r, s);
  CREATE INDEX t3rs ON t3(r+s);
}

do_catchsql_test 1.1 {
  ALTER TABLE nosuch DROP COLUMN z;
} {1 {no such table: nosuch}}

do_catchsql_test 1.2 {
  ALTER TABLE v1 DROP COLUMN c;
} {1 {cannot drop column from view "v1"}}

ifcapable fts5 {
  do_execsql_test 1.3.1 {
    CREATE VIRTUAL TABLE ft1 USING fts5(one, two);
  }
  do_catchsql_test 1.3.2 {
    ALTER TABLE ft1 DROP COLUMN two;
  } {1 {cannot drop column from virtual table "ft1"}}
}

do_catchsql_test 1.4 {
  ALTER TABLE sqlite_schema DROP COLUMN sql;
} {1 {table sqlite_master may not be altered}}

do_catchsql_test 1.5 {
  ALTER TABLE t1 DROP COLUMN d;
} {1 {no such column: "d"}}

do_execsql_test 1.6.1 {
  ALTER TABLE t1 DROP COLUMN b;
}
do_execsql_test 1.6.2 {
  SELECT sql FROM sqlite_schema WHERE name = 't1'
} {{CREATE TABLE t1(a, c)}}

do_execsql_test 1.7.1 {
  ALTER TABLE t1 DROP COLUMN c;
}
do_execsql_test 1.7.2 {
  SELECT sql FROM sqlite_schema WHERE name = 't1'
} {{CREATE TABLE t1(a)}}

do_catchsql_test 1.7.3 {
  ALTER TABLE t1 DROP COLUMN a;
} {1 {cannot drop column "a": no other columns exist}}


do_catchsql_test 1.8 {
  ALTER TABLE t2 DROP COLUMN z
} {1 {cannot drop UNIQUE column: "z"}}

do_catchsql_test 1.9 {
  ALTER TABLE t2 DROP COLUMN x
} {1 {cannot drop PRIMARY KEY column: "x"}}

do_catchsql_test 1.10 {
  ALTER TABLE t2 DROP COLUMN y
} {1 {error in index t2y after drop column: no such column: y}}

do_catchsql_test 1.11 {
  ALTER TABLE t3 DROP COLUMN s
} {1 {error in index t3rs after drop column: no such column: s}}

#-------------------------------------------------------------------------

foreach {tn wo} {
  1 {}
  2 {WITHOUT ROWID}
} { eval [string map [list %TN% $tn %WO% $wo] {

  reset_db
  do_execsql_test 2.%TN%.0 {
    CREATE TABLE t1(x, y INTEGER PRIMARY KEY, z) %WO% ;
    INSERT INTO t1 VALUES(1, 2, 3);
    INSERT INTO t1 VALUES(4, 5, 6);
    INSERT INTO t1 VALUES(7, 8, 9);
  }
  
  do_execsql_test 2.%TN%.1 {
    ALTER TABLE t1 DROP COLUMN x;
    SELECT * FROM t1;
  } {
    2 3  5 6  8 9
  }
  do_execsql_test 2.%TN%.2 {
    ALTER TABLE t1 DROP COLUMN z;
    SELECT * FROM t1;
  } {
    2 5 8
  }
}]}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 3.0 {
  CREATE TABLE t12(a, b, c, CHECK(c>10));
  CREATE TABLE t13(a, b, c CHECK(c>10));
}
do_catchsql_test 3.1 {
  ALTER TABLE t12 DROP COLUMN c;
} {1 {error in table t12 after drop column: no such column: c}}

do_catchsql_test 3.2 {
  ALTER TABLE t13 DROP COLUMN c;
} {0 {}}

#-------------------------------------------------------------------------
# Test that generated columns can be dropped. And that other columns from
# tables that contain generated columns can be dropped.
#
foreach {tn wo vs} {
  1 ""              ""
  2 ""              VIRTUAL
  3 ""              STORED
  4 "WITHOUT ROWID" STORED
  5 "WITHOUT ROWID" VIRTUAL
} {
  reset_db

  do_execsql_test 4.$tn.0 "
    CREATE TABLE 'my table'(a, b PRIMARY KEY, c AS (a+b) $vs, d) $wo
  "
  do_execsql_test 4.$tn.1 {
    INSERT INTO "my table"(a, b, d) VALUES(1, 2, 'hello');
    INSERT INTO "my table"(a, b, d) VALUES(3, 4, 'world');

    SELECT * FROM "my table"
  } {
    1 2 3 hello
    3 4 7 world
  }

  do_execsql_test 4.$tn.2 {
    ALTER TABLE "my table" DROP COLUMN c;
  }
  do_execsql_test 4.$tn.3 {
    SELECT * FROM "my table"
  } {
    1 2 hello
    3 4 world
  }
  
  do_execsql_test 4.$tn.4 "
    CREATE TABLE x1(a, b, c PRIMARY KEY, d AS (b+c) $vs, e) $wo
  "
  do_execsql_test 4.$tn.5 {
    INSERT INTO x1(a, b, c, e) VALUES(1, 2, 3, 4);
    INSERT INTO x1(a, b, c, e) VALUES(5, 6, 7, 8);
    INSERT INTO x1(a, b, c, e) VALUES(9, 10, 11, 12);
    SELECT * FROM x1;
  } {
    1 2 3 5 4
    5 6 7 13 8
    9 10 11 21 12
  }

  do_execsql_test 4.$tn.6 {
    ALTER TABLE x1 DROP COLUMN a
  }
  do_execsql_test 4.$tn.7 {
    SELECT * FROM x1
  } {
    2 3 5 4
    6 7 13 8
    10 11 21 12
  }
  do_execsql_test 4.$tn.8 {
    ALTER TABLE x1 DROP COLUMN e
  }
  do_execsql_test 4.$tn.9 {
    SELECT * FROM x1
  } {
    2 3 5
    6 7 13
    10 11 21
  }
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 5.0 {
  CREATE TABLE p1(a PRIMARY KEY, b UNIQUE);
  CREATE TABLE c1(x, y, z REFERENCES p1(c));
  CREATE TABLE c2(x, y, z, w REFERENCES p1(b));
}
do_execsql_test 5.1 {
  ALTER TABLE c1 DROP COLUMN z;
  ALTER TABLE c2 DROP COLUMN z;
  SELECT sql FROM sqlite_schema WHERE name IN ('c1', 'c2');
} {
  {CREATE TABLE c1(x, y)} 
  {CREATE TABLE c2(x, y, w REFERENCES p1(b))}
}

do_execsql_test 5.2.1 {
  CREATE VIEW v1 AS SELECT d, e FROM p1
}
do_catchsql_test 5.2.2 {
  ALTER TABLE c1 DROP COLUMN x
} {1 {error in view v1: no such column: d}}
do_execsql_test 5.3.1 {
  DROP VIEW v1;
  CREATE VIEW v1 AS SELECT x, y FROM c1;
}
do_catchsql_test 5.3.2 {
  ALTER TABLE c1 DROP COLUMN x
} {1 {error in view v1 after drop column: no such column: x}}

do_execsql_test 5.4.1 {
  CREATE TRIGGER tr AFTER INSERT ON c1 BEGIN
    INSERT INTO p1 VALUES(new.y, new.xyz);
  END;
}
do_catchsql_test 5.4.2 {
  ALTER TABLE c1 DROP COLUMN y
} {1 {error in trigger tr: no such column: new.xyz}}
do_execsql_test 5.5.1 {
  DROP TRIGGER tr;
  CREATE TRIGGER tr AFTER INSERT ON c1 BEGIN
    INSERT INTO p1 VALUES(new.y, new.z);
  END;
}
do_catchsql_test 5.5.2 {
  ALTER TABLE c1 DROP COLUMN y
} {1 {error in trigger tr: no such column: new.z}}

# 2021-03-06 dbsqlfuzz crash-419aa525df93db6e463772c686ac6da27b46da9e
reset_db
do_catchsql_test 6.0 {
  CREATE TABLE t1(a,b,c);
  CREATE TABLE t2(x,y,z);
  PRAGMA writable_schema=ON;
  UPDATE sqlite_schema SET sql='CREATE INDEX t1b ON t1(b)' WHERE name='t2';
  PRAGMA writable_schema=OFF;
  ALTER TABLE t2 DROP COLUMN z;
} {1 {database disk image is malformed}}
reset_db
do_catchsql_test 6.1 {
  CREATE TABLE t1(a,b,c);
  CREATE TABLE t2(x,y,z);
  PRAGMA writable_schema=ON;
  UPDATE sqlite_schema SET sql='CREATE VIEW t2(x,y,z) AS SELECT b,a,c FROM t1'
   WHERE name='t2';
  PRAGMA writable_schema=OFF;
  ALTER TABLE t2 DROP COLUMN z;
} {1 {database disk image is malformed}}

finish_test
Added test/alterdropcol2.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
# 2021 February 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.
#
#*************************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix alterdropcol2

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {
  finish_test
  return
}

# EVIDENCE-OF: R-58318-35349 The DROP COLUMN syntax is used to remove an
# existing column from a table.
do_execsql_test 1.0 {
  CREATE TABLE t1(c, b, a, PRIMARY KEY(b, a)) WITHOUT ROWID;
  INSERT INTO t1 VALUES(1, 2, 3), (4, 5, 6);
}
do_execsql_test 1.1 {
  ALTER TABLE t1 DROP c;
}

# EVIDENCE-OF: The DROP COLUMN command removes the named column from the table,
# and also rewrites the entire table to purge the data associated with that
# column.  
do_execsql_test 1.2.1 {
  SELECT * FROM t1;
} {2 3   5 6}

do_execsql_test 1.2.2 {
  SELECT sql FROM sqlite_schema;
} {
  {CREATE TABLE t1(b, a, PRIMARY KEY(b, a)) WITHOUT ROWID}
}

proc do_atdc_error_test {tn schema atdc error} {
  reset_db
  execsql $schema
  uplevel [list do_catchsql_test $tn $atdc [list 1 [string trim $error]]]
}

#-------------------------------------------------------------------------
# Test cases 2.* attempt to verify the following:
#
# EVIDENCE-OF: R-24098-10282 The DROP COLUMN command only works if the column
# is not referenced by any other parts of the schema and is not a PRIMARY KEY
# and does not have a UNIQUE constraint.
#

# EVIDENCE-OF: R-05184-13006 The column is a PRIMARY KEY.
#
do_atdc_error_test 2.1.1 {
  CREATE TABLE x1(a PRIMARY KEY, b, c);
} { 
  ALTER TABLE x1 DROP COLUMN a 
} {
  cannot drop PRIMARY KEY column: "a"
}

# EVIDENCE-OF: R-43412-16016 The column has a UNIQUE constraint.
#
do_atdc_error_test 2.2.1 {
  CREATE TABLE x1(a PRIMARY KEY, b, c UNIQUE);
} { 
  ALTER TABLE x1 DROP COLUMN c 
} {
  cannot drop UNIQUE column: "c"
}
do_atdc_error_test 2.2.2 {
  CREATE TABLE x1(a PRIMARY KEY, b, c, UNIQUE(b, c));
} { 
  ALTER TABLE x1 DROP COLUMN c 
} {
  error in table x1 after drop column: no such column: c
}

# EVIDENCE-OF: R-46731-08965: The column is indexed.
#
do_atdc_error_test 2.3.1 {
  CREATE TABLE 'one two'('x y', 'z 1', 'a b');
  CREATE INDEX idx ON 'one two'('z 1');
} { 
  ALTER TABLE 'one two' DROP COLUMN 'z 1' 
} {
  error in index idx after drop column: no such column: z 1
}
do_atdc_error_test 2.3.2 {
  CREATE TABLE x1(a, b, c);
  CREATE INDEX idx ON x1(a);
} { 
  ALTER TABLE x1 DROP COLUMN a;
} {
  error in index idx after drop column: no such column: a
}

# EVIDENCE-OF: R-46731-08965: The column is indexed.
#
do_atdc_error_test 2.4.1 {
  CREATE TABLE x1234(a, b, c PRIMARY KEY) WITHOUT ROWID;
  CREATE INDEX i1 ON x1234(b) WHERE ((a+5) % 10)==0;
} { 
  ALTER TABLE x1234 DROP a
} {
  error in index i1 after drop column: no such column: a
}

# EVIDENCE-OF: R-18825-17786 The column appears in a table CHECK constraint.
#
do_atdc_error_test 2.5.1 {
  CREATE TABLE x1234(a, b, c PRIMARY KEY, CHECK(((a+5)%10)!=0)) WITHOUT ROWID;
} { 
  ALTER TABLE x1234 DROP a
} {
  error in table x1234 after drop column: no such column: a
}

# EVIDENCE-OF: R-55640-01652 The column is used in a foreign key constraint.
#
do_atdc_error_test 2.6.1 {
  CREATE TABLE p1(x, y UNIQUE);
  CREATE TABLE c1(u, v, FOREIGN KEY (v) REFERENCES p1(y))
} { 
  ALTER TABLE c1 DROP v
} {
  error in table c1 after drop column: unknown column "v" in foreign key definition
}

# EVIDENCE-OF: R-20795-39479 The column is used in the expression of a 
# generated column.
do_atdc_error_test 2.7.1 {
  CREATE TABLE c1(u, v, w AS (u+v));
} { 
  ALTER TABLE c1 DROP v
} {
  error in table c1 after drop column: no such column: v
}
do_atdc_error_test 2.7.2 {
  CREATE TABLE c1(u, v, w AS (u+v) STORED);
} { 
  ALTER TABLE c1 DROP u
} {
  error in table c1 after drop column: no such column: u
}

# EVIDENCE-OF: R-01515-49025 The column appears in a trigger or view.
#
do_atdc_error_test 2.8.1 {
  CREATE TABLE log(l);
  CREATE TABLE c1(u, v, w);
  CREATE TRIGGER tr1 AFTER INSERT ON c1 BEGIN
    INSERT INTO log VALUES(new.w);
  END;
} { 
  ALTER TABLE c1 DROP w
} {
  error in trigger tr1 after drop column: no such column: new.w
}
do_atdc_error_test 2.8.2 {
  CREATE TABLE c1(u, v, w);
  CREATE VIEW v1 AS SELECT u, v, w FROM c1;
} { 
  ALTER TABLE c1 DROP w
} {
  error in view v1 after drop column: no such column: w
}
do_atdc_error_test 2.8.3 {
  CREATE TABLE c1(u, v, w);
  CREATE VIEW v1 AS SELECT * FROM c1 WHERE w IS NOT NULL;
} { 
  ALTER TABLE c1 DROP w
} {
  error in view v1 after drop column: no such column: w
}

#-------------------------------------------------------------------------
# Verify that a column that is part of a CHECK constraint may be dropped
# if the CHECK constraint was specified as part of the column definition.
#

# EVIDENCE-OF: R-60924-11170 However, the column being deleted can be used in a
# column CHECK constraint because the column CHECK constraint is dropped
# together with the column itself.
do_execsql_test 3.0 {
  CREATE TABLE yyy(q, w, e CHECK (e > 0), r);
  INSERT INTO yyy VALUES(1,1,1,1), (2,2,2,2);

  CREATE TABLE zzz(q, w, e, r, CHECK (e > 0));
  INSERT INTO zzz VALUES(1,1,1,1), (2,2,2,2);
}
do_catchsql_test 3.1.1 {
  INSERT INTO yyy VALUES(0,0,0,0);
} {1 {CHECK constraint failed: e > 0}}
do_catchsql_test 3.1.2 {
  INSERT INTO yyy VALUES(0,0,0,0);
} {1 {CHECK constraint failed: e > 0}}

do_execsql_test 3.2.1 {
  ALTER TABLE yyy DROP e;
}
do_catchsql_test 3.2.2 {
  ALTER TABLE zzz DROP e;
} {1 {error in table zzz after drop column: no such column: e}}

finish_test
Changes to test/alterlegacy.test.
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
}

# Legacy behavior is to corrupt the schema in this case, as the table name in
# the CHECK constraint is incorrect after "t1" is renamed. This version is
# slightly different - it rejects the change and rolls back the transaction.
do_catchsql_test 1.2 {
  ALTER TABLE t1 RENAME TO t1new;
} {1 {no such column: t1.a}}

do_execsql_test 1.3 {
  CREATE TABLE t3(c, d);
  ALTER TABLE t3 RENAME TO t3new;
  DROP TABLE t3new;
}

do_execsql_test 1.4 {
  SELECT sql FROM sqlite_master
} {
  {CREATE TABLE t1(a, b, CHECK(t1.a != t1.b))}
  {CREATE TABLE t2(a, b)}
  {CREATE INDEX t2expr ON t2(a) WHERE t2.b>0}
}


do_catchsql_test 1.3 {
  ALTER TABLE t2 RENAME TO t2new;
} {1 {no such column: t2.b}}
do_execsql_test 1.4 {
  SELECT sql FROM sqlite_master
} {
  {CREATE TABLE t1(a, b, CHECK(t1.a != t1.b))}
  {CREATE TABLE t2(a, b)}
  {CREATE INDEX t2expr ON t2(a) WHERE t2.b>0}
}







|


















|







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
}

# Legacy behavior is to corrupt the schema in this case, as the table name in
# the CHECK constraint is incorrect after "t1" is renamed. This version is
# slightly different - it rejects the change and rolls back the transaction.
do_catchsql_test 1.2 {
  ALTER TABLE t1 RENAME TO t1new;
} {1 {error in table t1new after rename: no such column: t1.a}}

do_execsql_test 1.3 {
  CREATE TABLE t3(c, d);
  ALTER TABLE t3 RENAME TO t3new;
  DROP TABLE t3new;
}

do_execsql_test 1.4 {
  SELECT sql FROM sqlite_master
} {
  {CREATE TABLE t1(a, b, CHECK(t1.a != t1.b))}
  {CREATE TABLE t2(a, b)}
  {CREATE INDEX t2expr ON t2(a) WHERE t2.b>0}
}


do_catchsql_test 1.3 {
  ALTER TABLE t2 RENAME TO t2new;
} {1 {error in index t2expr after rename: no such column: t2.b}}
do_execsql_test 1.4 {
  SELECT sql FROM sqlite_master
} {
  {CREATE TABLE t1(a, b, CHECK(t1.a != t1.b))}
  {CREATE TABLE t2(a, b)}
  {CREATE INDEX t2expr ON t2(a) WHERE t2.b>0}
}
Added test/altermalloc3.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
# 2021 February 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.
#
#*************************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
set testprefix altermalloc3

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {
  finish_test
  return
}

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b, c, d, PRIMARY KEY(d, b)) WITHOUT ROWID;
  INSERT INTO t1 VALUES(1, 2, 3, 4);
}
faultsim_save_and_close

do_faultsim_test 1 -prep {
  faultsim_restore_and_reopen
} -body {
  execsql { ALTER TABLE t1 DROP COLUMN c }
} -test {
  faultsim_test_result {0 {}}
}


finish_test

Changes to test/altertab.test.
706
707
708
709
710
711
712


























713
714
715
  ALTER TABLE idx2 RENAME x TO y;
  SELECT sql FROM sqlite_master;
} {
  {CREATE TABLE "ggiiggoo"(a text)} 
  {CREATE TABLE "idx2"(y text COLLATE compare64)}
  {CREATE VIEW v1 AS SELECT * FROM "idx2" WHERE y='abc'}
}



























finish_test








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



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
  ALTER TABLE idx2 RENAME x TO y;
  SELECT sql FROM sqlite_master;
} {
  {CREATE TABLE "ggiiggoo"(a text)} 
  {CREATE TABLE "idx2"(y text COLLATE compare64)}
  {CREATE VIEW v1 AS SELECT * FROM "idx2" WHERE y='abc'}
}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 24.1.0 {
  CREATE TABLE t1(a, b);
  CREATE TRIGGER AFTER INSERT ON t1 BEGIN
    INSERT INTO nosuchtable VALUES(new.a) ON CONFLICT(a) DO NOTHING;
  END;
}
do_catchsql_test 24.1.1 {
  ALTER TABLE t1 RENAME TO t2;
} {1 {error in trigger AFTER: no such table: main.nosuchtable}}

reset_db
do_execsql_test 24.2.0 {
  CREATE TABLE t1(a, b);
  CREATE TRIGGER AFTER INSERT ON t1 BEGIN
    INSERT INTO v1 VALUES(new.a) ON CONFLICT(a) DO NOTHING;
  END;
  CREATE VIEW v1 AS SELECT * FROM nosuchtable;
}
do_catchsql_test 24.2.1 {
  ALTER TABLE t1 RENAME TO t2;
} {1 {error in trigger AFTER: no such table: main.nosuchtable}}


finish_test

Changes to test/altertab3.test.
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
    SELECT a, sum() w3 FROM t1 
    WINDOW b AS (ORDER BY NOT EXISTS(SELECT 1 FROM abc));
  END;
}

do_catchsql_test 11.2 {
  ALTER TABLE t1 RENAME TO t1x;
} {1 {error in trigger b: no such table: abc}}

do_execsql_test 11.3 {
  DROP TRIGGER b;
  CREATE TRIGGER b AFTER INSERT ON t1 WHEN new.a BEGIN
    SELECT a, sum() w3 FROM t1 
    WINDOW b AS (ORDER BY NOT EXISTS(SELECT 1 FROM t1));
  END;







|







249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
    SELECT a, sum() w3 FROM t1 
    WINDOW b AS (ORDER BY NOT EXISTS(SELECT 1 FROM abc));
  END;
}

do_catchsql_test 11.2 {
  ALTER TABLE t1 RENAME TO t1x;
} {1 {error in trigger b: no such table: main.abc}}

do_execsql_test 11.3 {
  DROP TRIGGER b;
  CREATE TRIGGER b AFTER INSERT ON t1 WHEN new.a BEGIN
    SELECT a, sum() w3 FROM t1 
    WINDOW b AS (ORDER BY NOT EXISTS(SELECT 1 FROM t1));
  END;
Changes to test/attach.test.
905
906
907
908
909
910
911















912
913
  CREATE TABLE db2.Table2(col1 INTEGER, col2 INTEGER, col3 INTEGER, col4);
  CREATE UNIQUE INDEX db2.idx_col1_unique ON Table2 (col1);
  CREATE UNIQUE INDEX db2.idx_col23_unique ON Table2 (col2, col3);
  CREATE INDEX db2.idx_col2 ON Table2 (col2);
  INSERT INTO Table2 VALUES(1,2,3,4);
  PRAGMA integrity_check;
} {ok}
















finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
  CREATE TABLE db2.Table2(col1 INTEGER, col2 INTEGER, col3 INTEGER, col4);
  CREATE UNIQUE INDEX db2.idx_col1_unique ON Table2 (col1);
  CREATE UNIQUE INDEX db2.idx_col23_unique ON Table2 (col2, col3);
  CREATE INDEX db2.idx_col2 ON Table2 (col2);
  INSERT INTO Table2 VALUES(1,2,3,4);
  PRAGMA integrity_check;
} {ok}

# 2021-03-10 Forum post https://sqlite.org/forum/forumpost/a006d86f72
#
reset_db
do_test attach-13.1 {
  sqlite3 db :memory:
  db eval {CREATE TABLE base(x);}
  for {set i 0} {$i<$SQLITE_MAX_ATTACHED} {incr i} {
    db eval "ATTACH ':memory:' AS a$i"
  }
  set m "a[expr {$SQLITE_MAX_ATTACHED-1}]"
  db eval "CREATE TABLE $m.t1(a INTEGER PRIMARY KEY, b);"
  db eval "CREATE TABLE $m.t2(a INTEGER PRIMARY KEY, b);"
  db eval {SELECT a FROM t1 WHERE b IN (SELECT a FROM t2);}
} {}

finish_test
Added test/avfs.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
# 2021-03-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 tests for the appendvfs extension.
#
# Tests performed:
# avfs-1.0. Test that an appendvfs DB can be added to an empty (ZLF) file.
# avfs-1.1. Test that the DB can be read with correct content upon reopen.
# avfs-1.2. Test that an appendvfs DB can be added to a simple text file.
# avfs-1.3. Test that the DB can be read with correct content upon reopen.
# avfs-1.4. Test that appended DB is aligned to default page boundary.
# avfs-2.1. Test that the simple text file retains its initial text.
# avfs-3.1. Test that the appendvfs can grow and shrink, remaining intact.
# avfs-3.2. Test that appendvfs is intact after grow/shrink/close/reopen.
# avfs-4.1. Test shell's ability to append to a non-appendvfs file.
# avfs-4.2. Test shell's ability to append to empty or nonexistent file.
# avfs-4.3. Test shell's ability to reopen and alter an appendvfs file.
# avfs-5.1. Test appendvfs refusal to open too-tiny DB appended onto ZLF.
# avfs-5.2. Test appendvfs refusal to open too-tiny DB appended on other.
# ...
# (more to come)

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix avfs

# Do not attempt this test if SQLITE_OMIT_VIRTUALTABLE is defined. 
#
ifcapable !vtab {
  finish_test
  return
}

set CLI [test_find_cli]
db close
# forcedelete test.db

load_static_extension db appendvfs

set ::fa avfs.adb
set ::fza avfs.sdb
forcedelete $::fa $::fza
set ::result {}

proc shellDoesAr {} {
  set shdo "sh_app1.sql"
  forcedelete $shdo
  set fd [open $shdo w]
  puts $fd ".help\n.q"
  close $fd
  set res [catchcmd "-batch -cmd \".read $shdo\""]
  return [regexp {^.archive} [lindex $res 1]]
}

set ::vf "&vfs=apndvfs"

# Return file offset of appendvfs portion of a file, or {} if none such.
proc fosAvfs {fname} {
  if {[file size $fname] < 25} {
    return {}
  }
  if {[catch {set fd [open $fname rb]}]} {
    return {}
  }
  seek $fd -25 end
  set am [read $fd 17]
  set ao [read $fd 8]
  close $fd
  if {$am ne "Start-Of-SQLite3-"} {
    return {}
  }
  binary scan $ao "W" rvo
  return $rvo
}

do_test 1.0 {
  set results {}
  set out [open $::fza wb]
  close $out
  sqlite3 adb "file:$::fza?mode=rwc$::vf" -uri 1
  adb eval {
    PRAGMA page_size=1024;
    PRAGMA cache_size=10;
    CREATE TABLE t1(a TEXT);
    INSERT INTO t1 VALUES ('dog'),('cat');
    SELECT group_concat(a) as pets FROM (SELECT a FROM t1 ORDER BY a);
  } { lappend results $pets }
  adb close
  lappend results [fosAvfs $fza]
  set ::result [join $results " | "]
} {cat,dog | 0}

do_test 1.1 {
  set results {}
  sqlite3 adb "file:$::fza?mode=rw$::vf" -uri 1
  adb eval {
    SELECT group_concat(a) as pets FROM (SELECT a FROM t1 ORDER BY a DESC);
  } { lappend results $pets }
  adb close
  set ::result [join $results " | "]
} {dog,cat}

do_test 1.2 {
  set results {}
  set out [open $::fa wb]
  set ::tlo { "Just some text," "and more text," "ending at 3 lines." }
  puts $out [join $::tlo "\n"]
  close $out
  set adbSz [file size $::fa]
  sqlite3 adb "file:$::fa?mode=rwc$::vf" -uri 1
  adb eval {
    PRAGMA auto_vacuum = 0;
    PRAGMA page_size=512;
    PRAGMA cache_size=0;
    CREATE TABLE t1(a TEXT);
    INSERT INTO t1 VALUES ('dog'),('cat'),('pig');
    SELECT group_concat(a) as pets FROM (SELECT a FROM t1 ORDER BY a);
  } { lappend results $pets }
  adb close
  set adaSz [file size $::fa]
  lappend results "Bytes before/after $adbSz/$adaSz"
  set ::result [join $results " | "]
} {cat,dog,pig | Bytes before/after 50/5145}

do_test 1.3 {
  set results {}
  sqlite3 adb "file:$::fa?mode=rw$::vf" -uri 1
  adb eval {
    SELECT group_concat(a) as pets FROM (SELECT a FROM t1 ORDER BY a DESC);
  } { lappend results $pets }
  adb close
  set ::result [join $results " | "]
} {pig,dog,cat}

do_test 1.4 {
  set ::result [fosAvfs $fa]
} {4096}

do_test 2.1 {
  set in [open $::fa r]
  set tli {}
  for {set i [llength $::tlo]} {$i > 0} {incr i -1} {
    lappend tli [gets $in]
  }
  close $in
  if { [join $tli ":"] ne [join $::tlo ":"] } {
    set ::result "Appendee changed."
  } else {
    set ::result "Appendee intact."
  }
} {Appendee intact.}

# Set of repeatable random integers for a couple tests.
proc rint {v} {
  return [::tcl::mathfunc::int [expr $v * 100000]]
}
array set ::randints [list 0 [rint [::tcl::mathfunc::srand 0]]]
for {set i 1} {$i < 10000} {incr i} {
  set ::randints($i) [rint [::tcl::mathfunc::rand]]
}

do_test 3.1 {
  set results {}
  sqlite3 adb "file:$::fa?mode=rw$::vf" -uri 1
  adb eval {
    DROP TABLE t1;
    PRAGMA cache_size=10;
    CREATE TABLE ri (i INTEGER);
    BEGIN;
  }
  for {set i 0} {$i < 10000} {incr i} {
    set r $::randints($i)
    set s $::randints([incr i])
    set t $::randints([incr i])
    set u $::randints([incr i])
    set v $::randints([incr i])
    adb eval {
      INSERT INTO ri VALUES ($r),($s),($t),($u),($v)
    }
  }
  adb eval {
    COMMIT;
    SELECT integrity_check as ic FROM pragma_integrity_check();
  } { lappend results $ic }
  set adbSz [file size $::fa]
  set qr {}
  adb eval {
    SELECT count(*) as ic FROM ri;
    DELETE FROM ri WHERE (i % 50) <> 25;
    SELECT integrity_check as ic FROM pragma_integrity_check();
    VACUUM;
    SELECT integrity_check as ic FROM pragma_integrity_check();
    SELECT count(*) as ic FROM ri;
  } { lappend qr $ic }
  adb close
  set adaSz [file size $::fa]
  set adba [expr ($adbSz + 0.1)/$adaSz]
  # lappend results $adbSz $adaSz
  set results [concat $results [lrange $qr 0 2]]
  lappend results [expr {$adba > 10.0 && $adba < 20.0}]
  set ::result [join $results " | "]
} {ok | 10000 | ok | ok | 1}

do_test 3.2 {
  set results {}
  sqlite3 adb "file:$::fa?mode=rw$::vf" -uri 1
  adb eval {
    SELECT integrity_check as ic FROM pragma_integrity_check();
  } { lappend results $ic }
  adb close
  set ::result [join $results " | "]
} {ok}

set ::cliDoesAr [shellDoesAr]

do_test 4.1 {
  set shdo "sh_app1.sql"
  set shod "sh_app1.adb"
  forcedelete $shdo $shod
  set ofd [open $shdo w]
  if {$::cliDoesAr} {
    puts $ofd ".ar -c"
  } else {
    puts $ofd "pragma page_size=512;"
    puts $ofd "create table sqlar (a);"
  }
  puts $ofd ".tables"
  puts $ofd ".q"
  close $ofd
  set ofd [open $shod wb]
  puts $ofd "Some text."
  close $ofd
  set res [catchcmd "-append -batch -init $shdo $shod" ""]
  lappend res [fosAvfs $shod]
  forcedelete $shdo $shod
  set ::result [join $res " | "]
} {0 | sqlar | 4096}

do_test 4.2 {
  set shdo "sh_app1.sql"
  set shod "sh_app1.adb"
  forcedelete $shdo $shod
  set ofd [open $shdo w]
  if {$::cliDoesAr} {
    puts $ofd ".ar -c"
  } else {
    puts $ofd "pragma page_size=512;"
    puts $ofd "create table sqlar (a);"
  }
  puts $ofd ".tables"
  puts $ofd ".q"
  close $ofd
  set ofd [open $shod wb]
  close $ofd
  set res [catchcmd "-append -batch -init $shdo $shod" ""]
  lappend res [fosAvfs $shod]
  forcedelete $shdo ; # Leave $shod for next test.
  set ::result [join $res " | "]
} {0 | sqlar | 0}

do_test 4.3 {
  set shdo "sh_app1.sql"
  set shod "sh_app1.adb" ; # Same as test 4.2, reusing ADB.
  forcedelete $shdo
  set ofd [open $shdo w]
  if {$::cliDoesAr} {
    puts $ofd ".ar -u $shdo"
    puts $ofd "select count(*) from sqlar where name = '$shdo';"
  } else {
    puts $ofd "insert into sqlar values (1);"
    puts $ofd "select count(*) from sqlar;"
  }
  puts $ofd ".q"
  close $ofd
  set res [catchcmd "-append -batch -init $shdo $shod" ""]
  sqlite3 adb "file:$shod?mode=rw$::vf" -uri 1
  adb eval {
    SELECT count(*) as n FROM sqlar
  } { lappend res $n }
  adb close
  forcedelete $shdo $shod;
  set ::result [join $res " | "]
} {0 | 1 | 1}

do_test 5.1 {
  set fake "faketiny.sdb"
  forcedelete $fake
  set ofd [open $fake wb]
  puts -nonewline $ofd "SQLite format 3"
  puts -nonewline $ofd [binary format "c" 0]
  puts -nonewline $ofd "Start-Of-SQLite3-"
  puts -nonewline $ofd [binary format "W" 0]
  close $ofd
  if {[catch {sqlite3 adb "file:$fake?mode=rw$::vf" -uri 1}]} {
    set res "Open failed."
  } else {
    adb close
    set res "Opened when should not."
  }
  forcedelete $fake
  set ::result $res
} {Open failed.}

do_test 5.2 {
  set fake "faketiny.sdb"
  forcedelete $fake
  set ofd [open $fake wb]
  set fakeAppendee "Dog ate my homework.\n"
  puts -nonewline $ofd $fakeAppendee
  puts -nonewline $ofd "SQLite format 3"
  puts -nonewline $ofd [binary format "c" 0]
  puts -nonewline $ofd "Start-Of-SQLite3-"
  puts -nonewline $ofd [binary format "W" [string length $fakeAppendee]]
  close $ofd
  if {[catch {sqlite3 adb "file:$fake?mode=rw$::vf" -uri 1}]} {
    set res "Open failed."
  } else {
    adb close
    set res "Opened when should not."
  }
  forcedelete $fake
  set ::result $res
} {Open failed.}

forcedelete $::fa $::fza

unset -nocomplain ::fa ::fza ::tlo ::result ::randints ::cliDoesAr

finish_test
Changes to test/backup2.test.
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162
} {1 {wrong # args: should be "db backup ?DATABASE? FILENAME"}}

# Try to restore from an unreadable file.
#
if {$tcl_platform(platform)=="windows"} {
  set msg {cannot open source database: unable to open database file}
} elseif {[string match *BSD $tcl_platform(os)]} {
  set msg {restore failed: file is not a database}
} else {
  set msg {cannot open source database: disk I/O error}
}
do_test backup2-10 {
  forcedelete bu3.db
  file mkdir bu3.db
  set rc [catch {db restore temp bu3.db} res]

  lappend rc $res
} [list 1 $msg]

# Try to restore from something that is not a database file.
#
do_test backup2-11 {
  set rc [catch {db restore temp bu2.db} res]
  lappend rc $res







|







>
|







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
} {1 {wrong # args: should be "db backup ?DATABASE? FILENAME"}}

# Try to restore from an unreadable file.
#
if {$tcl_platform(platform)=="windows"} {
  set msg {cannot open source database: unable to open database file}
} elseif {[string match *BSD $tcl_platform(os)]} {
  set msg {}
} else {
  set msg {cannot open source database: disk I/O error}
}
do_test backup2-10 {
  forcedelete bu3.db
  file mkdir bu3.db
  set rc [catch {db restore temp bu3.db} res]
  if {[string match *BSD $tcl_platform(os)]} { set res "" }
  list $rc $res
} [list 1 $msg]

# Try to restore from something that is not a database file.
#
do_test backup2-11 {
  set rc [catch {db restore temp bu2.db} res]
  lappend rc $res
Added test/columncount.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
# 2021 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 implements regression tests for SQLite library.  The
# focus of this file is testing the sqlite3_column_count() API.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix columncount

proc do_ccsql_test {tn sql res} {

  uplevel [list do_test $tn [subst -nocommands {
    set stmt [sqlite3_prepare_v2 db {$sql} -1 dummy]
    set res [sqlite3_column_count [set stmt]]
    while {[sqlite3_step [set stmt]]=="SQLITE_ROW"} {
      for {set i 0} {[set i] < [sqlite3_data_count [set stmt]]} {incr i} {
        lappend res [sqlite3_column_text [set stmt] [set i]]
      }
    }
  
    set rc [sqlite3_finalize [set stmt]]
    if {[set rc]!="SQLITE_OK"} {
      error [sqlite3_errmsg db]
    }

    set res
  }] [list {*}$res]]

}

do_execsql_test 1.0 {
  CREATE TABLE t1(x, y, z);
  INSERT INTO t1 VALUES('a', 'b', 'c');
}

do_ccsql_test 1.1 { SELECT * FROM t1 }      {3    a b c}
do_ccsql_test 1.2 { CREATE TABLE t2(a, b) } {0}

do_ccsql_test 1.3 { ALTER TABLE t2 RENAME TO t3 } {0}
do_ccsql_test 1.4 { ALTER TABLE t3 RENAME b TO ccc } {0}
do_ccsql_test 1.5 { ALTER TABLE t3 ADD COLUMN d } {0}

do_ccsql_test 1.6 { DROP TABLE t3 } {0}



finish_test

Added test/corruptN.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
# 2020-12-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.
#
#***********************************************************************
#
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix corruptN

# These tests deal with corrupt database files
#
database_may_be_corrupt

reset_db
do_test 1.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 4096 pagesize 512 filename sql024239.txt.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 02 00 01 01 00 40 20 20 00 00 00 0c 00 00 00 07   .....@  ........
|     32: 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 04   ................
|     48: 00 00 00 00 89 00 00 04 00 10 00 01 0a 00 00 01   ................
|     80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0c   ................
|     96: 00 2e 2c 50 0d 00 00 00 06 01 06 00 01 da 01 b0   ..,P............
|    112: 01 56 01 86 01 2a 01 06 00 00 00 00 00 00 00 00   .V...*..........
|    256: 00 00 00 00 00 00 22 07 06 17 11 11 01 31 74 61   .............1ta
|    272: 62 6c 65 74 34 74 34 07 43 52 45 41 54 45 20 54   blet4t4.CREATE T
|    288: 41 42 4c 45 20 74 34 28 78 29 2a 06 06 17 13 11   ABLE t4(x)*.....
|    304: 01 3f 69 6e 64 65 78 74 33 78 74 33 05 43 52 45   .?indext3xt3.CRE
|    320: 41 54 45 20 49 4e 44 45 58 20 74 33 78 20 4f 4e   ATE INDEX t3x ON
|    336: 20 74 33 28 78 29 2e 04 06 17 15 11 01 45 69 6e    t3(x).......Ein
|    352: 64 65 78 74 32 63 64 74 32 05 43 52 45 41 54 45   dext2cdt2.CREATE
|    368: 20 49 4e 44 45 58 20 74 32 63 64 20 4f 4e 20 74    INDEX t2cd ON t
|    384: 32 28 63 2c 64 29 28 05 06 17 11 11 01 3d 74 61   2(c,d)(......=ta
|    400: 62 6c 65 74 33 74 33 07 43 52 45 41 54 45 20 54   blet3t3.CREATE T
|    416: 41 42 4c 45 20 74 33 28 63 2c 78 2c 65 2c 66 29   ABLE t3(c,x,e,f)
|    432: 28 02 06 17 11 11 01 3d 74 61 62 6c 65 74 32 74   (......=tablet2t
|    448: 32 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 74   2.CREATE TABLE t
|    464: 32 28 63 2c 64 2c 65 2c 66 29 24 01 06 17 11 11   2(c,d,e,f)$.....
|    480: 01 35 74 61 62 6c 65 74 31 74 31 02 43 52 45 41   .5tablet1t1.CREA
|    496: 54 45 20 54 41 42 4c 45 20 74 31 28 61 2c 62 29   TE TABLE t1(a,b)
| page 2 offset 512
|      0: 0d 00 00 00 04 01 41 00 01 fa 01 f3 01 de 01 cf   ......A.........
|    160: 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00   .. .............
|    448: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0d   ................
|    464: 04 03 17 17 73 65 76 65 6e 65 69 67 68 74 13 03   ....seveneight..
|    480: 03 07 07 40 14 00 00 00 00 00 00 40 18 00 00 00   ...@.......@....
|    496: 00 00 00 05 02 03 01 01 03 04 04 01 03 09 01 02   ................
| page 3 offset 1024
|      0: 0d 00 00 00 08 01 54 00 01 f7 01 ec 01 c5 01 aa   ......T.........
|     16: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|    112: 00 00 dd 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|    336: 00 00 00 00 19 08 05 17 17 17 17 65 69 67 68 74   ...........eight
|    352: 65 69 67 68 74 73 65 76 65 6e 73 65 76 65 6e 25   eightsevenseven%
|    368: 07 05 07 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|    432: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08   ................
|    480: 00 00 0f 04 17 17 01 65 69 67 68 74 65 69 67 68   .......eighteigh
|    496: 74 08 15 04 07 07 01 40 18 00 00 00 00 00 00 40   t......@.......@
| page 4 offset 1536
|      0: 18 00 00 00 00 00 00 07 07 04 01 01 01 04 04 06   ................
|     16: 07 04 01 01 01 02 02 05 0f 04 17 17 01 73 6d 76   .............smv
|     32: 65 6e 65 69 67 68 74 04 15 04 07 07 01 40 14 00   eneight......@..
| page 5 offset 2048
|      0: 0a 00 00 00 08 01 96 00 01 fa 01 c4 01 f2 01 bc   ................
|     16: 01 dc 01 e1 01 96 01 cc 00 00 00 00 00 00 00 00   ................
|    160: 00 00 00 00 00 00 32 00 00 00 00 00 00 00 00 00   ......2.........
|    368: 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00   ................
|    400: 00 00 00 00 00 00 0f 04 17 17 01 85 69 67 68 74   ............ight
|    416: 65 69 67 68 74 08 15 04 07 07 01 40 18 00 00 00   eight......@....
|    432: 00 00 00 40 18 00 00 00 00 00 00 07 07 04 01 01   ...@............
|    448: 01 04 04 06 07 04 01 01 01 02 02 05 0f 04 17 17   ................
|    464: 01 73 6d 76 65 6e 65 69 67 68 74 04 15 04 07 07   .smveneight.....
|    480: 01 40 14 00 00 00 00 00 00 40 18 00 00 00 00 00   .@.......@......
|    496: 00 03 07 04 01 01 01 03 04 02 05 04 03 01 09 02   ................
| page 6 offset 2560
|      0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|     16: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00   ................
|    304: 00 00 00 26 00 00 00 00 00 00 00 00 00 00 00 00   ...&............
| page 7 offset 3072
|      0: 0d 00 00 00 08 01 c2 00 01 fb 01 f6 01 f1 01 ec   ................
|     16: 01 e0 01 d4 01 cb 01 c2 00 00 00 00 00 00 00 00   ................
|    128: 00 00 00 00 00 00 00 00 00 00 00 00 00 20 00 04   ............. ..
|    384: 00 00 00 00 00 00 00 00 00 07 08 02 17 65 69 fc   .............ei.
|    400: 68 74 07 07 02 17 65 69 67 68 74 0a fb fd f8 bf   ht....eight.....
|    416: e7 ff ff ff 00 00 00 0a 05 02 07 40 18 00 00 00   ...........@....
|    432: 00 00 00 03 04 02 01 04 03 03 02 01 04 03 02 01   ................
|    448: ff ff ff ff ff ff 00 00 00 00 00 00 00 00 00 00   ................
| end sql024239.txt.db
}]} {}

do_catchsql_test 1.1 {
  VACUUM;
} {1 {database disk image is malformed}}


finish_test
Changes to test/crash5.test.
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

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Only run these tests if memory debugging is turned on.
#
ifcapable !crashtest||!memorymanage {
   puts "Skipping crash5 tests: not compiled with -DSQLITE_MEMDEBUG..."
   finish_test
   return
}

db close

for {set ii 0} {$ii < 10} {incr ii} {
  for {set jj 50} {$jj < 100} {incr jj} {

    # Set up the database so that it is an auto-vacuum database 
    # containing a single table (root page 3) with a single row. 
    # The row has an overflow page (page 4).
    forcedelete test.db test.db-journal
    sqlite3 db test.db
    set c [string repeat 3 1500]
    db eval {
      pragma auto_vacuum = 1;
      CREATE TABLE t1(a, b, c);
      INSERT INTO t1 VALUES('1111111111', '2222222222', $c);
    }
    db close

    do_test crash5-$ii.$jj.1 {
      crashsql -delay 1 -file test.db-journal -seed $ii -tclbody [join [list \
        [list set iFail $jj] {














        sqlite3_crashparams 0 [file join [get_pwd] test.db-journal]
      
        # Begin a transaction and evaluate a "CREATE INDEX" statement
        # with the iFail'th malloc() set to fail. This operation will
        # have to move the current contents of page 4 (the overflow
        # page) to make room for the new root page. The bug is that
        # if malloc() fails at a particular point in sqlite3PagerMovepage(),
        # sqlite mistakenly thinks that the page being moved (page 4) has 
        # been safely synced into the journal. If the page is written
        # to later in the transaction, it may be written out to the database
        # before the relevant part of the journal has been synced.
        #
        db eval BEGIN
        sqlite3_memdebug_fail $iFail -repeat 0
        catch {db eval { CREATE UNIQUE INDEX i1 ON t1(a); }} msg
        # puts "$n $msg ac=[sqlite3_get_autocommit db]"

      

        # If the transaction is still active (it may not be if the malloc()
        # failure occurred in the OS layer), write to the database. Make sure
        # page 4 is among those written.
        #
        if {![sqlite3_get_autocommit db]} {
          db eval {
            DELETE FROM t1;  -- This will put page 4 on the free list.
            INSERT INTO t1 VALUES('111111111', '2222222222', '33333333');
            INSERT INTO t1 SELECT * FROM t1;                     -- 2
            INSERT INTO t1 SELECT * FROM t1;                     -- 4
            INSERT INTO t1 SELECT * FROM t1;                     -- 8
            INSERT INTO t1 SELECT * FROM t1;                     -- 16
            INSERT INTO t1 SELECT * FROM t1;                     -- 32
            INSERT INTO t1 SELECT * FROM t1 WHERE rowid%2;       -- 48
          }
        }
        
        # If the right malloc() failed during the 'CREATE INDEX' above and
        # the transaction was not rolled back, then the sqlite cache now 
        # has a dirty page 4 that it incorrectly believes is already safely
        # in the synced part of the journal file. When 
        # sqlite3_release_memory() is called sqlite tries to free memory
        # by writing page 4 out to the db file. If it crashes later on,
        # before syncing the journal... Corruption!
        #
        sqlite3_crashparams 1 [file join [get_pwd] test.db-journal]
        sqlite3_release_memory 8092

      }]] {}
      expr 1
    } {1}
  
    sqlite3 db test.db
    do_test crash5-$ii.$jj.2 {
      db eval {pragma integrity_check}







|







|

















>
>
>
>
>
>
>
>
>
>
>
>
>
>














|
|
>

>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>







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

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Only run these tests if memory debugging is turned on.
#
ifcapable !crashtest||!memorymanage {
   puts "Skipping crash5 tests: not compiled with -DSQLITE_ENABLE_MEMORY_MANAGEMENT..."
   finish_test
   return
}

db close

for {set ii 0} {$ii < 10} {incr ii} {
  for {set jj 1} {$jj < 100} {incr jj} {

    # Set up the database so that it is an auto-vacuum database 
    # containing a single table (root page 3) with a single row. 
    # The row has an overflow page (page 4).
    forcedelete test.db test.db-journal
    sqlite3 db test.db
    set c [string repeat 3 1500]
    db eval {
      pragma auto_vacuum = 1;
      CREATE TABLE t1(a, b, c);
      INSERT INTO t1 VALUES('1111111111', '2222222222', $c);
    }
    db close

    do_test crash5-$ii.$jj.1 {
      crashsql -delay 1 -file test.db-journal -seed $ii -tclbody [join [list \
        [list set iFail $jj] {
        proc get_pwd {} {
          if {$::tcl_platform(platform) eq "windows"} {
            if {[info exists ::env(ComSpec)]} {
              set comSpec $::env(ComSpec)
            } else {
              # NOTE: Hard-code the typical default value.
              set comSpec {C:\Windows\system32\cmd.exe}
            }
            return [string map [list \\ /] \
              [string trim [exec -- $comSpec /c echo %CD%]]]
          } else {
            return [pwd]
          }
        }
        sqlite3_crashparams 0 [file join [get_pwd] test.db-journal]
      
        # Begin a transaction and evaluate a "CREATE INDEX" statement
        # with the iFail'th malloc() set to fail. This operation will
        # have to move the current contents of page 4 (the overflow
        # page) to make room for the new root page. The bug is that
        # if malloc() fails at a particular point in sqlite3PagerMovepage(),
        # sqlite mistakenly thinks that the page being moved (page 4) has 
        # been safely synced into the journal. If the page is written
        # to later in the transaction, it may be written out to the database
        # before the relevant part of the journal has been synced.
        #
        db eval BEGIN
        sqlite3_memdebug_fail $iFail -repeat 0
        set rc [catch {db eval { CREATE UNIQUE INDEX i1 ON t1(a); }} msg]
#       puts "$msg ac=[sqlite3_get_autocommit db] iFail=$iFail"
#       puts "fail=[sqlite3_memdebug_fail -1]"
      
        if {$rc} {
          # If the transaction is still active (it may not be if the malloc()
          # failure occurred in the OS layer), write to the database. Make sure
          # page 4 is among those written.
          #
          if {![sqlite3_get_autocommit db]} {
            db eval {
              DELETE FROM t1;  -- This will put page 4 on the free list.
              INSERT INTO t1 VALUES('111111111', '2222222222', '33333333');
              INSERT INTO t1 SELECT * FROM t1;                     -- 2
              INSERT INTO t1 SELECT * FROM t1;                     -- 4
              INSERT INTO t1 SELECT * FROM t1;                     -- 8
              INSERT INTO t1 SELECT * FROM t1;                     -- 16
              INSERT INTO t1 SELECT * FROM t1;                     -- 32
              INSERT INTO t1 SELECT * FROM t1 WHERE rowid%2;       -- 48
            }
          }
          
          # If the right malloc() failed during the 'CREATE INDEX' above and
          # the transaction was not rolled back, then the sqlite cache now 
          # has a dirty page 4 that it incorrectly believes is already safely
          # in the synced part of the journal file. When 
          # sqlite3_release_memory() is called sqlite tries to free memory
          # by writing page 4 out to the db file. If it crashes later on,
          # before syncing the journal... Corruption!
          #
          sqlite3_crashparams 1 [file join [get_pwd] test.db-journal]
          sqlite3_release_memory 8092
        }
      }]] {}
      expr 1
    } {1}
  
    sqlite3 db test.db
    do_test crash5-$ii.$jj.2 {
      db eval {pragma integrity_check}
Changes to test/dbfuzz2.c.
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
        mxCb = strtol(argv[++i], 0, 0);
        continue;
      }
      if( strcmp(z,"memtrace")==0 ){
        sqlite3MemTraceActivate(stdout);
        continue;
      }
      if( strcmp(z,"mem")==0 ){
        bVdbeDebug = 1;
        continue;
      }
      if( strcmp(z,"max-db-size")==0 ){
        if( i+1==argc ){
          fprintf(stderr, "missing argument to %s\n", argv[i]);
          exit(1);
        }
        szMax = strtol(argv[++i], 0, 0);
        continue;












      }
#ifndef _WIN32
      if( strcmp(z,"max-stack")==0
       || strcmp(z,"max-data")==0
       || strcmp(z,"max-as")==0
      ){
        struct rlimit x,y;







<
<
<
<







>
>
>
>
>
>
>
>
>
>
>
>







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
        mxCb = strtol(argv[++i], 0, 0);
        continue;
      }
      if( strcmp(z,"memtrace")==0 ){
        sqlite3MemTraceActivate(stdout);
        continue;
      }




      if( strcmp(z,"max-db-size")==0 ){
        if( i+1==argc ){
          fprintf(stderr, "missing argument to %s\n", argv[i]);
          exit(1);
        }
        szMax = strtol(argv[++i], 0, 0);
        continue;
      }
      if( strcmp(z, "lookaside")==0 ){
        int sz, nSlot;
        if( i+2>=argc ){
          fprintf(stderr, 
             "--lookaside requires two arguments: slot-size num-slots\n");
          exit(1);
        }
        sz = atoi(argv[++i]);
        nSlot = atoi(argv[++i]);
        sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, nSlot);
        continue;
      }
#ifndef _WIN32
      if( strcmp(z,"max-stack")==0
       || strcmp(z,"max-data")==0
       || strcmp(z,"max-as")==0
      ){
        struct rlimit x,y;
Added test/exists2.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
# 2021 January 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 cases where EXISTS expressions are
# transformed to IN() expressions by where.c
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix exists2

do_execsql_test 1.0 {
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
  INSERT INTO t1 VALUES(1, 'one');
  INSERT INTO t1 VALUES(2, 'two');
  INSERT INTO t1 VALUES(3, 'three');
  INSERT INTO t1 VALUES(4, 'four');
  INSERT INTO t1 VALUES(5, 'five');
  INSERT INTO t1 VALUES(6, 'six');
  INSERT INTO t1 VALUES(7, 'seven');

  CREATE TABLE t2(c INTEGER, d INTEGER);
  INSERT INTO t2 VALUES(1, 1);
  INSERT INTO t2 VALUES(3, 2);
  INSERT INTO t2 VALUES(5, 3);
  INSERT INTO t2 VALUES(7, 4);
}

proc do_execsql_eqp_test {tn sql eqp res} {
  uplevel [list do_eqp_test $tn.1 $sql [string trim $eqp]]
  uplevel [list do_execsql_test $tn.2 $sql $res]
}

do_execsql_eqp_test 1.1 {
  SELECT t1.* FROM t1 WHERE EXISTS(SELECT * FROM t2 WHERE t1.a=t2.c);
} {
  USING INTEGER PRIMARY KEY
} {
  1 one 3 three 5 five 7 seven
}

do_execsql_eqp_test 1.2 {
  SELECT t1.* FROM t1 WHERE EXISTS(SELECT * FROM t2 WHERE t2.c=t1.a);
} {
  SEARCH TABLE t1 USING INTEGER PRIMARY KEY
} {
  1 one 3 three 5 five 7 seven
}

do_execsql_eqp_test 1.3 {
  SELECT t1.* FROM t1 WHERE EXISTS(SELECT * FROM t2 WHERE t2.c+1=t1.a);
} {
  SEARCH TABLE t1 USING INTEGER PRIMARY KEY
} {
  2 two 4 four 6 six
}

do_execsql_eqp_test 1.4 {
  SELECT t1.* FROM t1 WHERE EXISTS(SELECT * FROM t2 WHERE t2.c+1=t1.a+1);
} {
  SCAN TABLE t1
} {
  1 one 3 three 5 five 7 seven
}

do_execsql_eqp_test 1.5 {
  SELECT t1.* FROM t1 WHERE EXISTS(
    SELECT * FROM t2 WHERE t1.a=t2.c AND d IN (1, 2, 3)
  );
} {
  SEARCH TABLE t1 USING INTEGER PRIMARY KEY
} {
  1 one 3 three 5 five
}

do_execsql_eqp_test 1.6 {
  SELECT t1.* FROM t1 WHERE EXISTS(
    SELECT * FROM t2 WHERE d IN (1, 2, 3)AND t1.a=t2.c 
  );
} {
  SEARCH TABLE t1 USING INTEGER PRIMARY KEY
} {
  1 one 3 three 5 five
}

do_execsql_eqp_test 1.7 {
  SELECT t1.* FROM t1 WHERE EXISTS(
    SELECT * FROM t2 WHERE d IN (1, 2, 3)AND t1.a=t2.c 
  );
} {
  SEARCH TABLE t1 USING INTEGER PRIMARY KEY
} {
  1 one 3 three 5 five
}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 2.0 {
  CREATE TABLE t3(a TEXT PRIMARY KEY, b TEXT, x INT) WITHOUT ROWID;
  CREATE TABLE t4(c TEXT COLLATE nocase, y INT);

  INSERT INTO t3 VALUES('one', 'i', 1);
  INSERT INTO t3 VALUES('two', 'ii', 2);
  INSERT INTO t3 VALUES('three', 'iii', 3);
  INSERT INTO t3 VALUES('four', 'iv', 4);
  INSERT INTO t3 VALUES('five', 'v', 5);

  INSERT INTO t4 VALUES('FIVE',5), ('four',4), ('TWO',2), ('one',1);
}

do_execsql_test 2.1 { SELECT a FROM t3, t4 WHERE a=c } {four one}
do_execsql_test 2.2 { SELECT a FROM t3, t4 WHERE c=a } {five four one two}

do_execsql_eqp_test 2.3 {
  SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE a=c)
} {
  SEARCH TABLE t3 USING PRIMARY KEY
} {
  four one
}

do_execsql_eqp_test 2.4 {
  SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE c=a)
} {
  SCAN TABLE t3
} {
  five four one two
}

do_execsql_test 2.5 {
  CREATE INDEX t3anc ON t3(a COLLATE nocase, x);
}

do_execsql_eqp_test 2.6 {
  SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE c=a)
} {
  SEARCH TABLE t3 USING COVERING INDEX t3anc
} {
  five four one two
}
do_execsql_test 2.6a {
  SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE (c,y)=(a,x))
} {five four one two}

do_execsql_eqp_test 2.7 {
  SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE a=c)
} {
  SEARCH TABLE t3 USING PRIMARY KEY
} {
  four one
}
do_execsql_test 2.7a {
  SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE (a,x)=(c,y))
} {
  four one
}

# EXISTS clauses using vector expressions in the WHERE clause.
#
reset_db
do_execsql_test 3.0 {
  CREATE TABLE t1(a,b);
  INSERT INTO t1(a,b) VALUES(1,111),(2,222),(8,888);
  CREATE TABLE t2(x INTEGER PRIMARY KEY, y);
  INSERT INTO t2(x,y) VALUES(2,222),(3,333),(7,333);
  SELECT y FROM t2 WHERE EXISTS(SELECT 1 FROM t1 WHERE (x,y)=(a,b));
} {222}
do_execsql_test 3.1 {
  SELECT y FROM t2 WHERE EXISTS(SELECT 1 FROM t1 WHERE (a,b)=(x,y));
} {222}
do_execsql_test 3.2 {
  SELECT y FROM t2 WHERE EXISTS(SELECT 1 FROM t1 WHERE (x,b)=(a,y));
} {222}





finish_test
Added test/existsfault.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
# 2021 January 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 cases where EXISTS expressions are
# transformed to IN() expressions by where.c
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix existsfault

do_execsql_test 1 {
  CREATE TABLE t1(a PRIMARY KEY, b);
  INSERT INTO t1 VALUES(1, 'one');
  INSERT INTO t1 VALUES(2, 'two');
  INSERT INTO t1 VALUES(3, 'three');
  INSERT INTO t1 VALUES(4, 'four');
  INSERT INTO t1 VALUES(5, 'five');
  INSERT INTO t1 VALUES(6, 'six');
  INSERT INTO t1 VALUES(7, 'seven');

  CREATE TABLE t2(c INTEGER, d INTEGER);
  INSERT INTO t2 VALUES(1, 1);
  INSERT INTO t2 VALUES(3, 2);
  INSERT INTO t2 VALUES(5, 3);
  INSERT INTO t2 VALUES(7, 4);
}
faultsim_save_and_close

do_faultsim_test 1 -prep {
  faultsim_restore_and_reopen
} -body {
  execsql {
    SELECT t1.* FROM t1 WHERE EXISTS(
        SELECT * FROM t2 WHERE t2.c=t1.a AND d IN (1, 2, 3)
    )
  }
} -test {
  faultsim_test_result {0 {1 one 3 three 5 five}}
}


finish_test

Changes to test/fts3corrupt4.test.
6293
6294
6295
6296
6297
6298
6299
























































































6300
6301
  INSERT INTO t1_segdir VALUES(0,0,0,0,0,X'000130120106000106000106001f030001030001030000083230313630363039090107000107000107000001340901050001050001050000013509010400010400010400010730303030303030091c0400010400010400000662696e6172793c0301020200030102020003010202000301020200030102020003010202000301020200030102020003010202000301020200030102020003010202000008636f6d70696c657209010200010200010200000664627374617409070300010300010300010465627567090402000102000102000006656e61626c653f07020001020001020001020001020001020001020001020001020001020001020001020001010001020001020001020001020001020001020001020001020001087874656e73696f6e091f0400010400010400000466747334090a0300010300010300030135090d03000103000103000003676363090103000103000103000106656f706f6c790910030001030001030000056a736f6e310913030001030001030000046c6f6164091f030001030001030000036d6178091c02000102000102000105656d6f7279091c03000103000103000304737973350916030001030001030000066e6f636173653c02010202000301020200030102020003010202000301020200030102020003010202000301020200030102020003010202000301020200030102020000046f6d6974091f020001020001020000057274726565091903000103000103000302696d3c01010202000301020200030102020003010202000301020200030102020003010202000301a202000301020200030102020003010202000301020200000a746872656164736166650922020001020001020000047674616209070400010400010400000178b401010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200');
  INSERT INTO t1_segdir VALUES(0,1,0,0,0,X'0001300425061b000008323031363036303903250700000134032505000001350325040001073030303030303003251a000008636f6d70696c657203250200000664627374617403250a00010465627567032508000006656e61626c650925090504040404040001087874656e73696f6e03251d0000046674733403250d0003013503250f000003676363032503000106656f706f6c790325110000056a736f6e310325130000046c6f616403251c0000036d6178032518000105656d6f7279032519000304737973350325150000046f6d697403251b000005727472656503251700000a7468726561647361666503251e0000047674616333250b00');
}

do_catchsql_test 47.3 {
  SELECT matchinfo(t1) FROM t1 WHERE t1 MATCH '"json1 enable"';
} {1 {database disk image is malformed}}

























































































finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


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
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
  INSERT INTO t1_segdir VALUES(0,0,0,0,0,X'000130120106000106000106001f030001030001030000083230313630363039090107000107000107000001340901050001050001050000013509010400010400010400010730303030303030091c0400010400010400000662696e6172793c0301020200030102020003010202000301020200030102020003010202000301020200030102020003010202000301020200030102020003010202000008636f6d70696c657209010200010200010200000664627374617409070300010300010300010465627567090402000102000102000006656e61626c653f07020001020001020001020001020001020001020001020001020001020001020001020001010001020001020001020001020001020001020001020001020001087874656e73696f6e091f0400010400010400000466747334090a0300010300010300030135090d03000103000103000003676363090103000103000103000106656f706f6c790910030001030001030000056a736f6e310913030001030001030000046c6f6164091f030001030001030000036d6178091c02000102000102000105656d6f7279091c03000103000103000304737973350916030001030001030000066e6f636173653c02010202000301020200030102020003010202000301020200030102020003010202000301020200030102020003010202000301020200030102020000046f6d6974091f020001020001020000057274726565091903000103000103000302696d3c01010202000301020200030102020003010202000301020200030102020003010202000301a202000301020200030102020003010202000301020200000a746872656164736166650922020001020001020000047674616209070400010400010400000178b401010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200');
  INSERT INTO t1_segdir VALUES(0,1,0,0,0,X'0001300425061b000008323031363036303903250700000134032505000001350325040001073030303030303003251a000008636f6d70696c657203250200000664627374617403250a00010465627567032508000006656e61626c650925090504040404040001087874656e73696f6e03251d0000046674733403250d0003013503250f000003676363032503000106656f706f6c790325110000056a736f6e310325130000046c6f616403251c0000036d6178032518000105656d6f7279032519000304737973350325150000046f6d697403251b000005727472656503251700000a7468726561647361666503251e0000047674616333250b00');
}

do_catchsql_test 47.3 {
  SELECT matchinfo(t1) FROM t1 WHERE t1 MATCH '"json1 enable"';
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
#
reset_db
do_test 48.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 20480 pagesize 4096 filename sql038051.txt.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00   .....@  ........
|     96: 00 00 00 00 0d 0e fc 00 05 0e 13 00 0f ca 0f 6c   ...............l
|    112: 0f 04 0e 13 0e c9 00 00 00 00 00 00 00 00 00 00   ................
|   3600: 00 00 00 81 33 04 07 17 1f 1f 01 82 35 74 61 62   ....3.......5tab
|   3616: 6c 65 78 31 5f 73 65 67 64 69 72 78 31 5f 73 65   lex1_segdirx1_se
|   3632: 67 64 69 72 04 43 52 45 41 54 45 20 54 41 42 4c   gdir.CREATE TABL
|   3648: 45 20 27 78 31 5f 73 65 67 64 69 72 27 28 6c 65   E 'x1_segdir'(le
|   3664: 76 65 6c 20 49 4e 54 45 47 45 52 2c 69 64 78 20   vel INTEGER,idx 
|   3680: 49 4e 54 45 47 45 52 2c 73 74 61 72 74 5f 62 6c   INTEGER,start_bl
|   3696: 6f 63 6b 20 49 4e 54 45 47 45 52 2c 6c 65 61 76   ock INTEGER,leav
|   3712: 65 73 5f 65 6e 64 5f 62 6c 6f 63 6b 20 49 4e 54   es_end_block INT
|   3728: 45 47 45 52 2c 65 6e 64 5f 62 6c 6f 63 6b 20 49   EGER,end_block I
|   3744: 4e 54 45 47 45 52 2c 72 6f 6f 74 20 42 4c 4f 42   NTEGER,root BLOB
|   3760: 2c 50 52 49 4d 41 52 59 20 4b 45 59 28 6c 65 76   ,PRIMARY KEY(lev
|   3776: 65 6c 2c 20 69 64 78 29 29 31 05 06 17 45 1f 01   el, idx))1...E..
|   3792: 00 69 6e 64 65 78 73 71 6c 69 74 65 5f 61 75 74   .indexsqlite_aut
|   3808: 6f 69 6e 64 65 78 5f 78 31 5f 73 65 67 64 69 72   oindex_x1_segdir
|   3824: 5f 31 78 31 5f 73 65 67 64 69 72 05 00 00 00 08   _1x1_segdir.....
|   3840: 00 00 00 00 66 03 07 17 23 23 01 81 13 74 61 62   ....f...##...tab
|   3856: 6c 65 78 31 5f 73 65 67 6d 65 6e 74 73 78 31 5f   lex1_segmentsx1_
|   3872: 73 65 67 6d 65 6e 74 73 03 43 52 45 41 54 45 20   segments.CREATE 
|   3888: 54 41 42 4c 45 20 27 78 31 5f 73 65 67 6d 65 6e   TABLE 'x1_segmen
|   3904: 74 73 27 28 62 6c 6f 63 6b 69 64 20 49 4e 54 45   ts'(blockid INTE
|   3920: 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c   GER PRIMARY KEY,
|   3936: 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 5c 02 07 17    block BLOB)....
|   3952: 21 21 01 81 03 74 61 62 6c 65 78 31 5f 63 6f 6e   !!...tablex1_con
|   3968: 74 65 6e 74 78 31 5f 63 6f 6e 74 65 6e 74 02 43   tentx1_content.C
|   3984: 52 45 41 54 45 20 54 41 42 4c 45 20 27 78 31 5f   REATE TABLE 'x1_
|   4000: 63 6f 6e 74 65 6e 74 27 28 64 6f 63 69 64 20 49   content'(docid I
|   4016: 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b   NTEGER PRIMARY K
|   4032: 45 59 2c 20 27 63 30 78 27 29 34 01 06 17 11 11   EY, 'c0x')4.....
|   4048: 08 57 74 61 62 6c 65 78 31 78 31 43 52 45 41 54   .Wtablex1x1CREAT
|   4064: 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 20   E VIRTUAL TABLE 
|   4080: 78 31 20 55 53 49 4e 47 20 66 74 73 33 28 78 29   x1 USING fts3(x)
| page 2 offset 4096
|      0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   3920: 00 00 00 2e 04 03 00 63 62 72 61 69 6e 73 74 65   .......cbrainste
|   3936: 6d 20 62 72 61 69 6e 73 74 65 6d 73 20 62 72 61   m brainstems bra
|   3952: 69 6e 73 74 6f 72 6d 20 62 72 61 69 6e 73 74 6f   instorm brainsto
|   3968: 72 6d 73 2b 03 03 00 5d 62 72 61 69 6e 20 62 72   rms+...]brain br
|   3984: 61 69 6e 63 68 69 6c 64 20 62 72 61 69 6e 65 64   ainchild brained
|   4000: 20 62 72 61 69 6e 69 6e 67 20 62 72 61 69 6e 73    braining brains
|   4016: 26 02 03 00 53 62 72 61 67 73 20 62 72 61 69 64   &...Sbrags braid
|   4032: 20 62 72 61 69 64 65 64 20 62 72 61 69 64 69 6e    braided braidin
|   4048: 67 20 62 72 61 69 64 73 26 01 03 00 53 62 72 61   g braids&...Sbra
|   4064: 65 73 20 62 72 61 67 20 62 72 61 67 67 65 64 20   es brag bragged 
|   4080: 62 72 61 c3 67 65 72 20 62 72 61 67 67 69 6e 67   bra.ger bragging
| page 3 offset 8192
|      0: 0d 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00   ................
| page 4 offset 12288
|      0: 0d 00 00 00 04 0f 20 00 0f c8 0f 90 0f 54 0f 20   ...... ......T. 
|   3872: 32 04 07 08 01 08 08 15 58 03 30 20 33 38 00 09   2.......X.0 38..
|   3888: 62 72 61 69 6e 73 74 65 6d 03 04 02 00 09 01 73   brainstem......s
|   3904: 03 04 03 00 07 03 6f 72 6d 03 04 04 00 0a 01 73   ......orm......s
|   3920: 03 04 05 00 3a 03 07 08 01 08 08 15 68 02 30 20   ....:.......h.0 
|   3936: 34 36 00 05 62 72 61 69 6e 03 03 02 00 05 05 63   46..brain......c
|   3952: 68 69 6c 64 03 03 03 00 05 02 65 64 03 03 04 00   hild......ed....
|   3968: 05 03 69 6e 67 03 03 05 00 05 01 73 03 03 06 00   ..ing......s....
|   3984: 36 02 07 08 09 08 08 15 62 30 20 34 33 00 05 62   6.......b0 43..b
|   4000: 72 61 67 73 03 02 02 00 03 02 69 64 03 02 03 00   rags......id....
|   4016: 05 02 65 64 03 02 04 00 05 03 69 6e 67 03 02 05   ..ed......ing...
|   4032: 00 05 01 73 03 02 06 00 36 01 07 08 08 08 08 15   ...s....6.......
|   4048: 62 30 20 34 33 00 05 62 72 61 65 73 03 01 02 00   b0 43..braes....
|   4064: 03 01 68 03 01 03 00 04 03 67 65 74 03 01 04 00   ..h......get....
|   4080: 06 01 72 03 01 05 00 05 03 69 6e 67 03 01 06 00   ..r......ing....
| page 5 offset 16384
|      0: 0a 00 00 00 04 0f e7 00 0f fb 0f f5 0f ee 0f e7   ................
|   4064: 00 00 00 00 00 00 00 06 04 08 01 01 03 04 06 04   ................
|   4080: 08 01 01 02 03 05 04 08 09 01 02 04 04 08 08 09   ................
| end sql038051.txt.db
}]} {}

do_catchsql_test 48.1 {
  INSERT INTO x1(x1) VALUES('nodesize=24'),('merge=3,4');
  INSERT INTO x1(x1) VALUES( 'merge=3,4' ),('merge=3,4');
} {1 {database disk image is malformed}}


finish_test
Changes to test/fts3corrupt6.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 2020 June 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 implements regression tests for SQLite library.  The
# focus of this script is testing the FTS3 module.
#
# $Id: fts3aa.test,v 1.1 2007/08/20 17:38:42 shess Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/fts3_common.tcl
set testprefix fts3corrupt6

# If SQLITE_ENABLE_FTS3 is defined, omit this file.













<
<







1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20
# 2020 June 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 implements regression tests for SQLite library.  The
# focus of this script is testing the FTS3 module.
#



set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/fts3_common.tcl
set testprefix fts3corrupt6

# If SQLITE_ENABLE_FTS3 is defined, omit this file.
49
50
51
52
53
54
55










56
57
58
59
60
  INSERT INTO t1_content VALUES(0,NULL,NULL,NULL,NULL);
  INSERT INTO t1_segdir VALUES(0,0,0,0,'0 42',X'000131030102000103323334050101010200000461616161050101020200000462626262050101030200');
}

do_execsql_test 1.3 {
  SELECT 42+matchinfo(t1,'yxyyxy')  FROM t1 WHERE t1 MATCH  x'2b0a312b0a312a312a2a0b5d0a0b0b0a312a0a0b0b0a312a0b310a392a0b0a27312a2a0b5d0a312a0b310a31315d0b310a312a316d2a0b313b15bceaa50a312a0b0a27312a2a0b5d0a312a0b310a312b0b2a310a312a0b2a0b2a0b2e5d0a0bff313336e34a2a312a0b0a3c310b0a0b4b4b0b4b2a4bec40322b2a0b310a0a312a0a0a0a0a0a0a0a0a0b310a312a2a2a0b5d0a0b0b0a312a0b310a312a0b0a4e4541530b310a5df5ced70a0a0a0a0a4f520a0a0a0a0a0a0a312a0b0a4e4541520b310a5d616161610a0a0a0a4f520a0a0a0a0a0a312b0a312a312a0a0a0a0a0a0a004a0b0a310b220a0b0a310a4a22310a0b0a7e6fe0e0e030e0e0e0e0e01176e02000e0e0e0e0e01131320226310a0b0a310a4a22310a0b0a310a766f8b8b4ee0e0300ae0090909090909090909090909090909090909090909090909090909090909090947aaaa540b09090909090909090909090909090909090909090909090909090909090909fae0e0f2f22164e0e0f273e07fefefef7d6dfafafafa6d6d6d6d';
} {42}











set sqlite_fts3_enable_parentheses $saved_sqlite_fts3_enable_parentheses
finish_test









>
>
>
>
>
>
>
>
>
>





47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
  INSERT INTO t1_content VALUES(0,NULL,NULL,NULL,NULL);
  INSERT INTO t1_segdir VALUES(0,0,0,0,'0 42',X'000131030102000103323334050101010200000461616161050101020200000462626262050101030200');
}

do_execsql_test 1.3 {
  SELECT 42+matchinfo(t1,'yxyyxy')  FROM t1 WHERE t1 MATCH  x'2b0a312b0a312a312a2a0b5d0a0b0b0a312a0a0b0b0a312a0b310a392a0b0a27312a2a0b5d0a312a0b310a31315d0b310a312a316d2a0b313b15bceaa50a312a0b0a27312a2a0b5d0a312a0b310a312b0b2a310a312a0b2a0b2a0b2e5d0a0bff313336e34a2a312a0b0a3c310b0a0b4b4b0b4b2a4bec40322b2a0b310a0a312a0a0a0a0a0a0a0a0a0b310a312a2a2a0b5d0a0b0b0a312a0b310a312a0b0a4e4541530b310a5df5ced70a0a0a0a0a4f520a0a0a0a0a0a0a312a0b0a4e4541520b310a5d616161610a0a0a0a4f520a0a0a0a0a0a312b0a312a312a0a0a0a0a0a0a004a0b0a310b220a0b0a310a4a22310a0b0a7e6fe0e0e030e0e0e0e0e01176e02000e0e0e0e0e01131320226310a0b0a310a4a22310a0b0a310a766f8b8b4ee0e0300ae0090909090909090909090909090909090909090909090909090909090909090947aaaa540b09090909090909090909090909090909090909090909090909090909090909fae0e0f2f22164e0e0f273e07fefefef7d6dfafafafa6d6d6d6d';
} {42}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
  CREATE VIRTUAL TABLE t0 USING fts3(a);
  INSERT INTO t0_segdir VALUES(0,0,0,0,'0 42',X'000131030782000103323334050100fff200010461616161050101020200000462626262050101030200');
}
do_execsql_test 2.1 {
  SELECT count(*) FROM t0 WHERE t0 MATCH '(1 NEAR 1) AND (aaaa OR 1)';
} 1

set sqlite_fts3_enable_parentheses $saved_sqlite_fts3_enable_parentheses
finish_test


Changes to test/fts4rename.test.
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
  CREATE VIRTUAL TABLE temp.t1 USING fts3(a);
  BEGIN;
  CREATE TABLE t2(x);
} {}

do_catchsql_test 1.1 {
  ALTER TABLE t1_content RENAME c0a TO docid;
} {1 {duplicate column name: docid}}

do_catchsql_test 1.2 {
  UPDATE t1 SET Col0 = 1 ;
} {1 {no such column: Col0}}

do_catchsql_test 1.3 {
  ROLLBACK;







|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
  CREATE VIRTUAL TABLE temp.t1 USING fts3(a);
  BEGIN;
  CREATE TABLE t2(x);
} {}

do_catchsql_test 1.1 {
  ALTER TABLE t1_content RENAME c0a TO docid;
} {1 {error in table t1_content after rename: duplicate column name: docid}}

do_catchsql_test 1.2 {
  UPDATE t1 SET Col0 = 1 ;
} {1 {no such column: Col0}}

do_catchsql_test 1.3 {
  ROLLBACK;
Changes to test/fts4unicode.test.
562
563
564
565
566
567
568


















569
570
  CREATE VIRTUAL TABLE ft1 USING fts3tokenize(
    "unicode61", "tokenchars=@.", "separators=1234567890"
  );
  SELECT token FROM ft1 WHERE input = 'berlin@street123sydney.road';
} {
  berlin@street sydney.road
}



















finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


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
  CREATE VIRTUAL TABLE ft1 USING fts3tokenize(
    "unicode61", "tokenchars=@.", "separators=1234567890"
  );
  SELECT token FROM ft1 WHERE input = 'berlin@street123sydney.road';
} {
  berlin@street sydney.road
}

# Test for embedded nul characters in fts4 unicode index.
#
do_execsql_test 12.0 {
  CREATE VIRTUAL TABLE t12 USING fts4(tokenize=unicode61);
  INSERT INTO t12 VALUES('abc' || char(0) || 'def');
  SELECT hex(CAST(content AS blob)) FROM t12;
} {61626300646566}
do_execsql_test 12.1 {
  INSERT INTO t12(t12) VALUES('integrity-check');
} {}
do_execsql_test 12.2 { 
  CREATE VIRTUAL TABLE t12aux USING fts4aux(t12);
  SELECT * FROM t12aux;
} {abc * 1 1 abc 0 1 1}
do_execsql_test 12.3 { 
  SELECT hex(CAST(content AS blob)) FROM t12 WHERE t12 MATCH 'abc'
} {61626300646566}

finish_test
Added test/func7.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
# 2020-12-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.
#
#*************************************************************************
#
# Test cases for SQL functions based off the standard math library
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !mathlib {
  finish_test
  return
}

do_execsql_test func7-100 {
  SELECT ceil(99.9), ceiling(-99.01), floor(17), floor(-17.99);
} {100.0 -99.0 17 -18.0}
do_execsql_test func7-110 {
  SELECT quote(ceil(NULL)), ceil('-99.99');
} {NULL -99.0}
do_execsql_test func7-200 {
  SELECT round(ln(5),2), log(100.0), log(100), log(2,'256');
} {1.61 2.0 2.0 8.0}
do_execsql_test func7-210 {
  SELECT ln(-5), log(-5,100.0);
} {{} {}}

# Test cases derived from PostgreSQL documentation
#
do_execsql_test func7-pg-100 {
  SELECT abs(-17.4)
} {17.4}
do_execsql_test func7-pg-110 {
  SELECT ceil(42.2)
} {43.0}
do_execsql_test func7-pg-120 {
  SELECT ceil(-42.2)
} {-42.0}
do_execsql_test func7-pg-130 {
  SELECT round(exp(1.0),7)
} {2.7182818}
do_execsql_test func7-pg-140 {
  SELECT floor(42.8)
} {42.0}
do_execsql_test func7-pg-150 {
  SELECT floor(-42.8)
} {-43.0}
do_execsql_test func7-pg-160 {
  SELECT round(ln(2.0),7)
} {0.6931472}
do_execsql_test func7-pg-170 {
  SELECT log(100.0)
} {2.0}
do_execsql_test func7-pg-180 {
  SELECT log10(1000.0)
} {3.0}
do_execsql_test func7-pg-190 {
  SELECT log(2.0, 64.0)
} {6.0}
do_execsql_test func7-pg-200 {
   SELECT mod(9,4);
} {1.0}
do_execsql_test func7-pg-210 {
   SELECT round(pi(),7);
} {3.1415927}
do_execsql_test func7-pg-220 {
   SELECT power(9,3);
} {729.0}
do_execsql_test func7-pg-230 {
   SELECT round(radians(45.0),7);
} {0.7853982}
do_execsql_test func7-pg-240 {
   SELECT round(42.4);
} {42.0}
do_execsql_test func7-pg-250 {
   SELECT round(42.4382,2);
} {42.44}
do_execsql_test func7-pg-260 {
   SELECT sign(-8.4);
} {-1}
do_execsql_test func7-pg-270 {
   SELECT round( sqrt(2), 7);
} {1.4142136}
do_execsql_test func7-pg-280 {
   SELECT trunc(42.8), trunc(-42.8);
} {42.0 -42.0}
do_execsql_test func7-pg-300 {
   SELECT acos(1);
} {0.0}
do_execsql_test func7-pg-301 {
   SELECT degrees(acos(0.5));
} {60.0}
do_execsql_test func7-pg-310 {
   SELECT round( asin(1), 7);
} {1.5707963}
do_execsql_test func7-pg-311 {
   SELECT degrees( asin(0.5) );
} {30.0}
do_execsql_test func7-pg-320 {
   SELECT round( atan(1), 7);
} {0.7853982}
do_execsql_test func7-pg-321 {
   SELECT degrees( atan(1) );
} {45.0}
do_execsql_test func7-pg-330 {
   SELECT round( atan2(1,0), 7);
} {1.5707963}
do_execsql_test func7-pg-331 {
   SELECT degrees( atan2(1,0) );
} {90.0}
do_execsql_test func7-pg-400 {
   SELECT cos(0);
} {1.0}
do_execsql_test func7-pg-401 {
   SELECT cos( radians(60.0) );
} {0.5}
do_execsql_test func7-pg-400 {
   SELECT cos(0);
} {1.0}
do_execsql_test func7-pg-410 {
   SELECT round( sin(1), 7);
} {0.841471}
do_execsql_test func7-pg-411 {
   SELECT sin( radians(30) );
} {0.5}
do_execsql_test func7-pg-420 {
   SELECT round( tan(1), 7);
} {1.5574077}
do_execsql_test func7-pg-421 {
   SELECT tan( radians(45) );
} {1.0}
do_execsql_test func7-pg-500 {
   SELECT round( sinh(1), 7);
} {1.1752012}
do_execsql_test func7-pg-510 {
   SELECT round( cosh(0), 7);
} {1.0}
do_execsql_test func7-pg-520 {
   SELECT round( tanh(1), 7);
} {0.7615942}
do_execsql_test func7-pg-530 {
   SELECT round( asinh(1), 7);
} {0.8813736}
do_execsql_test func7-pg-540 {
   SELECT round( acosh(1), 7);
} {0.0}
do_execsql_test func7-pg-550 {
   SELECT round( atanh(0.5), 7);
} {0.5493061}

# Test cases derived from MySQL documentation
#
do_execsql_test func7-mysql-100 {
   SELECT acos(1);
} {0.0}
do_execsql_test func7-mysql-110 {
   SELECT acos(1.0001);
} {{}}
do_execsql_test func7-mysql-120 {
   SELECT round( acos(0.0), 7);
} {1.5707963}
do_execsql_test func7-mysql-130 {
   SELECT round( asin(0.2), 7);
} {0.2013579}
do_execsql_test func7-mysql-140 {
   SELECT asin('foo');
} {{}}  ;# Note: MySQL returns 0 here, not NULL.
         # SQLite deliberately returns NULL.
         # SQLServer and Oracle throw an error.
do_execsql_test func7-mysql-150 {
   SELECT round( atan(2), 7), round( atan(-2), 7);
} {1.1071487 -1.1071487}
do_execsql_test func7-mysql-160 {
   SELECT round( atan2(-2,2), 7), round( atan2(pi(),0), 7);
} {-0.7853982 1.5707963}
do_execsql_test func7-mysql-170 {
   SELECT ceiling(1.23), ceiling(-1.23);
} {2.0 -1.0}
do_execsql_test func7-mysql-180 {
   SELECT cos(pi());
} {-1.0}
do_execsql_test func7-mysql-190 {
   SELECT degrees(pi()), degrees(pi()/2);
} {180.0 90.0}
do_execsql_test func7-mysql-190 {
   SELECT round( exp(2), 7), round( exp(-2), 7), exp(0);
} {7.3890561 0.1353353 1.0}
do_execsql_test func7-mysql-200 {
   SELECT floor(1.23), floor(-1.23);
} {1.0 -2.0}
do_execsql_test func7-mysql-210 {
   SELECT round(ln(2),7), quote(ln(-2));
} {0.6931472 NULL}
#do_execsql_test func7-mysql-220 {
#   SELECT round(log(2),7), log(-2);
#} {0.6931472 NULL}
# log() means natural logarithm in MySQL
do_execsql_test func7-mysql-230 {
   SELECT log(2,65536), log(10,100), quote(log(1,100)), quote(log(0,100));
} {16.0 2.0 NULL NULL}
do_execsql_test func7-mysql-240 {
   SELECT log2(65536), quote(log2(-100)), quote(log2(0));
} {16.0 NULL NULL}
do_execsql_test func7-mysql-250 {
   SELECT round(log10(2),7), log10(100), quote(log10(-100));
} {0.30103 2.0 NULL}
do_execsql_test func7-mysql-260 {
   SELECT mod(234,10), 253%7, mod(29,9), 29%9;
} {4.0 1 2.0 2}
do_execsql_test func7-mysql-270 {
   SELECT mod(34.5,3);
} {1.5}
do_execsql_test func7-mysql-280 {
   SELECT pow(2,2), pow(2,-2);
} {4.0 0.25}
do_execsql_test func7-mysql-281 {
   SELECT power(2,2), power(2,-2);
} {4.0 0.25}
do_execsql_test func7-mysql-290 {
   SELECT round(radians(90),7);
} {1.5707963}
do_execsql_test func7-mysql-300 {
   SELECT sign(-32), sign(0), sign(234);
} {-1 0 1}
do_execsql_test func7-mysql-310 {
   SELECT sin(pi()) BETWEEN -1.0e-15 AND 1.0e-15;
} {1}
do_execsql_test func7-mysql-320 {
   SELECT sqrt(4), round(sqrt(20),7), quote(sqrt(-16));
} {2.0 4.472136 NULL}
do_execsql_test func7-mysql-330 {
   SELECT tan(pi()) BETWEEN -1.0e-15 AND 1.0e-15;
} {1}
do_execsql_test func7-mysql-331 {
   SELECT round(tan(pi()+1),7);
} {1.5574077}


finish_test
Changes to test/fuzzcheck.c.
451
452
453
454
455
456
457
458





459
460
461
462
463
464
465
  while( p ){
    pNext = p->pNext;
    free(p);
    p = pNext;
  }
}

/* Return the current wall-clock time */





static sqlite3_int64 timeOfDay(void){
  static sqlite3_vfs *clockVfs = 0;
  sqlite3_int64 t;
  if( clockVfs==0 ){
    clockVfs = sqlite3_vfs_find(0);
    if( clockVfs==0 ) return 0;
  }







|
>
>
>
>
>







451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
  while( p ){
    pNext = p->pNext;
    free(p);
    p = pNext;
  }
}

/* Return the current wall-clock time
**
** The number of milliseconds since the julian epoch.
** 1907-01-01 00:00:00  ->  210866716800000
** 2021-01-01 00:00:00  ->  212476176000000
*/
static sqlite3_int64 timeOfDay(void){
  static sqlite3_vfs *clockVfs = 0;
  sqlite3_int64 t;
  if( clockVfs==0 ){
    clockVfs = sqlite3_vfs_find(0);
    if( clockVfs==0 ) return 0;
  }
709
710
711
712
713
714
715

716
717
718
719
720
721
722
** stop.  So return non-zero if the cut-off time is exceeded.
*/
static int progress_handler(void *pClientData) {
  FuzzCtx *p = (FuzzCtx*)pClientData;
  sqlite3_int64 iNow = timeOfDay();
  int rc = iNow>=p->iCutoffTime;
  sqlite3_int64 iDiff = iNow - p->iLastCb;

  if( iDiff > p->mxInterval ) p->mxInterval = iDiff;
  p->nCb++;
  if( rc==0 && p->mxCb>0 && p->mxCb<=p->nCb ) rc = 1;
  if( rc && !p->timeoutHit && eVerbosity>=2 ){
    printf("Timeout on progress callback %d\n", p->nCb);
    fflush(stdout);
    p->timeoutHit = 1;







>







714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
** stop.  So return non-zero if the cut-off time is exceeded.
*/
static int progress_handler(void *pClientData) {
  FuzzCtx *p = (FuzzCtx*)pClientData;
  sqlite3_int64 iNow = timeOfDay();
  int rc = iNow>=p->iCutoffTime;
  sqlite3_int64 iDiff = iNow - p->iLastCb;
  /* printf("time-remaining: %lld\n", p->iCutoffTime - iNow); */
  if( iDiff > p->mxInterval ) p->mxInterval = iDiff;
  p->nCb++;
  if( rc==0 && p->mxCb>0 && p->mxCb<=p->nCb ) rc = 1;
  if( rc && !p->timeoutHit && eVerbosity>=2 ){
    printf("Timeout on progress callback %d\n", p->nCb);
    fflush(stdout);
    p->timeoutHit = 1;
749
750
751
752
753
754
755
756
757
758

759
760
761
762
763
764
765
     || sqlite3_stricmp("temp_store_directory", zArg1)==0
    ){
      return SQLITE_DENY;
    }
    if( sqlite3_stricmp("oom",zArg1)==0 && zArg2!=0 && zArg2[0]!=0 ){
      oomCounter = atoi(zArg2);
    }
  }else if( (eCode==SQLITE_ATTACH || eCode==SQLITE_DETACH)
            && zArg1 && zArg1[0] ){
    return SQLITE_DENY;

  }
  return SQLITE_OK;
}

/*
** Run the SQL text
*/







|
|
|
>







755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
     || sqlite3_stricmp("temp_store_directory", zArg1)==0
    ){
      return SQLITE_DENY;
    }
    if( sqlite3_stricmp("oom",zArg1)==0 && zArg2!=0 && zArg2[0]!=0 ){
      oomCounter = atoi(zArg2);
    }
  }else if( eCode==SQLITE_ATTACH ){
    if( zArg1==0 || (zArg1[0]!=0 && strcmp(zArg1,":memory:")!=0) ){
      return SQLITE_DENY;
    }
  }
  return SQLITE_OK;
}

/*
** Run the SQL text
*/
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
    printf("SQL-ERROR (%d): %s\n", rc, sqlite3_errmsg(db));
    fflush(stdout);    
  } /* End if( SQLITE_OK ) */
  return sqlite3_finalize(pStmt);
}

/* Invoke this routine to run a single test case */
int runCombinedDbSqlInput(const uint8_t *aData, size_t nByte){
  int rc;                    /* SQLite API return value */
  int iSql;                  /* Index in aData[] of start of SQL */
  unsigned char *aDb = 0;    /* Decoded database content */
  int nDb = 0;               /* Size of the decoded database */
  int i;                     /* Loop counter */
  int j;                     /* Start of current SQL statement */
  char *zSql = 0;            /* SQL text to run */







|







838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
    printf("SQL-ERROR (%d): %s\n", rc, sqlite3_errmsg(db));
    fflush(stdout);    
  } /* End if( SQLITE_OK ) */
  return sqlite3_finalize(pStmt);
}

/* Invoke this routine to run a single test case */
int runCombinedDbSqlInput(const uint8_t *aData, size_t nByte, int iTimeout){
  int rc;                    /* SQLite API return value */
  int iSql;                  /* Index in aData[] of start of SQL */
  unsigned char *aDb = 0;    /* Decoded database content */
  int nDb = 0;               /* Size of the decoded database */
  int i;                     /* Loop counter */
  int j;                     /* Start of current SQL statement */
  char *zSql = 0;            /* SQL text to run */
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892

  /* Invoke the progress handler frequently to check to see if we
  ** are taking too long.  The progress handler will return true
  ** (which will block further processing) if more than giTimeout seconds have
  ** elapsed since the start of the test.
  */
  cx.iLastCb = timeOfDay();
  cx.iCutoffTime = cx.iLastCb + giTimeout;  /* Now + giTimeout seconds */
  cx.mxCb = mxProgressCb;
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  sqlite3_progress_handler(cx.db, 10, progress_handler, (void*)&cx);
#endif

  /* Set a limit on the maximum size of a prepared statement, and the
  ** maximum length of a string or blob */







|







885
886
887
888
889
890
891
892
893
894
895
896
897
898
899

  /* Invoke the progress handler frequently to check to see if we
  ** are taking too long.  The progress handler will return true
  ** (which will block further processing) if more than giTimeout seconds have
  ** elapsed since the start of the test.
  */
  cx.iLastCb = timeOfDay();
  cx.iCutoffTime = cx.iLastCb + (iTimeout<giTimeout ? iTimeout : giTimeout);
  cx.mxCb = mxProgressCb;
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  sqlite3_progress_handler(cx.db, 10, progress_handler, (void*)&cx);
#endif

  /* Set a limit on the maximum size of a prepared statement, and the
  ** maximum length of a string or blob */
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
"  --prng-seed N        Seed value for the PRGN inside of SQLite\n"
"  -q|--quiet           Reduced output\n"
"  --rebuild            Rebuild and vacuum the database file\n"
"  --result-trace       Show the results of each SQL command\n"
"  --skip N             Skip the first N test cases\n"
"  --spinner            Use a spinner to show progress\n"
"  --sqlid N            Use only SQL where sqlid=N\n"
"  --timeout N          Abort if any single test needs more than N seconds\n"
"  -v|--verbose         Increased output.  Repeat for more output.\n"
"  --vdbe-debug         Activate VDBE debugging.\n"
  );
}

int main(int argc, char **argv){
  sqlite3_int64 iBegin;        /* Start time of this program */







|







1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
"  --prng-seed N        Seed value for the PRGN inside of SQLite\n"
"  -q|--quiet           Reduced output\n"
"  --rebuild            Rebuild and vacuum the database file\n"
"  --result-trace       Show the results of each SQL command\n"
"  --skip N             Skip the first N test cases\n"
"  --spinner            Use a spinner to show progress\n"
"  --sqlid N            Use only SQL where sqlid=N\n"
"  --timeout N          Maximum time for any one test in N millseconds\n"
"  -v|--verbose         Increased output.  Repeat for more output.\n"
"  --vdbe-debug         Activate VDBE debugging.\n"
  );
}

int main(int argc, char **argv){
  sqlite3_int64 iBegin;        /* Start time of this program */
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
  char **azSrcDb = 0;          /* Array of source database names */
  int iSrcDb;                  /* Loop over all source databases */
  int nTest = 0;               /* Total number of tests performed */
  char *zDbName = "";          /* Appreviated name of a source database */
  const char *zFailCode = 0;   /* Value of the TEST_FAILURE env variable */
  int cellSzCkFlag = 0;        /* --cell-size-check */
  int sqlFuzz = 0;             /* True for SQL fuzz. False for DB fuzz */
  int iTimeout = 120;          /* Default 120-second timeout */
  int nMem = 0;                /* Memory limit override */
  int nMemThisDb = 0;          /* Memory limit set by the CONFIG table */
  char *zExpDb = 0;            /* Write Databases to files in this directory */
  char *zExpSql = 0;           /* Write SQL to files in this directory */
  void *pHeap = 0;             /* Heap for use by SQLite */
  int ossFuzz = 0;             /* enable OSS-FUZZ testing */
  int ossFuzzThisDb = 0;       /* ossFuzz value for this particular database */
  int nativeMalloc = 0;        /* Turn off MEMSYS3/5 and lookaside if true */
  sqlite3_vfs *pDfltVfs;       /* The default VFS */
  int openFlags4Data;          /* Flags for sqlite3_open_v2() */

  int nV;                      /* How much to increase verbosity with -vvvv */


  registerOomSimulator();
  sqlite3_initialize();
  iBegin = timeOfDay();
#ifdef __unix__
  signal(SIGALRM, signalHandler);
  signal(SIGSEGV, signalHandler);







|










>

>







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
  char **azSrcDb = 0;          /* Array of source database names */
  int iSrcDb;                  /* Loop over all source databases */
  int nTest = 0;               /* Total number of tests performed */
  char *zDbName = "";          /* Appreviated name of a source database */
  const char *zFailCode = 0;   /* Value of the TEST_FAILURE env variable */
  int cellSzCkFlag = 0;        /* --cell-size-check */
  int sqlFuzz = 0;             /* True for SQL fuzz. False for DB fuzz */
  int iTimeout = 120000;       /* Default 120-second timeout */
  int nMem = 0;                /* Memory limit override */
  int nMemThisDb = 0;          /* Memory limit set by the CONFIG table */
  char *zExpDb = 0;            /* Write Databases to files in this directory */
  char *zExpSql = 0;           /* Write SQL to files in this directory */
  void *pHeap = 0;             /* Heap for use by SQLite */
  int ossFuzz = 0;             /* enable OSS-FUZZ testing */
  int ossFuzzThisDb = 0;       /* ossFuzz value for this particular database */
  int nativeMalloc = 0;        /* Turn off MEMSYS3/5 and lookaside if true */
  sqlite3_vfs *pDfltVfs;       /* The default VFS */
  int openFlags4Data;          /* Flags for sqlite3_open_v2() */
  int bTimer = 0;              /* Show elapse time for each test */
  int nV;                      /* How much to increase verbosity with -vvvv */
  sqlite3_int64 tmStart;       /* Start of each test */

  registerOomSimulator();
  sqlite3_initialize();
  iBegin = timeOfDay();
#ifdef __unix__
  signal(SIGALRM, signalHandler);
  signal(SIGSEGV, signalHandler);
1592
1593
1594
1595
1596
1597
1598



1599
1600
1601
1602
1603
1604
1605
      }else
      if( strcmp(z,"skip")==0 ){
        if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
        nSkip = atoi(argv[++i]);
      }else
      if( strcmp(z,"spinner")==0 ){
        bSpinner = 1;



      }else
      if( strcmp(z,"sqlid")==0 ){
        if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
        onlySqlid = integerValue(argv[++i]);
      }else
      if( strcmp(z,"timeout")==0 ){
        if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);







>
>
>







1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
      }else
      if( strcmp(z,"skip")==0 ){
        if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
        nSkip = atoi(argv[++i]);
      }else
      if( strcmp(z,"spinner")==0 ){
        bSpinner = 1;
      }else
      if( strcmp(z,"timer")==0 ){
        bTimer = 1;
      }else
      if( strcmp(z,"sqlid")==0 ){
        if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
        onlySqlid = integerValue(argv[++i]);
      }else
      if( strcmp(z,"timeout")==0 ){
        if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
1890
1891
1892
1893
1894
1895
1896

1897
1898
1899
1900
1901
1902
1903
    /* Reset the in-memory virtual filesystem */
    formatVfs();
    
    /* Run a test using each SQL script against each database.
    */
    if( !verboseFlag && !quietFlag && !bSpinner ) printf("%s:", zDbName);
    for(pSql=g.pFirstSql; pSql; pSql=pSql->pNext){

      if( isDbSql(pSql->a, pSql->sz) ){
        sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d",pSql->id);
        if( bSpinner ){
          int nTotal =g.nSql;
          int idx = pSql->seq;
          printf("\r%s: %d/%d   ", zDbName, idx, nTotal);
          fflush(stdout);







>







1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
    /* Reset the in-memory virtual filesystem */
    formatVfs();
    
    /* Run a test using each SQL script against each database.
    */
    if( !verboseFlag && !quietFlag && !bSpinner ) printf("%s:", zDbName);
    for(pSql=g.pFirstSql; pSql; pSql=pSql->pNext){
      tmStart = timeOfDay();
      if( isDbSql(pSql->a, pSql->sz) ){
        sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d",pSql->id);
        if( bSpinner ){
          int nTotal =g.nSql;
          int idx = pSql->seq;
          printf("\r%s: %d/%d   ", zDbName, idx, nTotal);
          fflush(stdout);
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922




1923
1924
1925
1926
1927
1928
1929
            fflush(stdout);
            prevAmt = amt;
          }
        }
        if( nSkip>0 ){
          nSkip--;
        }else{
          runCombinedDbSqlInput(pSql->a, pSql->sz);
        }
        nTest++;




        g.zTestName[0] = 0;
        disableOom();
        continue;
      }
      for(pDb=g.pFirstDb; pDb; pDb=pDb->pNext){
        int openFlags;
        const char *zVfs = "inmem";







|


>
>
>
>







1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
            fflush(stdout);
            prevAmt = amt;
          }
        }
        if( nSkip>0 ){
          nSkip--;
        }else{
          runCombinedDbSqlInput(pSql->a, pSql->sz, iTimeout);
        }
        nTest++;
        if( bTimer ){
          sqlite3_int64 tmEnd = timeOfDay();
          printf("%lld %s\n", tmEnd - tmStart, g.zTestName);
        }
        g.zTestName[0] = 0;
        disableOom();
        continue;
      }
      for(pDb=g.pFirstDb; pDb; pDb=pDb->pNext){
        int openFlags;
        const char *zVfs = "inmem";
1968
1969
1970
1971
1972
1973
1974
1975


1976
1977
1978
1979
1980
1981
1982
            zVfs = 0;
          }
          rc = sqlite3_open_v2("main.db", &db, openFlags, zVfs);
          if( rc ) fatalError("cannot open inmem database");
          sqlite3_limit(db, SQLITE_LIMIT_LENGTH, 100000000);
          sqlite3_limit(db, SQLITE_LIMIT_LIKE_PATTERN_LENGTH, 50);
          if( cellSzCkFlag ) runSql(db, "PRAGMA cell_size_check=ON", runFlags);
          setAlarm(iTimeout);


#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
          if( sqlFuzz || vdbeLimitFlag ){
            sqlite3_progress_handler(db, 100000, progressHandler,
                                     &vdbeLimitFlag);
          }
#endif
#ifdef SQLITE_TESTCTRL_PRNG_SEED







|
>
>







1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
            zVfs = 0;
          }
          rc = sqlite3_open_v2("main.db", &db, openFlags, zVfs);
          if( rc ) fatalError("cannot open inmem database");
          sqlite3_limit(db, SQLITE_LIMIT_LENGTH, 100000000);
          sqlite3_limit(db, SQLITE_LIMIT_LIKE_PATTERN_LENGTH, 50);
          if( cellSzCkFlag ) runSql(db, "PRAGMA cell_size_check=ON", runFlags);
          setAlarm((iTimeout+999)/1000);
          /* Enable test functions */
          sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, db);
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
          if( sqlFuzz || vdbeLimitFlag ){
            sqlite3_progress_handler(db, 100000, progressHandler,
                                     &vdbeLimitFlag);
          }
#endif
#ifdef SQLITE_TESTCTRL_PRNG_SEED
1994
1995
1996
1997
1998
1999
2000




2001
2002
2003
2004
2005
2006
2007
        }
        if( sqlite3_memory_used()>0 ){
           fatalError("memory leak: %lld bytes outstanding",
                      sqlite3_memory_used());
        }
        reformatVfs();
        nTest++;




        g.zTestName[0] = 0;

        /* Simulate an error if the TEST_FAILURE environment variable is "5".
        ** This is used to verify that automated test script really do spot
        ** errors that occur in this test program.
        */
        if( zFailCode ){







>
>
>
>







2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
        }
        if( sqlite3_memory_used()>0 ){
           fatalError("memory leak: %lld bytes outstanding",
                      sqlite3_memory_used());
        }
        reformatVfs();
        nTest++;
        if( bTimer ){
          sqlite3_int64 tmEnd = timeOfDay();
          printf("%lld %s\n", tmEnd - tmStart, g.zTestName);
        }
        g.zTestName[0] = 0;

        /* Simulate an error if the TEST_FAILURE environment variable is "5".
        ** This is used to verify that automated test script really do spot
        ** errors that occur in this test program.
        */
        if( zFailCode ){
Changes to test/fuzzdata8.db.

cannot compute difference between binary files

Changes to test/fuzzerfault.test.
84
85
86
87
88
89
90



















91
92
    CREATE VIRTUAL TABLE x1 USING fuzzer(x1_rules);
    SELECT count(*) FROM (SELECT * FROM x1 WHERE word MATCH 'a' LIMIT 2);
  }
} -test {
  faultsim_test_result {0 2} {1 {vtable constructor failed: x1}}
}





















finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


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
    CREATE VIRTUAL TABLE x1 USING fuzzer(x1_rules);
    SELECT count(*) FROM (SELECT * FROM x1 WHERE word MATCH 'a' LIMIT 2);
  }
} -test {
  faultsim_test_result {0 2} {1 {vtable constructor failed: x1}}
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 4.0 {
  CREATE TABLE t1_a(a INTEFDR PRIMARY KEY, b TEXT);
  CREATE TABLE t3_a(k FnTEGER PRIMARY KEY, v TEXT);
  CREATE TABLE t3_b(k INTEÀ5R PRIMARY KEY, v TEXT);
  CREATE VIEW t3 AS SELECT * FROM t3_a UNION ALL SELECT * FROM t3_b;
}
faultsim_save_and_close

do_faultsim_test 4 -faults oom-t* -prep {
  faultsim_restore_and_reopen
} -body {
  execsql { 
    SELECT 1 FROM t1_a LEFT JOIN t3 ON ((1+1) AND k=1)
  }
} -test {
  faultsim_test_result {0 {}} 
}

finish_test
Changes to test/having.test.
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

  2 "SELECT a, sum(b) FROM t1 GROUP BY a HAVING sum(b)>5 AND a=2"
    "SELECT a, sum(b) FROM t1 WHERE a=2 GROUP BY a HAVING sum(b)>5"

  3 "SELECT a, sum(b) FROM t1 GROUP BY a COLLATE binary HAVING a=2"
    "SELECT a, sum(b) FROM t1 WHERE a=2 GROUP BY a COLLATE binary"

  5 "SELECT a, sum(b) FROM t1 GROUP BY a COLLATE binary HAVING 0"
    "SELECT a, sum(b) FROM t1 WHERE 0 GROUP BY a COLLATE binary"

  6 "SELECT count(*) FROM t1,t2 WHERE a=c GROUP BY b, d HAVING b=d"
    "SELECT count(*) FROM t1,t2 WHERE a=c AND b=d GROUP BY b, d"

  7 {
      SELECT count(*) FROM t1,t2 WHERE a=c GROUP BY b, d 
      HAVING b=d COLLATE nocase







|
|







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

  2 "SELECT a, sum(b) FROM t1 GROUP BY a HAVING sum(b)>5 AND a=2"
    "SELECT a, sum(b) FROM t1 WHERE a=2 GROUP BY a HAVING sum(b)>5"

  3 "SELECT a, sum(b) FROM t1 GROUP BY a COLLATE binary HAVING a=2"
    "SELECT a, sum(b) FROM t1 WHERE a=2 GROUP BY a COLLATE binary"

  5 "SELECT a, sum(b) FROM t1 GROUP BY a COLLATE binary HAVING 1"
    "SELECT a, sum(b) FROM t1 WHERE 1 GROUP BY a COLLATE binary"

  6 "SELECT count(*) FROM t1,t2 WHERE a=c GROUP BY b, d HAVING b=d"
    "SELECT count(*) FROM t1,t2 WHERE a=c AND b=d GROUP BY b, d"

  7 {
      SELECT count(*) FROM t1,t2 WHERE a=c GROUP BY b, d 
      HAVING b=d COLLATE nocase
150
151
152
153
154
155
156






157



























158
# result as the following. But it does not.
#
set ::nondeter_ret 0
do_execsql_test 4.3 {
  SELECT a, sum(b) FROM t3 WHERE nondeter(a) GROUP BY a
} {1 4 2 2}



































finish_test







>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

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
# result as the following. But it does not.
#
set ::nondeter_ret 0
do_execsql_test 4.3 {
  SELECT a, sum(b) FROM t3 WHERE nondeter(a) GROUP BY a
} {1 4 2 2}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 5.0 {
  CREATE TABLE t1(a, b);
  CREATE TABLE t2(x, y);
  INSERT INTO t1 VALUES('a', 'b');
}

# The WHERE clause (a=2), uses an aggregate column from the outer query.
# If the HAVING term (0) is moved into the WHERE clause in this case,
# SQLite would at one point optimize (a=2 AND 0) to simply (0). Which
# is logically correct, but happened to cause problems in aggregate
# processing for the outer query. This test case verifies that those 
# problems are no longer present.
do_execsql_test 5.1 {
  SELECT min(b), (
    SELECT x FROM t2 WHERE a=2 GROUP BY y HAVING 0
  ) FROM t1;
} {b {}}

# From chromium
# https://bugs.chromium.org/p/chromium/issues/detail?id=1161869
#
do_execsql_test 5.2 {
  SELECT EXISTS (
    SELECT * FROM (
      SELECT * FROM (
        SELECT 1
      ) WHERE Col0 = 1   GROUP BY 1
    )   WHERE 0
  )
  FROM (SELECT 1 Col0)   GROUP BY 1
} {0}

finish_test
Changes to test/hook.test.
952
953
954
955
956
957
958



959






















































960

    preupdate {DELETE main sqlite_stat1 1 1}
    preupdate {DELETE main sqlite_stat1 2 2}
    preupdate {INSERT main sqlite_stat1 1 1}
    preupdate {INSERT main sqlite_stat1 2 2}
  }]
}



























































finish_test








>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
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
    preupdate {DELETE main sqlite_stat1 1 1}
    preupdate {DELETE main sqlite_stat1 2 2}
    preupdate {INSERT main sqlite_stat1 1 1}
    preupdate {INSERT main sqlite_stat1 2 2}
  }]
}

#-------------------------------------------------------------------------
# Test that the pre-update hook is fired for INSERT statements that use
# the xfer optimization on without rowid tables.
#
reset_db
do_execsql_test 12.1 {
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
  CREATE TABLE t2(a INTEGER PRIMARY KEY, b) WITHOUT ROWID;

  INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t1 VALUES(3, 4);
  INSERT INTO t2 VALUES(5, 6);
  INSERT INTO t2 VALUES(7, 8);

  CREATE TABLE t3 (a INTEGER PRIMARY KEY, b) WITHOUT ROWID;
}

db preupdate hook preupdate_cb
db update_hook update_cb

proc preupdate_cb {args} { lappend ::res "preupdate" $args }
proc update_cb {args} { lappend ::res "update" $args }

set ::res [list]
do_test 12.2 {
  execsql VACUUM
  set ::res
} {}

do_test 12.3 {
  set ::res [list]
  execsql { INSERT INTO t3 SELECT a, b FROM t2 }
  set ::res
} {preupdate {INSERT main t3 0 0} preupdate {INSERT main t3 0 0}}

do_test 12.4 {
  execsql { DELETE FROM t3 }
  set ::res [list]
  execsql { INSERT INTO t3 SELECT * FROM t2 }
  set ::res
} {preupdate {INSERT main t3 0 0} preupdate {INSERT main t3 0 0}}

do_execsql_test 12.5 {
  CREATE TABLE t4(a COLLATE nocase PRIMARY KEY, b) WITHOUT ROWID;
  INSERT INTO t4 VALUES('abc', 1);
  INSERT INTO t4 VALUES('DEF', 2);
}

set ::res [list]
do_test 12.6 {
  execsql VACUUM
  set ::res
} {}

do_catchsql_test 12.6 {
  INSERT INTO t4 VALUES('def', 3);
} {1 {UNIQUE constraint failed: t4.a}}

finish_test

Changes to test/in4.test.
360
361
362
363
364
365
366




























367
368
    INSERT INTO t2(e) VALUES(1);
  }

  do_execsql_test 7.3 {
    SELECT * FROM t2 LEFT JOIN t1 ON c IN (d) AND b IN (10,10,10);
  } {{} 1 {} {} {}}
}





























finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


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
    INSERT INTO t2(e) VALUES(1);
  }

  do_execsql_test 7.3 {
    SELECT * FROM t2 LEFT JOIN t1 ON c IN (d) AND b IN (10,10,10);
  } {{} 1 {} {} {}}
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 8.0 {
  CREATE TABLE t1(x INTEGER PRIMARY KEY, y);
  CREATE UNIQUE INDEX t1y ON t1(y);
  INSERT INTO t1 VALUES(111, 'AAA'),(222, 'BBB'),(333, 'CCC');
  CREATE TABLE t2(z);
  INSERT INTO t2 VALUES('BBB'),('AAA');
  ANALYZE sqlite_schema;
  INSERT INTO sqlite_stat1 VALUES('t1', 't1y','100 1');
}

db close
sqlite3 db test.db

do_execsql_test 8.1 {
  SELECT t1.x FROM t2 CROSS JOIN t1 WHERE t2.z = t1.y;
} {222 111}

do_execsql_test 8.2 {
  SELECT t1.x FROM t2 CROSS JOIN t1 WHERE t2.z = t1.y AND +t1.x IN (111, 222);
} {222 111}

do_execsql_test 8.3 {
  SELECT t1.x FROM t2 CROSS JOIN t1 WHERE t2.z = t1.y AND t1.x IN (111, 222);
} {222 111}


finish_test
Changes to test/like.test.
1126
1127
1128
1129
1130
1131
1132







1133
1134
    (4,'abc%'),
    (5,'abc%%');
  SELECT id FROM t1 WHERE x LIKE 'abc%%' ESCAPE '%';
} {4}
do_execsql_test 17.1 {
  SELECT id FROM t1 WHERE x LIKE 'abc__' ESCAPE '_';
} {2}








finish_test







>
>
>
>
>
>
>


1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
    (4,'abc%'),
    (5,'abc%%');
  SELECT id FROM t1 WHERE x LIKE 'abc%%' ESCAPE '%';
} {4}
do_execsql_test 17.1 {
  SELECT id FROM t1 WHERE x LIKE 'abc__' ESCAPE '_';
} {2}

# 2021-02-15 ticket c0aeea67d58ae0fd
#
do_execsql_test 17.1 {
  SELECT 'x' LIKE '%' ESCAPE '_';
} {1}


finish_test
Changes to test/limit.test.
637
638
639
640
641
642
643























644
645
do_execsql_test limit-14.6 {
  SELECT 123 LIMIT -1 OFFSET 0
} {123}
do_execsql_test limit-14.7 {
  SELECT 123 LIMIT -1 OFFSET 1
} {}

























finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


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
do_execsql_test limit-14.6 {
  SELECT 123 LIMIT -1 OFFSET 0
} {123}
do_execsql_test limit-14.7 {
  SELECT 123 LIMIT -1 OFFSET 1
} {}

# 2021-03-05 dbsqlfuzz crash-d811039c9f44f2d43199d5889fcf4085ef6221b9
#
reset_db
do_execsql_test limit-15.1 {
  CREATE TABLE t1(a PRIMARY KEY, b TEXT);
  CREATE TABLE t4(c PRIMARY KEY, d);
  CREATE TABLE t5(e PRIMARY KEY, f);
  CREATE TABLE t6(g, h);
  CREATE TABLE t3_a(k, v);
  CREATE TABLE t3_b(k, v);
  CREATE VIEW t3 AS SELECT * FROM t3_a UNION ALL SELECT * FROM t3_b;
  INSERT INTO t5(e,f) VALUES(500000,'orange');
  INSERT INTO t4(c,d) VALUES(300000,'blue'),(400,'green'),(8000,'grey');
  INSERT INTO t1(a,b) VALUES(300000,'purple');
  INSERT INTO t3_a VALUES(300000,'yellow'),(500,'pink'),(8000,'red');
  INSERT INTO t6 default values;
  SELECT (
      SELECT 100000 FROM
          (SELECT 200000 FROM t6 WHERE a = ( SELECT 300000 FROM t3 WHERE a ) ),
          (SELECT 400000 FROM t5 WHERE e=500000),
          (SELECT 600000 FROM t4 WHERE c=a)
  ) FROM t1;
} {100000}

finish_test
Added test/notnull2.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
# 2021 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 implements regression tests for SQLite library.  The
# focus of this file is testing optimizations associated with "IS NULL"
# and "IS NOT NULL" operators on columns with NOT NULL constraints.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix notnull2

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b);
  CREATE TABLE t2(c, d NOT NULL);

  WITH x(i) AS (
    SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<1000
  )
  INSERT INTO t1 SELECT i, i FROM x;
  INSERT INTO t2 SELECT * FROM t1;
}

proc do_vmstep_test {tn sql nstep {res {}}} {
  uplevel [list do_execsql_test $tn.0 $sql $res]

  set vmstep [db status vmstep]
  if {[string range $nstep 0 0]=="+"} {
    set body "if {$vmstep<$nstep} {
      error \"got $vmstep, expected more than [string range $nstep 1 end]\"
    }"
  } else {
    set body "if {$vmstep>$nstep} {
      error \"got $vmstep, expected less than $nstep\"
    }"
  }

  # set name "$tn.vmstep=$vmstep,expect=$nstep"
  set name "$tn.1"
  uplevel [list do_test $name $body {}]
}

do_vmstep_test 1.1.1 {
  SELECT * FROM t1 LEFT JOIN t2 WHERE a=c AND d IS NULL;
} 100 {}
do_vmstep_test 1.1.2 {
  SELECT * FROM t1 LEFT JOIN t2 WHERE a=c AND c IS NULL;
} +1000 {}

do_vmstep_test 1.2.1 {
  SELECT * FROM ( SELECT * FROM t2 ) WHERE d IS NULL
} 100 {}
do_vmstep_test 1.2.2 {
  SELECT * FROM ( SELECT * FROM t2 ) WHERE c IS NULL
} +1000 {}

do_vmstep_test 1.3.1 {
  SELECT * FROM t2 WHERE d IS NULL
} 100 {}
do_vmstep_test 1.3.2 {
  SELECT * FROM t2 WHERE c IS NULL
} +1000 {}

do_vmstep_test 1.4.1 {
  SELECT (d IS NOT NULL) FROM t2 WHERE 0==( d IS NOT NULL )
} 100 {}
do_vmstep_test 1.4.2 {
  SELECT * FROM t2 WHERE 0==( c IS NOT NULL )
} +1000 {}

do_vmstep_test 1.5.1 {
  SELECT count(*) FROM t2 WHERE EXISTS(
    SELECT t2.d IS NULL FROM t1 WHERE t1.a=450
  )
} 10000 {1000}
do_vmstep_test 1.5.2 {
  SELECT count(*) FROM t2 WHERE EXISTS(
    SELECT t2.c IS NULL FROM t1 WHERE t1.a=450
  )
} +100000 {1000}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
  CREATE TABLE T1(a INTEGER PRIMARY KEY, b);
  CREATE TABLE T3(k, v);
}

do_execsql_test 2.1 {
  SELECT * FROM (SELECT a, b FROM t1) LEFT JOIN t3 ON a IS NULL;
}

finish_test

Added test/notnullfault.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
# 2021 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 implements regression tests for SQLite library.  The
# focus of this file is testing optimizations associated with "IS NULL"
# and "IS NOT NULL" operators on columns with NOT NULL constraints.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix notnullfault

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b);
  CREATE TABLE t2(c, d NOT NULL);
}
faultsim_save_and_close

do_faultsim_test 1 -prep {
  faultsim_restore_and_reopen
} -body {
  execsql {
    SELECT * FROM t2 WHERE d NOT NULL
  }
} -test {
  faultsim_test_result {0 {}}
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
  CREATE TABLE t1(a, b, c); 
  CREATE TABLE t2(a, b, c, PRIMARY KEY(a, b, c)) WITHOUT ROWID;
}
faultsim_save_and_close

do_faultsim_test 2.1 -faults oom-t* -prep {
  faultsim_restore_and_reopen
} -body {
  execsql {
    SELECT dense_rank() OVER win FROM t2
    WINDOW win AS (ORDER BY c IS NULL)
  }
} -test {
  faultsim_test_result {0 {}}
}

finish_test

Changes to test/permutations.test.
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
  unregister_jt_vfs
} -files [test_set $::allquicktests -exclude {
  wal* incrvacuum.test ioerr.test corrupt4.test io.test crash8.test 
  async4.test bigfile.test backcompat.test e_wal* fstat.test mmap2.test
  pager1.test syscall.test tkt3457.test *malloc* mmap* multiplex* nolock*
  pager2.test *fault* rowal* snapshot* superlock* symlink.test
  delete_db.test shmlock.test chunksize.test
  busy2.test
}]

if {[info commands register_demovfs] != ""} {
  test_suite "demovfs" -description {
    Check that the demovfs (code in test_demovfs.c) more or less works.
  } -initialize {
    register_demovfs







|







985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
  unregister_jt_vfs
} -files [test_set $::allquicktests -exclude {
  wal* incrvacuum.test ioerr.test corrupt4.test io.test crash8.test 
  async4.test bigfile.test backcompat.test e_wal* fstat.test mmap2.test
  pager1.test syscall.test tkt3457.test *malloc* mmap* multiplex* nolock*
  pager2.test *fault* rowal* snapshot* superlock* symlink.test
  delete_db.test shmlock.test chunksize.test
  busy2.test avfs.test
}]

if {[info commands register_demovfs] != ""} {
  test_suite "demovfs" -description {
    Check that the demovfs (code in test_demovfs.c) more or less works.
  } -initialize {
    register_demovfs
1058
1059
1060
1061
1062
1063
1064
1065

1066
1067
1068
1069
1070
1071
1072
} -files [
  test_set \
    [glob -nocomplain $::testdir/window*.test]                       \
    where.test where2.test where3.test where4.test where5.test       \
    where6.test where7.test where8.test where9.test                  \
    whereA.test whereB.test wherelimit.test                          \
    select1.test select2.test select3.test select4.test select5.test \
    select7.test select8.test selectA.test selectC.test     

] -dbconfig {
  optimization_control $::dbhandle all 0
}

test_suite "prepare" -description {
  Run tests with the db connection using sqlite3_prepare() instead of _v2().
} -dbconfig {







|
>







1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
} -files [
  test_set \
    [glob -nocomplain $::testdir/window*.test]                       \
    where.test where2.test where3.test where4.test where5.test       \
    where6.test where7.test where8.test where9.test                  \
    whereA.test whereB.test wherelimit.test                          \
    select1.test select2.test select3.test select4.test select5.test \
    select7.test select8.test selectA.test selectC.test              \
    -exclude windowpushd.test
] -dbconfig {
  optimization_control $::dbhandle all 0
}

test_suite "prepare" -description {
  Run tests with the db connection using sqlite3_prepare() instead of _v2().
} -dbconfig {
1133
1134
1135
1136
1137
1138
1139
1140
1141











1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
  set ::G(perm:name)         $name
  set ::G(perm:prefix)       $options(-prefix)
  set ::G(isquick)           1
  set ::G(perm:dbconfig)     $options(-dbconfig)
  set ::G(perm:presql)       $options(-presql)

  foreach file [lsort $options(-files)] {
    uplevel $options(-initialize)
    if {[file tail $file] == $file} { set file [file join $::testdir $file] }











    slave_test_file $file
    uplevel $options(-shutdown)

    unset -nocomplain ::G(perm:sqlite3_args)
  }

  unset ::G(perm:name)
  unset ::G(perm:prefix)
  unset ::G(perm:dbconfig)
  unset ::G(perm:presql)







<

>
>
>
>
>
>
>
>
>
>
>


<







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
  set ::G(perm:name)         $name
  set ::G(perm:prefix)       $options(-prefix)
  set ::G(isquick)           1
  set ::G(perm:dbconfig)     $options(-dbconfig)
  set ::G(perm:presql)       $options(-presql)

  foreach file [lsort $options(-files)] {

    if {[file tail $file] == $file} { set file [file join $::testdir $file] }

    if {[info exists ::env(SQLITE_TEST_PATTERN_LIST)]} {
      set ok 0
      foreach p $::env(SQLITE_TEST_PATTERN_LIST) {
        set p [string map {% *} $p]
        if {[string match $p [file tail $file]]} {set ok 1 ; break}
      }
      if {!$ok} continue
    }

    uplevel $options(-initialize)
    slave_test_file $file
    uplevel $options(-shutdown)

    unset -nocomplain ::G(perm:sqlite3_args)
  }

  unset ::G(perm:name)
  unset ::G(perm:prefix)
  unset ::G(perm:dbconfig)
  unset ::G(perm:presql)
Changes to test/releasetest_data.tcl.
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
  Fail2     {-O0}
  Fail3     {-O0}
  Fail4     {-O0}
  FuzzFail1 {-O0}
  FuzzFail2 {-O0}
}]
if {$tcl_platform(os)=="Darwin"} {
  lappend Configs(Apple -DSQLITE_ENABLE_LOCKING_STYLE=1
}

array set ::Platforms [strip_comments {
  Linux-x86_64 {
    "Check-Symbols*"          checksymbols
    "Fast-One"                "fuzztest test"
    "Debug-One"               "mptest test"
    "Debug-Two"               "test"
    "Have-Not"                test
    "Secure-Delete"           test
    "Unlock-Notify"           "QUICKTEST_INCLUDE=notify2.test test"
    "User-Auth"               tcltest
    "Update-Delete-Limit"     test
    "Extra-Robustness"        test
    "Device-Two"              "threadtest test"
    "No-lookaside"            test
    "Devkit"                  test
    "Apple"                   test
    "Sanitize"                {QUICKTEST_OMIT=crash*,shell*,sqldiff*,sessionB.test test}
    "Device-One"              fulltest
    "Default"                 "threadtest fulltest"
    "Valgrind*"               valgrindtest
  }
  Linux-i686 {
    "Devkit"                  test
    "Have-Not"                test







|





|












|







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
  Fail2     {-O0}
  Fail3     {-O0}
  Fail4     {-O0}
  FuzzFail1 {-O0}
  FuzzFail2 {-O0}
}]
if {$tcl_platform(os)=="Darwin"} {
  lappend Configs(Apple) -DSQLITE_ENABLE_LOCKING_STYLE=1
}

array set ::Platforms [strip_comments {
  Linux-x86_64 {
    "Check-Symbols*"          checksymbols
    "Fast-One"                "QUICKTEST_INCLUDE=rbu.test fuzztest test"
    "Debug-One"               "mptest test"
    "Debug-Two"               "test"
    "Have-Not"                test
    "Secure-Delete"           test
    "Unlock-Notify"           "QUICKTEST_INCLUDE=notify2.test test"
    "User-Auth"               tcltest
    "Update-Delete-Limit"     test
    "Extra-Robustness"        test
    "Device-Two"              "threadtest test"
    "No-lookaside"            test
    "Devkit"                  test
    "Apple"                   test
    "Sanitize"                test
    "Device-One"              fulltest
    "Default"                 "threadtest fulltest"
    "Valgrind*"               valgrindtest
  }
  Linux-i686 {
    "Devkit"                  test
    "Have-Not"                test
350
351
352
353
354
355
356








357
358
359
360
361
362
363
    Fail2*     "TEST_FAILURE=2 valgrindtest"
    Fail3*     "TEST_FAILURE=3 valgrindtest"
    Fail4*     "TEST_FAILURE=4 test"
    FuzzFail1* "TEST_FAILURE=5 test"
    FuzzFail2* "TEST_FAILURE=5 valgrindtest"
  }
}]









# Configuration verification: Check that each entry in the list of configs
# specified for each platforms exists.
#
foreach {key value} [array get ::Platforms] {
  foreach {v t} $value {
    if {[string range $v end end]=="*"} {







>
>
>
>
>
>
>
>







350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
    Fail2*     "TEST_FAILURE=2 valgrindtest"
    Fail3*     "TEST_FAILURE=3 valgrindtest"
    Fail4*     "TEST_FAILURE=4 test"
    FuzzFail1* "TEST_FAILURE=5 test"
    FuzzFail2* "TEST_FAILURE=5 valgrindtest"
  }
}]

#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
# End of configuration section.
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------

# Configuration verification: Check that each entry in the list of configs
# specified for each platforms exists.
#
foreach {key value} [array get ::Platforms] {
  foreach {v t} $value {
    if {[string range $v end end]=="*"} {
582
583
584
585
586
587
588
589

590



591


592
593
594
595
596
597
598
    if {[string range $config end end]=="*"} {
      set bNosynthetic 1
      set config [string range $config 0 end-1]
    }
    puts "$config \"$target\""
    if {$bNodebug==0 && $bNosynthetic==0} {
      set iHas [string first SQLITE_DEBUG $::Configs($config)]
      set dtarget test

      if {$target=="tcltest"} {



        set dtarget tcltest


      }
      if {$iHas>=0} {
        puts "$config-ndebug \"$dtarget\""
      } else {
        puts "$config-debug \"$dtarget\""
      }
    }







|
>
|
>
>
>
|
>
>







590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
    if {[string range $config end end]=="*"} {
      set bNosynthetic 1
      set config [string range $config 0 end-1]
    }
    puts "$config \"$target\""
    if {$bNodebug==0 && $bNosynthetic==0} {
      set iHas [string first SQLITE_DEBUG $::Configs($config)]
      set dtarget [list]
      set iQTI [lsearch -glob $target QUICKTEST_*]
      if {$iQTI>=0} {
        lappend dtarget [lindex $target $iQTI]
      }
      if {[lsearch $target tcltest]>=0} {
        lappend dtarget tcltest
      } else {
        lappend dtarget test
      }
      if {$iHas>=0} {
        puts "$config-ndebug \"$dtarget\""
      } else {
        puts "$config-debug \"$dtarget\""
      }
    }
Added test/returning1.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
# 2021-01-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 implements regression tests for SQLite library.  The
# focus of this file is the new RETURNING clause
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix returning1

do_execsql_test 1.0 {
  CREATE TABLE t1(a INTEGER PRIMARY KEY,b,c DEFAULT 'pax');
  INSERT INTO t1(b) VALUES(10),('happy'),(NULL) RETURNING a,b,c;
} {1 10 pax 2 happy pax 3 {} pax}
do_execsql_test 1.1 {
  SELECT * FROM t1;
} {1 10 pax 2 happy pax 3 {} pax}
do_execsql_test 1.2 {
  INSERT INTO t1(b,c) VALUES(5,99) RETURNING b,c,a,rowid;
} {5 99 4 4}
do_execsql_test 1.3 {
  SELECT * FROM t1;
} {1 10 pax 2 happy pax 3 {} pax 4 5 99}
do_execsql_test 1.4 {
  INSERT INTO t1 DEFAULT VALUES RETURNING *;
} {5 {} pax}
do_execsql_test 1.5 {
  SELECT * FROM t1;
} {1 10 pax 2 happy pax 3 {} pax 4 5 99 5 {} pax}
do_execsql_test 1.6 {
  CREATE TABLE t2(x,y,z);
  INSERT INTO t2 VALUES(11,12,13),(21,'b','c'),(31,'b-value',4.75);
}
do_execsql_test 1.7 {
  INSERT INTO t1 SELECT * FROM t2 RETURNING *;
} {11 12 13 21 b c 31 b-value 4.75}
do_execsql_test 1.8 {
  SELECT *, '|' FROM t1;
} {1 10 pax | 2 happy pax | 3 {} pax | 4 5 99 | 5 {} pax | 11 12 13 | 21 b c | 31 b-value 4.75 |}

do_execsql_test 2.1 {
  UPDATE t1 SET c='bellum' WHERE c='pax' RETURNING rowid, b, '|';
} {1 10 | 2 happy | 3 {} | 5 {} |}
do_execsql_test 2.2 {
  SELECT *, '|' FROM t1;
} {1 10 bellum | 2 happy bellum | 3 {} bellum | 4 5 99 | 5 {} bellum | 11 12 13 | 21 b c | 31 b-value 4.75 |}

do_execsql_test 3.1 {
  DELETE FROM t1 WHERE c='bellum' RETURNING rowid, *, '|';
} {1 1 10 bellum | 2 2 happy bellum | 3 3 {} bellum | 5 5 {} bellum |}
do_execsql_test 3.2 {
  SELECT *, '|' FROM t1;
} {4 5 99 | 11 12 13 | 21 b c | 31 b-value 4.75 |}

do_execsql_test 4.1 {
  CREATE TABLE t4(a INT, b INT DEFAULT 1234, c INT DEFAULT -16);
  CREATE UNIQUE INDEX t4a ON t4(a);
  INSERT INTO t4(a,b,c) VALUES(1,2,3);
} {}
do_execsql_test 4.2 {
  INSERT INTO t4(a,b,c) VALUES(1,22,33)
  ON CONFLICT(a) DO UPDATE SET b=44
  RETURNING *;
} {1 44 3}
do_execsql_test 4.3 {
  SELECT * FROM t4;
} {1 44 3}
do_execsql_test 4.4 {
  DELETE FROM t4;
  INSERT INTO t4 VALUES(1,2,3),(4,5,6),(7,8,9);
} {}
do_execsql_test 4.5 {
  INSERT INTO t4(a,b,c) VALUES(2,3,4),(4,5,6),(5,6,7)
  ON CONFLICT(a) DO UPDATE SET b=100
  RETURNING *, '|';
} {2 3 4 | 4 100 6 | 5 6 7 |}

#-------------------------------------------------------------------------
# Test RETURNING on a table with virtual columns.
#
reset_db
do_execsql_test 5.0 {
  CREATE TABLE t1(xyz);
  CREATE TABLE t2(a as (1+1), b);
}

do_execsql_test 5.1 {
  UPDATE t2 SET b='123' WHERE b='abc' RETURNING (SELECT b FROM t1);
} {}

do_execsql_test 5.2 {
  INSERT INTO t2(b) VALUES('abc');
}

do_execsql_test 5.3 {
  UPDATE t2 SET b='123' WHERE b='abc' RETURNING (SELECT b FROM t1);
} {{}}

do_execsql_test 5.4 {
  INSERT INTO t2(b) VALUES('abc');
  INSERT INTO t1(xyz) VALUES(1);
  UPDATE t2 SET b='123' WHERE b='abc' RETURNING b;
} {123}

do_execsql_test 5.5 {
  INSERT INTO t2(b) VALUES('abc');
  UPDATE t2 SET b='123' WHERE b='abc' RETURNING (SELECT b FROM t1);
} {123}

finish_test

Changes to test/rowvalue.test.
640
641
642
643
644
645
646













647
#
reset_db
do_catchsql_test 27.10 {
  CREATE TABLE t0(c0 CHECK(((0, 0) > (0, c0))));
  INSERT INTO t0(c0) VALUES(0) ON CONFLICT(c0) DO UPDATE SET c0 = 3;
} {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}}














finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>

640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
#
reset_db
do_catchsql_test 27.10 {
  CREATE TABLE t0(c0 CHECK(((0, 0) > (0, c0))));
  INSERT INTO t0(c0) VALUES(0) ON CONFLICT(c0) DO UPDATE SET c0 = 3;
} {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}}

# 2021-02-03
# https://bugs.chromium.org/p/chromium/issues/detail?id=1173511
# Faulty assert() statement.
#
reset_db
do_catchsql_test 28.10 {
  CREATE TABLE t0(c0 PRIMARY KEY, c1);
  CREATE TRIGGER trigger0 BEFORE DELETE ON t0 BEGIN
   SELECT (SELECT c0,c1  FROM t0)  FROM t0;
  END ;
  DELETE FROM t0;
} {1 {sub-select returns 2 columns - expected 1}}

finish_test
Changes to test/select1.test.
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
      SELECT x FROM t2 WHERE x=c OR x=(SELECT x FROM (VALUES(0)))
    ) WHERE x>c OR x=c
  );
} {1}

# 2019-12-17 gramfuzz find
#
do_execsql_test select-19.10 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(x);
} {}
do_catchsql_test select-19.20 {
  INSERT INTO t1
    SELECT 1,2,3,4,5,6,7
    UNION ALL SELECT 1,2,3,4,5,6,7
    ORDER BY 1;
} {1 {table t1 has 1 columns but 7 values were supplied}}
do_catchsql_test select-19.21 {
  INSERT INTO t1
    SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
    UNION ALL SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
    ORDER BY 1;
} {1 {table t1 has 1 columns but 15 values were supplied}}

# 2020-01-01 Found by Yongheng's fuzzer
#
reset_db
do_execsql_test select-20.10 {
  CREATE TABLE t1 (
    a INTEGER PRIMARY KEY,
    b AS('Y') UNIQUE
  );
  INSERT INTO t1(a) VALUES (10);
  SELECT * FROM t1 JOIN t1 USING(a,b)
   WHERE ((SELECT t1.a FROM t1 AS x GROUP BY b) AND b=0)
      OR a = 10;
} {10 Y}
do_execsql_test select-20.20 {
  SELECT ifnull(a, max((SELECT 123))), count(a) FROM t1 ;
} {10 1}

# 2020-10-02 dbsqlfuzz find
reset_db
do_execsql_test select-21.1 {
  CREATE TABLE t1(a IMTEGES PRIMARY KEY,R);
  CREATE TABLE t2(x UNIQUE);
  CREATE VIEW v1a(z,y) AS SELECT x IS NULL, x FROM t2;
  SELECT a,(+a)b,(+a)b,(+a)b,NOT EXISTS(SELECT null FROM t2),CASE z WHEN 487 THEN 992 WHEN 391 THEN 203 WHEN 10 THEN '?k<D Q' END,'' FROM t1 LEFT JOIN v1a ON z=b;
} {}

finish_test







|



|





|









|









|





|







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
      SELECT x FROM t2 WHERE x=c OR x=(SELECT x FROM (VALUES(0)))
    ) WHERE x>c OR x=c
  );
} {1}

# 2019-12-17 gramfuzz find
#
do_execsql_test select1-19.10 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(x);
} {}
do_catchsql_test select1-19.20 {
  INSERT INTO t1
    SELECT 1,2,3,4,5,6,7
    UNION ALL SELECT 1,2,3,4,5,6,7
    ORDER BY 1;
} {1 {table t1 has 1 columns but 7 values were supplied}}
do_catchsql_test select1-19.21 {
  INSERT INTO t1
    SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
    UNION ALL SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
    ORDER BY 1;
} {1 {table t1 has 1 columns but 15 values were supplied}}

# 2020-01-01 Found by Yongheng's fuzzer
#
reset_db
do_execsql_test select1-20.10 {
  CREATE TABLE t1 (
    a INTEGER PRIMARY KEY,
    b AS('Y') UNIQUE
  );
  INSERT INTO t1(a) VALUES (10);
  SELECT * FROM t1 JOIN t1 USING(a,b)
   WHERE ((SELECT t1.a FROM t1 AS x GROUP BY b) AND b=0)
      OR a = 10;
} {10 Y}
do_execsql_test select1-20.20 {
  SELECT ifnull(a, max((SELECT 123))), count(a) FROM t1 ;
} {10 1}

# 2020-10-02 dbsqlfuzz find
reset_db
do_execsql_test select1-21.1 {
  CREATE TABLE t1(a IMTEGES PRIMARY KEY,R);
  CREATE TABLE t2(x UNIQUE);
  CREATE VIEW v1a(z,y) AS SELECT x IS NULL, x FROM t2;
  SELECT a,(+a)b,(+a)b,(+a)b,NOT EXISTS(SELECT null FROM t2),CASE z WHEN 487 THEN 992 WHEN 391 THEN 203 WHEN 10 THEN '?k<D Q' END,'' FROM t1 LEFT JOIN v1a ON z=b;
} {}

finish_test
Changes to test/selectC.test.
257
258
259
260
261
262
263
264
265
266
267
268
269
270
  SELECT * FROM x1, x4
} {
  a 21 a 22 a 23 a 24 a 25 a 302 a 303 a 301
  b 21 b 22 b 23 b 24 b 25 b 302 b 303 b 301
}

do_execsql_test 5.3 {
  SELECT * FROM x1, (SELECT b FROM vvv UNION ALL SELECT c from x3);
} {
  a 21 a 22 a 23 a 24 a 25 a 302 a 303 a 301
  b 21 b 22 b 23 b 24 b 25 b 302 b 303 b 301
}

finish_test







|

|
|



257
258
259
260
261
262
263
264
265
266
267
268
269
270
  SELECT * FROM x1, x4
} {
  a 21 a 22 a 23 a 24 a 25 a 302 a 303 a 301
  b 21 b 22 b 23 b 24 b 25 b 302 b 303 b 301
}

do_execsql_test 5.3 {
  SELECT * FROM x1, (SELECT b FROM vvv UNION ALL SELECT c from x3) ORDER BY 1,2;
} {
  a 21 a 22 a 23 a 24 a 25 a 301 a 302 a 303
  b 21 b 22 b 23 b 24 b 25 b 301 b 302 b 303
}

finish_test
Changes to test/shell1.test.
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
  # too many arguments
  catchcmd "test.db" ".show BAD"
} {1 {Usage: .show}}

# .stats ON|OFF          Turn stats on or off
#do_test shell1-3.23b.1 {
#  catchcmd "test.db" ".stats"
#} {1 {Usage: .stats on|off}}
do_test shell1-3.23b.2 {
  catchcmd "test.db" ".stats ON"
} {0 {}}
do_test shell1-3.23b.3 {
  catchcmd "test.db" ".stats OFF"
} {0 {}}
do_test shell1-3.23b.4 {
  # too many arguments
  catchcmd "test.db" ".stats OFF BAD"
} {1 {Usage: .stats ?on|off?}}

# Ticket 7be932dfa60a8a6b3b26bcf7623ec46e0a403ddb 2018-06-07
# Adverse interaction between .stats and .eqp
#
do_test shell1-3.23b.5 {
  catchcmd "test.db" [string map {"\n    " "\n"} {
    CREATE TEMP TABLE t1(x);







|









|







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
  # too many arguments
  catchcmd "test.db" ".show BAD"
} {1 {Usage: .show}}

# .stats ON|OFF          Turn stats on or off
#do_test shell1-3.23b.1 {
#  catchcmd "test.db" ".stats"
#} {1 {Usage: .stats on|off|stmt|vmstep}}
do_test shell1-3.23b.2 {
  catchcmd "test.db" ".stats ON"
} {0 {}}
do_test shell1-3.23b.3 {
  catchcmd "test.db" ".stats OFF"
} {0 {}}
do_test shell1-3.23b.4 {
  # too many arguments
  catchcmd "test.db" ".stats OFF BAD"
} {1 {Usage: .stats ?on|off|stmt|vmstep?}}

# Ticket 7be932dfa60a8a6b3b26bcf7623ec46e0a403ddb 2018-06-07
# Adverse interaction between .stats and .eqp
#
do_test shell1-3.23b.5 {
  catchcmd "test.db" [string map {"\n    " "\n"} {
    CREATE TEMP TABLE t1(x);
Changes to test/shell4.test.
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
} {0 {}}
do_test shell4-1.3.3 {
  catchcmd "test.db" ".stats OFF"
} {0 {}}
do_test shell4-1.3.4 {
  # too many arguments
  catchcmd "test.db" ".stats OFF BAD"
} {1 {Usage: .stats ?on|off?}}

# NB. whitespace is important
do_test shell4-1.4.1 {
  set res [catchcmd "test.db" {.show}]
  list [regexp {stats: off} $res]
} {1}








|







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
} {0 {}}
do_test shell4-1.3.3 {
  catchcmd "test.db" ".stats OFF"
} {0 {}}
do_test shell4-1.3.4 {
  # too many arguments
  catchcmd "test.db" ".stats OFF BAD"
} {1 {Usage: .stats ?on|off|stmt|vmstep?}}

# NB. whitespace is important
do_test shell4-1.4.1 {
  set res [catchcmd "test.db" {.show}]
  list [regexp {stats: off} $res]
} {1}

Changes to test/speedtest1.c.
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
  char zNum[2000];              /* A number name */

  sz = n = g.szTest*500;
  zNum[0] = 0;
  maxb = roundup_allones(sz);
  speedtest1_begin_test(100, "%d INSERTs into table with no index", n);
  speedtest1_exec("BEGIN");
  speedtest1_exec("CREATE%s TABLE t1(a INTEGER %s, b INTEGER %s, c TEXT %s);",
                  isTemp(9), g.zNN, g.zNN, g.zNN);
  speedtest1_prepare("INSERT INTO t1 VALUES(?1,?2,?3); --  %d times", n);
  for(i=1; i<=n; i++){
    x1 = swizzle(i,maxb);
    speedtest1_numbername(x1, zNum, sizeof(zNum));
    sqlite3_bind_int64(g.pStmt, 1, (sqlite3_int64)x1);
    sqlite3_bind_int(g.pStmt, 2, i);
    sqlite3_bind_text(g.pStmt, 3, zNum, -1, SQLITE_STATIC);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();


  n = sz;
  speedtest1_begin_test(110, "%d ordered INSERTS with one index/PK", n);
  speedtest1_exec("BEGIN");
  speedtest1_exec(
     "CREATE%s TABLE t2(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
     isTemp(5), g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
  speedtest1_prepare("INSERT INTO t2 VALUES(?1,?2,?3); -- %d times", n);
  for(i=1; i<=n; i++){
    x1 = swizzle(i,maxb);
    speedtest1_numbername(x1, zNum, sizeof(zNum));
    sqlite3_bind_int(g.pStmt, 1, i);
    sqlite3_bind_int64(g.pStmt, 2, (sqlite3_int64)x1);
    sqlite3_bind_text(g.pStmt, 3, zNum, -1, SQLITE_STATIC);
    speedtest1_run();







|

|
















|

|







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
  char zNum[2000];              /* A number name */

  sz = n = g.szTest*500;
  zNum[0] = 0;
  maxb = roundup_allones(sz);
  speedtest1_begin_test(100, "%d INSERTs into table with no index", n);
  speedtest1_exec("BEGIN");
  speedtest1_exec("CREATE%s TABLE z1(a INTEGER %s, b INTEGER %s, c TEXT %s);",
                  isTemp(9), g.zNN, g.zNN, g.zNN);
  speedtest1_prepare("INSERT INTO z1 VALUES(?1,?2,?3); --  %d times", n);
  for(i=1; i<=n; i++){
    x1 = swizzle(i,maxb);
    speedtest1_numbername(x1, zNum, sizeof(zNum));
    sqlite3_bind_int64(g.pStmt, 1, (sqlite3_int64)x1);
    sqlite3_bind_int(g.pStmt, 2, i);
    sqlite3_bind_text(g.pStmt, 3, zNum, -1, SQLITE_STATIC);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();


  n = sz;
  speedtest1_begin_test(110, "%d ordered INSERTS with one index/PK", n);
  speedtest1_exec("BEGIN");
  speedtest1_exec(
     "CREATE%s TABLE z2(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
     isTemp(5), g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
  speedtest1_prepare("INSERT INTO z2 VALUES(?1,?2,?3); -- %d times", n);
  for(i=1; i<=n; i++){
    x1 = swizzle(i,maxb);
    speedtest1_numbername(x1, zNum, sizeof(zNum));
    sqlite3_bind_int(g.pStmt, 1, i);
    sqlite3_bind_int64(g.pStmt, 2, (sqlite3_int64)x1);
    sqlite3_bind_text(g.pStmt, 3, zNum, -1, SQLITE_STATIC);
    speedtest1_run();
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
                          0, groupStep, groupFinal);
#endif

  n = 25;
  speedtest1_begin_test(130, "%d SELECTS, numeric BETWEEN, unindexed", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "SELECT count(*), avg(b), sum(length(c)), group_concat(c) FROM t1\n"
    " WHERE b BETWEEN ?1 AND ?2; -- %d times", n
  );
  for(i=1; i<=n; i++){
    if( (i-1)%g.nRepeat==0 ){
      x1 = speedtest1_random()%maxb;
      x2 = speedtest1_random()%10 + sz/5000 + x1;
    }
    sqlite3_bind_int(g.pStmt, 1, x1);
    sqlite3_bind_int(g.pStmt, 2, x2);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();


  n = 10;
  speedtest1_begin_test(140, "%d SELECTS, LIKE, unindexed", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "SELECT count(*), avg(b), sum(length(c)), group_concat(c) FROM t1\n"
    " WHERE c LIKE ?1; -- %d times", n
  );
  for(i=1; i<=n; i++){
    if( (i-1)%g.nRepeat==0 ){
      x1 = speedtest1_random()%maxb;
      zNum[0] = '%';
      len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);







|



















|







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
                          0, groupStep, groupFinal);
#endif

  n = 25;
  speedtest1_begin_test(130, "%d SELECTS, numeric BETWEEN, unindexed", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "SELECT count(*), avg(b), sum(length(c)), group_concat(c) FROM z1\n"
    " WHERE b BETWEEN ?1 AND ?2; -- %d times", n
  );
  for(i=1; i<=n; i++){
    if( (i-1)%g.nRepeat==0 ){
      x1 = speedtest1_random()%maxb;
      x2 = speedtest1_random()%10 + sz/5000 + x1;
    }
    sqlite3_bind_int(g.pStmt, 1, x1);
    sqlite3_bind_int(g.pStmt, 2, x2);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();


  n = 10;
  speedtest1_begin_test(140, "%d SELECTS, LIKE, unindexed", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "SELECT count(*), avg(b), sum(length(c)), group_concat(c) FROM z1\n"
    " WHERE c LIKE ?1; -- %d times", n
  );
  for(i=1; i<=n; i++){
    if( (i-1)%g.nRepeat==0 ){
      x1 = speedtest1_random()%maxb;
      zNum[0] = '%';
      len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
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
  speedtest1_end_test();


  n = 10;
  speedtest1_begin_test(142, "%d SELECTS w/ORDER BY, unindexed", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "SELECT a, b, c FROM t1 WHERE c LIKE ?1\n"
    " ORDER BY a; -- %d times", n
  );
  for(i=1; i<=n; i++){
    if( (i-1)%g.nRepeat==0 ){
      x1 = speedtest1_random()%maxb;
      zNum[0] = '%';
      len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
      zNum[len] = '%';
      zNum[len+1] = 0;
    }
    sqlite3_bind_text(g.pStmt, 1, zNum, len+1, SQLITE_STATIC);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();

  n = 10; /* g.szTest/5; */
  speedtest1_begin_test(145, "%d SELECTS w/ORDER BY and LIMIT, unindexed", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "SELECT a, b, c FROM t1 WHERE c LIKE ?1\n"
    " ORDER BY a LIMIT 10; -- %d times", n
  );
  for(i=1; i<=n; i++){
    if( (i-1)%g.nRepeat==0 ){
      x1 = speedtest1_random()%maxb;
      zNum[0] = '%';
      len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
      zNum[len] = '%';
      zNum[len+1] = 0;
    }
    sqlite3_bind_text(g.pStmt, 1, zNum, len+1, SQLITE_STATIC);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();


  speedtest1_begin_test(150, "CREATE INDEX five times");
  speedtest1_exec("BEGIN;");
  speedtest1_exec("CREATE UNIQUE INDEX t1b ON t1(b);");
  speedtest1_exec("CREATE INDEX t1c ON t1(c);");
  speedtest1_exec("CREATE UNIQUE INDEX t2b ON t2(b);");
  speedtest1_exec("CREATE INDEX t2c ON t2(c DESC);");
  speedtest1_exec("CREATE INDEX t3bc ON t3(b,c);");
  speedtest1_exec("COMMIT;");
  speedtest1_end_test();


  n = sz/5;
  speedtest1_begin_test(160, "%d SELECTS, numeric BETWEEN, indexed", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "SELECT count(*), avg(b), sum(length(c)), group_concat(a) FROM t1\n"
    " WHERE b BETWEEN ?1 AND ?2; -- %d times", n
  );
  for(i=1; i<=n; i++){
    if( (i-1)%g.nRepeat==0 ){
      x1 = speedtest1_random()%maxb;
      x2 = speedtest1_random()%10 + sz/5000 + x1;
    }
    sqlite3_bind_int(g.pStmt, 1, x1);
    sqlite3_bind_int(g.pStmt, 2, x2);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();


  n = sz/5;
  speedtest1_begin_test(161, "%d SELECTS, numeric BETWEEN, PK", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "SELECT count(*), avg(b), sum(length(c)), group_concat(a) FROM t2\n"
    " WHERE a BETWEEN ?1 AND ?2; -- %d times", n
  );
  for(i=1; i<=n; i++){
    if( (i-1)%g.nRepeat==0 ){
      x1 = speedtest1_random()%maxb;
      x2 = speedtest1_random()%10 + sz/5000 + x1;
    }
    sqlite3_bind_int(g.pStmt, 1, x1);
    sqlite3_bind_int(g.pStmt, 2, x2);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();


  n = sz/5;
  speedtest1_begin_test(170, "%d SELECTS, text BETWEEN, indexed", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "SELECT count(*), avg(b), sum(length(c)), group_concat(a) FROM t1\n"
    " WHERE c BETWEEN ?1 AND (?1||'~'); -- %d times", n
  );
  for(i=1; i<=n; i++){
    if( (i-1)%g.nRepeat==0 ){
      x1 = swizzle(i, maxb);
      len = speedtest1_numbername(x1, zNum, sizeof(zNum)-1);
    }







|




















|



















|
|
|
|









|



















|



















|







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
  speedtest1_end_test();


  n = 10;
  speedtest1_begin_test(142, "%d SELECTS w/ORDER BY, unindexed", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "SELECT a, b, c FROM z1 WHERE c LIKE ?1\n"
    " ORDER BY a; -- %d times", n
  );
  for(i=1; i<=n; i++){
    if( (i-1)%g.nRepeat==0 ){
      x1 = speedtest1_random()%maxb;
      zNum[0] = '%';
      len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
      zNum[len] = '%';
      zNum[len+1] = 0;
    }
    sqlite3_bind_text(g.pStmt, 1, zNum, len+1, SQLITE_STATIC);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();

  n = 10; /* g.szTest/5; */
  speedtest1_begin_test(145, "%d SELECTS w/ORDER BY and LIMIT, unindexed", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "SELECT a, b, c FROM z1 WHERE c LIKE ?1\n"
    " ORDER BY a LIMIT 10; -- %d times", n
  );
  for(i=1; i<=n; i++){
    if( (i-1)%g.nRepeat==0 ){
      x1 = speedtest1_random()%maxb;
      zNum[0] = '%';
      len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
      zNum[len] = '%';
      zNum[len+1] = 0;
    }
    sqlite3_bind_text(g.pStmt, 1, zNum, len+1, SQLITE_STATIC);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();


  speedtest1_begin_test(150, "CREATE INDEX five times");
  speedtest1_exec("BEGIN;");
  speedtest1_exec("CREATE UNIQUE INDEX t1b ON z1(b);");
  speedtest1_exec("CREATE INDEX t1c ON z1(c);");
  speedtest1_exec("CREATE UNIQUE INDEX t2b ON z2(b);");
  speedtest1_exec("CREATE INDEX t2c ON z2(c DESC);");
  speedtest1_exec("CREATE INDEX t3bc ON t3(b,c);");
  speedtest1_exec("COMMIT;");
  speedtest1_end_test();


  n = sz/5;
  speedtest1_begin_test(160, "%d SELECTS, numeric BETWEEN, indexed", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "SELECT count(*), avg(b), sum(length(c)), group_concat(a) FROM z1\n"
    " WHERE b BETWEEN ?1 AND ?2; -- %d times", n
  );
  for(i=1; i<=n; i++){
    if( (i-1)%g.nRepeat==0 ){
      x1 = speedtest1_random()%maxb;
      x2 = speedtest1_random()%10 + sz/5000 + x1;
    }
    sqlite3_bind_int(g.pStmt, 1, x1);
    sqlite3_bind_int(g.pStmt, 2, x2);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();


  n = sz/5;
  speedtest1_begin_test(161, "%d SELECTS, numeric BETWEEN, PK", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "SELECT count(*), avg(b), sum(length(c)), group_concat(a) FROM z2\n"
    " WHERE a BETWEEN ?1 AND ?2; -- %d times", n
  );
  for(i=1; i<=n; i++){
    if( (i-1)%g.nRepeat==0 ){
      x1 = speedtest1_random()%maxb;
      x2 = speedtest1_random()%10 + sz/5000 + x1;
    }
    sqlite3_bind_int(g.pStmt, 1, x1);
    sqlite3_bind_int(g.pStmt, 2, x2);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();


  n = sz/5;
  speedtest1_begin_test(170, "%d SELECTS, text BETWEEN, indexed", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "SELECT count(*), avg(b), sum(length(c)), group_concat(a) FROM z1\n"
    " WHERE c BETWEEN ?1 AND (?1||'~'); -- %d times", n
  );
  for(i=1; i<=n; i++){
    if( (i-1)%g.nRepeat==0 ){
      x1 = swizzle(i, maxb);
      len = speedtest1_numbername(x1, zNum, sizeof(zNum)-1);
    }
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
    "  a INTEGER %s %s,\n"
    "  b INTEGER %s,\n"
    "  c TEXT %s\n"
    ") %s",
    isTemp(1), g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
  speedtest1_exec("CREATE INDEX t4b ON t4(b)");
  speedtest1_exec("CREATE INDEX t4c ON t4(c)");
  speedtest1_exec("INSERT INTO t4 SELECT * FROM t1");
  speedtest1_exec("COMMIT");
  speedtest1_end_test();

  n = sz;
  speedtest1_begin_test(190, "DELETE and REFILL one table", n);
  speedtest1_exec("DELETE FROM t2;");
  speedtest1_exec("INSERT INTO t2 SELECT * FROM t1;");
  speedtest1_end_test();


  speedtest1_begin_test(200, "VACUUM");
  speedtest1_exec("VACUUM");
  speedtest1_end_test();


  speedtest1_begin_test(210, "ALTER TABLE ADD COLUMN, and query");
  speedtest1_exec("ALTER TABLE t2 ADD COLUMN d DEFAULT 123");
  speedtest1_exec("SELECT sum(d) FROM t2");
  speedtest1_end_test();


  n = sz/5;
  speedtest1_begin_test(230, "%d UPDATES, numeric BETWEEN, indexed", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "UPDATE t2 SET d=b*2 WHERE b BETWEEN ?1 AND ?2; -- %d times", n
  );
  for(i=1; i<=n; i++){
    x1 = speedtest1_random()%maxb;
    x2 = speedtest1_random()%10 + sz/5000 + x1;
    sqlite3_bind_int(g.pStmt, 1, x1);
    sqlite3_bind_int(g.pStmt, 2, x2);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();


  n = sz;
  speedtest1_begin_test(240, "%d UPDATES of individual rows", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "UPDATE t2 SET d=b*3 WHERE a=?1; -- %d times", n
  );
  for(i=1; i<=n; i++){
    x1 = speedtest1_random()%sz + 1;
    sqlite3_bind_int(g.pStmt, 1, x1);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();

  speedtest1_begin_test(250, "One big UPDATE of the whole %d-row table", sz);
  speedtest1_exec("UPDATE t2 SET d=b*4");
  speedtest1_end_test();


  speedtest1_begin_test(260, "Query added column after filling");
  speedtest1_exec("SELECT sum(d) FROM t2");
  speedtest1_end_test();



  n = sz/5;
  speedtest1_begin_test(270, "%d DELETEs, numeric BETWEEN, indexed", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "DELETE FROM t2 WHERE b BETWEEN ?1 AND ?2; -- %d times", n
  );
  for(i=1; i<=n; i++){
    x1 = speedtest1_random()%maxb + 1;
    x2 = speedtest1_random()%10 + sz/5000 + x1;
    sqlite3_bind_int(g.pStmt, 1, x1);
    sqlite3_bind_int(g.pStmt, 2, x2);
    speedtest1_run();







|





|
|









|
|







|
















|










|




|








|







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
    "  a INTEGER %s %s,\n"
    "  b INTEGER %s,\n"
    "  c TEXT %s\n"
    ") %s",
    isTemp(1), g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
  speedtest1_exec("CREATE INDEX t4b ON t4(b)");
  speedtest1_exec("CREATE INDEX t4c ON t4(c)");
  speedtest1_exec("INSERT INTO t4 SELECT * FROM z1");
  speedtest1_exec("COMMIT");
  speedtest1_end_test();

  n = sz;
  speedtest1_begin_test(190, "DELETE and REFILL one table", n);
  speedtest1_exec("DELETE FROM z2;");
  speedtest1_exec("INSERT INTO z2 SELECT * FROM z1;");
  speedtest1_end_test();


  speedtest1_begin_test(200, "VACUUM");
  speedtest1_exec("VACUUM");
  speedtest1_end_test();


  speedtest1_begin_test(210, "ALTER TABLE ADD COLUMN, and query");
  speedtest1_exec("ALTER TABLE z2 ADD COLUMN d DEFAULT 123");
  speedtest1_exec("SELECT sum(d) FROM z2");
  speedtest1_end_test();


  n = sz/5;
  speedtest1_begin_test(230, "%d UPDATES, numeric BETWEEN, indexed", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "UPDATE z2 SET d=b*2 WHERE b BETWEEN ?1 AND ?2; -- %d times", n
  );
  for(i=1; i<=n; i++){
    x1 = speedtest1_random()%maxb;
    x2 = speedtest1_random()%10 + sz/5000 + x1;
    sqlite3_bind_int(g.pStmt, 1, x1);
    sqlite3_bind_int(g.pStmt, 2, x2);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();


  n = sz;
  speedtest1_begin_test(240, "%d UPDATES of individual rows", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "UPDATE z2 SET d=b*3 WHERE a=?1; -- %d times", n
  );
  for(i=1; i<=n; i++){
    x1 = speedtest1_random()%sz + 1;
    sqlite3_bind_int(g.pStmt, 1, x1);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();

  speedtest1_begin_test(250, "One big UPDATE of the whole %d-row table", sz);
  speedtest1_exec("UPDATE z2 SET d=b*4");
  speedtest1_end_test();


  speedtest1_begin_test(260, "Query added column after filling");
  speedtest1_exec("SELECT sum(d) FROM z2");
  speedtest1_end_test();



  n = sz/5;
  speedtest1_begin_test(270, "%d DELETEs, numeric BETWEEN, indexed", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "DELETE FROM z2 WHERE b BETWEEN ?1 AND ?2; -- %d times", n
  );
  for(i=1; i<=n; i++){
    x1 = speedtest1_random()%maxb + 1;
    x2 = speedtest1_random()%10 + sz/5000 + x1;
    sqlite3_bind_int(g.pStmt, 1, x1);
    sqlite3_bind_int(g.pStmt, 2, x2);
    speedtest1_run();
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
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();


  speedtest1_begin_test(290, "Refill two %d-row tables using REPLACE", sz);
  speedtest1_exec("REPLACE INTO t2(a,b,c) SELECT a,b,c FROM t1");
  speedtest1_exec("REPLACE INTO t3(a,b,c) SELECT a,b,c FROM t1");
  speedtest1_end_test();

  speedtest1_begin_test(300, "Refill a %d-row table using (b&1)==(a&1)", sz);
  speedtest1_exec("DELETE FROM t2;");
  speedtest1_exec("INSERT INTO t2(a,b,c)\n"
                  " SELECT a,b,c FROM t1  WHERE (b&1)==(a&1);");
  speedtest1_exec("INSERT INTO t2(a,b,c)\n"
                  " SELECT a,b,c FROM t1  WHERE (b&1)<>(a&1);");
  speedtest1_end_test();


  n = sz/5;
  speedtest1_begin_test(310, "%d four-ways joins", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "SELECT t1.c FROM t1, t2, t3, t4\n"
    " WHERE t4.a BETWEEN ?1 AND ?2\n"
    "   AND t3.a=t4.b\n"
    "   AND t2.a=t3.b\n"
    "   AND t1.c=t2.c"
  );
  for(i=1; i<=n; i++){
    x1 = speedtest1_random()%sz + 1;
    x2 = speedtest1_random()%10 + x1 + 4;
    sqlite3_bind_int(g.pStmt, 1, x1);
    sqlite3_bind_int(g.pStmt, 2, x2);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();

  speedtest1_begin_test(320, "subquery in result set", n);
  speedtest1_prepare(
    "SELECT sum(a), max(c),\n"
    "       avg((SELECT a FROM t2 WHERE 5+t2.b=t1.b) AND rowid<?1), max(c)\n"
    " FROM t1 WHERE rowid<?1;"
  );
  sqlite3_bind_int(g.pStmt, 1, est_square_root(g.szTest)*50);
  speedtest1_run();
  speedtest1_end_test();

  sz = n = g.szTest*700;
  zNum[0] = 0;







|
|



|
|
|
|
|







|


|
|














|
|







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
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();


  speedtest1_begin_test(290, "Refill two %d-row tables using REPLACE", sz);
  speedtest1_exec("REPLACE INTO z2(a,b,c) SELECT a,b,c FROM z1");
  speedtest1_exec("REPLACE INTO t3(a,b,c) SELECT a,b,c FROM z1");
  speedtest1_end_test();

  speedtest1_begin_test(300, "Refill a %d-row table using (b&1)==(a&1)", sz);
  speedtest1_exec("DELETE FROM z2;");
  speedtest1_exec("INSERT INTO z2(a,b,c)\n"
                  " SELECT a,b,c FROM z1  WHERE (b&1)==(a&1);");
  speedtest1_exec("INSERT INTO z2(a,b,c)\n"
                  " SELECT a,b,c FROM z1  WHERE (b&1)<>(a&1);");
  speedtest1_end_test();


  n = sz/5;
  speedtest1_begin_test(310, "%d four-ways joins", n);
  speedtest1_exec("BEGIN");
  speedtest1_prepare(
    "SELECT z1.c FROM z1, z2, t3, t4\n"
    " WHERE t4.a BETWEEN ?1 AND ?2\n"
    "   AND t3.a=t4.b\n"
    "   AND z2.a=t3.b\n"
    "   AND z1.c=z2.c"
  );
  for(i=1; i<=n; i++){
    x1 = speedtest1_random()%sz + 1;
    x2 = speedtest1_random()%10 + x1 + 4;
    sqlite3_bind_int(g.pStmt, 1, x1);
    sqlite3_bind_int(g.pStmt, 2, x2);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();

  speedtest1_begin_test(320, "subquery in result set", n);
  speedtest1_prepare(
    "SELECT sum(a), max(c),\n"
    "       avg((SELECT a FROM z2 WHERE 5+z2.b=z1.b) AND rowid<?1), max(c)\n"
    " FROM z1 WHERE rowid<?1;"
  );
  sqlite3_bind_int(g.pStmt, 1, est_square_root(g.szTest)*50);
  speedtest1_run();
  speedtest1_end_test();

  sz = n = g.szTest*700;
  zNum[0] = 0;
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
  speedtest1_run();
  speedtest1_end_test();

  nElem = 10000*g.szTest;
  speedtest1_begin_test(400, "EXCEPT operator on %d-element tables", nElem);
  speedtest1_prepare(
    "WITH RECURSIVE \n"
    "  t1(x) AS (VALUES(2) UNION ALL SELECT x+2 FROM t1 WHERE x<%d),\n"
    "  t2(y) AS (VALUES(3) UNION ALL SELECT y+3 FROM t2 WHERE y<%d)\n"
    "SELECT count(x), avg(x) FROM (\n"
    "  SELECT x FROM t1 EXCEPT SELECT y FROM t2 ORDER BY 1\n"
    ");",
    nElem, nElem
  );
  speedtest1_run();
  speedtest1_end_test();
}








|
|

|







1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
  speedtest1_run();
  speedtest1_end_test();

  nElem = 10000*g.szTest;
  speedtest1_begin_test(400, "EXCEPT operator on %d-element tables", nElem);
  speedtest1_prepare(
    "WITH RECURSIVE \n"
    "  z1(x) AS (VALUES(2) UNION ALL SELECT x+2 FROM z1 WHERE x<%d),\n"
    "  z2(y) AS (VALUES(3) UNION ALL SELECT y+3 FROM z2 WHERE y<%d)\n"
    "SELECT count(x), avg(x) FROM (\n"
    "  SELECT x FROM z1 EXCEPT SELECT y FROM z2 ORDER BY 1\n"
    ");",
    nElem, nElem
  );
  speedtest1_run();
  speedtest1_end_test();
}

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
  int i;
  char zFP1[100];
  char zFP2[100];
  
  n = g.szTest*5000;
  speedtest1_begin_test(100, "Fill a table with %d FP values", n*2);
  speedtest1_exec("BEGIN");
  speedtest1_exec("CREATE%s TABLE t1(a REAL %s, b REAL %s);",
                  isTemp(1), g.zNN, g.zNN);
  speedtest1_prepare("INSERT INTO t1 VALUES(?1,?2); -- %d times", n);
  for(i=1; i<=n; i++){
    speedtest1_random_ascii_fp(zFP1);
    speedtest1_random_ascii_fp(zFP2);
    sqlite3_bind_text(g.pStmt, 1, zFP1, -1, SQLITE_STATIC);
    sqlite3_bind_text(g.pStmt, 2, zFP2, -1, SQLITE_STATIC);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();

  n = g.szTest/25 + 2;
  speedtest1_begin_test(110, "%d range queries", n);
  speedtest1_prepare("SELECT sum(b) FROM t1 WHERE a BETWEEN ?1 AND ?2");
  for(i=1; i<=n; i++){
    speedtest1_random_ascii_fp(zFP1);
    speedtest1_random_ascii_fp(zFP2);
    sqlite3_bind_text(g.pStmt, 1, zFP1, -1, SQLITE_STATIC);
    sqlite3_bind_text(g.pStmt, 2, zFP2, -1, SQLITE_STATIC);
    speedtest1_run();
  }
  speedtest1_end_test();

  speedtest1_begin_test(120, "CREATE INDEX three times");
  speedtest1_exec("BEGIN;");
  speedtest1_exec("CREATE INDEX t1a ON t1(a);");
  speedtest1_exec("CREATE INDEX t1b ON t1(b);");
  speedtest1_exec("CREATE INDEX t1ab ON t1(a,b);");
  speedtest1_exec("COMMIT;");
  speedtest1_end_test();

  n = g.szTest/3 + 2;
  speedtest1_begin_test(130, "%d indexed range queries", n);
  speedtest1_prepare("SELECT sum(b) FROM t1 WHERE a BETWEEN ?1 AND ?2");
  for(i=1; i<=n; i++){
    speedtest1_random_ascii_fp(zFP1);
    speedtest1_random_ascii_fp(zFP2);
    sqlite3_bind_text(g.pStmt, 1, zFP1, -1, SQLITE_STATIC);
    sqlite3_bind_text(g.pStmt, 2, zFP2, -1, SQLITE_STATIC);
    speedtest1_run();
  }
  speedtest1_end_test();

  n = g.szTest*5000;
  speedtest1_begin_test(140, "%d calls to round()", n);
  speedtest1_exec("SELECT sum(round(a,2)+round(b,4)) FROM t1;");
  speedtest1_end_test();


  speedtest1_begin_test(150, "%d printf() calls", n*4);
  speedtest1_exec(
    "WITH c(fmt) AS (VALUES('%%g'),('%%e'),('%%!g'),('%%.20f'))"
    "SELECT sum(printf(fmt,a)) FROM t1, c"
  );
  speedtest1_end_test();
}

#ifdef SQLITE_ENABLE_RTREE
/* Generate two numbers between 1 and mx.  The first number is less than
** the second.  Usually the numbers are near each other but can sometimes







|

|












|











|
|
|





|











|






|







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
  int i;
  char zFP1[100];
  char zFP2[100];
  
  n = g.szTest*5000;
  speedtest1_begin_test(100, "Fill a table with %d FP values", n*2);
  speedtest1_exec("BEGIN");
  speedtest1_exec("CREATE%s TABLE z1(a REAL %s, b REAL %s);",
                  isTemp(1), g.zNN, g.zNN);
  speedtest1_prepare("INSERT INTO z1 VALUES(?1,?2); -- %d times", n);
  for(i=1; i<=n; i++){
    speedtest1_random_ascii_fp(zFP1);
    speedtest1_random_ascii_fp(zFP2);
    sqlite3_bind_text(g.pStmt, 1, zFP1, -1, SQLITE_STATIC);
    sqlite3_bind_text(g.pStmt, 2, zFP2, -1, SQLITE_STATIC);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();

  n = g.szTest/25 + 2;
  speedtest1_begin_test(110, "%d range queries", n);
  speedtest1_prepare("SELECT sum(b) FROM z1 WHERE a BETWEEN ?1 AND ?2");
  for(i=1; i<=n; i++){
    speedtest1_random_ascii_fp(zFP1);
    speedtest1_random_ascii_fp(zFP2);
    sqlite3_bind_text(g.pStmt, 1, zFP1, -1, SQLITE_STATIC);
    sqlite3_bind_text(g.pStmt, 2, zFP2, -1, SQLITE_STATIC);
    speedtest1_run();
  }
  speedtest1_end_test();

  speedtest1_begin_test(120, "CREATE INDEX three times");
  speedtest1_exec("BEGIN;");
  speedtest1_exec("CREATE INDEX t1a ON z1(a);");
  speedtest1_exec("CREATE INDEX t1b ON z1(b);");
  speedtest1_exec("CREATE INDEX t1ab ON z1(a,b);");
  speedtest1_exec("COMMIT;");
  speedtest1_end_test();

  n = g.szTest/3 + 2;
  speedtest1_begin_test(130, "%d indexed range queries", n);
  speedtest1_prepare("SELECT sum(b) FROM z1 WHERE a BETWEEN ?1 AND ?2");
  for(i=1; i<=n; i++){
    speedtest1_random_ascii_fp(zFP1);
    speedtest1_random_ascii_fp(zFP2);
    sqlite3_bind_text(g.pStmt, 1, zFP1, -1, SQLITE_STATIC);
    sqlite3_bind_text(g.pStmt, 2, zFP2, -1, SQLITE_STATIC);
    speedtest1_run();
  }
  speedtest1_end_test();

  n = g.szTest*5000;
  speedtest1_begin_test(140, "%d calls to round()", n);
  speedtest1_exec("SELECT sum(round(a,2)+round(b,4)) FROM z1;");
  speedtest1_end_test();


  speedtest1_begin_test(150, "%d printf() calls", n*4);
  speedtest1_exec(
    "WITH c(fmt) AS (VALUES('%%g'),('%%e'),('%%!g'),('%%.20f'))"
    "SELECT sum(printf(fmt,a)) FROM z1, c"
  );
  speedtest1_end_test();
}

#ifdef SQLITE_ENABLE_RTREE
/* Generate two numbers between 1 and mx.  The first number is less than
** the second.  Usually the numbers are near each other but can sometimes
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
    sqlite3_bind_int(g.pStmt, 7, z1);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();

  speedtest1_begin_test(101, "Copy from rtree to a regular table");
  speedtest1_exec("CREATE TABLE t1(id INTEGER PRIMARY KEY,x0,x1,y0,y1,z0,z1)");
  speedtest1_exec("INSERT INTO t1 SELECT * FROM rt1");
  speedtest1_end_test();

  n = g.szTest*200;
  speedtest1_begin_test(110, "%d one-dimensional intersect slice queries", n);
  speedtest1_prepare("SELECT count(*) FROM rt1 WHERE x0>=?1 AND x1<=?2");
  iStep = mxCoord/n;
  for(i=0; i<n; i++){
    sqlite3_bind_int(g.pStmt, 1, i*iStep);
    sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
    speedtest1_run();
    aCheck[i] = atoi(g.zResult);
  }
  speedtest1_end_test();

  if( g.bVerify ){
    n = g.szTest*200;
    speedtest1_begin_test(111, "Verify result from 1-D intersect slice queries");
    speedtest1_prepare("SELECT count(*) FROM t1 WHERE x0>=?1 AND x1<=?2");
    iStep = mxCoord/n;
    for(i=0; i<n; i++){
      sqlite3_bind_int(g.pStmt, 1, i*iStep);
      sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
      speedtest1_run();
      if( aCheck[i]!=atoi(g.zResult) ){
        fatal_error("Count disagree step %d: %d..%d.  %d vs %d",







|
|

















|







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
    sqlite3_bind_int(g.pStmt, 7, z1);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();

  speedtest1_begin_test(101, "Copy from rtree to a regular table");
  speedtest1_exec("CREATE TABLE z1(id INTEGER PRIMARY KEY,x0,x1,y0,y1,z0,z1)");
  speedtest1_exec("INSERT INTO z1 SELECT * FROM rt1");
  speedtest1_end_test();

  n = g.szTest*200;
  speedtest1_begin_test(110, "%d one-dimensional intersect slice queries", n);
  speedtest1_prepare("SELECT count(*) FROM rt1 WHERE x0>=?1 AND x1<=?2");
  iStep = mxCoord/n;
  for(i=0; i<n; i++){
    sqlite3_bind_int(g.pStmt, 1, i*iStep);
    sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
    speedtest1_run();
    aCheck[i] = atoi(g.zResult);
  }
  speedtest1_end_test();

  if( g.bVerify ){
    n = g.szTest*200;
    speedtest1_begin_test(111, "Verify result from 1-D intersect slice queries");
    speedtest1_prepare("SELECT count(*) FROM z1 WHERE x0>=?1 AND x1<=?2");
    iStep = mxCoord/n;
    for(i=0; i<n; i++){
      sqlite3_bind_int(g.pStmt, 1, i*iStep);
      sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
      speedtest1_run();
      if( aCheck[i]!=atoi(g.zResult) ){
        fatal_error("Count disagree step %d: %d..%d.  %d vs %d",
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
    aCheck[i] = atoi(g.zResult);
  }
  speedtest1_end_test();

  if( g.bVerify ){
    n = g.szTest*200;
    speedtest1_begin_test(121, "Verify result from 1-D overlap slice queries");
    speedtest1_prepare("SELECT count(*) FROM t1 WHERE y1>=?1 AND y0<=?2");
    iStep = mxCoord/n;
    for(i=0; i<n; i++){
      sqlite3_bind_int(g.pStmt, 1, i*iStep);
      sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
      speedtest1_run();
      if( aCheck[i]!=atoi(g.zResult) ){
        fatal_error("Count disagree step %d: %d..%d.  %d vs %d",







|







1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
    aCheck[i] = atoi(g.zResult);
  }
  speedtest1_end_test();

  if( g.bVerify ){
    n = g.szTest*200;
    speedtest1_begin_test(121, "Verify result from 1-D overlap slice queries");
    speedtest1_prepare("SELECT count(*) FROM z1 WHERE y1>=?1 AND y0<=?2");
    iStep = mxCoord/n;
    for(i=0; i<n; i++){
      sqlite3_bind_int(g.pStmt, 1, i*iStep);
      sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
      speedtest1_run();
      if( aCheck[i]!=atoi(g.zResult) ){
        fatal_error("Count disagree step %d: %d..%d.  %d vs %d",
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
    sqlite3_bind_int(g.pStmt, 1, i*iStep);
    speedtest1_run();
    aCheck[i] = atoi(g.zResult);
  }
  speedtest1_end_test();

  speedtest1_begin_test(170, "Restore deleted entries using INSERT OR IGNORE");
  speedtest1_exec("INSERT OR IGNORE INTO rt1 SELECT * FROM t1");
  speedtest1_end_test();
}
#endif /* SQLITE_ENABLE_RTREE */

/*
** A testset that does key/value storage on tables with many columns.
** This is the kind of workload generated by ORMs such as CoreData.







|







1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
    sqlite3_bind_int(g.pStmt, 1, i*iStep);
    speedtest1_run();
    aCheck[i] = atoi(g.zResult);
  }
  speedtest1_end_test();

  speedtest1_begin_test(170, "Restore deleted entries using INSERT OR IGNORE");
  speedtest1_exec("INSERT OR IGNORE INTO rt1 SELECT * FROM z1");
  speedtest1_end_test();
}
#endif /* SQLITE_ENABLE_RTREE */

/*
** A testset that does key/value storage on tables with many columns.
** This is the kind of workload generated by ORMs such as CoreData.
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
  char zNum[2000];              /* A number name */

  const int NROW  = 500*g.szTest;
  const int NROW2 = 100*g.szTest;

  speedtest1_exec(
      "BEGIN;"
      "CREATE TABLE t1(rowid INTEGER PRIMARY KEY, i INTEGER, t TEXT);"
      "CREATE TABLE t2(rowid INTEGER PRIMARY KEY, i INTEGER, t TEXT);"
      "CREATE TABLE t3(rowid INTEGER PRIMARY KEY, i INTEGER, t TEXT);"
      "CREATE VIEW v1 AS SELECT rowid, i, t FROM t1;"
      "CREATE VIEW v2 AS SELECT rowid, i, t FROM t2;"
      "CREATE VIEW v3 AS SELECT rowid, i, t FROM t3;"
  );
  for(jj=1; jj<=3; jj++){
    speedtest1_prepare("INSERT INTO t%d VALUES(NULL,?1,?2)", jj);
    for(ii=0; ii<NROW; ii++){
      int x1 = speedtest1_random() % NROW;
      speedtest1_numbername(x1, zNum, sizeof(zNum));
      sqlite3_bind_int(g.pStmt, 1, x1);
      sqlite3_bind_text(g.pStmt, 2, zNum, -1, SQLITE_STATIC);
      speedtest1_run();
    }
  }
  speedtest1_exec(
      "CREATE INDEX i1 ON t1(t);"
      "CREATE INDEX i2 ON t2(t);"
      "CREATE INDEX i3 ON t3(t);"
      "COMMIT;"
  );

  speedtest1_begin_test(100, "speed4p-join1");
  speedtest1_prepare(
      "SELECT * FROM t1, t2, t3 WHERE t1.oid = t2.oid AND t2.oid = t3.oid"
  );
  speedtest1_run();
  speedtest1_end_test();

  speedtest1_begin_test(110, "speed4p-join2");
  speedtest1_prepare(
      "SELECT * FROM t1, t2, t3 WHERE t1.t = t2.t AND t2.t = t3.t"
  );
  speedtest1_run();
  speedtest1_end_test();

  speedtest1_begin_test(120, "speed4p-view1");
  for(jj=1; jj<=3; jj++){
    speedtest1_prepare("SELECT * FROM v%d WHERE rowid = ?", jj);







|
|

|
|













|
|






|






|







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
  char zNum[2000];              /* A number name */

  const int NROW  = 500*g.szTest;
  const int NROW2 = 100*g.szTest;

  speedtest1_exec(
      "BEGIN;"
      "CREATE TABLE z1(rowid INTEGER PRIMARY KEY, i INTEGER, t TEXT);"
      "CREATE TABLE z2(rowid INTEGER PRIMARY KEY, i INTEGER, t TEXT);"
      "CREATE TABLE t3(rowid INTEGER PRIMARY KEY, i INTEGER, t TEXT);"
      "CREATE VIEW v1 AS SELECT rowid, i, t FROM z1;"
      "CREATE VIEW v2 AS SELECT rowid, i, t FROM z2;"
      "CREATE VIEW v3 AS SELECT rowid, i, t FROM t3;"
  );
  for(jj=1; jj<=3; jj++){
    speedtest1_prepare("INSERT INTO t%d VALUES(NULL,?1,?2)", jj);
    for(ii=0; ii<NROW; ii++){
      int x1 = speedtest1_random() % NROW;
      speedtest1_numbername(x1, zNum, sizeof(zNum));
      sqlite3_bind_int(g.pStmt, 1, x1);
      sqlite3_bind_text(g.pStmt, 2, zNum, -1, SQLITE_STATIC);
      speedtest1_run();
    }
  }
  speedtest1_exec(
      "CREATE INDEX i1 ON z1(t);"
      "CREATE INDEX i2 ON z2(t);"
      "CREATE INDEX i3 ON t3(t);"
      "COMMIT;"
  );

  speedtest1_begin_test(100, "speed4p-join1");
  speedtest1_prepare(
      "SELECT * FROM z1, z2, t3 WHERE z1.oid = z2.oid AND z2.oid = t3.oid"
  );
  speedtest1_run();
  speedtest1_end_test();

  speedtest1_begin_test(110, "speed4p-join2");
  speedtest1_prepare(
      "SELECT * FROM z1, z2, t3 WHERE z1.t = z2.t AND z2.t = t3.t"
  );
  speedtest1_run();
  speedtest1_end_test();

  speedtest1_begin_test(120, "speed4p-view1");
  for(jj=1; jj<=3; jj++){
    speedtest1_prepare("SELECT * FROM v%d WHERE rowid = ?", jj);
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
      speedtest1_run();
    }
  }
  speedtest1_end_test();

  speedtest1_begin_test(150, "speed4p-subselect1");
  speedtest1_prepare("SELECT "
      "(SELECT t FROM t1 WHERE rowid = ?1),"
      "(SELECT t FROM t2 WHERE rowid = ?1),"
      "(SELECT t FROM t3 WHERE rowid = ?1)"
  );
  for(jj=0; jj<NROW2; jj++){
    sqlite3_bind_int(g.pStmt, 1, jj*3);
    speedtest1_run();
  }
  speedtest1_end_test();

  speedtest1_begin_test(160, "speed4p-rowid-update");
  speedtest1_exec("BEGIN");
  speedtest1_prepare("UPDATE t1 SET i=i+1 WHERE rowid=?1");
  for(jj=0; jj<NROW2; jj++){
    sqlite3_bind_int(g.pStmt, 1, jj);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();

  speedtest1_exec("CREATE TABLE t5(t TEXT PRIMARY KEY, i INTEGER);");
  speedtest1_begin_test(170, "speed4p-insert-ignore");
  speedtest1_exec("INSERT OR IGNORE INTO t5 SELECT t, i FROM t1");
  speedtest1_end_test();

  speedtest1_exec(
      "CREATE TABLE log(op TEXT, r INTEGER, i INTEGER, t TEXT);"
      "CREATE TABLE t4(rowid INTEGER PRIMARY KEY, i INTEGER, t TEXT);"
      "CREATE TRIGGER t4_trigger1 AFTER INSERT ON t4 BEGIN"
      "  INSERT INTO log VALUES('INSERT INTO t4', new.rowid, new.i, new.t);"







|
|










|









|







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
      speedtest1_run();
    }
  }
  speedtest1_end_test();

  speedtest1_begin_test(150, "speed4p-subselect1");
  speedtest1_prepare("SELECT "
      "(SELECT t FROM z1 WHERE rowid = ?1),"
      "(SELECT t FROM z2 WHERE rowid = ?1),"
      "(SELECT t FROM t3 WHERE rowid = ?1)"
  );
  for(jj=0; jj<NROW2; jj++){
    sqlite3_bind_int(g.pStmt, 1, jj*3);
    speedtest1_run();
  }
  speedtest1_end_test();

  speedtest1_begin_test(160, "speed4p-rowid-update");
  speedtest1_exec("BEGIN");
  speedtest1_prepare("UPDATE z1 SET i=i+1 WHERE rowid=?1");
  for(jj=0; jj<NROW2; jj++){
    sqlite3_bind_int(g.pStmt, 1, jj);
    speedtest1_run();
  }
  speedtest1_exec("COMMIT");
  speedtest1_end_test();

  speedtest1_exec("CREATE TABLE t5(t TEXT PRIMARY KEY, i INTEGER);");
  speedtest1_begin_test(170, "speed4p-insert-ignore");
  speedtest1_exec("INSERT OR IGNORE INTO t5 SELECT t, i FROM z1");
  speedtest1_end_test();

  speedtest1_exec(
      "CREATE TABLE log(op TEXT, r INTEGER, i INTEGER, t TEXT);"
      "CREATE TABLE t4(rowid INTEGER PRIMARY KEY, i INTEGER, t TEXT);"
      "CREATE TRIGGER t4_trigger1 AFTER INSERT ON t4 BEGIN"
      "  INSERT INTO log VALUES('INSERT INTO t4', new.rowid, new.i, new.t);"
Added test/startup.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
/*
** 2021-01-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 file implements a program used to measure the start-up performance
** of SQLite.
**
** To use:
**
**     ./startup init
**     valgrind --tool=cachegrind ./startup run
**
**
** The "./startup init" command creates the test database file named
** "startup.db".  The performance test is run by the "./startup run"
** command.  That command does nothing but open the database file and
** parse the entire schema.
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "sqlite3.h"

static const char zHelp[] =
  "Usage: %s COMMAND\n"
  "Commands:\n"
  "  init                Initialized the startup.db database file\n"
  "  run                 Run the startup performance test\n"
  "Options:\n"
  "  --dbname NAME       Set the name of the test database file\n"
  "  --heap SZ MIN       Memory allocator uses SZ bytes & min allocation MIN\n"
  "  --stats             Show statistics at the end\n"
/* TBD
  "  --journal M         Set the journal_mode to M\n"
  "  --lookaside N SZ    Configure lookaside for N slots of SZ bytes each\n"
  "  --mmap SZ           MMAP the first SZ bytes of the database file\n"
  "  --multithread       Set multithreaded mode\n"
  "  --nomemstat         Disable memory statistics\n"
  "  --pagesize N        Set the page size to N\n"
  "  --pcache N SZ       Configure N pages of pagecache each of size SZ bytes\n"
  "  --serialized        Set serialized threading mode\n"
  "  --singlethread      Set single-threaded mode - disables all mutexing\n"
  "  --utf16be           Set text encoding to UTF-16BE\n"
  "  --utf16le           Set text encoding to UTF-16LE\n"
  "  --utf8              Set text encoding to UTF-8\n"
*/
;

static void usage(const char *argv0){
  printf(zHelp, argv0);
  exit(1);
}

/*
** The test schema is derived from the Fossil repository for SQLite itself.
** The schema covers the repository, the local checkout database, and
** the global configuration database.
*/
static const char zTestSchema[] = 
  "CREATE TABLE repo_blob(\n"
  "  rid INTEGER PRIMARY KEY,\n"
  "  rcvid INTEGER,\n"
  "  size INTEGER,\n"
  "  uuid TEXT UNIQUE NOT NULL,\n"
  "  content BLOB,\n"
  "  CHECK( length(uuid)>=40 AND rid>0 )\n"
  ");\n"
  "CREATE TABLE repo_delta(\n"
  "  rid INTEGER PRIMARY KEY,\n"
  "  srcid INTEGER NOT NULL REFERENCES blob\n"
  ");\n"
  "CREATE TABLE repo_rcvfrom(\n"
  "  rcvid INTEGER PRIMARY KEY,\n"
  "  uid INTEGER REFERENCES user,\n"
  "  mtime DATETIME,\n"
  "  nonce TEXT UNIQUE,\n"
  "  ipaddr TEXT\n"
  ");\n"
  "CREATE TABLE repo_private(rid INTEGER PRIMARY KEY);\n"
  "CREATE TABLE repo_accesslog(\n"
  "  uname TEXT,\n"
  "  ipaddr TEXT,\n"
  "  success BOOLEAN,\n"
  "  mtime TIMESTAMP);\n"
  "CREATE TABLE repo_user(\n"
  "  uid INTEGER PRIMARY KEY,\n"
  "  login TEXT UNIQUE,\n"
  "  pw TEXT,\n"
  "  cap TEXT,\n"
  "  cookie TEXT,\n"
  "  ipaddr TEXT,\n"
  "  cexpire DATETIME,\n"
  "  info TEXT,\n"
  "  mtime DATE,\n"
  "  photo BLOB\n"
  ");\n"
  "CREATE TABLE repo_reportfmt(\n"
  "   rn INTEGER PRIMARY KEY,\n"
  "   owner TEXT,\n"
  "   title TEXT UNIQUE,\n"
  "   mtime INTEGER,\n"
  "   cols TEXT,\n"
  "   sqlcode TEXT\n"
  ");\n"
  "CREATE TABLE repo_sqlite_stat2(tbl,idx,sampleno,sample);\n"
  "CREATE TABLE repo_sqlite_stat1(tbl,idx,stat);\n"
  "CREATE TABLE repo_sqlite_stat3(tbl,idx,neq,nlt,ndlt,sample);\n"
  "CREATE TABLE repo_config(\n"
  "  name TEXT PRIMARY KEY NOT NULL,\n"
  "  value CLOB, mtime INTEGER,\n"
  "  CHECK( typeof(name)='text' AND length(name)>=1 )\n"
  ") WITHOUT ROWID;\n"
  "CREATE TABLE repo_shun(uuid PRIMARY KEY,\n"
  "  mtime INTEGER,\n"
  "  scom TEXT) WITHOUT ROWID;\n"
  "CREATE TABLE repo_concealed(\n"
  "  hash TEXT PRIMARY KEY,\n"
  "  content TEXT\n"
  ", mtime INTEGER) WITHOUT ROWID;\n"
  "CREATE TABLE repo_admin_log(\n"
  " id INTEGER PRIMARY KEY,\n"
  " time INTEGER, -- Seconds since 1970\n"
  " page TEXT,    -- path of page\n"
  " who TEXT,     -- User who made the change\n"
  "  what TEXT     -- What changed\n"
  ");\n"
  "CREATE TABLE repo_unversioned(\n"
  "  name TEXT PRIMARY KEY,\n"
  "  rcvid INTEGER,\n"
  "  mtime DATETIME,\n"
  "  hash TEXT,\n"
  "  sz INTEGER,\n"
  "  encoding INT,\n"
  "  content BLOB\n"
  ") WITHOUT ROWID;\n"
  "CREATE TABLE repo_subscriber(\n"
  "  subscriberId INTEGER PRIMARY KEY,\n"
  "  subscriberCode BLOB DEFAULT (randomblob(32)) UNIQUE,\n"
  "  semail TEXT UNIQUE COLLATE nocase,\n"
  "  suname TEXT,\n"
  "  sverified BOOLEAN DEFAULT true,\n"
  "  sdonotcall BOOLEAN,\n"
  "  sdigest BOOLEAN,\n"
  "  ssub TEXT,\n"
  "  sctime INTDATE,\n"
  "  mtime INTDATE,\n"
  "  smip TEXT\n"
  ");\n"
  "CREATE TABLE repo_pending_alert(\n"
  "  eventid TEXT PRIMARY KEY,\n"
  "  sentSep BOOLEAN DEFAULT false,\n"
  "  sentDigest BOOLEAN DEFAULT false\n"
  ", sentMod BOOLEAN DEFAULT false) WITHOUT ROWID;\n"
  "CREATE INDEX repo_delta_i1 ON repo_delta(srcid);\n"
  "CREATE INDEX repo_blob_rcvid ON repo_blob(rcvid);\n"
  "CREATE INDEX repo_subscriberUname\n"
  "  ON repo_subscriber(suname) WHERE suname IS NOT NULL;\n"
  "CREATE VIEW repo_artifact(rid,rcvid,size,atype,srcid,hash,content) AS\n"
  "     SELECT blob.rid,rcvid,size,1,srcid,uuid,content\n"
  "       FROM repo_blob LEFT JOIN repo_delta ON (blob.rid=delta.rid);\n"
  "CREATE TABLE repo_filename(\n"
  "  fnid INTEGER PRIMARY KEY,\n"
  "  name TEXT UNIQUE\n"
  ");\n"
  "CREATE TABLE repo_mlink(\n"
  "  mid INTEGER,\n"
  "  fid INTEGER,\n"
  "  pmid INTEGER,\n"
  "  pid INTEGER,\n"
  "  fnid INTEGER REFERENCES filename,\n"
  "  pfnid INTEGER,\n"
  "  mperm INTEGER,\n"
  "  isaux BOOLEAN DEFAULT 0\n"
  ");\n"
  "CREATE INDEX repo_mlink_i1 ON repo_mlink(mid);\n"
  "CREATE INDEX repo_mlink_i2 ON repo_mlink(fnid);\n"
  "CREATE INDEX repo_mlink_i3 ON repo_mlink(fid);\n"
  "CREATE INDEX repo_mlink_i4 ON repo_mlink(pid);\n"
  "CREATE TABLE repo_plink(\n"
  "  pid INTEGER REFERENCES blob,\n"
  "  cid INTEGER REFERENCES blob,\n"
  "  isprim BOOLEAN,\n"
  "  mtime DATETIME,\n"
  "  baseid INTEGER REFERENCES blob,\n"
  "  UNIQUE(pid, cid)\n"
  ");\n"
  "CREATE INDEX repo_plink_i2 ON repo_plink(cid,pid);\n"
  "CREATE TABLE repo_leaf(rid INTEGER PRIMARY KEY);\n"
  "CREATE TABLE repo_event(\n"
  "  type TEXT,\n"
  "  mtime DATETIME,\n"
  "  objid INTEGER PRIMARY KEY,\n"
  "  tagid INTEGER,\n"
  "  uid INTEGER REFERENCES user,\n"
  "  bgcolor TEXT,\n"
  "  euser TEXT,\n"
  "  user TEXT,\n"
  "  ecomment TEXT,\n"
  "  comment TEXT,\n"
  "  brief TEXT,\n"
  "  omtime DATETIME\n"
  ");\n"
  "CREATE INDEX repo_event_i1 ON repo_event(mtime);\n"
  "CREATE TABLE repo_phantom(\n"
  "  rid INTEGER PRIMARY KEY\n"
  ");\n"
  "CREATE TABLE repo_orphan(\n"
  "  rid INTEGER PRIMARY KEY,\n"
  "  baseline INTEGER\n"
  ");\n"
  "CREATE INDEX repo_orphan_baseline ON repo_orphan(baseline);\n"
  "CREATE TABLE repo_unclustered(\n"
  "  rid INTEGER PRIMARY KEY\n"
  ");\n"
  "CREATE TABLE repo_unsent(\n"
  "  rid INTEGER PRIMARY KEY\n"
  ");\n"
  "CREATE TABLE repo_tag(\n"
  "  tagid INTEGER PRIMARY KEY,\n"
  "  tagname TEXT UNIQUE\n"
  ");\n"
  "CREATE TABLE repo_tagxref(\n"
  "  tagid INTEGER REFERENCES tag,\n"
  "  tagtype INTEGER,\n"
  "  srcid INTEGER REFERENCES blob,\n"
  "  origid INTEGER REFERENCES blob,\n"
  "  value TEXT,\n"
  "  mtime TIMESTAMP,\n"
  "  rid INTEGER REFERENCE blob,\n"
  "  UNIQUE(rid, tagid)\n"
  ");\n"
  "CREATE INDEX repo_tagxref_i1 ON repo_tagxref(tagid, mtime);\n"
  "CREATE TABLE repo_backlink(\n"
  "  target TEXT,\n"
  "  srctype INT,\n"
  "  srcid INT,\n"
  "  mtime TIMESTAMP,\n"
  "  UNIQUE(target, srctype, srcid)\n"
  ");\n"
  "CREATE INDEX repo_backlink_src ON repo_backlink(srcid, srctype);\n"
  "CREATE TABLE repo_attachment(\n"
  "  attachid INTEGER PRIMARY KEY,\n"
  "  isLatest BOOLEAN DEFAULT 0,\n"
  "  mtime TIMESTAMP,\n"
  "  src TEXT,\n"
  "  target TEXT,\n"
  "  filename TEXT,\n"
  "  comment TEXT,\n"
  "  user TEXT\n"
  ");\n"
  "CREATE INDEX repo_attachment_idx1\n"
  " ON repo_attachment(target, filename, mtime);\n"
  "CREATE INDEX repo_attachment_idx2 ON repo_attachment(src);\n"
  "CREATE TABLE repo_cherrypick(\n"
  "  parentid INT,\n"
  "  childid INT,\n"
  "  isExclude BOOLEAN DEFAULT false,\n"
  "  PRIMARY KEY(parentid, childid)\n"
  ") WITHOUT ROWID;\n"
  "CREATE INDEX repo_cherrypick_cid ON repo_cherrypick(childid);\n"
  "CREATE TABLE repo_ticket(\n"
  "  -- Do not change any column that begins with tkt_\n"
  "  tkt_id INTEGER PRIMARY KEY,\n"
  "  tkt_uuid TEXT UNIQUE,\n"
  "  tkt_mtime DATE,\n"
  "  tkt_ctime DATE,\n"
  "  -- Add as many fields as required below this line\n"
  "  type TEXT,\n"
  "  status TEXT,\n"
  "  subsystem TEXT,\n"
  "  priority TEXT,\n"
  "  severity TEXT,\n"
  "  foundin TEXT,\n"
  "  private_contact TEXT,\n"
  "  resolution TEXT,\n"
  "  title TEXT,\n"
  "  comment TEXT\n"
  ");\n"
  "CREATE TABLE repo_ticketchng(\n"
  "  -- Do not change any column that begins with tkt_\n"
  "  tkt_id INTEGER REFERENCES ticket,\n"
  "  tkt_rid INTEGER REFERENCES blob,\n"
  "  tkt_mtime DATE,\n"
  "  -- Add as many fields as required below this line\n"
  "  login TEXT,\n"
  "  username TEXT,\n"
  "  mimetype TEXT,\n"
  "  icomment TEXT\n"
  ");\n"
  "CREATE INDEX repo_ticketchng_idx1 ON repo_ticketchng(tkt_id, tkt_mtime);\n"
  "CREATE TRIGGER repo_alert_trigger1\n"
  "AFTER INSERT ON repo_event BEGIN\n"
  "  INSERT INTO repo_pending_alert(eventid)\n"
  "    SELECT printf('%.1c%d',new.type,new.objid) WHERE true\n"
  "    ON CONFLICT(eventId) DO NOTHING;\n"
  "END;\n"
  "CREATE TABLE repo_vcache(\n"
  "  vid INTEGER,         -- check-in ID\n"
  "  fname TEXT,          -- filename\n"
  "  rid INTEGER,         -- artifact ID\n"
  "  PRIMARY KEY(vid,fname)\n"
  ") WITHOUT ROWID;\n"
  "CREATE TABLE localdb_vvar(\n"
  "  name TEXT PRIMARY KEY NOT NULL,\n"
  "  value CLOB,\n"
  "  CHECK( typeof(name)='text' AND length(name)>=1 )\n"
  ");\n"
  "CREATE TABLE localdb_vfile(\n"
  "  id INTEGER PRIMARY KEY,\n"
  "  vid INTEGER REFERENCES blob,\n"
  "  chnged INT DEFAULT 0,\n"
  "  deleted BOOLEAN DEFAULT 0,\n"
  "  isexe BOOLEAN,\n"
  "  islink BOOLEAN,\n"
  "  rid INTEGER,\n"
  "  mrid INTEGER,\n"
  "  mtime INTEGER,\n"
  "  pathname TEXT,\n"
  "  origname TEXT, mhash,\n"
  "  UNIQUE(pathname,vid)\n"
  ");\n"
  "CREATE TABLE localdb_sqlite_stat1(tbl,idx,stat);\n"
  "CREATE TABLE localdb_vcache(\n"
  "  vid INTEGER,         -- check-in ID\n"
  "  fname TEXT,          -- filename\n"
  "  rid INTEGER,         -- artifact ID\n"
  "  PRIMARY KEY(vid,fname)\n"
  ") WITHOUT ROWID;\n"
  "CREATE TABLE localdb_stash(\n"
  "  stashid INTEGER PRIMARY KEY,\n"
  "  vid INTEGER,\n"
  "  hash TEXT,\n"
  "  comment TEXT,\n"
  "  ctime TIMESTAMP\n"
  ");\n"
  "CREATE TABLE localdb_stashfile(\n"
  "  stashid INTEGER REFERENCES stash,\n"
  "  isAdded BOOLEAN,\n"
  "  isRemoved BOOLEAN,\n"
  "  isExec BOOLEAN,\n"
  "  isLink BOOLEAN,\n"
  "  rid INTEGER,\n"
  "  hash TEXT,\n"
  "  origname TEXT,\n"
  "  newname TEXT,\n"
  "  delta BLOB,\n"
  "  PRIMARY KEY(newname, stashid)\n"
  ");\n"
  "CREATE TABLE localdb_vmerge(\n"
  "  id INTEGER REFERENCES vfile,\n"
  "  merge INTEGER,\n"
  "  mhash TEXT\n"
  ");\n"
  "CREATE UNIQUE INDEX localdb_vmergex1 ON localdb_vmerge(id,mhash);\n"
  "CREATE TRIGGER localdb_vmerge_ck1 AFTER INSERT ON localdb_vmerge\n"
  "WHEN new.mhash IS NULL BEGIN\n"
  "  SELECT raise(FAIL,\n"
  "  'trying to update a newer checkout with an older version of Fossil');\n"
  "END;\n"
  "CREATE TABLE configdb_global_config(\n"
  "  name TEXT PRIMARY KEY,\n"
  "  value TEXT\n"
  ");\n"
  "CREATE TABLE configdb_sqlite_stat1(tbl,idx,stat);\n"
;

#ifdef __linux__
#include <sys/types.h>
#include <unistd.h>

/*
** Attempt to display I/O stats on Linux using /proc/PID/io
*/
static void displayLinuxIoStats(FILE *out){
  FILE *in;
  char z[200];
  sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
  in = fopen(z, "rb");
  if( in==0 ) return;
  while( fgets(z, sizeof(z), in)!=0 ){
    static const struct {
      const char *zPattern;
      const char *zDesc;
    } aTrans[] = {
      { "rchar: ",                  "Bytes received by read():" },
      { "wchar: ",                  "Bytes sent to write():"    },
      { "syscr: ",                  "Read() system calls:"      },
      { "syscw: ",                  "Write() system calls:"     },
      { "read_bytes: ",             "Bytes rcvd from storage:"  },
      { "write_bytes: ",            "Bytes sent to storage:"    },
      { "cancelled_write_bytes: ",  "Cancelled write bytes:"    },
    };
    int i;
    for(i=0; i<sizeof(aTrans)/sizeof(aTrans[0]); i++){
      int n = (int)strlen(aTrans[i].zPattern);
      if( strncmp(aTrans[i].zPattern, z, n)==0 ){
        fprintf(out, "-- %-28s %s", aTrans[i].zDesc, &z[n]);
        break;
      }
    }
  }
  fclose(in);
}   
#endif

/*
** Return the value of a hexadecimal digit.  Return -1 if the input
** is not a hex digit.
*/
static int hexDigitValue(char c){
  if( c>='0' && c<='9' ) return c - '0';
  if( c>='a' && c<='f' ) return c - 'a' + 10;
  if( c>='A' && c<='F' ) return c - 'A' + 10;
  return -1;
}

/*
** Interpret zArg as an integer value, possibly with suffixes.
*/
static int integerValue(const char *zArg){
  sqlite3_int64 v = 0;
  static const struct { char *zSuffix; int iMult; } aMult[] = {
    { "KiB", 1024 },
    { "MiB", 1024*1024 },
    { "GiB", 1024*1024*1024 },
    { "KB",  1000 },
    { "MB",  1000000 },
    { "GB",  1000000000 },
    { "K",   1000 },
    { "M",   1000000 },
    { "G",   1000000000 },
  };
  int i;
  int isNeg = 0;
  if( zArg[0]=='-' ){
    isNeg = 1;
    zArg++;
  }else if( zArg[0]=='+' ){
    zArg++;
  }
  if( zArg[0]=='0' && zArg[1]=='x' ){
    int x;
    zArg += 2;
    while( (x = hexDigitValue(zArg[0]))>=0 ){
      v = (v<<4) + x;
      zArg++;
    }
  }else{
    while( isdigit(zArg[0]) ){
      v = v*10 + zArg[0] - '0';
      zArg++;
    }
  }
  for(i=0; i<sizeof(aMult)/sizeof(aMult[0]); i++){
    if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
      v *= aMult[i].iMult;
      break;
    }
  }
  if( v>0x7fffffff ){
    printf("ERROR: parameter too large - max 2147483648\n");
    exit(1);
  }
  return (int)(isNeg? -v : v);
}


int main(int argc, char **argv){
  const char *zCmd = 0;
  int i;
  int bAutovac = 0;
  int showStats = 0;
  const char *zDbName = "./startup.db";
  int nHeap = 0;
  int mnHeap = 0;

  for(i=1; i<argc; i++){
    const char *z = argv[i];
    if( z[0]!='-' ){
      if( zCmd ){
        usage(argv[0]);
      }
      zCmd = z;
      continue;
    }
    if( z[1]=='-' ) z++;
    if( strcmp(z, "-autovacuum")==0 ){
      bAutovac = 1;
    }else
    if( strcmp(z, "-dbname")==0 ){
      if( i==argc-1 ){
        printf("ERROR: missing argument on \"%s\"\n", argv[0]);
        exit(1);
      }
      zDbName = argv[++i];
    }else
    if( strcmp(z,"-heap")==0 ){
      if( i>=argc-2 ){
        printf("ERROR: missing arguments on %s\n", argv[i]);
        exit(1);
      }
      nHeap = integerValue(argv[i+1]);
      mnHeap = integerValue(argv[i+2]);
      i += 2;
    }else
    if( strcmp(z,"-stats")==0 ){
       showStats = 1;
    }else
    {
      printf("ERROR: unknown option \"%s\"\n", argv[i]);
      usage(argv[0]);
    }
  }
  if( zCmd==0 ){
    printf("ERROR: no COMMAND specified\n");
    usage(argv[0]);
  }
  if( strcmp(zCmd, "run")==0 ){
    sqlite3 *db;
    int rc;
    char *zErr = 0;
    void *pHeap = 0;
    if( nHeap>0 ){
      pHeap = malloc( nHeap );
      if( pHeap==0 ){
        printf("ERROR: cannot allocate %d-byte heap\n", nHeap);
        exit(1);
      }
      rc = sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nHeap, mnHeap);
      if( rc ){
        printf("ERROR: heap configuration failed: %d\n", rc);
        exit(1);
      }
    }
    rc = sqlite3_open(zDbName, &db);
    if( rc ){
      printf("SQLite error: %s\n", sqlite3_errmsg(db));
    }else{
      sqlite3_exec(db, "PRAGMA synchronous", 0, 0, &zErr);
    }
    if( zErr ){
      printf("ERROR: %s\n", zErr);
      sqlite3_free(zErr);
    }
    if( showStats ){
      int iCur, iHi;
      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHi, 0);
      printf("-- Lookaside Slots Used:        %d (max %d)\n", iCur,iHi);
      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHi, 0);
      printf("-- Successful lookasides:       %d\n", iHi);
      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur,&iHi,0);
      printf("-- Lookaside size faults:       %d\n", iHi);
      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur,&iHi,0);
      printf("-- Lookaside OOM faults:        %d\n", iHi);
      sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHi, 0);
      printf("-- Pager Heap Usage:            %d bytes\n", iCur);
      sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHi, 1);
      printf("-- Page cache hits:             %d\n", iCur);
      sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHi, 1);
      printf("-- Page cache misses:           %d\n", iCur);
      sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHi, 1);
      printf("-- Page cache writes:           %d\n", iCur); 
      sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHi, 0);
      printf("-- Schema Heap Usage:           %d bytes\n", iCur); 
      sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHi, 0);
      printf("-- Statement Heap Usage:        %d bytes\n", iCur); 
    }
    sqlite3_close(db);
    free(pHeap);
    /* Global memory usage statistics printed after the database connection
    ** has closed.  Memory usage should be zero at this point. */
    if( showStats ){
      int iCur, iHi;
      sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHi, 0);
      printf("-- Memory Used (bytes):         %d (max %d)\n", iCur,iHi);
      sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHi, 0);
      printf("-- Outstanding Allocations:     %d (max %d)\n", iCur,iHi);
      sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHi, 0);
      printf("-- Pcache Overflow Bytes:       %d (max %d)\n", iCur,iHi);
      sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHi, 0);
      printf("-- Largest Allocation:          %d bytes\n",iHi);
      sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHi, 0);
      printf("-- Largest Pcache Allocation:   %d bytes\n",iHi);
#ifdef __linux__
      displayLinuxIoStats(stdout);
#endif
    }
    return 0;
  }
  if( strcmp(zCmd, "init")==0 ){
    sqlite3 *db;
    char *zAux;
    char *zErr = 0;
    int rc;
    unlink(zDbName);
    zAux = sqlite3_mprintf("%s-journal", zDbName);
    unlink(zAux);
    sqlite3_free(zAux);
    zAux = sqlite3_mprintf("%s-wal", zDbName);
    unlink(zAux);
    sqlite3_free(zAux);
    rc = sqlite3_open(zDbName, &db);
    if( rc ){
      printf("SQLite error: %s\n", sqlite3_errmsg(db));
    }else{
      sqlite3_exec(db, "BEGIN", 0, 0, 0);
      sqlite3_exec(db, zTestSchema, 0, 0, &zErr);
      sqlite3_exec(db, "COMMIT", 0, 0, 0);
    }
    if( zErr ){
      printf("ERROR: %s\n", zErr);
      sqlite3_free(zErr);
    }
    sqlite3_close(db);
    return 0;

  }
}
Changes to test/tester.tcl.
170
171
172
173
174
175
176






177
178
179
180
181
182
183
184
185
proc get_pwd {} {
  if {$::tcl_platform(platform) eq "windows"} {
    #
    # NOTE: Cannot use [file normalize] here because it would alter the
    #       case of the result to what Tcl considers canonical, which would
    #       defeat the purpose of this procedure.
    #






    return [string map [list \\ /] \
        [string trim [exec -- $::env(ComSpec) /c echo %CD%]]]
  } else {
    return [pwd]
  }
}

# Copy file $from into $to. This is used because some versions of
# TCL for windows (notably the 8.4.1 binary package shipped with the







>
>
>
>
>
>

|







170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
proc get_pwd {} {
  if {$::tcl_platform(platform) eq "windows"} {
    #
    # NOTE: Cannot use [file normalize] here because it would alter the
    #       case of the result to what Tcl considers canonical, which would
    #       defeat the purpose of this procedure.
    #
    if {[info exists ::env(ComSpec)]} {
      set comSpec $::env(ComSpec)
    } else {
      # NOTE: Hard-code the typical default value.
      set comSpec {C:\Windows\system32\cmd.exe}
    }
    return [string map [list \\ /] \
        [string trim [exec -- $comSpec /c echo %CD%]]]
  } else {
    return [pwd]
  }
}

# Copy file $from into $to. This is used because some versions of
# TCL for windows (notably the 8.4.1 binary package shipped with the
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
  # puts [dumpbytes $msg]
  list $rc $msg
}

proc filepath_normalize {p} {
  # test cases should be written to assume "unix"-like file paths
  if {$::tcl_platform(platform)!="unix"} {
    # lreverse*2 as a hack to remove any unneeded {} after the string map
    lreverse [lreverse [string map {\\ /} [regsub -nocase -all {[a-z]:[/\\]+} $p {/}]]]
  } {
    set p
  }
}
proc do_filepath_test {name cmd expected} {
  uplevel [list do_test $name [
    subst -nocommands { filepath_normalize [ $cmd ] }







|
|







904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
  # puts [dumpbytes $msg]
  list $rc $msg
}

proc filepath_normalize {p} {
  # test cases should be written to assume "unix"-like file paths
  if {$::tcl_platform(platform)!="unix"} {
    string map [list \\ / \{/ / .db\} .db] \
        [regsub -nocase -all {[a-z]:[/\\]+} $p {/}]
  } {
    set p
  }
}
proc do_filepath_test {name cmd expected} {
  uplevel [list do_test $name [
    subst -nocommands { filepath_normalize [ $cmd ] }
1685
1686
1687
1688
1689
1690
1691


1692
1693
1694

1695
1696
1697
1698
1699
1700
1701

  # $crashfile gets compared to the native filename in
  # cfSync(), which can be different then what TCL uses by
  # default, so here we force it to the "nativename" format.
  set cfile [string map {\\ \\\\} [file nativename [file join [get_pwd] $crashfile]]]

  set f [open crash.tcl w]


  puts $f "sqlite3_crash_enable 1 $dfltvfs"
  puts $f "sqlite3_crashparams $blocksize $dc $crashdelay $cfile"
  puts $f "sqlite3_test_control_pending_byte $::sqlite_pending_byte"


  # This block sets the cache size of the main database to 10
  # pages. This is done in case the build is configured to omit
  # "PRAGMA cache_size".
  if {$opendb!=""} {
    puts $f $opendb 
    puts $f {db eval {SELECT * FROM sqlite_master;}}







>
>



>







1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710

  # $crashfile gets compared to the native filename in
  # cfSync(), which can be different then what TCL uses by
  # default, so here we force it to the "nativename" format.
  set cfile [string map {\\ \\\\} [file nativename [file join [get_pwd] $crashfile]]]

  set f [open crash.tcl w]
  puts $f "sqlite3_initialize ; sqlite3_shutdown"
  puts $f "catch { install_malloc_faultsim 1 }"
  puts $f "sqlite3_crash_enable 1 $dfltvfs"
  puts $f "sqlite3_crashparams $blocksize $dc $crashdelay $cfile"
  puts $f "sqlite3_test_control_pending_byte $::sqlite_pending_byte"
  puts $f "autoinstall_test_functions"

  # This block sets the cache size of the main database to 10
  # pages. This is done in case the build is configured to omit
  # "PRAGMA cache_size".
  if {$opendb!=""} {
    puts $f $opendb 
    puts $f {db eval {SELECT * FROM sqlite_master;}}
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
  if {[string length $sql]>0} {
    puts $f "db eval {"
    puts $f   "$sql"
    puts $f "}"
  }
  close $f
  set r [catch {
    exec [info nameofexec] crash.tcl >@stdout
  } msg]

  # Windows/ActiveState TCL returns a slightly different
  # error message.  We map that to the expected message
  # so that we don't have to change all of the test
  # cases.
  if {$::tcl_platform(platform)=="windows"} {







|







1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
  if {[string length $sql]>0} {
    puts $f "db eval {"
    puts $f   "$sql"
    puts $f "}"
  }
  close $f
  set r [catch {
    exec [info nameofexec] crash.tcl >@stdout 2>@stdout
  } msg]

  # Windows/ActiveState TCL returns a slightly different
  # error message.  We map that to the expected message
  # so that we don't have to change all of the test
  # cases.
  if {$::tcl_platform(platform)=="windows"} {
Changes to test/trace3.test.
246
247
248
249
250
251
252















































































253
254

do_test trace3-11.2 {
  set ::stmtlist(record) {}
  db trace_v2 trace_v2_record 8
  db close
  set ::stmtlist(record)
} {/^-?\d+$/}
















































































finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


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

do_test trace3-11.2 {
  set ::stmtlist(record) {}
  db trace_v2 trace_v2_record 8
  db close
  set ::stmtlist(record)
} {/^-?\d+$/}

#-------------------------------------------------------------------------
reset_db
do_test 12.1.0 {
  set ::STMT [sqlite3_prepare_v2 $DB \
    "SELECT ?1 || ?1 || ?1 || ?2 || ?3 || ?4 || ? || ?1 || ?" -1 TAIL
  ]
  sqlite3_bind_parameter_count $::STMT
} {6}

do_test 12.1.1 {
  sqlite3_bind_text $STMT 1 "A" 1
  sqlite3_bind_text $STMT 2 "B" 1
  sqlite3_bind_text $STMT 3 "C" 1
  sqlite3_bind_text $STMT 4 "D" 1
  sqlite3_bind_text $STMT 5 "E" 1
  sqlite3_bind_text $STMT 6 "F" 1
  sqlite3_expanded_sql $STMT
} {SELECT 'A' || 'A' || 'A' || 'B' || 'C' || 'D' || 'E' || 'A' || 'F'}

do_test 12.1.2 {
  sqlite3_step $STMT
  sqlite3_column_text $STMT 0
} {AAABCDEAF}

do_test 12.1.3 {
  sqlite3_finalize $STMT
} {SQLITE_OK}

do_test 12.2.0 {
  execsql {
    CREATE TABLE nameFtsFuzzySearchTable(
      word, distance, langid, score, top, scope
    );
  }
  set ::STMT [sqlite3_prepare_v2 $DB {
    SELECT
      substr(word,1,length(?1)-1) AS term,
      distance,
      langid,
      score
    FROM
      nameFtsFuzzySearchTable
    WHERE
      word MATCH (?1) AND abs(?1) = abs(term)
      AND top = ?2 AND distance > ?3 AND scope = ?4 AND langid = ?
    GROUP BY term, langid 
    HAVING (1.0 - ((distance / 100.0) / CAST( length(?1) - 1 AS REAL ))) >= ?
  } -1 TAIL]
  sqlite3_bind_parameter_count $::STMT
} {6}

do_test 12.1.1 {
  sqlite3_bind_text $STMT 1 "A" 1
  sqlite3_bind_text $STMT 2 "B" 1
  sqlite3_bind_text $STMT 3 "C" 1
  sqlite3_bind_text $STMT 4 "D" 1
  sqlite3_bind_text $STMT 5 "E" 1
  sqlite3_bind_text $STMT 6 "F" 1
  sqlite3_expanded_sql $STMT
} {
    SELECT
      substr(word,1,length('A')-1) AS term,
      distance,
      langid,
      score
    FROM
      nameFtsFuzzySearchTable
    WHERE
      word MATCH ('A') AND abs('A') = abs(term)
      AND top = 'B' AND distance > 'C' AND scope = 'D' AND langid = 'E'
    GROUP BY term, langid 
    HAVING (1.0 - ((distance / 100.0) / CAST( length('A') - 1 AS REAL ))) >= 'F'
  }

do_test 12.1.2 {
  sqlite3_finalize $STMT
} {SQLITE_OK}


finish_test
Changes to test/triggerE.test.
54
55
56
57
58
59
60


61
62
63
64
65
66
67
  3 { BEFORE DELETE ON t1 BEGIN SELECT * FROM (SELECT * FROM (SELECT ?)); END; }
  5 { BEFORE DELETE ON t1 BEGIN SELECT * FROM t2 GROUP BY ?; END; }
  6 { BEFORE DELETE ON t1 BEGIN SELECT * FROM t2 LIMIT ?; END; }
  7 { BEFORE DELETE ON t1 BEGIN SELECT * FROM t2 ORDER BY ?; END; }
  8 { BEFORE UPDATE ON t1 BEGIN UPDATE t2 SET c = ?; END; }
  9 { BEFORE UPDATE ON t1 BEGIN UPDATE t2 SET c = 1 WHERE d = ?; END; }
 10 { AFTER INSERT ON t1 BEGIN SELECT * FROM pragma_stats(?); END; }


} {
  catchsql {drop trigger tr1}
  do_catchsql_test 1.1.$tn "CREATE TRIGGER tr1 $defn" [list 1 $errmsg]
  do_catchsql_test 1.2.$tn "CREATE TEMP TRIGGER tr1 $defn" [list 1 $errmsg]
}

#-------------------------------------------------------------------------







>
>







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  3 { BEFORE DELETE ON t1 BEGIN SELECT * FROM (SELECT * FROM (SELECT ?)); END; }
  5 { BEFORE DELETE ON t1 BEGIN SELECT * FROM t2 GROUP BY ?; END; }
  6 { BEFORE DELETE ON t1 BEGIN SELECT * FROM t2 LIMIT ?; END; }
  7 { BEFORE DELETE ON t1 BEGIN SELECT * FROM t2 ORDER BY ?; END; }
  8 { BEFORE UPDATE ON t1 BEGIN UPDATE t2 SET c = ?; END; }
  9 { BEFORE UPDATE ON t1 BEGIN UPDATE t2 SET c = 1 WHERE d = ?; END; }
 10 { AFTER INSERT ON t1 BEGIN SELECT * FROM pragma_stats(?); END; }
 11 { BEFORE INSERT ON t1 BEGIN 
      INSERT INTO t1 SELECT max(b) OVER(ORDER BY $1) FROM t1; END }
} {
  catchsql {drop trigger tr1}
  do_catchsql_test 1.1.$tn "CREATE TRIGGER tr1 $defn" [list 1 $errmsg]
  do_catchsql_test 1.2.$tn "CREATE TEMP TRIGGER tr1 $defn" [list 1 $errmsg]
}

#-------------------------------------------------------------------------
Added test/unionall.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
# 2020-12-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.  The
# focus of this file is flattening UNION ALL sub-queries.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix unionall

do_execsql_test 1.0 {
  CREATE TABLE t1_a(a INTEGER PRIMARY KEY, b TEXT);
  CREATE TABLE t1_b(c INTEGER PRIMARY KEY, d TEXT);
  CREATE TABLE t1_c(e INTEGER PRIMARY KEY, f TEXT);

  INSERT INTO t1_a VALUES(1, 'one'), (4, 'four');
  INSERT INTO t1_b VALUES(2, 'two'), (5, 'five');
  INSERT INTO t1_c VALUES(3, 'three'), (6, 'six');

  CREATE VIEW t1 AS 
    SELECT a, b FROM t1_a   UNION ALL
    SELECT c, d FROM t1_b   UNION ALL
    SELECT e, f FROM t1_c;

  CREATE TABLE i1(x);
  INSERT INTO i1 VALUES(2), (5), (6), (1);
}

do_execsql_test 1.1 {
  SELECT a, b FROM (
    SELECT a, b FROM t1_a   UNION ALL
    SELECT c, d FROM t1_b   UNION ALL
    SELECT e, f FROM t1_c
  ) ORDER BY a
} {
  1 one 2 two 3 three 4 four 5 five 6 six
}

do_execsql_test 1.2 {
  SELECT a, b FROM t1 ORDER BY a
} {
  1 one 2 two 3 three 4 four 5 five 6 six
}

do_execsql_test 1.3 {
  SELECT a, b FROM i1, t1 WHERE a=x ORDER BY a
} {1 one 2 two 5 five 6 six}


#-------------------------------------------------------------------------
reset_db

do_execsql_test 2.1.0 {
  CREATE TABLE t1(x, y);
  INSERT INTO t1 VALUES(1, 'one');
  INSERT INTO t1 VALUES(1, 'ONE');
  INSERT INTO t1 VALUES(2, 'two');
  INSERT INTO t1 VALUES(2, 'TWO');
  INSERT INTO t1 VALUES(3, 'three');
  INSERT INTO t1 VALUES(3, 'THREE');
}

do_execsql_test 2.1.1 {
  WITH s(i) AS (
      SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<3
  )
  SELECT * FROM (
    SELECT 0 AS i UNION ALL SELECT i FROM s UNION ALL SELECT 0
  ), t1 WHERE x=i;
} {
  1 1 one 1 1 ONE 2 2 two 2 2 TWO 3 3 three 3 3 THREE
}

do_catchsql_test 2.1.2 {
  WITH s(i) AS (
      SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<3 UNION ALL SELECT 4
  )
  SELECT * FROM s, t1 WHERE x=i;
} {1 {circular reference: s}}

do_execsql_test 2.2.0 {
  CREATE TABLE t2_a(k INTEGER PRIMARY KEY, v TEXT);
  CREATE TABLE t2_b(k INTEGER PRIMARY KEY, v TEXT);

  CREATE VIEW t2 AS 
    SELECT * FROM t2_a 
    UNION ALL 
    SELECT * FROM t2_b;

  CREATE TRIGGER t2_insert INSTEAD OF INSERT ON t2 BEGIN
    INSERT INTO t2_a SELECT new.k, new.v WHERE (new.k%2)==0;
    INSERT INTO t2_b SELECT new.k, new.v WHERE (new.k%2)==1;
  END;

  INSERT INTO t2 VALUES(5, 'v'), (4, 'iv'), (3, 'iii'), (2, 'ii');
}

do_execsql_test 2.2.1 {
  SELECT * FROM t1, t2 WHERE x=k;
} {
  2 two 2 ii 2 TWO 2 ii 3 three 3 iii 3 THREE 3 iii
}

do_execsql_test 2.2.2 {
  SELECT * FROM t1 LEFT JOIN t2 ON (x=k);
} {
  1 one {} {}
  1 ONE {} {}
  2 two 2 ii 2 TWO 2 ii 3 three 3 iii 3 THREE 3 iii
}

do_execsql_test 2.2.3 {
  SELECT x1.*, x2.* FROM t2 AS x1, t2 AS x2 WHERE x1.k=x2.k+1
} {
  4 iv   3 iii 
  3 iii  2 ii 
  5 v    4 iv
}

do_execsql_test 2.2.4 {
  SELECT * FROM t1, t2 WHERE x=k ORDER BY y;
} {
  3 THREE 3 iii 
  2 TWO 2 ii 
  3 three 3 iii 
  2 two 2 ii
}
do_execsql_test 2.2.5 {
  SELECT * FROM t1, t2 WHERE x=k ORDER BY y||'';
} {
  3 THREE 3 iii 
  2 TWO 2 ii 
  3 three 3 iii 
  2 two 2 ii
}
do_execsql_test 2.2.6 {
  SELECT * FROM t1, t2 WHERE x=k ORDER BY v
} {
  2 two   2 ii
  2 TWO   2 ii 
  3 three 3 iii 
  3 THREE 3 iii 
}
do_execsql_test 2.2.7 {
  SELECT * FROM t1, t2 WHERE x=k ORDER BY v||''
} {
  2 two   2 ii
  2 TWO   2 ii 
  3 three 3 iii 
  3 THREE 3 iii 
}
do_execsql_test 2.2.8 {
  SELECT * FROM t1, t2 WHERE x=k ORDER BY k,v||''
} {
  2 two   2 ii
  2 TWO   2 ii 
  3 three 3 iii 
  3 THREE 3 iii 
}
do_execsql_test 2.2.9a {
  SELECT * FROM t1, t2 ORDER BY +k
} {
  1 one 2 ii 1 ONE 2 ii 2 two 2 ii 
  2 TWO 2 ii 3 three 2 ii 3 THREE 2 ii 
  
  1 one 3 iii 1 ONE 3 iii 2 two 3 iii 
  2 TWO 3 iii 3 three 3 iii 3 THREE 3 iii 

  1 one 4 iv 1 ONE 4 iv 2 two 4 iv 
  2 TWO 4 iv 3 three 4 iv 3 THREE 4 iv 

  1 one 5 v 1 ONE 5 v 2 two 5 v 
  2 TWO 5 v 3 three 5 v 3 THREE 5 v
}

do_execsql_test 2.2.9b {
  SELECT * FROM t1, t2 ORDER BY k
} {
  1 one 2 ii 1 ONE 2 ii 2 two 2 ii 
  2 TWO 2 ii 3 three 2 ii 3 THREE 2 ii 
  
  1 one 3 iii 1 ONE 3 iii 2 two 3 iii 
  2 TWO 3 iii 3 three 3 iii 3 THREE 3 iii 

  1 one 4 iv 1 ONE 4 iv 2 two 4 iv 
  2 TWO 4 iv 3 three 4 iv 3 THREE 4 iv 

  1 one 5 v 1 ONE 5 v 2 two 5 v 
  2 TWO 5 v 3 three 5 v 3 THREE 5 v
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 3.0 {
  CREATE TABLE t1(c INTEGER PRIMARY KEY, d TEXT);
  INSERT INTO t1 VALUES(1,2);
  CREATE TABLE t3_a(k INTEGER PRIMARY KEY, v TEXT);
  INSERT INTO t3_a VALUES(2,'ii');
  CREATE TABLE t3_b(k INTEGER PRIMARY KEY, v TEXT);
  CREATE VIEW t3 AS
    SELECT * FROM t3_a
    UNION ALL
    SELECT * FROM t3_b;
} {}

do_execsql_test 3.1 {
  SELECT * FROM t1, t3 ORDER BY k;
} {1 2 2 ii}

reset_db
do_execsql_test 4.0 {

  CREATE TABLE t1_a(a INTEGER PRIMARY KEY, b TEXT);
  INSERT INTO t1_a VALUES(123, 't1_a');
  CREATE TABLE t1_b(c INTEGER PRIMARY KEY, d TEXT);

  CREATE VIEW t1 AS
    SELECT a, b FROM t1_a
    UNION ALL
    SELECT c, d FROM t1_b;

  CREATE TABLE t3_a(k INTEGER PRIMARY KEY, v TEXT);
  INSERT INTO t3_a VALUES(456, 't3_a');
  CREATE TABLE t3_b(k INTEGER PRIMARY KEY, v TEXT);

  CREATE VIEW t3 AS
    SELECT * FROM t3_a
    UNION ALL
    SELECT * FROM t3_b;
}

do_execsql_test 4.1 {
  SELECT * FROM t1, t3 ORDER BY k;
} {123 t1_a 456 t3_a}

do_execsql_test 4.2 {
  SELECT * FROM (SELECT * FROM t1, t3) ORDER BY k;
} {123 t1_a 456 t3_a}

do_execsql_test 4.3 {
  SELECT * FROM (SELECT * FROM t1, t3), (
    SELECT max(a) OVER () FROM t1
      UNION ALL
    SELECT min(a) OVER () FROM t1
  )
  ORDER BY k;
} {
  123 t1_a 456 t3_a 123
  123 t1_a 456 t3_a 123
}

do_execsql_test 4.3 {
  SELECT * FROM (SELECT * FROM t1, t3), (
    SELECT group_concat(a) OVER (ORDER BY a), 
           group_concat(a) OVER (ORDER BY a),
           group_concat(a) OVER (ORDER BY a),
           group_concat(a) OVER (ORDER BY a),
           group_concat(a) OVER (ORDER BY a),
           group_concat(a) OVER (ORDER BY a),
           group_concat(a) OVER (ORDER BY a),
           group_concat(a) OVER (ORDER BY a),
           group_concat(a) OVER (ORDER BY a)
    FROM t1
  )
  ORDER BY k;
} {
  123 t1_a 456 t3_a 123 123 123 123 123 123 123 123 123
}

do_execsql_test 4.3 {
  SELECT * FROM (SELECT * FROM t1, t3) AS o, (
    SELECT * FROM t1 LEFT JOIN t3 ON a=k
  );
} {
  123 t1_a 456 t3_a 123 t1_a {} {}
}

# 2020-12-30: dbsqlfuzz find
reset_db
do_execsql_test 5.1 {
  CREATE TABLE t1_a(a INTEGER PRIMARY KEY, b TEXT);
  INSERT INTO t1_a VALUES(1,'one');
  INSERT INTO t1_a VALUES(0,NULL);
  CREATE TABLE t1_b(c INTEGER PRIMARY KEY, d TEXT);
  INSERT INTO t1_b VALUES(2,'two');
  INSERT INTO t1_b VALUES(5,'five');
  CREATE TABLE t1_c(e INTEGER PRIMARY KEY, f TEXT);
  INSERT INTO t1_c VALUES(3,'three');
  INSERT INTO t1_c VALUES(6,'six');
  CREATE TABLE t2(k,v);
  INSERT INTO t2 VALUES(5,'v');
  INSERT INTO t2 VALUES(4,'iv');
  INSERT INTO t2 VALUES(3,'iii');
  INSERT INTO t2 VALUES(2,'ii');
  CREATE TABLE t3_a(k INTEGER PRIMARY KEY, v TEXT);
  INSERT INTO t3_a VALUES(2,'ii');
  INSERT INTO t3_a VALUES(4,'iv');
  CREATE TABLE t3_b(k INTEG5R PRIMARY KEY, v TEXT);
  INSERT INTO t3_b VALUES(NULL,'iii');
  INSERT INTO t3_b VALUES(NULL,'v');
  CREATE VIEW t1 AS 
    SELECT a, b FROM t1_a   UNION ALL
    SELECT c, d FROM t1_b   UNION ALL
    SELECT e, f FROM t1_c;
  CREATE VIEW t3 AS 
      SELECT * FROM t3_a 
      UNION ALL 
      SELECT * FROM t3_b;
  CREATE TRIGGER t3_insert INSTEAD OF INSERT ON t3 BEGIN
      INSERT INTO t3_a SELECT new.k, new.v WHERE (new.k%2)==0;
      INSERT INTO t3_b SELECT new.k, new.v WHERE (new.k%2)==1;
  END;
} {}
do_execsql_test 5.10 {
  SELECT *, '+' FROM t1 LEFT JOIN t2 ON (a NOT IN(SELECT v FROM t1, t3 WHERE a=k)=NOT EXISTS(SELECT 1 FROM t1 LEFT JOIN t3 ON (a=k)));
} {0 {} {} {} + 1 one {} {} + 2 two {} {} + 5 five {} {} + 3 three {} {} + 6 six {} {} +}
do_execsql_test 5.20 {
  SELECT *, '+' FROM t1 LEFT JOIN t3 ON (a NOT IN(SELECT v FROM t1 LEFT JOIN t2 ON (a=k))=k);
} {0 {} {} {} + 1 one {} {} + 2 two {} {} + 5 five {} {} + 3 three {} {} + 6 six {} {} +}

reset_db
do_execsql_test 6.0 {
  CREATE TABLE t1(a,b);
  INSERT INTO t1 VALUES(1,2);
  CREATE TABLE t2(a,b);
  INSERT INTO t2 VALUES(3,4);

  CREATE TABLE t3(a,b);
  INSERT INTO t3 VALUES(5,6);
  CREATE TABLE t4(a,b);
  INSERT INTO t4 VALUES(7,8);

  CREATE TABLE t5(a,b);
  INSERT INTO t5 VALUES(9,10);
}

do_execsql_test 6.1 {
  WITH x(c) AS (
    SELECT 1000 FROM t1 UNION ALL SELECT 800 FROM t2
  ),
  y(d) AS (
    SELECT  100 FROM t3 UNION ALL SELECT 400 FROM t4
  )
  SELECT * FROM t5, x, y;
} {
  9 10 1000 100     9 10 1000 400
  9 10 800 100      9 10 800 400
}

finish_test
Added test/unionall2.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
# 2020-12-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 implements regression tests for SQLite library.  The
# focus of this file is flattening UNION ALL sub-queries.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix unionall2

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b);
  CREATE TABLE t2(c, d);

  CREATE VIEW v1 AS SELECT * FROM t1, t2;
  CREATE VIEW v2 AS SELECT * FROM t1, t2;

  CREATE VIEW vA AS
    SELECT * FROM v1, (
      SELECT * FROM t1 LEFT JOIN t2 ON (a=c)
    )
    UNION ALL
    SELECT * FROM v1, v2
}

do_execsql_test 1.1 {
  SELECT 1 FROM vA, vA, vA, vA, vA, vA, vA, vA, vA, vA
}


finish_test
Added test/unionallfault.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
# 2020-12-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.
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix unionallfault

do_execsql_test 1.0 {
  CREATE TABLE t1(x,y,z);
  CREATE TABLE t3(x,y,z);
}
faultsim_save_and_close


do_faultsim_test 1 -faults oom-t* -prep {
  faultsim_restore_and_reopen
} -body {
  execsql {
    SELECT * FROM t1, (
      SELECT x FROM t1 UNION ALL SELECT y FROM t1
    ), t3
  }
} -test {
  faultsim_test_result {0 {}}
}

finish_test
Added test/upsert5.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
# 2020-12-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.
#
#***********************************************************************
#
# Test cases for generalized UPSERT

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix upsert5

foreach {tn sql} {
  1 { CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c UNIQUE, d UNIQUE, e UNIQUE) }
  2 { CREATE TABLE t1(a INT PRIMARY KEY, b, c UNIQUE, d UNIQUE, e UNIQUE) }
  3 { CREATE TABLE t1(a INT PRIMARY KEY, b, c UNIQUE, d UNIQUE, e UNIQUE) WITHOUT ROWID}
  4 { CREATE TABLE t1(e UNIQUE, d UNIQUE, c UNIQUE, a INTEGER PRIMARY KEY, b) }
  5 { CREATE TABLE t1(e UNIQUE, d UNIQUE, c UNIQUE, a INT PRIMARY KEY, b) }
  6 { CREATE TABLE t1(e UNIQUE, d UNIQUE, c UNIQUE, a INT PRIMARY KEY, b) WITHOUT ROWID}
} {
  reset_db
  execsql $sql

  do_execsql_test 1.$tn.100 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,3,4,5)
      ON CONFLICT(a) DO UPDATE SET b='a'
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT(e) DO UPDATE SET b='e';
    SELECT a,b,c,d,e FROM t1;
  } {1 a 3 4 5}
  do_execsql_test 1.$tn.101 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,4,5)
      ON CONFLICT(a) DO UPDATE SET b='a'
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT(e) DO UPDATE SET b='e';
    SELECT a,b,c,d,e FROM t1;
  } {1 c 3 4 5}
  do_execsql_test 1.$tn.102 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,4,5)
      ON CONFLICT(a) DO UPDATE SET b='a'
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT(e) DO UPDATE SET b='e';
    SELECT a,b,c,d,e FROM t1;
  } {1 d 3 4 5}
  do_execsql_test 1.$tn.103 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5)
      ON CONFLICT(a) DO UPDATE SET b='a'
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT(e) DO UPDATE SET b='e';
    SELECT a,b,c,d,e FROM t1;
  } {1 e 3 4 5}
  do_execsql_test 1.$tn.200 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(a) DO UPDATE SET b='a'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT(e) DO UPDATE SET b='e';
    SELECT a,b,c,d,e FROM t1;
  } {1 a 3 4 5}
  do_execsql_test 1.$tn.201 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,3,94,95)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(a) DO UPDATE SET b='a'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT(e) DO UPDATE SET b='e';
    SELECT a,b,c,d,e FROM t1;
  } {1 c 3 4 5}
  do_execsql_test 1.$tn.202 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,3,4,5)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(a) DO UPDATE SET b='a'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT(e) DO UPDATE SET b='e';
    SELECT a,b,c,d,e FROM t1;
  } {1 c 3 4 5}
  do_execsql_test 1.$tn.203 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,5)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(a) DO UPDATE SET b='a'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT(e) DO UPDATE SET b='e';
    SELECT a,b,c,d,e FROM t1;
  } {1 a 3 4 5}
  do_execsql_test 1.$tn.204 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,4,95)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(a) DO UPDATE SET b='a'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT(e) DO UPDATE SET b='e';
    SELECT a,b,c,d,e FROM t1;
  } {1 a 3 4 5}
  do_execsql_test 1.$tn.210 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT(a) DO UPDATE SET b='a'
      ON CONFLICT(e) DO UPDATE SET b='e';
    SELECT a,b,c,d,e FROM t1;
  } {1 a 3 4 5}
  do_execsql_test 1.$tn.211 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,4,95)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT(a) DO UPDATE SET b='a'
      ON CONFLICT(e) DO UPDATE SET b='e';
    SELECT a,b,c,d,e FROM t1;
  } {1 d 3 4 5}
  do_execsql_test 1.$tn.212 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,5)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT(a) DO UPDATE SET b='a'
      ON CONFLICT(e) DO UPDATE SET b='e';
    SELECT a,b,c,d,e FROM t1;
  } {1 a 3 4 5}
  do_execsql_test 1.$tn.213 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT(a) DO UPDATE SET b='a'
      ON CONFLICT(e) DO UPDATE SET b='e';
    SELECT a,b,c,d,e FROM t1;
  } {1 e 3 4 5}
  do_execsql_test 1.$tn.214 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT(e) DO UPDATE SET b='e'
      ON CONFLICT(a) DO UPDATE SET b='a';
    SELECT a,b,c,d,e FROM t1;
  } {1 e 3 4 5}
  do_execsql_test 1.$tn.215 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,5)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT(e) DO UPDATE SET b='e'
      ON CONFLICT(a) DO UPDATE SET b='a';
    SELECT a,b,c,d,e FROM t1;
  } {1 e 3 4 5}
  do_execsql_test 1.$tn.216 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT(e) DO UPDATE SET b='e'
      ON CONFLICT(a) DO UPDATE SET b='a';
    SELECT a,b,c,d,e FROM t1;
  } {1 a 3 4 5}

  do_execsql_test 1.$tn.300 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT(a) DO UPDATE SET b='a1'
      ON CONFLICT(a) DO UPDATE SET b='a2'
      ON CONFLICT(a) DO UPDATE SET b='a3'
      ON CONFLICT(a) DO UPDATE SET b='a4'
      ON CONFLICT(a) DO UPDATE SET b='a5'
      ON CONFLICT(e) DO UPDATE SET b='e';
    SELECT a,b,c,d,e FROM t1;
  } {1 a1 3 4 5}
  do_execsql_test 1.$tn.301 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT(a) DO UPDATE SET b='a1'
      ON CONFLICT(a) DO UPDATE SET b='a2'
      ON CONFLICT(a) DO UPDATE SET b='a3'
      ON CONFLICT(a) DO UPDATE SET b='a4'
      ON CONFLICT(a) DO UPDATE SET b='a5'
      ON CONFLICT(e) DO UPDATE SET b='e';
    SELECT a,b,c,d,e FROM t1;
  } {1 e 3 4 5}

  do_execsql_test 1.$tn.400 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT DO UPDATE set b='x';
    SELECT a,b,c,d,e FROM t1;
  } {1 x 3 4 5}
  do_execsql_test 1.$tn.401 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT DO UPDATE set b='x';
    SELECT a,b,c,d,e FROM t1;
  } {1 x 3 4 5}
  do_execsql_test 1.$tn.402 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT DO UPDATE set b='x';
    SELECT a,b,c,d,e FROM t1;
  } {1 x 3 4 5}
  do_execsql_test 1.$tn.403 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,94,95)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT DO UPDATE set b='x';
    SELECT a,b,c,d,e FROM t1;
  } {1 c 3 4 5}
  do_execsql_test 1.$tn.404 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,4,95)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT DO UPDATE set b='x';
    SELECT a,b,c,d,e FROM t1;
  } {1 c 3 4 5}
  do_execsql_test 1.$tn.405 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,4,5)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT DO UPDATE set b='x';
    SELECT a,b,c,d,e FROM t1;
  } {1 d 3 4 5}

  do_execsql_test 1.$tn.410 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
      ON CONFLICT DO UPDATE set b='x';
    SELECT a,b,c,d,e FROM t1;
  } {1 x 3 4 5}
  do_execsql_test 1.$tn.411 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5)
      ON CONFLICT DO UPDATE set b='x';
    SELECT a,b,c,d,e FROM t1;
  } {1 x 3 4 5}
  do_execsql_test 1.$tn.412 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,4,95)
      ON CONFLICT DO UPDATE set b='x';
    SELECT a,b,c,d,e FROM t1;
  } {1 x 3 4 5}
  do_execsql_test 1.$tn.413 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,94,95)
      ON CONFLICT DO UPDATE set b='x';
    SELECT a,b,c,d,e FROM t1;
  } {1 x 3 4 5}

  do_execsql_test 1.$tn.420 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
      ON CONFLICT(c) DO NOTHING
      ON CONFLICT(d) DO NOTHING
      ON CONFLICT DO UPDATE set b='x';
    SELECT a,b,c,d,e FROM t1;
  } {1 x 3 4 5}
  do_execsql_test 1.$tn.421 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5)
      ON CONFLICT(c) DO NOTHING
      ON CONFLICT(d) DO NOTHING
      ON CONFLICT DO UPDATE set b='x';
    SELECT a,b,c,d,e FROM t1;
  } {1 x 3 4 5}
  do_execsql_test 1.$tn.422 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,4,95)
      ON CONFLICT(c) DO NOTHING
      ON CONFLICT(d) DO NOTHING
      ON CONFLICT DO UPDATE set b='x';
    SELECT a,b,c,d,e FROM t1;
  } {1 2 3 4 5}
  do_execsql_test 1.$tn.423 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,94,95)
      ON CONFLICT(c) DO NOTHING
      ON CONFLICT(d) DO NOTHING
      ON CONFLICT DO UPDATE set b='x';
    SELECT a,b,c,d,e FROM t1;
  } {1 2 3 4 5}

  do_execsql_test 1.$tn.500 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT DO NOTHING;
    SELECT a,b,c,d,e FROM t1;
  } {1 2 3 4 5}
  do_execsql_test 1.$tn.501 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT DO NOTHING;
    SELECT a,b,c,d,e FROM t1;
  } {1 2 3 4 5}
  do_execsql_test 1.$tn.502 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT DO NOTHING;
    SELECT a,b,c,d,e FROM t1;
  } {1 2 3 4 5}
  do_execsql_test 1.$tn.503 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,94,95)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT DO NOTHING;
    SELECT a,b,c,d,e FROM t1;
  } {1 c 3 4 5}
  do_execsql_test 1.$tn.504 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,4,95)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT DO NOTHING;
    SELECT a,b,c,d,e FROM t1;
  } {1 c 3 4 5}
  do_execsql_test 1.$tn.505 {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
    INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,4,5)
      ON CONFLICT(c) DO UPDATE SET b='c'
      ON CONFLICT(d) DO UPDATE SET b='d'
      ON CONFLICT DO NOTHING;
    SELECT a,b,c,d,e FROM t1;
  } {1 d 3 4 5}

}

finish_test
Changes to test/vacuum2.test.
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  execsql {
    CREATE TABLE t1(x);
    CREATE TABLE t2(y);
    INSERT INTO t1 VALUES(1);
  }
  hexio_get_int [hexio_read test.db 24 4]
} [expr {[hexio_get_int [hexio_read test.db 24 4]]+3}]
do_test vacuum2-2.1 {
  execsql {
    VACUUM
  }
  hexio_get_int [hexio_read test.db 24 4]
} [expr {[hexio_get_int [hexio_read test.db 24 4]]+1}]

############################################################################







|







52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  execsql {
    CREATE TABLE t1(x);
    CREATE TABLE t2(y);
    INSERT INTO t1 VALUES(1);
  }
  hexio_get_int [hexio_read test.db 24 4]
} [expr {[hexio_get_int [hexio_read test.db 24 4]]+3}]
do_test vacuum2-2.2 {
  execsql {
    VACUUM
  }
  hexio_get_int [hexio_read test.db 24 4]
} [expr {[hexio_get_int [hexio_read test.db 24 4]]+1}]

############################################################################
Added test/vacuum6.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
# 2016-08-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 a test for VACUUM on attached databases.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix vacuum6

# If the VACUUM statement is disabled in the current build, skip all
# the tests in this file.
#
ifcapable !vacuum {
  finish_test
  return
}


do_execsql_test 1.0 {
  CREATE TABLE t1(x INTEGER PRIMARY KEY, y);
  INSERT INTO t1 VALUES(1, 1);
} {}

do_execsql_test 1.1 {
  VACUUM
}

reset_db
do_execsql_test 1.2 {
  CREATE TABLE t1(x,b);
  CREATE INDEX x1 ON t1(x);
  CREATE INDEX x2 ON t1(x);
  CREATE INDEX x3 ON t1(x);
  INSERT INTO t1 SELECT 2,'';
  VACUUM;
}

#-------------------------------------------------------------------------
#
reset_db
foreach {tn sz} {1 400 2 4000 3 9999} {
  reset_db
  do_execsql_test 2.$tn.1 {
    CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
    WITH s(i) AS (
        SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100
    )
    INSERT INTO t1 SELECT i, randomblob($sz) FROM s;
  }

  do_execsql_test 2.$tn.2 {
    vacuum;
  }

  do_execsql_test 2.$tn.3 {
    PRAGMA integrity_check;
  } {ok}
}

reset_db
do_execsql_test 3.0 {
  PRAGMA page_size = 1024;
  CREATE TABLE t1(x INTEGER PRIMARY KEY, y);
  INSERT INTO t1 VALUES(2, randomblob(1200));
} {}
do_execsql_test 3.1 {
  PRAGMA page_size = 512;
  VACUUM;
}
do_execsql_test 3.2 {
  PRAGMA integrity_check
} {ok}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 4.0 {
  CREATE TABLE tx(a, b);
  CREATE INDEX i1 ON tx(b);
  WITH s(i) AS (
      SELECT 8000 UNION ALL SELECT i+1 FROM s WHERE i<10000
  )
  INSERT INTO tx SELECT i, randomblob(i) FROM s;

  SELECT sum(length(b)) FROM tx;
} {18009000}
foreach {tn pgsz av} {
  1 2048   0
  2 1024   1
  3 65536  0
  4 8192   1
  5 512    0
  6 4096   1
} {
  do_execsql_test 4.1.$tn.1 "
    PRAGMA page_size = $pgsz;
    PRAGMA auto_vacuum = $av;
  "
  do_execsql_test 4.1.$tn.2 VACUUM
  integrity_check 4.1.$tn.3
}

finish_test
Changes to test/view.test.
40
41
42
43
44
45
46




47
48
49
50

51
52
53
54
55
56
57
58
59
} {1 2 4 5 7 8}
do_test view-1.1.100 {
  db config enable_view off
  catchsql {
    SELECT * FROM v1 ORDER BY a;
  }
} {1 {access to view "v1" prohibited}}




do_test view-1.1.110 {
  db config enable_view on
  catchsql {
    SELECT * FROM v1 ORDER BY a;

  }
} {0 {1 2 4 5 7 8}}
do_test view-1.2 {
  catchsql {
    ROLLBACK;
    SELECT * FROM v1 ORDER BY a;
  }
} {1 {no such table: v1}}
do_test view-1.3 {







>
>
>
>




>

|







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
} {1 2 4 5 7 8}
do_test view-1.1.100 {
  db config enable_view off
  catchsql {
    SELECT * FROM v1 ORDER BY a;
  }
} {1 {access to view "v1" prohibited}}
do_execsql_test view-1.1.101 {
  CREATE TEMP VIEW v1temp AS SELECT a, b FROM t1;
  SELECT * FROM v1temp ORDER BY a;
} {1 2 4 5 7 8}
do_test view-1.1.110 {
  db config enable_view on
  catchsql {
    SELECT * FROM v1 ORDER BY a;
    SELECT * FROM v1temp ORDER BY a;
  }
} {0 {1 2 4 5 7 8 1 2 4 5 7 8}}
do_test view-1.2 {
  catchsql {
    ROLLBACK;
    SELECT * FROM v1 ORDER BY a;
  }
} {1 {no such table: v1}}
do_test view-1.3 {
Changes to test/wal.test.
1510
1511
1512
1513
1514
1515
1516































1517
1518
1519
  sqlite3 db test.db
  do_test wal-25.$mode {
    db eval "PRAGMA journal_mode=$mode"
    db eval {ATTACH 'test2.db' AS t2; PRAGMA journal_mode=WAL;}
  } {wal}
  db close
}
































test_restore_config_pagecache
finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



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
  sqlite3 db test.db
  do_test wal-25.$mode {
    db eval "PRAGMA journal_mode=$mode"
    db eval {ATTACH 'test2.db' AS t2; PRAGMA journal_mode=WAL;}
  } {wal}
  db close
}

# 2021-03-10 forum post https://sqlite.org/forum/forumpost/a006d86f72
#
file delete test.db
sqlite3 db test.db
db eval {PRAGMA journal_mode=WAL}
for {set i 0} {$i<$SQLITE_MAX_ATTACHED} {incr i} {
  do_test wal-26.1.$i {
    file delete attached-$i.db
    db eval "ATTACH 'attached-$i.db' AS a$i;"
    db eval "PRAGMA a$i.journal_mode=WAL;"
    db eval "CREATE TABLE a$i.t$i (x);"
    db eval "INSERT INTO t$i VALUES(zeroblob(10000));"
    db eval "DELETE FROM t$i;"
    db eval "INSERT INTO t$i VALUES(randomblob(10000));"
    expr {[file size attached-$i.db-wal]>10000}
  } {1}
}
for {set i [expr {$SQLITE_MAX_ATTACHED-1}]} {$i>=0} {incr i -1} {
  do_test wal-26.2.$i {
    db eval "PRAGMA a$i.wal_checkpoint(TRUNCATE);"
    file size attached-$i.db-wal
  } {0}
  for {set j 0} {$j<$i} {incr j} {
    do_test wal-26.2.$i.$j {
      expr {[file size attached-$j.db-wal]>10000}
    } {1}
  }
}
db close


test_restore_config_pagecache
finish_test
Changes to test/walvfs.test.
142
143
144
145
146
147
148


149
150
151
152
153
154
155

156
157
158




159
160
161
162
163
164
165

set ::cnt 2
proc xWrite {method file args} {
  if {[file tail $file]=="test.db"} {
    incr ::cnt -1
    if {$::cnt==0} {
      sqlite3_memdebug_fail 1 -repeat 0


      catchsql { SELECT 'a big long string!' }
      sqlite3_interrupt db
    }
  }
  return SQLITE_OK
}


do_catchsql_test 3.2 {
  PRAGMA wal_checkpoint
} {1 {out of memory}}





#-------------------------------------------------------------------------
#
reset_db
db close
do_test 4.0 {
  sqlite3 db test.db -vfs tvfs







>
>
|






>



>
>
>
>







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

set ::cnt 2
proc xWrite {method file args} {
  if {[file tail $file]=="test.db"} {
    incr ::cnt -1
    if {$::cnt==0} {
      sqlite3_memdebug_fail 1 -repeat 0
      # For this test to pass, the following statement must call malloc() at 
      # least once. Even if the lookaside is enabled.
      set ::xwrite_stmt_res [catchsql { SELECT hex(randomblob(4000)) }]
      sqlite3_interrupt db
    }
  }
  return SQLITE_OK
}

set ::xwrite_stmt_res ""
do_catchsql_test 3.2 {
  PRAGMA wal_checkpoint
} {1 {out of memory}}
do_test 3.2.2 {
  set ::xwrite_stmt_res
} {1 {out of memory}}
unset ::xwrite_stmt_res

#-------------------------------------------------------------------------
#
reset_db
db close
do_test 4.0 {
  sqlite3 db test.db -vfs tvfs
Changes to test/whereL.test.
22
23
24
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
  CREATE TABLE t3(a INT PRIMARY KEY, j, k, l, m);
  CREATE VIEW v4 AS SELECT * FROM t2 UNION ALL SELECT * FROM t3;
}
do_eqp_test 110 {
  SELECT * FROM t1, v4 WHERE t1.a=?1 AND v4.a=t1.a;
} {
  QUERY PLAN
  |--MATERIALIZE xxxxxx
  |  `--COMPOUND QUERY
  |     |--LEFT-MOST SUBQUERY
  |     |  `--SEARCH TABLE t2 USING INDEX sqlite_autoindex_t2_1 (a=?)

  |     `--UNION ALL
  |        `--SEARCH TABLE t3 USING INDEX sqlite_autoindex_t3_1 (a=?)
  |--SCAN SUBQUERY xxxxxx
  `--SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (a=?)
}

# The scan of the t1 table goes first since that enables the ORDER BY
# sort to be omitted.  This would not be possible without constant
# propagation because without it the t1 table would depend on t3.
#
do_eqp_test 120 {







<
|
|
|
>
|
|
<
|







22
23
24
25
26
27
28

29
30
31
32
33
34

35
36
37
38
39
40
41
42
  CREATE TABLE t3(a INT PRIMARY KEY, j, k, l, m);
  CREATE VIEW v4 AS SELECT * FROM t2 UNION ALL SELECT * FROM t3;
}
do_eqp_test 110 {
  SELECT * FROM t1, v4 WHERE t1.a=?1 AND v4.a=t1.a;
} {
  QUERY PLAN

  `--COMPOUND QUERY
     |--LEFT-MOST SUBQUERY
     |  |--SEARCH TABLE t2 USING INDEX sqlite_autoindex_t2_1 (a=?)
     |  `--SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (a=?)
     `--UNION ALL
        |--SEARCH TABLE t3 USING INDEX sqlite_autoindex_t3_1 (a=?)

        `--SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (a=?)
}

# The scan of the t1 table goes first since that enables the ORDER BY
# sort to be omitted.  This would not be possible without constant
# propagation because without it the t1 table would depend on t3.
#
do_eqp_test 120 {
Changes to test/wherelimit.test.
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
    execsql {SELECT count(*) FROM t1}
  } {20}
  do_test wherelimit-1.3 {
    # limit 5
    execsql {DELETE FROM t1 ORDER BY x LIMIT 5}
    execsql {SELECT count(*) FROM t1}
  } {15}








  do_test wherelimit-1.4 {
    # limit 5, offset 2
    execsql {DELETE FROM t1 ORDER BY x LIMIT 5 OFFSET 2}


    execsql {SELECT count(*) FROM t1}
  } {10}
  do_test wherelimit-1.5 {
    # limit 5, offset -2
    execsql {DELETE FROM t1 ORDER BY x LIMIT 5 OFFSET -2}
    execsql {SELECT count(*) FROM t1}
  } {5}
  do_test wherelimit-1.6 {
    # limit -5 (no limit), offset 2
    execsql {DELETE FROM t1 ORDER BY x LIMIT 2, -5}
    execsql {SELECT count(*) FROM t1}
  } {2}
  do_test wherelimit-1.7 {
    # limit 5, offset -2 (no offset)
    execsql {DELETE FROM t1 ORDER BY x LIMIT -2, 5}
    execsql {SELECT count(*) FROM t1}
  } {0}
  create_test_data 5
  do_test wherelimit-1.8 {







>
>
>
>
>
>
>
>


|
>
>

|




|




|







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
    execsql {SELECT count(*) FROM t1}
  } {20}
  do_test wherelimit-1.3 {
    # limit 5
    execsql {DELETE FROM t1 ORDER BY x LIMIT 5}
    execsql {SELECT count(*) FROM t1}
  } {15}
  create_test_data 4
  do_test wherelimit-1.3b {
    # limit 5
    execsql {DELETE FROM t1 RETURNING x, y, '|' ORDER BY x, y LIMIT 5}
  } {1 1 | 1 2 | 1 3 | 1 4 | 2 1 |}
  do_test wherelimit-1.3c {
    execsql {SELECT count(*) FROM t1}
  } {11}
  do_test wherelimit-1.4 {
    # limit 5, offset 2
    execsql {DELETE FROM t1 RETURNING x, y, '|' ORDER BY x  LIMIT 5 OFFSET 2}
  } {2 4 | 3 1 | 3 2 | 3 3 | 3 4 |}
  do_test wherelimit-1.4cnt {
    execsql {SELECT count(*) FROM t1}
  } {6}
  do_test wherelimit-1.5 {
    # limit 5, offset -2
    execsql {DELETE FROM t1 ORDER BY x LIMIT 5 OFFSET -2}
    execsql {SELECT count(*) FROM t1}
  } {1}
  do_test wherelimit-1.6 {
    # limit -5 (no limit), offset 2
    execsql {DELETE FROM t1 ORDER BY x LIMIT 2, -5}
    execsql {SELECT count(*) FROM t1}
  } {1}
  do_test wherelimit-1.7 {
    # limit 5, offset -2 (no offset)
    execsql {DELETE FROM t1 ORDER BY x LIMIT -2, 5}
    execsql {SELECT count(*) FROM t1}
  } {0}
  create_test_data 5
  do_test wherelimit-1.8 {
223
224
225
226
227
228
229
230


231
232
233
234
235
236
237
  } {36}
  do_test wherelimit-3.1 {
    execsql {UPDATE t1 SET y=1 WHERE x=1}
    execsql {SELECT count(*) FROM t1 WHERE y=1}
  } {11}
  create_test_data 6
  do_test wherelimit-3.2 {
    execsql {UPDATE t1 SET y=1 WHERE x=1 LIMIT 5}


    execsql {SELECT count(*) FROM t1 WHERE y=1}
  } {10}
  do_test wherelimit-3.3 {
    # limit 5
    execsql {UPDATE t1 SET y=2 WHERE x=2 ORDER BY x LIMIT 5}
    execsql {SELECT count(*) FROM t1 WHERE y=2}
  } {9}







|
>
>







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
  } {36}
  do_test wherelimit-3.1 {
    execsql {UPDATE t1 SET y=1 WHERE x=1}
    execsql {SELECT count(*) FROM t1 WHERE y=1}
  } {11}
  create_test_data 6
  do_test wherelimit-3.2 {
    execsql {UPDATE t1 SET y=1 WHERE x=1 RETURNING x, old.y, '|' LIMIT 5}
  } {1 1 | 1 2 | 1 3 | 1 4 | 1 5 |}
  do_test wherelimit-3.2cnt {
    execsql {SELECT count(*) FROM t1 WHERE y=1}
  } {10}
  do_test wherelimit-3.3 {
    # limit 5
    execsql {UPDATE t1 SET y=2 WHERE x=2 ORDER BY x LIMIT 5}
    execsql {SELECT count(*) FROM t1 WHERE y=2}
  } {9}
Changes to test/windowB.test.
331
332
333
334
335
336
337





















338
339
  ) FROM t1;
} {{} 46 {} 46  7 {} 7 {} 8 {} 8 {}  abc 1004 abc 1004 xyz 3333}
do_execsql_test 7.4 {
  SELECT a, min(c) OVER (
    ORDER BY a RANGE BETWEEN 0 PRECEDING AND 2 PRECEDING
  ) FROM t1;
} {{} 45 {} 45  7 {} 7 {} 8 {} 8 {}  abc 1001 abc 1001 xyz 3333}






















finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


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
  ) FROM t1;
} {{} 46 {} 46  7 {} 7 {} 8 {} 8 {}  abc 1004 abc 1004 xyz 3333}
do_execsql_test 7.4 {
  SELECT a, min(c) OVER (
    ORDER BY a RANGE BETWEEN 0 PRECEDING AND 2 PRECEDING
  ) FROM t1;
} {{} 45 {} 45  7 {} 7 {} 8 {} 8 {}  abc 1001 abc 1001 xyz 3333}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 8.0 {
  BEGIN TRANSACTION;
    CREATE TABLE t1(a, c);
    INSERT INTO t1 VALUES('aa', 111);
    INSERT INTO t1 VALUES('BB', 660);
    INSERT INTO t1 VALUES('CC', 938);
    INSERT INTO t1 VALUES('dd', 979);
  COMMIT;

  CREATE INDEX i1 ON t1(a COLLATE nocase);
}

do_execsql_test 8.1 {
  SELECT sum(c) OVER
    (ORDER BY a COLLATE nocase RANGE BETWEEN 10.0 PRECEDING AND 5.0 PRECEDING)
  FROM t1;
} {111 660 938 979}


finish_test
Changes to test/windowfault.test.
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
      )
    )
  }
} -test {
  faultsim_test_result {0 {}}
}


reset_db
do_execsql_test 11.0 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(c0 INTEGER UNIQUE);
  INSERT INTO t0 VALUES(0);
} {}

do_faultsim_test 11 -faults oom* -prep {
} -body {
  execsql {
    SELECT * FROM t0 WHERE 
      (0, t0.c0) IN (SELECT DENSE_RANK() OVER(), LAG(0) OVER() FROM t0);
  }
} -test {
  faultsim_test_result {0 {}}
}

do_faultsim_test 11 -faults oom* -prep {
} -body {
  execsql {
    VALUES(false),(current_date collate binary) 
    intersect 
    values(count() not like group_concat(cast(cast(0e00 as text) as integer) <= NULL || 0.4e-0 || 0x8 & true ) over () collate rtrim);
  }

















} -test {
  faultsim_test_result {0 {}}
}

finish_test







>







|









|






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





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
      )
    )
  }
} -test {
  faultsim_test_result {0 {}}
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 11.0 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(c0 INTEGER UNIQUE);
  INSERT INTO t0 VALUES(0);
} {}

do_faultsim_test 11.1 -faults oom* -prep {
} -body {
  execsql {
    SELECT * FROM t0 WHERE 
      (0, t0.c0) IN (SELECT DENSE_RANK() OVER(), LAG(0) OVER() FROM t0);
  }
} -test {
  faultsim_test_result {0 {}}
}

do_faultsim_test 11.2 -faults oom* -prep {
} -body {
  execsql {
    VALUES(false),(current_date collate binary) 
    intersect 
    values(count() not like group_concat(cast(cast(0e00 as text) as integer) <= NULL || 0.4e-0 || 0x8 & true ) over () collate rtrim);
  }
} -test {
  faultsim_test_result {0 {}}
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 12.0 {
  CREATE TABLE t1(a, b, c);
} {}
do_faultsim_test 12 -faults oom* -prep {
} -body {
  execsql {
    WITH v(a, b, row_number) AS (
      SELECT a, b, row_number() OVER (PARTITION BY a ORDER BY b) FROM t1
    )
    SELECT * FROM v WHERE a=2
  }
} -test {
  faultsim_test_result {0 {}}
}

finish_test
Added test/windowpushd.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
# 2021 February 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.  The
# focus of this file is testing the push-down optimization when
# WHERE constraints are pushed down into a sub-query that uses
# window functions.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix windowpushd

do_execsql_test 1.0 {
  CREATE TABLE t1(id INTEGER PRIMARY KEY, grp_id);
  CREATE INDEX i1 ON t1(grp_id);
  CREATE VIEW lll AS SELECT
    row_number() OVER (PARTITION BY grp_id), 
    grp_id, id 
  FROM t1
}

do_execsql_test 1.1 {
  INSERT INTO t1 VALUES
    (1, 2), (2, 3), (3, 3), (4, 1), (5, 1),
    (6, 1), (7, 1), (8, 1), (9, 3), (10, 3), 
    (11, 2), (12, 3), (13, 3), (14, 2), (15, 1),
    (16, 2), (17, 1), (18, 2), (19, 3), (20, 2)
}

do_execsql_test 1.2 {
  SELECT * FROM lll
} {
  1 1 4 2 1 5 3 1 6 4 1 7 5 1 8 6 1 15 7 1 17 
  1 2 1 2 2 11 3 2 14 4 2 16 5 2 18 6 2 20 
  1 3 2 2 3 3 3 3 9 4 3 10 5 3 12 6 3 13 7 3 19
}

do_execsql_test 1.3 {
  SELECT * FROM lll WHERE grp_id=2
} {
  1 2 1 2 2 11 3 2 14 4 2 16 5 2 18 6 2 20 
}

do_eqp_test 1.4 {
  SELECT * FROM lll WHERE grp_id=2
} {SEARCH TABLE t1 USING COVERING INDEX i1 (grp_id=?)}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
  CREATE TABLE t1(a, b, c, d);
  INSERT INTO t1 VALUES('A', 'C', 1,  0.1);
  INSERT INTO t1 VALUES('A', 'D', 2,  0.2);
  INSERT INTO t1 VALUES('A', 'E', 3,  0.3);
  INSERT INTO t1 VALUES('A', 'C', 4,  0.4);
  INSERT INTO t1 VALUES('B', 'D', 5,  0.5);
  INSERT INTO t1 VALUES('B', 'E', 6,  0.6);
  INSERT INTO t1 VALUES('B', 'C', 7,  0.7);
  INSERT INTO t1 VALUES('B', 'D', 8,  0.8);
  INSERT INTO t1 VALUES('C', 'E', 9,  0.9);
  INSERT INTO t1 VALUES('C', 'C', 10, 1.0);
  INSERT INTO t1 VALUES('C', 'D', 11, 1.1);
  INSERT INTO t1 VALUES('C', 'E', 12, 1.2);

  CREATE INDEX i1 ON t1(a);
  CREATE INDEX i2 ON t1(b);

  CREATE VIEW v1 AS SELECT a, c, max(c) OVER (PARTITION BY a) FROM t1;

  CREATE VIEW v2 AS SELECT a, c, 
      max(c) OVER (PARTITION BY a),
      row_number() OVER ()
  FROM t1;

  CREATE VIEW v3 AS SELECT b, d, 
      max(d) OVER (PARTITION BY b),
      row_number() OVER (PARTITION BY b)
  FROM t1;

  CREATE TABLE t2(x, y, z);
  INSERT INTO t2 VALUES('W', 3, 1);
  INSERT INTO t2 VALUES('W', 2, 2);
  INSERT INTO t2 VALUES('X', 1, 4);
  INSERT INTO t2 VALUES('X', 5, 7);
  INSERT INTO t2 VALUES('Y', 1, 9);
  INSERT INTO t2 VALUES('Y', 4, 2);
  INSERT INTO t2 VALUES('Z', 3, 3);
  INSERT INTO t2 VALUES('Z', 3, 4);
}

foreach tn {0 1} {
  optimization_control db push-down $tn

  do_execsql_test 2.$tn.1.1 {
    SELECT * FROM v1;
  } {
    A 1 4   A 2 4   A 3 4   A 4 4
    B 5 8   B 6 8   B 7 8   B 8 8
    C 9 12  C 10 12 C 11 12 C 12 12
  }

  do_execsql_test 2.$tn.1.2 {
    SELECT * FROM v1 WHERE a IN ('A', 'B');
  } {
    A 1 4   A 2 4   A 3 4   A 4 4
    B 5 8   B 6 8   B 7 8   B 8 8
  }

  do_execsql_test 2.$tn.1.3 {
    SELECT * FROM v1 WHERE a IS 'C'
  } {
    C 9 12  C 10 12 C 11 12 C 12 12
  }

  if {$tn==1} {
    do_eqp_test 2.$tn.1.4 {
      SELECT * FROM v1 WHERE a IN ('A', 'B');
    } {USING INDEX i1 (a=?)}

    do_eqp_test 2.$tn.1.5 {
      SELECT * FROM v1 WHERE a = 'c' COLLATE nocase
    } {USING INDEX i1}
  }

  do_execsql_test 2.$tn.2.1 {
    SELECT * FROM v2;
  } {
    A 1 4 1    A 2 4 2     A 3 4 3      A 4 4 4
    B 5 8 5    B 6 8 6     B 7 8 7      B 8 8 8
    C 9 12 9   C 10 12 10  C 11 12 11   C 12 12 12
  }

  do_execsql_test 2.$tn.2.2 {
    SELECT * FROM v2 WHERE a = 'C';
  } {
    C 9 12 9   C 10 12 10  C 11 12 11   C 12 12 12
  }

  do_execsql_test 2.$tn.3.1 { SELECT * FROM v3; } { 
    C 0.1 1.0 1 C 0.4 1.0 2 C 0.7 1.0 3 C 1.0 1.0 4 
    D 0.2 1.1 1 D 0.5 1.1 2 D 0.8 1.1 3 D 1.1 1.1 4 
    E 0.3 1.2 1 E 0.6 1.2 2 E 0.9 1.2 3 E 1.2 1.2 4
  }

  do_execsql_test 2.$tn.3.2 { SELECT * FROM v3 WHERE b<'E' } { 
    C 0.1 1.0 1 C 0.4 1.0 2 C 0.7 1.0 3 C 1.0 1.0 4 
    D 0.2 1.1 1 D 0.5 1.1 2 D 0.8 1.1 3 D 1.1 1.1 4 
  }

  if {$tn==1} {
    do_eqp_test 2.$tn.3.3 {
      SELECT * FROM v3 WHERE b='E'
    } {SEARCH TABLE t1 USING INDEX i2 (b=?)}
    do_eqp_test 2.$tn.3.4 {
      SELECT * FROM v3 WHERE b>'C'
    } {SEARCH TABLE t1 USING INDEX i2 (b>?)}
  }

  do_execsql_test 2.$tn.3.5 { SELECT * FROM v3 WHERE d<0.55; } { 
    C 0.1 1.0 1 C 0.4 1.0 2
    D 0.2 1.1 1 D 0.5 1.1 2
    E 0.3 1.2 1
  }
  if {$tn==1} {
    do_eqp_test 2.$tn.3.6 {
      SELECT * FROM v3 WHERE d<0.55
    } {SCAN TABLE t1 USING INDEX i2}
  }

  do_execsql_test 2.$tn.4.1 {
    SELECT * FROM (
      SELECT x, sum(y) AS s, max(z) AS m 
      FROM t2 GROUP BY x
    )
  } {
    W 5 2
    X 6 7
    Y 5 9
    Z 6 4
  }

  do_execsql_test 2.$tn.4.1 {
    SELECT * FROM (
      SELECT x, sum(y) AS s, max(z) AS m,
        max( max(z) ) OVER (PARTITION BY sum(y) 
            ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
        )
      FROM t2 GROUP BY x
    )
  } {
    W 5 2   9
    Y 5 9   9
    X 6 7   7
    Z 6 4   7
  }

  do_execsql_test 2.$tn.4.2 {
    SELECT * FROM (
      SELECT x, sum(y) AS s, max(z) AS m,
        max( max(z) ) OVER (PARTITION BY sum(y) 
            ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
        )
      FROM t2 GROUP BY x
    ) WHERE s=6
  } {
    X 6 7   7
    Z 6 4   7
  }

  do_execsql_test 2.$tn.4.3 {
    SELECT * FROM (
      SELECT x, sum(y) AS s, max(z) AS m,
        max( max(z) ) OVER (PARTITION BY sum(y) 
            ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
        )
      FROM t2 GROUP BY x
    ) WHERE s<6
  } {
    W 5 2   9
    Y 5 9   9
  }

}




finish_test

Changes to test/with3.test.
193
194
195
196
197
198
199





























200
201
      )
      SELECT t2a.b FROM t2 AS t2a JOIN t2 AS t2x
    )
    FROM t1 GROUP BY 1
  )
  GROUP BY 1;
} {elvis}






























finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


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
      )
      SELECT t2a.b FROM t2 AS t2a JOIN t2 AS t2x
    )
    FROM t1 GROUP BY 1
  )
  GROUP BY 1;
} {elvis}

# 2021-02-13
# Avoid manifesting the same CTE multiple times.
#
do_eqp_test 5.1 {
  WITH RECURSIVE c(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c WHERE x<1)
  SELECT x1.x||x2.x||x3.x||x4.x FROM c AS x1, c AS x2, c AS x3, c AS x4
  ORDER BY 1;
} {
  QUERY PLAN
  |--MATERIALIZE xxxxxx
  |  |--SETUP
  |  |  `--SCAN CONSTANT ROW
  |  `--RECURSIVE STEP
  |     `--SCAN TABLE c
  |--SCAN SUBQUERY xxxxxx AS x1
  |--SCAN SUBQUERY xxxxxx AS x2
  |--SCAN SUBQUERY xxxxxx AS x3
  |--SCAN SUBQUERY xxxxxx AS x4
  `--USE TEMP B-TREE FOR ORDER BY
}
do_execsql_test 5.2 {
  WITH RECURSIVE c(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c WHERE x<1)
  SELECT x1.x||x2.x||x3.x||x4.x FROM c AS x1, c AS x2, c AS x3, c AS x4
  ORDER BY 1;
} {0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111}




finish_test
Added test/with6.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
# 2021-02-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 implements regression tests for SQLite library.  The
# focus of this file is the MATERIALIZED hint to common table expressions
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix with6

ifcapable {!cte} {
  finish_test
  return
}

do_execsql_test 100 {
  WITH c(x) AS (VALUES(0),(1))
  SELECT c1.x||c2.x||c3.x FROM c c1, c c2, c c3;
} {000 001 010 011 100 101 110 111}
do_eqp_test 101 {
  WITH c(x) AS (VALUES(0),(1))
  SELECT c1.x||c2.x||c3.x FROM c c1, c c2, c c3;
} {
  QUERY PLAN
  |--MATERIALIZE xxxxxx
  |  `--SCAN 2 CONSTANT ROWS
  |--SCAN SUBQUERY xxxxxx AS c1
  |--SCAN SUBQUERY xxxxxx AS c2
  `--SCAN SUBQUERY xxxxxx AS c3
}

do_execsql_test 110 {
  WITH c(x) AS MATERIALIZED (VALUES(0),(1))
  SELECT c1.x||c2.x||c3.x FROM c c1, c c2, c c3;
} {000 001 010 011 100 101 110 111}
do_eqp_test 111 {
  WITH c(x) AS MATERIALIZED (VALUES(0),(1))
  SELECT c1.x||c2.x||c3.x FROM c c1, c c2, c c3;
} {
  QUERY PLAN
  |--MATERIALIZE xxxxxx
  |  `--SCAN 2 CONSTANT ROWS
  |--SCAN SUBQUERY xxxxxx AS c1
  |--SCAN SUBQUERY xxxxxx AS c2
  `--SCAN SUBQUERY xxxxxx AS c3
}

# Even though the CTE is not materialized, the self-join optimization
# kicks in and does the materialization for us.
#
do_execsql_test 120 {
  WITH c(x) AS NOT MATERIALIZED (VALUES(0),(1))
  SELECT c1.x||c2.x||c3.x FROM c c1, c c2, c c3;
} {000 001 010 011 100 101 110 111}
do_eqp_test 121 {
  WITH c(x) AS NOT MATERIALIZED (VALUES(0),(1))
  SELECT c1.x||c2.x||c3.x FROM c c1, c c2, c c3;
} {
  QUERY PLAN
  |--MATERIALIZE xxxxxx
  |  `--SCAN 2 CONSTANT ROWS
  |--SCAN SUBQUERY xxxxxx AS c1
  |--SCAN SUBQUERY xxxxxx AS c2
  `--SCAN SUBQUERY xxxxxx AS c3
}

do_execsql_test 130 {
  WITH c(x) AS NOT MATERIALIZED (VALUES(0),(1))
  SELECT c1.x||c2.x||c3.x
    FROM (SELECT x FROM c LIMIT 5) AS c1,
         (SELECT x FROM c LIMIT 5) AS c2,
         (SELECT x FROM c LIMIT 5) AS c3;
} {000 001 010 011 100 101 110 111}
do_eqp_test 131 {
  WITH c(x) AS NOT MATERIALIZED (VALUES(0),(1))
  SELECT c1.x||c2.x||c3.x
    FROM (SELECT x FROM c LIMIT 5) AS c1,
         (SELECT x FROM c LIMIT 5) AS c2,
         (SELECT x FROM c LIMIT 5) AS c3;
} {
  QUERY PLAN
  |--MATERIALIZE xxxxxx
  |  |--CO-ROUTINE xxxxxx
  |  |  `--SCAN 2 CONSTANT ROWS
  |  `--SCAN SUBQUERY xxxxxx
  |--MATERIALIZE xxxxxx
  |  |--CO-ROUTINE xxxxxx
  |  |  `--SCAN 2 CONSTANT ROWS
  |  `--SCAN SUBQUERY xxxxxx
  |--MATERIALIZE xxxxxx
  |  |--CO-ROUTINE xxxxxx
  |  |  `--SCAN 2 CONSTANT ROWS
  |  `--SCAN SUBQUERY xxxxxx
  |--SCAN SUBQUERY xxxxxx AS c1
  |--SCAN SUBQUERY xxxxxx AS c2
  `--SCAN SUBQUERY xxxxxx AS c3
}

# The (SELECT x FROM c LIMIT N) subqueries get materialized once each.
# Show multiple materializations are shown.  But there is only one
# materialization for c, shown by the "SCAN 2 CONSTANT ROWS" line.
#
do_execsql_test 140 {
  WITH c(x) AS MATERIALIZED (VALUES(0),(1))
  SELECT c1.x||c2.x||c3.x
    FROM (SELECT x FROM c LIMIT 5) AS c1,
         (SELECT x FROM c LIMIT 6) AS c2,
         (SELECT x FROM c LIMIT 7) AS c3;
} {000 001 010 011 100 101 110 111}
do_eqp_test 141 {
  WITH c(x) AS MATERIALIZED (VALUES(0),(1))
  SELECT c1.x||c2.x||c3.x
    FROM (SELECT x FROM c LIMIT 5) AS c1,
         (SELECT x FROM c LIMIT 6) AS c2,
         (SELECT x FROM c LIMIT 7) AS c3;
} {
  QUERY PLAN
  |--MATERIALIZE xxxxxx
  |  |--MATERIALIZE xxxxxx
  |  |  `--SCAN 2 CONSTANT ROWS
  |  `--SCAN SUBQUERY xxxxxx
  |--MATERIALIZE xxxxxx
  |  `--SCAN SUBQUERY xxxxxx
  |--MATERIALIZE xxxxxx
  |  `--SCAN SUBQUERY xxxxxx
  |--SCAN SUBQUERY xxxxxx AS c1
  |--SCAN SUBQUERY xxxxxx AS c2
  `--SCAN SUBQUERY xxxxxx AS c3
}

do_execsql_test 150 {
  WITH c(x) AS (VALUES(0),(1))
  SELECT c1.x||c2.x||c3.x
    FROM (SELECT x FROM c LIMIT 5) AS c1,
         (SELECT x FROM c LIMIT 6) AS c2,
         (SELECT x FROM c LIMIT 7) AS c3;
} {000 001 010 011 100 101 110 111}
do_eqp_test 151 {
  WITH c(x) AS (VALUES(0),(1))
  SELECT c1.x||c2.x||c3.x
    FROM (SELECT x FROM c LIMIT 5) AS c1,
         (SELECT x FROM c LIMIT 6) AS c2,
         (SELECT x FROM c LIMIT 7) AS c3;
} {
  QUERY PLAN
  |--MATERIALIZE xxxxxx
  |  |--MATERIALIZE xxxxxx
  |  |  `--SCAN 2 CONSTANT ROWS
  |  `--SCAN SUBQUERY xxxxxx
  |--MATERIALIZE xxxxxx
  |  `--SCAN SUBQUERY xxxxxx
  |--MATERIALIZE xxxxxx
  |  `--SCAN SUBQUERY xxxxxx
  |--SCAN SUBQUERY xxxxxx AS c1
  |--SCAN SUBQUERY xxxxxx AS c2
  `--SCAN SUBQUERY xxxxxx AS c3
}

do_execsql_test 160 {
  WITH c(x) AS (VALUES(0),(1))
  SELECT c2.x + 100*(SELECT sum(x+1) FROM c WHERE c.x<=c2.x)
    FROM c AS c2 WHERE c2.x<10;
} {100 301}
do_eqp_test 161 {
  WITH c(x) AS (VALUES(0),(1))
  SELECT c2.x + 100*(SELECT sum(x+1) FROM c WHERE c.x<=c2.x)
    FROM c AS c2 WHERE c2.x<10;
} {
  QUERY PLAN
  |--MATERIALIZE xxxxxx
  |  `--SCAN 2 CONSTANT ROWS
  |--SCAN SUBQUERY xxxxxx AS c2
  `--CORRELATED SCALAR SUBQUERY xxxxxx
     `--SCAN SUBQUERY xxxxxx
}

do_execsql_test 170 {
  WITH c(x) AS NOT MATERIALIZED (VALUES(0),(1))
  SELECT c2.x + 100*(SELECT sum(x+1) FROM c WHERE c.x<=c2.x)
    FROM c AS c2 WHERE c2.x<10;
} {100 301}
do_eqp_test 171 {
  WITH c(x) AS NOT MATERIALIZED (VALUES(0),(1))
  SELECT c2.x + 100*(SELECT sum(x+1) FROM c WHERE c.x<=c2.x)
    FROM c AS c2 WHERE c2.x<10;
} {
  QUERY PLAN
  |--CO-ROUTINE xxxxxx
  |  `--SCAN 2 CONSTANT ROWS
  |--SCAN SUBQUERY xxxxxx AS c2
  `--CORRELATED SCALAR SUBQUERY xxxxxx
     |--CO-ROUTINE xxxxxx
     |  `--SCAN 2 CONSTANT ROWS
     `--SCAN SUBQUERY xxxxxx
}


do_execsql_test 200 {
  CREATE TABLE t1(x);
  INSERT INTO t1(x) VALUES(4);
  CREATE VIEW t2(y) AS
    WITH c(z) AS (VALUES(4),(5),(6))
    SELECT c1.z+c2.z*100+t1.x*10000
      FROM t1,
           (SELECT z FROM c LIMIT 5) AS c1,
           (SELECT z FROM c LIMIT 5) AS c2;
  SELECT y FROM t2 ORDER BY y;
} {40404 40405 40406 40504 40505 40506 40604 40605 40606}
do_execsql_test 210 {
  DROP VIEW t2;
  CREATE VIEW t2(y) AS
    WITH c(z) AS NOT MATERIALIZED (VALUES(4),(5),(6))
    SELECT c1.z+c2.z*100+t1.x*10000
      FROM t1,
           (SELECT z FROM c LIMIT 5) AS c1,
           (SELECT z FROM c LIMIT 5) AS c2;
  SELECT y FROM t2 ORDER BY y;
} {40404 40405 40406 40504 40505 40506 40604 40605 40606}
do_eqp_test 211 {
  SELECT y FROM t2 ORDER BY y;
} {
  QUERY PLAN
  |--MATERIALIZE xxxxxx
  |  |--MATERIALIZE xxxxxx
  |  |  `--SCAN 3 CONSTANT ROWS
  |  `--SCAN SUBQUERY xxxxxx
  |--MATERIALIZE xxxxxx
  |  `--SCAN SUBQUERY xxxxxx
  |--SCAN SUBQUERY xxxxxx AS c1
  |--SCAN SUBQUERY xxxxxx AS c2
  |--SCAN TABLE t1
  `--USE TEMP B-TREE FOR ORDER BY
}
do_execsql_test 220 {
  DROP VIEW t2;
  CREATE VIEW t2(y) AS
    WITH c(z) AS MATERIALIZED (VALUES(4),(5),(6))
    SELECT c1.z+c2.z*100+t1.x*10000
      FROM t1,
           (SELECT z FROM c LIMIT 5) AS c1,
           (SELECT z FROM c LIMIT 5) AS c2;
  SELECT y FROM t2 ORDER BY y;
} {40404 40405 40406 40504 40505 40506 40604 40605 40606}



finish_test
Changes to tool/lemon.c.
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
  int minReduce;           /* Minimum reduce action */
  int maxAction;           /* Maximum action value of any kind */
  struct symbol **symbols; /* Sorted array of pointers to symbols */
  int errorcnt;            /* Number of errors */
  struct symbol *errsym;   /* The error symbol */
  struct symbol *wildcard; /* Token that matches anything */
  char *name;              /* Name of the generated parser */
  char *arg;               /* Declaration of the 3th argument to parser */
  char *ctx;               /* Declaration of 2nd argument to constructor */
  char *tokentype;         /* Type of terminal symbols in the parser stack */
  char *vartype;           /* The default type of non-terminal symbols */
  char *start;             /* Name of the start symbol for the grammar */
  char *stacksize;         /* Size of the parser stack */
  char *include;           /* Code to put at the start of the C file */
  char *error;             /* Code to execute when an error is seen */







|







397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
  int minReduce;           /* Minimum reduce action */
  int maxAction;           /* Maximum action value of any kind */
  struct symbol **symbols; /* Sorted array of pointers to symbols */
  int errorcnt;            /* Number of errors */
  struct symbol *errsym;   /* The error symbol */
  struct symbol *wildcard; /* Token that matches anything */
  char *name;              /* Name of the generated parser */
  char *arg;               /* Declaration of the 3rd argument to parser */
  char *ctx;               /* Declaration of 2nd argument to constructor */
  char *tokentype;         /* Type of terminal symbols in the parser stack */
  char *vartype;           /* The default type of non-terminal symbols */
  char *start;             /* Name of the start symbol for the grammar */
  char *stacksize;         /* Size of the parser stack */
  char *include;           /* Code to put at the start of the C file */
  char *error;             /* Code to execute when an error is seen */
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
  struct config *cfp;  /* For looping thru the config closure of "stp" */
  struct config *bcfp; /* For the inner loop on config closure of "stp" */
  struct config *newcfg;  /* */
  struct symbol *sp;   /* Symbol following the dot in configuration "cfp" */
  struct symbol *bsp;  /* Symbol following the dot in configuration "bcfp" */
  struct state *newstp; /* A pointer to a successor state */

  /* Each configuration becomes complete after it contibutes to a successor
  ** state.  Initially, all configurations are incomplete */
  for(cfp=stp->cfp; cfp; cfp=cfp->next) cfp->status = INCOMPLETE;

  /* Loop through all configurations of the state "stp" */
  for(cfp=stp->cfp; cfp; cfp=cfp->next){
    if( cfp->status==COMPLETE ) continue;    /* Already used by inner loop */
    if( cfp->dot>=cfp->rp->nrhs ) continue;  /* Can't shift this config */







|







1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
  struct config *cfp;  /* For looping thru the config closure of "stp" */
  struct config *bcfp; /* For the inner loop on config closure of "stp" */
  struct config *newcfg;  /* */
  struct symbol *sp;   /* Symbol following the dot in configuration "cfp" */
  struct symbol *bsp;  /* Symbol following the dot in configuration "bcfp" */
  struct state *newstp; /* A pointer to a successor state */

  /* Each configuration becomes complete after it contributes to a successor
  ** state.  Initially, all configurations are incomplete */
  for(cfp=stp->cfp; cfp; cfp=cfp->next) cfp->status = INCOMPLETE;

  /* Loop through all configurations of the state "stp" */
  for(cfp=stp->cfp; cfp; cfp=cfp->next){
    if( cfp->status==COMPLETE ) continue;    /* Already used by inner loop */
    if( cfp->dot>=cfp->rp->nrhs ) continue;  /* Can't shift this config */
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
** Inputs:
**   list:      Pointer to a singly-linked list of structures.
**   next:      Pointer to pointer to the second element of the list.
**   cmp:       A comparison function.
**
** Return Value:
**   A pointer to the head of a sorted list containing the elements
**   orginally in list.
**
** Side effects:
**   The "next" pointers for elements in list are changed.
*/
#define LISTSIZE 30
static char *msort(
  char *list,







|







1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
** Inputs:
**   list:      Pointer to a singly-linked list of structures.
**   next:      Pointer to pointer to the second element of the list.
**   cmp:       A comparison function.
**
** Return Value:
**   A pointer to the head of a sorted list containing the elements
**   originally in list.
**
** Side effects:
**   The "next" pointers for elements in list are changed.
*/
#define LISTSIZE 30
static char *msort(
  char *list,
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
    fprintf(fp,"\n");
  }
  fclose(fp);
  return;
}

/* Search for the file "name" which is in the same directory as
** the exacutable */
PRIVATE char *pathsearch(char *argv0, char *name, int modemask)
{
  const char *pathlist;
  char *pathbufptr = 0;
  char *pathbuf = 0;
  char *path,*cp;
  char c;







|







3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
    fprintf(fp,"\n");
  }
  fclose(fp);
  return;
}

/* Search for the file "name" which is in the same directory as
** the executable */
PRIVATE char *pathsearch(char *argv0, char *name, int modemask)
{
  const char *pathlist;
  char *pathbufptr = 0;
  char *pathbuf = 0;
  char *path,*cp;
  char c;
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878


  if( rp->nrhs==0 ){
    /* If there are no RHS symbols, then writing directly to the LHS is ok */
    lhsdirect = 1;
  }else if( rp->rhsalias[0]==0 ){
    /* The left-most RHS symbol has no value.  LHS direct is ok.  But
    ** we have to call the distructor on the RHS symbol first. */
    lhsdirect = 1;
    if( has_destructor(rp->rhs[0],lemp) ){
      append_str(0,0,0,0);
      append_str("  yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0,
                 rp->rhs[0]->index,1-rp->nrhs);
      rp->codePrefix = Strsafe(append_str(0,0,0,0));
      rp->noCode = 0;







|







3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878


  if( rp->nrhs==0 ){
    /* If there are no RHS symbols, then writing directly to the LHS is ok */
    lhsdirect = 1;
  }else if( rp->rhsalias[0]==0 ){
    /* The left-most RHS symbol has no value.  LHS direct is ok.  But
    ** we have to call the destructor on the RHS symbol first. */
    lhsdirect = 1;
    if( has_destructor(rp->rhs[0],lemp) ){
      append_str(0,0,0,0);
      append_str("  yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0,
                 rp->rhs[0]->index,1-rp->nrhs);
      rp->codePrefix = Strsafe(append_str(0,0,0,0));
      rp->noCode = 0;
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
  tplt_print(out,lemp,lemp->overflow,&lineno);
  tplt_xfer(lemp->name,in,out,&lineno);

  /* Generate the tables of rule information.  yyRuleInfoLhs[] and
  ** yyRuleInfoNRhs[].
  **
  ** Note: This code depends on the fact that rules are number
  ** sequentually beginning with 0.
  */
  for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){
    fprintf(out,"  %4d,  /* (%d) ", rp->lhs->index, i);
     rule_print(out, rp);
    fprintf(out," */\n"); lineno++;
  }
  tplt_xfer(lemp->name,in,out,&lineno);







|







4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
  tplt_print(out,lemp,lemp->overflow,&lineno);
  tplt_xfer(lemp->name,in,out,&lineno);

  /* Generate the tables of rule information.  yyRuleInfoLhs[] and
  ** yyRuleInfoNRhs[].
  **
  ** Note: This code depends on the fact that rules are number
  ** sequentially beginning with 0.
  */
  for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){
    fprintf(out,"  %4d,  /* (%d) ", rp->lhs->index, i);
     rule_print(out, rp);
    fprintf(out," */\n"); lineno++;
  }
  tplt_xfer(lemp->name,in,out,&lineno);
Changes to tool/lempar.c.
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
  YYACTIONTYPE yyact;             /* The next action */
  yyStackEntry *yymsp;            /* The top of the parser's stack */
  int yysize;                     /* Amount to pop the stack */
  ParseARG_FETCH
  (void)yyLookahead;
  (void)yyLookaheadToken;
  yymsp = yypParser->yytos;
  assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) );
#ifndef NDEBUG
  if( yyTraceFILE ){
    yysize = yyRuleInfoNRhs[yyruleno];
    if( yysize ){
      fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
        yyTracePrompt,
        yyruleno, yyRuleName[yyruleno],
        yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action",
        yymsp[yysize].stateno);
    }else{
      fprintf(yyTraceFILE, "%sReduce %d [%s]%s.\n",
        yyTracePrompt, yyruleno, yyRuleName[yyruleno],
        yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action");
    }
  }
#endif /* NDEBUG */

  /* Check that the stack is large enough to grow by a single entry
  ** if the RHS of the rule is empty.  This ensures that there is room
  ** enough on the stack to push the LHS value */
  if( yyRuleInfoNRhs[yyruleno]==0 ){
#ifdef YYTRACKMAXSTACKDEPTH
    if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
      yypParser->yyhwm++;
      assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack));
    }
#endif
#if YYSTACKDEPTH>0 
    if( yypParser->yytos>=yypParser->yystackEnd ){
      yyStackOverflow(yypParser);
      /* The call to yyStackOverflow() above pops the stack until it is
      ** empty, causing the main parser loop to exit.  So the return value
      ** is never used and does not matter. */
      return 0;
    }
#else
    if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){
      if( yyGrowStack(yypParser) ){
        yyStackOverflow(yypParser);
        /* The call to yyStackOverflow() above pops the stack until it is
        ** empty, causing the main parser loop to exit.  So the return value
        ** is never used and does not matter. */
        return 0;
      }
      yymsp = yypParser->yytos;
    }
#endif
  }

  switch( yyruleno ){
  /* Beginning here are the reduction cases.  A typical example
  ** follows:
  **   case 0:
  **  #line <lineno> <grammarfile>
  **     { ... }           // User supplied code







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







714
715
716
717
718
719
720

















































721
722
723
724
725
726
727
  YYACTIONTYPE yyact;             /* The next action */
  yyStackEntry *yymsp;            /* The top of the parser's stack */
  int yysize;                     /* Amount to pop the stack */
  ParseARG_FETCH
  (void)yyLookahead;
  (void)yyLookaheadToken;
  yymsp = yypParser->yytos;


















































  switch( yyruleno ){
  /* Beginning here are the reduction cases.  A typical example
  ** follows:
  **   case 0:
  **  #line <lineno> <grammarfile>
  **     { ... }           // User supplied code
921
922
923
924
925
926
927
928

929
930
931


















932

























933
934
935
936
937
938
939
940
    }else{
      fprintf(yyTraceFILE,"%sInput '%s' with pending reduce %d\n",
              yyTracePrompt,yyTokenName[yymajor],yyact-YY_MIN_REDUCE);
    }
  }
#endif

  do{

    assert( yyact==yypParser->yytos->stateno );
    yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact);
    if( yyact >= YY_MIN_REDUCE ){


















      yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor,

























                        yyminor ParseCTX_PARAM);
    }else if( yyact <= YY_MAX_SHIFTREDUCE ){
      yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor);
#ifndef YYNOERRORRECOVERY
      yypParser->yyerrcnt--;
#endif
      break;
    }else if( yyact==YY_ACCEPT_ACTION ){







|
>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







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
    }else{
      fprintf(yyTraceFILE,"%sInput '%s' with pending reduce %d\n",
              yyTracePrompt,yyTokenName[yymajor],yyact-YY_MIN_REDUCE);
    }
  }
#endif

  while(1){ /* Exit by "break" */
    assert( yypParser->yytos>=yypParser->yystack );
    assert( yyact==yypParser->yytos->stateno );
    yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact);
    if( yyact >= YY_MIN_REDUCE ){
      unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */
      assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) );
#ifndef NDEBUG
      if( yyTraceFILE ){
        int yysize = yyRuleInfoNRhs[yyruleno];
        if( yysize ){
          fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
            yyTracePrompt,
            yyruleno, yyRuleName[yyruleno],
            yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action",
            yypParser->yytos[yysize].stateno);
        }else{
          fprintf(yyTraceFILE, "%sReduce %d [%s]%s.\n",
            yyTracePrompt, yyruleno, yyRuleName[yyruleno],
            yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action");
        }
      }
#endif /* NDEBUG */

      /* Check that the stack is large enough to grow by a single entry
      ** if the RHS of the rule is empty.  This ensures that there is room
      ** enough on the stack to push the LHS value */
      if( yyRuleInfoNRhs[yyruleno]==0 ){
#ifdef YYTRACKMAXSTACKDEPTH
        if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
          yypParser->yyhwm++;
          assert( yypParser->yyhwm ==
                  (int)(yypParser->yytos - yypParser->yystack));
        }
#endif
#if YYSTACKDEPTH>0 
        if( yypParser->yytos>=yypParser->yystackEnd ){
          yyStackOverflow(yypParser);
          break;
        }
#else
        if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){
          if( yyGrowStack(yypParser) ){
            yyStackOverflow(yypParser);
            break;
          }
        }
#endif
      }
      yyact = yy_reduce(yypParser,yyruleno,yymajor,yyminor ParseCTX_PARAM);
    }else if( yyact <= YY_MAX_SHIFTREDUCE ){
      yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor);
#ifndef YYNOERRORRECOVERY
      yypParser->yyerrcnt--;
#endif
      break;
    }else if( yyact==YY_ACCEPT_ACTION ){
1039
1040
1041
1042
1043
1044
1045
1046

1047
1048
1049
1050
1051
1052
1053
#ifndef YYNOERRORRECOVERY
        yypParser->yyerrcnt = -1;
#endif
      }
      break;
#endif
    }
  }while( yypParser->yytos>yypParser->yystack );

#ifndef NDEBUG
  if( yyTraceFILE ){
    yyStackEntry *i;
    char cDiv = '[';
    fprintf(yyTraceFILE,"%sReturn. Stack=",yyTracePrompt);
    for(i=&yypParser->yystack[1]; i<=yypParser->yytos; i++){
      fprintf(yyTraceFILE,"%c%s", cDiv, yyTokenName[i->major]);







<
>







1034
1035
1036
1037
1038
1039
1040

1041
1042
1043
1044
1045
1046
1047
1048
#ifndef YYNOERRORRECOVERY
        yypParser->yyerrcnt = -1;
#endif
      }
      break;
#endif
    }

  }
#ifndef NDEBUG
  if( yyTraceFILE ){
    yyStackEntry *i;
    char cDiv = '[';
    fprintf(yyTraceFILE,"%sReturn. Stack=",yyTracePrompt);
    for(i=&yypParser->yystack[1]; i<=yypParser->yytos; i++){
      fprintf(yyTraceFILE,"%c%s", cDiv, yyTokenName[i->major]);
Changes to tool/mkkeywordhash.c.
151
152
153
154
155
156
157
158
159
160
161






162
163
164
165
166
167
168
#endif
#ifdef SQLITE_OMIT_WINDOWFUNC
#  define WINDOWFUNC 0
#else
#  define WINDOWFUNC 0x00100000
#endif
#ifdef SQLITE_OMIT_GENERATED_COLUMNS
#  define GENCOL 0
#else
#  define GENCOL 0x00200000
#endif







/*
** These are the keywords
*/
static Keyword aKeywordTable[] = {
  { "ABORT",            "TK_ABORT",        CONFLICT|TRIGGER, 0      },
  { "ACTION",           "TK_ACTION",       FKEY,             0      },







|

|

>
>
>
>
>
>







151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#endif
#ifdef SQLITE_OMIT_WINDOWFUNC
#  define WINDOWFUNC 0
#else
#  define WINDOWFUNC 0x00100000
#endif
#ifdef SQLITE_OMIT_GENERATED_COLUMNS
#  define GENCOL     0
#else
#  define GENCOL     0x00200000
#endif
#ifdef SQLITE_OMIT_RETURNING
#  define RETURNING  0
#else
#  define RETURNING  0x00400000
#endif


/*
** These are the keywords
*/
static Keyword aKeywordTable[] = {
  { "ABORT",            "TK_ABORT",        CONFLICT|TRIGGER, 0      },
  { "ACTION",           "TK_ACTION",       FKEY,             0      },
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
  { "FILTER",           "TK_FILTER",       WINDOWFUNC,       4      },
  { "FIRST",            "TK_FIRST",        ALWAYS,           4      },
  { "FOLLOWING",        "TK_FOLLOWING",    WINDOWFUNC,       4      },
  { "FOR",              "TK_FOR",          TRIGGER,          2      },
  { "FOREIGN",          "TK_FOREIGN",      FKEY,             1      },
  { "FROM",             "TK_FROM",         ALWAYS,           10     },
  { "FULL",             "TK_JOIN_KW",      ALWAYS,           3      },
  { "GENERATED",        "TK_GENERATED",    GENCOL,           1      },
  { "GLOB",             "TK_LIKE_KW",      ALWAYS,           3      },
  { "GROUP",            "TK_GROUP",        ALWAYS,           5      },
  { "GROUPS",           "TK_GROUPS",       WINDOWFUNC,       2      },
  { "HAVING",           "TK_HAVING",       ALWAYS,           5      },
  { "IF",               "TK_IF",           ALWAYS,           2      },
  { "IGNORE",           "TK_IGNORE",       CONFLICT|TRIGGER, 1      },
  { "IMMEDIATE",        "TK_IMMEDIATE",    ALWAYS,           1      },







|







225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
  { "FILTER",           "TK_FILTER",       WINDOWFUNC,       4      },
  { "FIRST",            "TK_FIRST",        ALWAYS,           4      },
  { "FOLLOWING",        "TK_FOLLOWING",    WINDOWFUNC,       4      },
  { "FOR",              "TK_FOR",          TRIGGER,          2      },
  { "FOREIGN",          "TK_FOREIGN",      FKEY,             1      },
  { "FROM",             "TK_FROM",         ALWAYS,           10     },
  { "FULL",             "TK_JOIN_KW",      ALWAYS,           3      },
  { "GENERATED",        "TK_GENERATED",    ALWAYS,           1      },
  { "GLOB",             "TK_LIKE_KW",      ALWAYS,           3      },
  { "GROUP",            "TK_GROUP",        ALWAYS,           5      },
  { "GROUPS",           "TK_GROUPS",       WINDOWFUNC,       2      },
  { "HAVING",           "TK_HAVING",       ALWAYS,           5      },
  { "IF",               "TK_IF",           ALWAYS,           2      },
  { "IGNORE",           "TK_IGNORE",       CONFLICT|TRIGGER, 1      },
  { "IMMEDIATE",        "TK_IMMEDIATE",    ALWAYS,           1      },
245
246
247
248
249
250
251

252
253
254
255
256
257
258
  { "JOIN",             "TK_JOIN",         ALWAYS,           5      },
  { "KEY",              "TK_KEY",          ALWAYS,           1      },
  { "LAST",             "TK_LAST",         ALWAYS,           4      },
  { "LEFT",             "TK_JOIN_KW",      ALWAYS,           5      },
  { "LIKE",             "TK_LIKE_KW",      ALWAYS,           5      },
  { "LIMIT",            "TK_LIMIT",        ALWAYS,           3      },
  { "MATCH",            "TK_MATCH",        ALWAYS,           2      },

  { "NATURAL",          "TK_JOIN_KW",      ALWAYS,           3      },
  { "NO",               "TK_NO",           FKEY|WINDOWFUNC,  2      },
  { "NOT",              "TK_NOT",          ALWAYS,           10     },
  { "NOTHING",          "TK_NOTHING",      UPSERT,           1      },
  { "NOTNULL",          "TK_NOTNULL",      ALWAYS,           3      },
  { "NULL",             "TK_NULL",         ALWAYS,           10     },
  { "NULLS",            "TK_NULLS",        ALWAYS,           3      },







>







251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
  { "JOIN",             "TK_JOIN",         ALWAYS,           5      },
  { "KEY",              "TK_KEY",          ALWAYS,           1      },
  { "LAST",             "TK_LAST",         ALWAYS,           4      },
  { "LEFT",             "TK_JOIN_KW",      ALWAYS,           5      },
  { "LIKE",             "TK_LIKE_KW",      ALWAYS,           5      },
  { "LIMIT",            "TK_LIMIT",        ALWAYS,           3      },
  { "MATCH",            "TK_MATCH",        ALWAYS,           2      },
  { "MATERIALIZED",     "TK_MATERIALIZED", CTE,              12     },
  { "NATURAL",          "TK_JOIN_KW",      ALWAYS,           3      },
  { "NO",               "TK_NO",           FKEY|WINDOWFUNC,  2      },
  { "NOT",              "TK_NOT",          ALWAYS,           10     },
  { "NOTHING",          "TK_NOTHING",      UPSERT,           1      },
  { "NOTNULL",          "TK_NOTNULL",      ALWAYS,           3      },
  { "NULL",             "TK_NULL",         ALWAYS,           10     },
  { "NULLS",            "TK_NULLS",        ALWAYS,           3      },
276
277
278
279
280
281
282

283
284
285
286
287
288
289
  { "REFERENCES",       "TK_REFERENCES",   FKEY,             1      },
  { "REGEXP",           "TK_LIKE_KW",      ALWAYS,           3      },
  { "REINDEX",          "TK_REINDEX",      REINDEX,          1      },
  { "RELEASE",          "TK_RELEASE",      ALWAYS,           1      },
  { "RENAME",           "TK_RENAME",       ALTER,            1      },
  { "REPLACE",          "TK_REPLACE",      CONFLICT,         10     },
  { "RESTRICT",         "TK_RESTRICT",     FKEY,             1      },

  { "RIGHT",            "TK_JOIN_KW",      ALWAYS,           0      },
  { "ROLLBACK",         "TK_ROLLBACK",     ALWAYS,           1      },
  { "ROW",              "TK_ROW",          TRIGGER,          1      },
  { "ROWS",             "TK_ROWS",         ALWAYS,           1      },
  { "SAVEPOINT",        "TK_SAVEPOINT",    ALWAYS,           1      },
  { "SELECT",           "TK_SELECT",       ALWAYS,           10     },
  { "SET",              "TK_SET",          ALWAYS,           10     },







>







283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
  { "REFERENCES",       "TK_REFERENCES",   FKEY,             1      },
  { "REGEXP",           "TK_LIKE_KW",      ALWAYS,           3      },
  { "REINDEX",          "TK_REINDEX",      REINDEX,          1      },
  { "RELEASE",          "TK_RELEASE",      ALWAYS,           1      },
  { "RENAME",           "TK_RENAME",       ALTER,            1      },
  { "REPLACE",          "TK_REPLACE",      CONFLICT,         10     },
  { "RESTRICT",         "TK_RESTRICT",     FKEY,             1      },
  { "RETURNING",        "TK_RETURNING",    RETURNING,        10     },
  { "RIGHT",            "TK_JOIN_KW",      ALWAYS,           0      },
  { "ROLLBACK",         "TK_ROLLBACK",     ALWAYS,           1      },
  { "ROW",              "TK_ROW",          TRIGGER,          1      },
  { "ROWS",             "TK_ROWS",         ALWAYS,           1      },
  { "SAVEPOINT",        "TK_SAVEPOINT",    ALWAYS,           1      },
  { "SELECT",           "TK_SELECT",       ALWAYS,           10     },
  { "SET",              "TK_SET",          ALWAYS,           10     },
377
378
379
380
381
382
383








384
385
386
387
388
389
390
  if( aKeywordTable[i].priority >= aKeywordTable[j].priority ) return;
  aKeywordTable[i].iNext = aKeywordTable[j].iNext;
  aKeywordTable[j].iNext = i+1;
  *pFrom = j+1;
  reorder(&aKeywordTable[i].iNext);
}









/*
** This routine does the work.  The generated code is printed on standard
** output.
*/
int main(int argc, char **argv){
  int i, j, k, h;
  int bestSize, bestCount;







>
>
>
>
>
>
>
>







385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
  if( aKeywordTable[i].priority >= aKeywordTable[j].priority ) return;
  aKeywordTable[i].iNext = aKeywordTable[j].iNext;
  aKeywordTable[j].iNext = i+1;
  *pFrom = j+1;
  reorder(&aKeywordTable[i].iNext);
}

/* Parameter to the hash function
*/
#define HASH_OP ^
#define HASH_CC '^'
#define HASH_C0 4
#define HASH_C1 3
#define HASH_C2 1

/*
** This routine does the work.  The generated code is printed on standard
** output.
*/
int main(int argc, char **argv){
  int i, j, k, h;
  int bestSize, bestCount;
407
408
409
410
411
412
413
414
415

416
417
418
419
420
421
422
  /* Fill in the lengths of strings and hashes for all entries. */
  for(i=0; i<nKeyword; i++){
    Keyword *p = &aKeywordTable[i];
    p->len = (int)strlen(p->zName);
    assert( p->len<sizeof(p->zOrigName) );
    memcpy(p->zOrigName, p->zName, p->len+1);
    totalLen += p->len;
    p->hash = (charMap(p->zName[0])*4) ^
              (charMap(p->zName[p->len-1])*3) ^ (p->len*1);

    p->id = i+1;
  }

  /* Sort the table from shortest to longest keyword */
  qsort(aKeywordTable, nKeyword, sizeof(aKeywordTable[0]), keywordCompare1);

  /* Look for short keywords embedded in longer keywords */







|
|
>







423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
  /* Fill in the lengths of strings and hashes for all entries. */
  for(i=0; i<nKeyword; i++){
    Keyword *p = &aKeywordTable[i];
    p->len = (int)strlen(p->zName);
    assert( p->len<sizeof(p->zOrigName) );
    memcpy(p->zOrigName, p->zName, p->len+1);
    totalLen += p->len;
    p->hash = (charMap(p->zName[0])*HASH_C0) HASH_OP
              (charMap(p->zName[p->len-1])*HASH_C1) HASH_OP
              (p->len*HASH_C2);
    p->id = i+1;
  }

  /* Sort the table from shortest to longest keyword */
  qsort(aKeywordTable, nKeyword, sizeof(aKeywordTable[0]), keywordCompare1);

  /* Look for short keywords embedded in longer keywords */
644
645
646
647
648
649
650
651

652
653
654
655
656
657
658
659
  printf("/* Check to see if z[0..n-1] is a keyword. If it is, write the\n");
  printf("** parser symbol code for that keyword into *pType.  Always\n");
  printf("** return the integer n (the length of the token). */\n");
  printf("static int keywordCode(const char *z, int n, int *pType){\n");
  printf("  int i, j;\n");
  printf("  const char *zKW;\n");
  printf("  if( n>=2 ){\n");
  printf("    i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n) %% %d;\n",

          bestSize);
  printf("    for(i=((int)aKWHash[i])-1; i>=0; i=((int)aKWNext[i])-1){\n");
  printf("      if( aKWLen[i]!=n ) continue;\n");
  printf("      zKW = &zKWText[aKWOffset[i]];\n");
  printf("#ifdef SQLITE_ASCII\n");
  printf("      if( (z[0]&~0x20)!=zKW[0] ) continue;\n");
  printf("      if( (z[1]&~0x20)!=zKW[1] ) continue;\n");
  printf("      j = 2;\n");







|
>
|







661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
  printf("/* Check to see if z[0..n-1] is a keyword. If it is, write the\n");
  printf("** parser symbol code for that keyword into *pType.  Always\n");
  printf("** return the integer n (the length of the token). */\n");
  printf("static int keywordCode(const char *z, int n, int *pType){\n");
  printf("  int i, j;\n");
  printf("  const char *zKW;\n");
  printf("  if( n>=2 ){\n");
  printf("    i = ((charMap(z[0])*%d) %c", HASH_C0, HASH_CC);
  printf(" (charMap(z[n-1])*%d) %c", HASH_C1, HASH_CC);
  printf(" n*%d) %% %d;\n", HASH_C2, bestSize);
  printf("    for(i=((int)aKWHash[i])-1; i>=0; i=((int)aKWNext[i])-1){\n");
  printf("      if( aKWLen[i]!=n ) continue;\n");
  printf("      zKW = &zKWText[aKWOffset[i]];\n");
  printf("#ifdef SQLITE_ASCII\n");
  printf("      if( (z[0]&~0x20)!=zKW[0] ) continue;\n");
  printf("      if( (z[1]&~0x20)!=zKW[1] ) continue;\n");
  printf("      j = 2;\n");